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