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