Merge branch 'vendor/LIBRESSL'
[dragonfly.git] / contrib / binutils-2.25 / bfd / stabs.c
1 /* Stabs in sections linking support.
2    Copyright (C) 1996-2014 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 \f
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 \f
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 \f
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 }