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