Home | History | Annotate | Line # | Download | only in bfd
stabs.c revision 1.1.1.1
      1  1.1  skrll /* Stabs in sections linking support.
      2  1.1  skrll    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      3  1.1  skrll    2006, 2007 Free Software Foundation, Inc.
      4  1.1  skrll    Written by Ian Lance Taylor, Cygnus Support.
      5  1.1  skrll 
      6  1.1  skrll    This file is part of BFD, the Binary File Descriptor library.
      7  1.1  skrll 
      8  1.1  skrll    This program is free software; you can redistribute it and/or modify
      9  1.1  skrll    it under the terms of the GNU General Public License as published by
     10  1.1  skrll    the Free Software Foundation; either version 3 of the License, or
     11  1.1  skrll    (at your option) any later version.
     12  1.1  skrll 
     13  1.1  skrll    This program is distributed in the hope that it will be useful,
     14  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  skrll    GNU General Public License for more details.
     17  1.1  skrll 
     18  1.1  skrll    You should have received a copy of the GNU General Public License
     19  1.1  skrll    along with this program; if not, write to the Free Software
     20  1.1  skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21  1.1  skrll    MA 02110-1301, USA.  */
     22  1.1  skrll 
     23  1.1  skrll 
     24  1.1  skrll /* This file contains support for linking stabs in sections, as used
     25  1.1  skrll    on COFF and ELF.  */
     26  1.1  skrll 
     27  1.1  skrll #include "sysdep.h"
     28  1.1  skrll #include "bfd.h"
     29  1.1  skrll #include "libbfd.h"
     30  1.1  skrll #include "aout/stab_gnu.h"
     31  1.1  skrll #include "safe-ctype.h"
     32  1.1  skrll 
     33  1.1  skrll /* Stabs entries use a 12 byte format:
     34  1.1  skrll      4 byte string table index
     35  1.1  skrll      1 byte stab type
     36  1.1  skrll      1 byte stab other field
     37  1.1  skrll      2 byte stab desc field
     38  1.1  skrll      4 byte stab value
     39  1.1  skrll    FIXME: This will have to change for a 64 bit object format.
     40  1.1  skrll 
     41  1.1  skrll    The stabs symbols are divided into compilation units.  For the
     42  1.1  skrll    first entry in each unit, the type of 0, the value is the length of
     43  1.1  skrll    the string table for this unit, and the desc field is the number of
     44  1.1  skrll    stabs symbols for this unit.  */
     45  1.1  skrll 
     46  1.1  skrll #define STRDXOFF  0
     47  1.1  skrll #define TYPEOFF   4
     48  1.1  skrll #define OTHEROFF  5
     49  1.1  skrll #define DESCOFF   6
     50  1.1  skrll #define VALOFF    8
     51  1.1  skrll #define STABSIZE  12
     52  1.1  skrll 
     53  1.1  skrll /* A linked list of totals that we have found for a particular header
     54  1.1  skrll    file.  A total is a unique identifier for a particular BINCL...EINCL
     55  1.1  skrll    sequence of STABs that can be used to identify duplicate sequences.
     56  1.1  skrll    It consists of three fields, 'sum_chars' which is the sum of all the
     57  1.1  skrll    STABS characters; 'num_chars' which is the number of these charactes
     58  1.1  skrll    and 'symb' which is a buffer of all the symbols in the sequence.  This
     59  1.1  skrll    buffer is only checked as a last resort.  */
     60  1.1  skrll 
     61  1.1  skrll struct stab_link_includes_totals
     62  1.1  skrll {
     63  1.1  skrll   struct stab_link_includes_totals *next;
     64  1.1  skrll   bfd_vma sum_chars;  /* Accumulated sum of STABS characters.  */
     65  1.1  skrll   bfd_vma num_chars;  /* Number of STABS characters.  */
     66  1.1  skrll   const char* symb;   /* The STABS characters themselves.  */
     67  1.1  skrll };
     68  1.1  skrll 
     69  1.1  skrll /* An entry in the header file hash table.  */
     70  1.1  skrll 
     71  1.1  skrll struct stab_link_includes_entry
     72  1.1  skrll {
     73  1.1  skrll   struct bfd_hash_entry root;
     74  1.1  skrll   /* List of totals we have found for this file.  */
     75  1.1  skrll   struct stab_link_includes_totals *totals;
     76  1.1  skrll };
     77  1.1  skrll 
     78  1.1  skrll /* This structure is used to hold a list of N_BINCL symbols, some of
     79  1.1  skrll    which might be converted into N_EXCL symbols.  */
     80  1.1  skrll 
     81  1.1  skrll struct stab_excl_list
     82  1.1  skrll {
     83  1.1  skrll   /* The next symbol to convert.  */
     84  1.1  skrll   struct stab_excl_list *next;
     85  1.1  skrll   /* The offset to this symbol in the section contents.  */
     86  1.1  skrll   bfd_size_type offset;
     87  1.1  skrll   /* The value to use for the symbol.  */
     88  1.1  skrll   bfd_vma val;
     89  1.1  skrll   /* The type of this symbol (N_BINCL or N_EXCL).  */
     90  1.1  skrll   int type;
     91  1.1  skrll };
     92  1.1  skrll 
     93  1.1  skrll /* This structure is stored with each .stab section.  */
     94  1.1  skrll 
     95  1.1  skrll struct stab_section_info
     96  1.1  skrll {
     97  1.1  skrll   /* This is a linked list of N_BINCL symbols which should be
     98  1.1  skrll      converted into N_EXCL symbols.  */
     99  1.1  skrll   struct stab_excl_list *excls;
    100  1.1  skrll 
    101  1.1  skrll   /* This is used to map input stab offsets within their sections
    102  1.1  skrll      to output stab offsets, to take into account stabs that have
    103  1.1  skrll      been deleted.  If it is NULL, the output offsets are the same
    104  1.1  skrll      as the input offsets, because no stabs have been deleted from
    105  1.1  skrll      this section.  Otherwise the i'th entry is the number of
    106  1.1  skrll      bytes of stabs that have been deleted prior to the i'th
    107  1.1  skrll      stab.  */
    108  1.1  skrll   bfd_size_type *cumulative_skips;
    109  1.1  skrll 
    110  1.1  skrll   /* This is an array of string indices.  For each stab symbol, we
    111  1.1  skrll      store the string index here.  If a stab symbol should not be
    112  1.1  skrll      included in the final output, the string index is -1.  */
    113  1.1  skrll   bfd_size_type stridxs[1];
    114  1.1  skrll };
    115  1.1  skrll 
    116  1.1  skrll 
    117  1.1  skrll /* The function to create a new entry in the header file hash table.  */
    119  1.1  skrll 
    120  1.1  skrll static struct bfd_hash_entry *
    121  1.1  skrll stab_link_includes_newfunc (struct bfd_hash_entry *entry,
    122  1.1  skrll 			    struct bfd_hash_table *table,
    123  1.1  skrll 			    const char *string)
    124  1.1  skrll {
    125  1.1  skrll   struct stab_link_includes_entry *ret =
    126  1.1  skrll     (struct stab_link_includes_entry *) entry;
    127  1.1  skrll 
    128  1.1  skrll   /* Allocate the structure if it has not already been allocated by a
    129  1.1  skrll      subclass.  */
    130  1.1  skrll   if (ret == NULL)
    131  1.1  skrll     ret = bfd_hash_allocate (table,
    132  1.1  skrll 			     sizeof (struct stab_link_includes_entry));
    133  1.1  skrll   if (ret == NULL)
    134  1.1  skrll     return NULL;
    135  1.1  skrll 
    136  1.1  skrll   /* Call the allocation method of the superclass.  */
    137  1.1  skrll   ret = ((struct stab_link_includes_entry *)
    138  1.1  skrll 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
    139  1.1  skrll   if (ret)
    140  1.1  skrll     /* Set local fields.  */
    141  1.1  skrll     ret->totals = NULL;
    142  1.1  skrll 
    143  1.1  skrll   return (struct bfd_hash_entry *) ret;
    144  1.1  skrll }
    145  1.1  skrll 
    146  1.1  skrll /* This function is called for each input file from the add_symbols
    148  1.1  skrll    pass of the linker.  */
    149  1.1  skrll 
    150  1.1  skrll bfd_boolean
    151  1.1  skrll _bfd_link_section_stabs (bfd *abfd,
    152  1.1  skrll 			 struct stab_info *sinfo,
    153  1.1  skrll 			 asection *stabsec,
    154  1.1  skrll 			 asection *stabstrsec,
    155  1.1  skrll 			 void * *psecinfo,
    156  1.1  skrll 			 bfd_size_type *pstring_offset)
    157  1.1  skrll {
    158  1.1  skrll   bfd_boolean first;
    159  1.1  skrll   bfd_size_type count, amt;
    160  1.1  skrll   struct stab_section_info *secinfo;
    161  1.1  skrll   bfd_byte *stabbuf = NULL;
    162  1.1  skrll   bfd_byte *stabstrbuf = NULL;
    163  1.1  skrll   bfd_byte *sym, *symend;
    164  1.1  skrll   bfd_size_type stroff, next_stroff, skip;
    165  1.1  skrll   bfd_size_type *pstridx;
    166  1.1  skrll 
    167  1.1  skrll   if (stabsec->size == 0
    168  1.1  skrll       || stabstrsec->size == 0)
    169  1.1  skrll     /* This file does not contain stabs debugging information.  */
    170  1.1  skrll     return TRUE;
    171  1.1  skrll 
    172  1.1  skrll   if (stabsec->size % STABSIZE != 0)
    173  1.1  skrll     /* Something is wrong with the format of these stab symbols.
    174  1.1  skrll        Don't try to optimize them.  */
    175  1.1  skrll     return TRUE;
    176  1.1  skrll 
    177  1.1  skrll   if ((stabstrsec->flags & SEC_RELOC) != 0)
    178  1.1  skrll     /* We shouldn't see relocations in the strings, and we aren't
    179  1.1  skrll        prepared to handle them.  */
    180  1.1  skrll     return TRUE;
    181  1.1  skrll 
    182  1.1  skrll   if (bfd_is_abs_section (stabsec->output_section)
    183  1.1  skrll       || bfd_is_abs_section (stabstrsec->output_section))
    184  1.1  skrll     /* At least one of the sections is being discarded from the
    185  1.1  skrll        link, so we should just ignore them.  */
    186  1.1  skrll     return TRUE;
    187  1.1  skrll 
    188  1.1  skrll   first = FALSE;
    189  1.1  skrll 
    190  1.1  skrll   if (sinfo->stabstr == NULL)
    191  1.1  skrll     {
    192  1.1  skrll       flagword flags;
    193  1.1  skrll 
    194  1.1  skrll       /* Initialize the stabs information we need to keep track of.  */
    195  1.1  skrll       first = TRUE;
    196  1.1  skrll       sinfo->strings = _bfd_stringtab_init ();
    197  1.1  skrll       if (sinfo->strings == NULL)
    198  1.1  skrll 	goto error_return;
    199  1.1  skrll       /* Make sure the first byte is zero.  */
    200  1.1  skrll       (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
    201  1.1  skrll       if (! bfd_hash_table_init (&sinfo->includes,
    202  1.1  skrll 				 stab_link_includes_newfunc,
    203  1.1  skrll 				 sizeof (struct stab_link_includes_entry)))
    204  1.1  skrll 	goto error_return;
    205  1.1  skrll       flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING
    206  1.1  skrll 	       | SEC_LINKER_CREATED);
    207  1.1  skrll       sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr",
    208  1.1  skrll 							   flags);
    209  1.1  skrll       if (sinfo->stabstr == NULL)
    210  1.1  skrll 	goto error_return;
    211  1.1  skrll     }
    212  1.1  skrll 
    213  1.1  skrll   /* Initialize the information we are going to store for this .stab
    214  1.1  skrll      section.  */
    215  1.1  skrll   count = stabsec->size / STABSIZE;
    216  1.1  skrll 
    217  1.1  skrll   amt = sizeof (struct stab_section_info);
    218  1.1  skrll   amt += (count - 1) * sizeof (bfd_size_type);
    219  1.1  skrll   *psecinfo = bfd_alloc (abfd, amt);
    220  1.1  skrll   if (*psecinfo == NULL)
    221  1.1  skrll     goto error_return;
    222  1.1  skrll 
    223  1.1  skrll   secinfo = (struct stab_section_info *) *psecinfo;
    224  1.1  skrll   secinfo->excls = NULL;
    225  1.1  skrll   stabsec->rawsize = stabsec->size;
    226  1.1  skrll   secinfo->cumulative_skips = NULL;
    227  1.1  skrll   memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
    228  1.1  skrll 
    229  1.1  skrll   /* Read the stabs information from abfd.  */
    230  1.1  skrll   if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)
    231  1.1  skrll       || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf))
    232  1.1  skrll     goto error_return;
    233  1.1  skrll 
    234  1.1  skrll   /* Look through the stabs symbols, work out the new string indices,
    235  1.1  skrll      and identify N_BINCL symbols which can be eliminated.  */
    236  1.1  skrll   stroff = 0;
    237  1.1  skrll   /* The stabs sections can be split when
    238  1.1  skrll      -split-by-reloc/-split-by-file is used.  We must keep track of
    239  1.1  skrll      each stab section's place in the single concatenated string
    240  1.1  skrll      table.  */
    241  1.1  skrll   next_stroff = pstring_offset ? *pstring_offset : 0;
    242  1.1  skrll   skip = 0;
    243  1.1  skrll 
    244  1.1  skrll   symend = stabbuf + stabsec->size;
    245  1.1  skrll   for (sym = stabbuf, pstridx = secinfo->stridxs;
    246  1.1  skrll        sym < symend;
    247  1.1  skrll        sym += STABSIZE, ++pstridx)
    248  1.1  skrll     {
    249  1.1  skrll       bfd_size_type symstroff;
    250  1.1  skrll       int type;
    251  1.1  skrll       const char *string;
    252  1.1  skrll 
    253  1.1  skrll       if (*pstridx != 0)
    254  1.1  skrll 	/* This symbol has already been handled by an N_BINCL pass.  */
    255  1.1  skrll 	continue;
    256  1.1  skrll 
    257  1.1  skrll       type = sym[TYPEOFF];
    258  1.1  skrll 
    259  1.1  skrll       if (type == 0)
    260  1.1  skrll 	{
    261  1.1  skrll 	  /* Special type 0 stabs indicate the offset to the next
    262  1.1  skrll 	     string table.  We only copy the very first one.  */
    263  1.1  skrll 	  stroff = next_stroff;
    264  1.1  skrll 	  next_stroff += bfd_get_32 (abfd, sym + 8);
    265  1.1  skrll 	  if (pstring_offset)
    266  1.1  skrll 	    *pstring_offset = next_stroff;
    267  1.1  skrll 	  if (! first)
    268  1.1  skrll 	    {
    269  1.1  skrll 	      *pstridx = (bfd_size_type) -1;
    270  1.1  skrll 	      ++skip;
    271  1.1  skrll 	      continue;
    272  1.1  skrll 	    }
    273  1.1  skrll 	  first = FALSE;
    274  1.1  skrll 	}
    275  1.1  skrll 
    276  1.1  skrll       /* Store the string in the hash table, and record the index.  */
    277  1.1  skrll       symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
    278  1.1  skrll       if (symstroff >= stabstrsec->size)
    279  1.1  skrll 	{
    280  1.1  skrll 	  (*_bfd_error_handler)
    281  1.1  skrll 	    (_("%B(%A+0x%lx): Stabs entry has invalid string index."),
    282  1.1  skrll 	     abfd, stabsec, (long) (sym - stabbuf));
    283  1.1  skrll 	  bfd_set_error (bfd_error_bad_value);
    284  1.1  skrll 	  goto error_return;
    285  1.1  skrll 	}
    286  1.1  skrll       string = (char *) stabstrbuf + symstroff;
    287  1.1  skrll       *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE);
    288  1.1  skrll 
    289  1.1  skrll       /* An N_BINCL symbol indicates the start of the stabs entries
    290  1.1  skrll 	 for a header file.  We need to scan ahead to the next N_EINCL
    291  1.1  skrll 	 symbol, ignoring nesting, adding up all the characters in the
    292  1.1  skrll 	 symbol names, not including the file numbers in types (the
    293  1.1  skrll 	 first number after an open parenthesis).  */
    294  1.1  skrll       if (type == (int) N_BINCL)
    295  1.1  skrll 	{
    296  1.1  skrll 	  bfd_vma sum_chars;
    297  1.1  skrll 	  bfd_vma num_chars;
    298  1.1  skrll 	  bfd_vma buf_len = 0;
    299  1.1  skrll 	  char * symb;
    300  1.1  skrll 	  char * symb_rover;
    301  1.1  skrll 	  int nest;
    302  1.1  skrll 	  bfd_byte * incl_sym;
    303  1.1  skrll 	  struct stab_link_includes_entry * incl_entry;
    304  1.1  skrll 	  struct stab_link_includes_totals * t;
    305  1.1  skrll 	  struct stab_excl_list * ne;
    306  1.1  skrll 
    307  1.1  skrll 	  symb = symb_rover = NULL;
    308  1.1  skrll 	  sum_chars = num_chars = 0;
    309  1.1  skrll 	  nest = 0;
    310  1.1  skrll 
    311  1.1  skrll 	  for (incl_sym = sym + STABSIZE;
    312  1.1  skrll 	       incl_sym < symend;
    313  1.1  skrll 	       incl_sym += STABSIZE)
    314  1.1  skrll 	    {
    315  1.1  skrll 	      int incl_type;
    316  1.1  skrll 
    317  1.1  skrll 	      incl_type = incl_sym[TYPEOFF];
    318  1.1  skrll 	      if (incl_type == 0)
    319  1.1  skrll 		break;
    320  1.1  skrll 	      else if (incl_type == (int) N_EXCL)
    321  1.1  skrll 		continue;
    322  1.1  skrll 	      else if (incl_type == (int) N_EINCL)
    323  1.1  skrll 		{
    324  1.1  skrll 		  if (nest == 0)
    325  1.1  skrll 		    break;
    326  1.1  skrll 		  --nest;
    327  1.1  skrll 		}
    328  1.1  skrll 	      else if (incl_type == (int) N_BINCL)
    329  1.1  skrll 		++nest;
    330  1.1  skrll 	      else if (nest == 0)
    331  1.1  skrll 		{
    332  1.1  skrll 		  const char *str;
    333  1.1  skrll 
    334  1.1  skrll 		  str = ((char *) stabstrbuf
    335  1.1  skrll 			 + stroff
    336  1.1  skrll 			 + bfd_get_32 (abfd, incl_sym + STRDXOFF));
    337  1.1  skrll 		  for (; *str != '\0'; str++)
    338  1.1  skrll 		    {
    339  1.1  skrll 		      if (num_chars >= buf_len)
    340  1.1  skrll 			{
    341  1.1  skrll 			  buf_len += 32 * 1024;
    342  1.1  skrll 			  symb = bfd_realloc_or_free (symb, buf_len);
    343  1.1  skrll 			  if (symb == NULL)
    344  1.1  skrll 			    goto error_return;
    345  1.1  skrll 			  symb_rover = symb + num_chars;
    346  1.1  skrll 			}
    347  1.1  skrll 		      * symb_rover ++ = * str;
    348  1.1  skrll 		      sum_chars += *str;
    349  1.1  skrll 		      num_chars ++;
    350  1.1  skrll 		      if (*str == '(')
    351  1.1  skrll 			{
    352  1.1  skrll 			  /* Skip the file number.  */
    353  1.1  skrll 			  ++str;
    354  1.1  skrll 			  while (ISDIGIT (*str))
    355  1.1  skrll 			    ++str;
    356  1.1  skrll 			  --str;
    357  1.1  skrll 			}
    358  1.1  skrll 		    }
    359  1.1  skrll 		}
    360  1.1  skrll 	    }
    361  1.1  skrll 
    362  1.1  skrll 	  BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
    363  1.1  skrll 
    364  1.1  skrll 	  /* If we have already included a header file with the same
    365  1.1  skrll 	     value, then replaced this one with an N_EXCL symbol.  */
    366  1.1  skrll 	  incl_entry = (struct stab_link_includes_entry * )
    367  1.1  skrll 	    bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE);
    368  1.1  skrll 	  if (incl_entry == NULL)
    369  1.1  skrll 	    goto error_return;
    370  1.1  skrll 
    371  1.1  skrll 	  for (t = incl_entry->totals; t != NULL; t = t->next)
    372  1.1  skrll 	    if (t->sum_chars == sum_chars
    373  1.1  skrll 		&& t->num_chars == num_chars
    374  1.1  skrll 		&& memcmp (t->symb, symb, num_chars) == 0)
    375  1.1  skrll 	      break;
    376  1.1  skrll 
    377  1.1  skrll 	  /* Record this symbol, so that we can set the value
    378  1.1  skrll 	     correctly.  */
    379  1.1  skrll 	  amt = sizeof *ne;
    380  1.1  skrll 	  ne = bfd_alloc (abfd, amt);
    381  1.1  skrll 	  if (ne == NULL)
    382  1.1  skrll 	    goto error_return;
    383  1.1  skrll 	  ne->offset = sym - stabbuf;
    384  1.1  skrll 	  ne->val = sum_chars;
    385  1.1  skrll 	  ne->type = (int) N_BINCL;
    386  1.1  skrll 	  ne->next = secinfo->excls;
    387  1.1  skrll 	  secinfo->excls = ne;
    388  1.1  skrll 
    389  1.1  skrll 	  if (t == NULL)
    390  1.1  skrll 	    {
    391  1.1  skrll 	      /* This is the first time we have seen this header file
    392  1.1  skrll 		 with this set of stabs strings.  */
    393  1.1  skrll 	      t = bfd_hash_allocate (&sinfo->includes, sizeof *t);
    394  1.1  skrll 	      if (t == NULL)
    395  1.1  skrll 		goto error_return;
    396  1.1  skrll 	      t->sum_chars = sum_chars;
    397  1.1  skrll 	      t->num_chars = num_chars;
    398  1.1  skrll 	      t->symb = symb = bfd_realloc_or_free (symb, num_chars); /* Trim data down.  */
    399  1.1  skrll 	      t->next = incl_entry->totals;
    400  1.1  skrll 	      incl_entry->totals = t;
    401  1.1  skrll 	    }
    402  1.1  skrll 	  else
    403  1.1  skrll 	    {
    404  1.1  skrll 	      bfd_size_type *incl_pstridx;
    405  1.1  skrll 
    406  1.1  skrll 	      /* We have seen this header file before.  Tell the final
    407  1.1  skrll 		 pass to change the type to N_EXCL.  */
    408  1.1  skrll 	      ne->type = (int) N_EXCL;
    409  1.1  skrll 
    410  1.1  skrll 	      /* Free off superfluous symbols.  */
    411  1.1  skrll 	      free (symb);
    412  1.1  skrll 
    413  1.1  skrll 	      /* Mark the skipped symbols.  */
    414  1.1  skrll 
    415  1.1  skrll 	      nest = 0;
    416  1.1  skrll 	      for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
    417  1.1  skrll 		   incl_sym < symend;
    418  1.1  skrll 		   incl_sym += STABSIZE, ++incl_pstridx)
    419  1.1  skrll 		{
    420  1.1  skrll 		  int incl_type;
    421  1.1  skrll 
    422  1.1  skrll 		  incl_type = incl_sym[TYPEOFF];
    423  1.1  skrll 
    424  1.1  skrll 		  if (incl_type == (int) N_EINCL)
    425  1.1  skrll 		    {
    426  1.1  skrll 		      if (nest == 0)
    427  1.1  skrll 			{
    428  1.1  skrll 			  *incl_pstridx = (bfd_size_type) -1;
    429  1.1  skrll 			  ++skip;
    430  1.1  skrll 			  break;
    431  1.1  skrll 			}
    432  1.1  skrll 		      --nest;
    433  1.1  skrll 		    }
    434  1.1  skrll 		  else if (incl_type == (int) N_BINCL)
    435  1.1  skrll 		    ++nest;
    436  1.1  skrll 		  else if (incl_type == (int) N_EXCL)
    437  1.1  skrll 		    /* Keep existing exclusion marks.  */
    438  1.1  skrll 		    continue;
    439  1.1  skrll 		  else if (nest == 0)
    440  1.1  skrll 		    {
    441  1.1  skrll 		      *incl_pstridx = (bfd_size_type) -1;
    442  1.1  skrll 		      ++skip;
    443  1.1  skrll 		    }
    444  1.1  skrll 		}
    445  1.1  skrll 	    }
    446  1.1  skrll 	}
    447  1.1  skrll     }
    448  1.1  skrll 
    449  1.1  skrll   free (stabbuf);
    450  1.1  skrll   stabbuf = NULL;
    451  1.1  skrll   free (stabstrbuf);
    452  1.1  skrll   stabstrbuf = NULL;
    453  1.1  skrll 
    454  1.1  skrll   /* We need to set the section sizes such that the linker will
    455  1.1  skrll      compute the output section sizes correctly.  We set the .stab
    456  1.1  skrll      size to not include the entries we don't want.  We set
    457  1.1  skrll      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
    458  1.1  skrll      from the link.  We record the size of the strtab in the first
    459  1.1  skrll      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
    460  1.1  skrll      for that section.  */
    461  1.1  skrll   stabsec->size = (count - skip) * STABSIZE;
    462  1.1  skrll   if (stabsec->size == 0)
    463  1.1  skrll     stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
    464  1.1  skrll   stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP;
    465  1.1  skrll   sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings);
    466  1.1  skrll 
    467  1.1  skrll   /* Calculate the `cumulative_skips' array now that stabs have been
    468  1.1  skrll      deleted for this section.  */
    469  1.1  skrll 
    470  1.1  skrll   if (skip != 0)
    471  1.1  skrll     {
    472  1.1  skrll       bfd_size_type i, offset;
    473  1.1  skrll       bfd_size_type *pskips;
    474  1.1  skrll 
    475  1.1  skrll       amt = count * sizeof (bfd_size_type);
    476  1.1  skrll       secinfo->cumulative_skips = bfd_alloc (abfd, amt);
    477  1.1  skrll       if (secinfo->cumulative_skips == NULL)
    478  1.1  skrll 	goto error_return;
    479  1.1  skrll 
    480  1.1  skrll       pskips = secinfo->cumulative_skips;
    481  1.1  skrll       pstridx = secinfo->stridxs;
    482  1.1  skrll       offset = 0;
    483  1.1  skrll 
    484  1.1  skrll       for (i = 0; i < count; i++, pskips++, pstridx++)
    485  1.1  skrll 	{
    486  1.1  skrll 	  *pskips = offset;
    487  1.1  skrll 	  if (*pstridx == (bfd_size_type) -1)
    488  1.1  skrll 	    offset += STABSIZE;
    489  1.1  skrll 	}
    490  1.1  skrll 
    491  1.1  skrll       BFD_ASSERT (offset != 0);
    492  1.1  skrll     }
    493  1.1  skrll 
    494  1.1  skrll   return TRUE;
    495  1.1  skrll 
    496  1.1  skrll  error_return:
    497  1.1  skrll   if (stabbuf != NULL)
    498  1.1  skrll     free (stabbuf);
    499  1.1  skrll   if (stabstrbuf != NULL)
    500  1.1  skrll     free (stabstrbuf);
    501  1.1  skrll   return FALSE;
    502  1.1  skrll }
    503  1.1  skrll 
    504  1.1  skrll /* This function is called for each input file before the stab
    506  1.1  skrll    section is relocated.  It discards stab entries for discarded
    507  1.1  skrll    functions and variables.  The function returns TRUE iff
    508  1.1  skrll    any entries have been deleted.
    509  1.1  skrll */
    510  1.1  skrll 
    511  1.1  skrll bfd_boolean
    512  1.1  skrll _bfd_discard_section_stabs (bfd *abfd,
    513  1.1  skrll 			    asection *stabsec,
    514  1.1  skrll 			    void * psecinfo,
    515  1.1  skrll 			    bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
    516  1.1  skrll 			    void * cookie)
    517  1.1  skrll {
    518  1.1  skrll   bfd_size_type count, amt;
    519  1.1  skrll   struct stab_section_info *secinfo;
    520  1.1  skrll   bfd_byte *stabbuf = NULL;
    521  1.1  skrll   bfd_byte *sym, *symend;
    522  1.1  skrll   bfd_size_type skip;
    523  1.1  skrll   bfd_size_type *pstridx;
    524  1.1  skrll   int deleting;
    525  1.1  skrll 
    526  1.1  skrll   if (stabsec->size == 0)
    527  1.1  skrll     /* This file does not contain stabs debugging information.  */
    528  1.1  skrll     return FALSE;
    529  1.1  skrll 
    530  1.1  skrll   if (stabsec->size % STABSIZE != 0)
    531  1.1  skrll     /* Something is wrong with the format of these stab symbols.
    532  1.1  skrll        Don't try to optimize them.  */
    533  1.1  skrll     return FALSE;
    534  1.1  skrll 
    535  1.1  skrll   if ((stabsec->output_section != NULL
    536  1.1  skrll        && bfd_is_abs_section (stabsec->output_section)))
    537  1.1  skrll     /* At least one of the sections is being discarded from the
    538  1.1  skrll        link, so we should just ignore them.  */
    539  1.1  skrll     return FALSE;
    540  1.1  skrll 
    541  1.1  skrll   /* We should have initialized our data in _bfd_link_stab_sections.
    542  1.1  skrll      If there was some bizarre error reading the string sections, though,
    543  1.1  skrll      we might not have.  Bail rather than asserting.  */
    544  1.1  skrll   if (psecinfo == NULL)
    545  1.1  skrll     return FALSE;
    546  1.1  skrll 
    547  1.1  skrll   count = stabsec->rawsize / STABSIZE;
    548  1.1  skrll   secinfo = (struct stab_section_info *) psecinfo;
    549  1.1  skrll 
    550  1.1  skrll   /* Read the stabs information from abfd.  */
    551  1.1  skrll   if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf))
    552  1.1  skrll     goto error_return;
    553  1.1  skrll 
    554  1.1  skrll   /* Look through the stabs symbols and discard any information for
    555  1.1  skrll      discarded functions.  */
    556  1.1  skrll   skip = 0;
    557  1.1  skrll   deleting = -1;
    558  1.1  skrll 
    559  1.1  skrll   symend = stabbuf + stabsec->rawsize;
    560  1.1  skrll   for (sym = stabbuf, pstridx = secinfo->stridxs;
    561  1.1  skrll        sym < symend;
    562  1.1  skrll        sym += STABSIZE, ++pstridx)
    563  1.1  skrll     {
    564  1.1  skrll       int type;
    565  1.1  skrll 
    566  1.1  skrll       if (*pstridx == (bfd_size_type) -1)
    567  1.1  skrll 	/* This stab was deleted in a previous pass.  */
    568  1.1  skrll 	continue;
    569  1.1  skrll 
    570  1.1  skrll       type = sym[TYPEOFF];
    571  1.1  skrll 
    572  1.1  skrll       if (type == (int) N_FUN)
    573  1.1  skrll 	{
    574  1.1  skrll 	  int strx = bfd_get_32 (abfd, sym + STRDXOFF);
    575  1.1  skrll 
    576  1.1  skrll 	  if (strx == 0)
    577  1.1  skrll 	    {
    578  1.1  skrll 	      if (deleting)
    579  1.1  skrll 		{
    580  1.1  skrll 		  skip++;
    581  1.1  skrll 		  *pstridx = -1;
    582  1.1  skrll 		}
    583  1.1  skrll 	      deleting = -1;
    584  1.1  skrll 	      continue;
    585  1.1  skrll 	    }
    586  1.1  skrll 	  deleting = 0;
    587  1.1  skrll 	  if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
    588  1.1  skrll 	    deleting = 1;
    589  1.1  skrll 	}
    590  1.1  skrll 
    591  1.1  skrll       if (deleting == 1)
    592  1.1  skrll 	{
    593  1.1  skrll 	  *pstridx = -1;
    594  1.1  skrll 	  skip++;
    595  1.1  skrll 	}
    596  1.1  skrll       else if (deleting == -1)
    597  1.1  skrll 	{
    598  1.1  skrll 	  /* Outside of a function.  Check for deleted variables.  */
    599  1.1  skrll 	  if (type == (int) N_STSYM || type == (int) N_LCSYM)
    600  1.1  skrll 	    if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
    601  1.1  skrll 	      {
    602  1.1  skrll 		*pstridx = -1;
    603  1.1  skrll 		skip ++;
    604  1.1  skrll 	      }
    605  1.1  skrll 	  /* We should also check for N_GSYM entries which reference a
    606  1.1  skrll 	     deleted global, but those are less harmful to debuggers
    607  1.1  skrll 	     and would require parsing the stab strings.  */
    608  1.1  skrll 	}
    609  1.1  skrll     }
    610  1.1  skrll 
    611  1.1  skrll   free (stabbuf);
    612  1.1  skrll   stabbuf = NULL;
    613  1.1  skrll 
    614  1.1  skrll   /* Shrink the stabsec as needed.  */
    615  1.1  skrll   stabsec->size -= skip * STABSIZE;
    616  1.1  skrll   if (stabsec->size == 0)
    617  1.1  skrll     stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
    618  1.1  skrll 
    619  1.1  skrll   /* Recalculate the `cumulative_skips' array now that stabs have been
    620  1.1  skrll      deleted for this section.  */
    621  1.1  skrll 
    622  1.1  skrll   if (skip != 0)
    623  1.1  skrll     {
    624  1.1  skrll       bfd_size_type i, offset;
    625  1.1  skrll       bfd_size_type *pskips;
    626  1.1  skrll 
    627  1.1  skrll       if (secinfo->cumulative_skips == NULL)
    628  1.1  skrll 	{
    629  1.1  skrll 	  amt = count * sizeof (bfd_size_type);
    630  1.1  skrll 	  secinfo->cumulative_skips = bfd_alloc (abfd, amt);
    631  1.1  skrll 	  if (secinfo->cumulative_skips == NULL)
    632  1.1  skrll 	    goto error_return;
    633  1.1  skrll 	}
    634  1.1  skrll 
    635  1.1  skrll       pskips = secinfo->cumulative_skips;
    636  1.1  skrll       pstridx = secinfo->stridxs;
    637  1.1  skrll       offset = 0;
    638  1.1  skrll 
    639  1.1  skrll       for (i = 0; i < count; i++, pskips++, pstridx++)
    640  1.1  skrll 	{
    641  1.1  skrll 	  *pskips = offset;
    642  1.1  skrll 	  if (*pstridx == (bfd_size_type) -1)
    643  1.1  skrll 	    offset += STABSIZE;
    644  1.1  skrll 	}
    645  1.1  skrll 
    646  1.1  skrll       BFD_ASSERT (offset != 0);
    647  1.1  skrll     }
    648  1.1  skrll 
    649  1.1  skrll   return skip > 0;
    650  1.1  skrll 
    651  1.1  skrll  error_return:
    652  1.1  skrll   if (stabbuf != NULL)
    653  1.1  skrll     free (stabbuf);
    654  1.1  skrll   return FALSE;
    655  1.1  skrll }
    656  1.1  skrll 
    657  1.1  skrll /* Write out the stab section.  This is called with the relocated
    658  1.1  skrll    contents.  */
    659  1.1  skrll 
    660  1.1  skrll bfd_boolean
    661  1.1  skrll _bfd_write_section_stabs (bfd *output_bfd,
    662  1.1  skrll 			  struct stab_info *sinfo,
    663  1.1  skrll 			  asection *stabsec,
    664  1.1  skrll 			  void * *psecinfo,
    665  1.1  skrll 			  bfd_byte *contents)
    666  1.1  skrll {
    667  1.1  skrll   struct stab_section_info *secinfo;
    668  1.1  skrll   struct stab_excl_list *e;
    669  1.1  skrll   bfd_byte *sym, *tosym, *symend;
    670  1.1  skrll   bfd_size_type *pstridx;
    671  1.1  skrll 
    672  1.1  skrll   secinfo = (struct stab_section_info *) *psecinfo;
    673  1.1  skrll 
    674  1.1  skrll   if (secinfo == NULL)
    675  1.1  skrll     return bfd_set_section_contents (output_bfd, stabsec->output_section,
    676  1.1  skrll 				     contents, stabsec->output_offset,
    677  1.1  skrll 				     stabsec->size);
    678  1.1  skrll 
    679  1.1  skrll   /* Handle each N_BINCL entry.  */
    680  1.1  skrll   for (e = secinfo->excls; e != NULL; e = e->next)
    681  1.1  skrll     {
    682  1.1  skrll       bfd_byte *excl_sym;
    683  1.1  skrll 
    684  1.1  skrll       BFD_ASSERT (e->offset < stabsec->rawsize);
    685  1.1  skrll       excl_sym = contents + e->offset;
    686  1.1  skrll       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
    687  1.1  skrll       excl_sym[TYPEOFF] = e->type;
    688  1.1  skrll     }
    689  1.1  skrll 
    690  1.1  skrll   /* Copy over all the stabs symbols, omitting the ones we don't want,
    691  1.1  skrll      and correcting the string indices for those we do want.  */
    692  1.1  skrll   tosym = contents;
    693  1.1  skrll   symend = contents + stabsec->rawsize;
    694  1.1  skrll   for (sym = contents, pstridx = secinfo->stridxs;
    695  1.1  skrll        sym < symend;
    696  1.1  skrll        sym += STABSIZE, ++pstridx)
    697  1.1  skrll     {
    698  1.1  skrll       if (*pstridx != (bfd_size_type) -1)
    699  1.1  skrll 	{
    700  1.1  skrll 	  if (tosym != sym)
    701  1.1  skrll 	    memcpy (tosym, sym, STABSIZE);
    702  1.1  skrll 	  bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
    703  1.1  skrll 
    704  1.1  skrll 	  if (sym[TYPEOFF] == 0)
    705  1.1  skrll 	    {
    706  1.1  skrll 	      /* This is the header symbol for the stabs section.  We
    707  1.1  skrll 		 don't really need one, since we have merged all the
    708  1.1  skrll 		 input stabs sections into one, but we generate one
    709  1.1  skrll 		 for the benefit of readers which expect to see one.  */
    710  1.1  skrll 	      BFD_ASSERT (sym == contents);
    711  1.1  skrll 	      bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
    712  1.1  skrll 			  tosym + VALOFF);
    713  1.1  skrll 	      bfd_put_16 (output_bfd,
    714  1.1  skrll 			  stabsec->output_section->size / STABSIZE - 1,
    715  1.1  skrll 			  tosym + DESCOFF);
    716  1.1  skrll 	    }
    717  1.1  skrll 
    718  1.1  skrll 	  tosym += STABSIZE;
    719  1.1  skrll 	}
    720  1.1  skrll     }
    721  1.1  skrll 
    722  1.1  skrll   BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);
    723  1.1  skrll 
    724  1.1  skrll   return bfd_set_section_contents (output_bfd, stabsec->output_section,
    725  1.1  skrll 				   contents, (file_ptr) stabsec->output_offset,
    726  1.1  skrll 				   stabsec->size);
    727  1.1  skrll }
    728  1.1  skrll 
    729  1.1  skrll /* Write out the .stabstr section.  */
    730  1.1  skrll 
    731  1.1  skrll bfd_boolean
    732  1.1  skrll _bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo)
    733  1.1  skrll {
    734  1.1  skrll   if (bfd_is_abs_section (sinfo->stabstr->output_section))
    735  1.1  skrll     /* The section was discarded from the link.  */
    736  1.1  skrll     return TRUE;
    737  1.1  skrll 
    738  1.1  skrll   BFD_ASSERT ((sinfo->stabstr->output_offset
    739  1.1  skrll 	       + _bfd_stringtab_size (sinfo->strings))
    740  1.1  skrll 	      <= sinfo->stabstr->output_section->size);
    741  1.1  skrll 
    742  1.1  skrll   if (bfd_seek (output_bfd,
    743  1.1  skrll 		(file_ptr) (sinfo->stabstr->output_section->filepos
    744  1.1  skrll 			    + sinfo->stabstr->output_offset),
    745  1.1  skrll 		SEEK_SET) != 0)
    746  1.1  skrll     return FALSE;
    747  1.1  skrll 
    748  1.1  skrll   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
    749  1.1  skrll     return FALSE;
    750  1.1  skrll 
    751  1.1  skrll   /* We no longer need the stabs information.  */
    752  1.1  skrll   _bfd_stringtab_free (sinfo->strings);
    753  1.1  skrll   bfd_hash_table_free (&sinfo->includes);
    754  1.1  skrll 
    755  1.1  skrll   return TRUE;
    756  1.1  skrll }
    757  1.1  skrll 
    758  1.1  skrll /* Adjust an address in the .stab section.  Given OFFSET within
    759  1.1  skrll    STABSEC, this returns the new offset in the adjusted stab section,
    760  1.1  skrll    or -1 if the address refers to a stab which has been removed.  */
    761  1.1  skrll 
    762  1.1  skrll bfd_vma
    763  1.1  skrll _bfd_stab_section_offset (asection *stabsec,
    764  1.1  skrll 			  void * psecinfo,
    765  1.1  skrll 			  bfd_vma offset)
    766  1.1  skrll {
    767  1.1  skrll   struct stab_section_info *secinfo;
    768  1.1  skrll 
    769  1.1  skrll   secinfo = (struct stab_section_info *) psecinfo;
    770  1.1  skrll 
    771  1.1  skrll   if (secinfo == NULL)
    772  1.1  skrll     return offset;
    773  1.1  skrll 
    774  1.1  skrll   if (offset >= stabsec->rawsize)
    775  1.1  skrll     return offset - stabsec->rawsize + stabsec->size;
    776  1.1  skrll 
    777  1.1  skrll   if (secinfo->cumulative_skips)
    778  1.1  skrll     {
    779  1.1  skrll       bfd_vma i;
    780  1.1  skrll 
    781  1.1  skrll       i = offset / STABSIZE;
    782  1.1  skrll 
    783  1.1  skrll       if (secinfo->stridxs [i] == (bfd_size_type) -1)
    784  1.1  skrll 	return (bfd_vma) -1;
    785  1.1  skrll 
    786  1.1  skrll       return offset - secinfo->cumulative_skips [i];
    787  1.1  skrll     }
    788             
    789               return offset;
    790             }
    791