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