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