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