diff options
author | obrien <obrien@FreeBSD.org> | 2002-01-27 12:00:11 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-01-27 12:00:11 +0000 |
commit | fc89183cdc6be5afa8deb7250fd15a20832ab528 (patch) | |
tree | 5c493199a70976c54e1b9c6a7804a3de85b43e84 /contrib/binutils/bfd/stabs.c | |
parent | 94820fd8060f6f43089d1a3ddb8a482402e7e494 (diff) | |
download | FreeBSD-src-fc89183cdc6be5afa8deb7250fd15a20832ab528.zip FreeBSD-src-fc89183cdc6be5afa8deb7250fd15a20832ab528.tar.gz |
Enlist the FreeBSD-CURRENT users as testers of what is to become Binutils
version 2.12.0. These bits are taken from the FSF anoncvs repo on
27-January-2002 03:41 PST.
Diffstat (limited to 'contrib/binutils/bfd/stabs.c')
-rw-r--r-- | contrib/binutils/bfd/stabs.c | 211 |
1 files changed, 192 insertions, 19 deletions
diff --git a/contrib/binutils/bfd/stabs.c b/contrib/binutils/bfd/stabs.c index 15b1af5..bba4a6d 100644 --- a/contrib/binutils/bfd/stabs.c +++ b/contrib/binutils/bfd/stabs.c @@ -1,5 +1,6 @@ /* Stabs in sections linking support. - Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -25,8 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libbfd.h" #include "aout/stab_gnu.h" - -#include <ctype.h> +#include "safe-ctype.h" /* Stabs entries use a 12 byte format: 4 byte string table index @@ -178,7 +178,7 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) { boolean first; struct stab_info *sinfo; - bfd_size_type count; + bfd_size_type count, amt; struct stab_section_info *secinfo; bfd_byte *stabbuf = NULL; bfd_byte *stabstrbuf = NULL; @@ -223,7 +223,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) { /* Initialize the stabs information we need to keep track of. */ first = true; - *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info)); + amt = sizeof (struct stab_info); + *psinfo = (PTR) bfd_alloc (abfd, amt); if (*psinfo == NULL) goto error_return; sinfo = (struct stab_info *) *psinfo; @@ -247,16 +248,16 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) count = stabsec->_raw_size / STABSIZE; - *psecinfo = bfd_alloc (abfd, - (sizeof (struct stab_section_info) - + (count - 1) * sizeof (bfd_size_type))); + amt = sizeof (struct stab_section_info); + amt += (count - 1) * sizeof (bfd_size_type); + *psecinfo = bfd_alloc (abfd, amt); if (*psecinfo == NULL) goto error_return; secinfo = (struct stab_section_info *) *psecinfo; secinfo->excls = NULL; secinfo->cumulative_skips = NULL; - memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type)); + memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type)); /* Read the stabs information from abfd. */ @@ -265,9 +266,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) if (stabbuf == NULL || stabstrbuf == NULL) goto error_return; - if (! bfd_get_section_contents (abfd, stabsec, stabbuf, 0, + if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0, stabsec->_raw_size) - || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, 0, + || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, (bfd_vma) 0, stabstrsec->_raw_size)) goto error_return; @@ -362,7 +363,7 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) { /* Skip the file number. */ ++str; - while (isdigit ((unsigned char) *str)) + while (ISDIGIT (*str)) ++str; --str; } @@ -383,7 +384,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) /* Record this symbol, so that we can set the value correctly. */ - ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne); + amt = sizeof *ne; + ne = (struct stab_excl_list *) bfd_alloc (abfd, amt); if (ne == NULL) goto error_return; ne->offset = sym - stabbuf; @@ -471,8 +473,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) bfd_size_type i, offset; bfd_size_type *pskips; - secinfo->cumulative_skips = - (bfd_size_type *) bfd_alloc (abfd, count * sizeof (bfd_size_type)); + amt = count * sizeof (bfd_size_type); + secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); if (secinfo->cumulative_skips == NULL) goto error_return; @@ -500,6 +502,176 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) return false; } + +/* This function is called for each input file before the stab + section is relocated. It discards stab entries for discarded + functions and variables. The function returns true iff + any entries have been deleted. +*/ + +boolean +_bfd_discard_section_stabs (abfd, stabsec, psecinfo, + reloc_symbol_deleted_p, cookie) + bfd *abfd; + asection *stabsec; + PTR psecinfo; + boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR)); + PTR cookie; +{ + bfd_size_type count, amt; + struct stab_section_info *secinfo; + bfd_byte *stabbuf = NULL; + bfd_byte *sym, *symend; + bfd_size_type skip; + bfd_size_type *pstridx; + int deleting; + + if (stabsec->_raw_size == 0) + { + /* This file does not contain stabs debugging information. */ + return false; + } + + if (stabsec->_raw_size % STABSIZE != 0) + { + /* Something is wrong with the format of these stab symbols. + Don't try to optimize them. */ + return false; + } + + if ((stabsec->output_section != NULL + && bfd_is_abs_section (stabsec->output_section))) + { + /* At least one of the sections is being discarded from the + link, so we should just ignore them. */ + return false; + } + + /* We should have initialized our data in _bfd_link_stab_sections. + If there was some bizarre error reading the string sections, though, + we might not have. Bail rather than asserting. */ + if (psecinfo == NULL) + return false; + + count = stabsec->_raw_size / STABSIZE; + secinfo = (struct stab_section_info *) psecinfo; + + /* Read the stabs information from abfd. */ + + stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size); + if (stabbuf == NULL) + goto error_return; + + if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0, + stabsec->_raw_size)) + goto error_return; + + /* Look through the stabs symbols and discard any information for + discarded functions. */ + + skip = 0; + deleting = -1; + + symend = stabbuf + stabsec->_raw_size; + for (sym = stabbuf, pstridx = secinfo->stridxs; + sym < symend; + sym += STABSIZE, ++pstridx) + { + int type; + + if (*pstridx == (bfd_size_type) -1) + { + /* This stab was deleted in a previous pass. */ + continue; + } + + type = sym[TYPEOFF]; + + if (type == N_FUN) + { + int strx = bfd_get_32 (abfd, sym + STRDXOFF); + + if (strx == 0) + { + if (deleting) + { + skip++; + *pstridx = -1; + } + deleting = -1; + continue; + } + deleting = 0; + if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) + deleting = 1; + } + + if (deleting == 1) + { + *pstridx = -1; + skip++; + } + else if (deleting == -1) + { + /* Outside of a function. Check for deleted variables. */ + if (type == N_STSYM || type == N_LCSYM) + if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) + { + *pstridx = -1; + skip ++; + } + /* We should also check for N_GSYM entries which reference a + deleted global, but those are less harmful to debuggers + and would require parsing the stab strings. */ + } + } + + free (stabbuf); + stabbuf = NULL; + + /* Shrink the stabsec as needed. */ + stabsec->_cooked_size -= skip * STABSIZE; + if (stabsec->_cooked_size == 0) + stabsec->flags |= SEC_EXCLUDE; + + /* Recalculate the `cumulative_skips' array now that stabs have been + deleted for this section. */ + + if (skip != 0) + { + bfd_size_type i, offset; + bfd_size_type *pskips; + + if (secinfo->cumulative_skips == NULL) + { + amt = count * sizeof (bfd_size_type); + secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); + if (secinfo->cumulative_skips == NULL) + goto error_return; + } + + pskips = secinfo->cumulative_skips; + pstridx = secinfo->stridxs; + offset = 0; + + for (i = 0; i < count; i++, pskips++, pstridx++) + { + *pskips = offset; + if (*pstridx == (bfd_size_type) -1) + offset += STABSIZE; + } + + BFD_ASSERT (offset != 0); + } + + return (skip > 0); + + error_return: + if (stabbuf != NULL) + free (stabbuf); + return false; +} + /* Write out the stab section. This is called with the relocated contents. */ @@ -522,7 +694,8 @@ _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents) if (secinfo == NULL) return bfd_set_section_contents (output_bfd, stabsec->output_section, - contents, stabsec->output_offset, + contents, + (file_ptr) stabsec->output_offset, stabsec->_raw_size); /* Handle each N_BINCL entry. */ @@ -571,7 +744,7 @@ _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents) BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size); return bfd_set_section_contents (output_bfd, stabsec->output_section, - contents, stabsec->output_offset, + contents, (file_ptr) stabsec->output_offset, stabsec->_cooked_size); } @@ -600,8 +773,8 @@ _bfd_write_stab_strings (output_bfd, psinfo) <= sinfo->stabstr->output_section->_raw_size); if (bfd_seek (output_bfd, - (sinfo->stabstr->output_section->filepos - + sinfo->stabstr->output_offset), + (file_ptr) (sinfo->stabstr->output_section->filepos + + sinfo->stabstr->output_offset), SEEK_SET) != 0) return false; |