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