Merge from vendor branch OPENSSH:
[dragonfly.git] / contrib / binutils-2.15 / 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->_raw_size == 0
198       || stabstrsec->_raw_size == 0)
199     {
200       /* This file does not contain stabs debugging information.  */
201       return TRUE;
202     }
203
204   if (stabsec->_raw_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->_raw_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   secinfo->cumulative_skips = NULL;
268   memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
269
270   /* Read the stabs information from abfd.  */
271
272   stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
273   stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
274   if (stabbuf == NULL || stabstrbuf == NULL)
275     goto error_return;
276
277   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
278                                   stabsec->_raw_size)
279       || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, (bfd_vma) 0,
280                                      stabstrsec->_raw_size))
281     goto error_return;
282
283   /* Look through the stabs symbols, work out the new string indices,
284      and identify N_BINCL symbols which can be eliminated.  */
285
286   stroff = 0;
287   /* The stabs sections can be split when
288      -split-by-reloc/-split-by-file is used.  We must keep track of
289      each stab section's place in the single concatenated string
290      table.  */
291   next_stroff = pstring_offset ? *pstring_offset : 0;
292   skip = 0;
293
294   symend = stabbuf + stabsec->_raw_size;
295   for (sym = stabbuf, pstridx = secinfo->stridxs;
296        sym < symend;
297        sym += STABSIZE, ++pstridx)
298     {
299       bfd_size_type symstroff;
300       int type;
301       const char *string;
302
303       if (*pstridx != 0)
304         {
305           /* This symbol has already been handled by an N_BINCL pass.  */
306           continue;
307         }
308
309       type = sym[TYPEOFF];
310
311       if (type == 0)
312         {
313           /* Special type 0 stabs indicate the offset to the next
314              string table.  We only copy the very first one.  */
315           stroff = next_stroff;
316           next_stroff += bfd_get_32 (abfd, sym + 8);
317           if (pstring_offset)
318             *pstring_offset = next_stroff;
319           if (! first)
320             {
321               *pstridx = (bfd_size_type) -1;
322               ++skip;
323               continue;
324             }
325           first = FALSE;
326         }
327
328       /* Store the string in the hash table, and record the index.  */
329       symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
330       if (symstroff >= stabstrsec->_raw_size)
331         {
332           (*_bfd_error_handler)
333             (_("%s(%s+0x%lx): Stabs entry has invalid string index."),
334              bfd_archive_filename (abfd),
335              bfd_get_section_name (abfd, stabsec),
336              (long) (sym - stabbuf));
337           bfd_set_error (bfd_error_bad_value);
338           goto error_return;
339         }
340       string = (char *) stabstrbuf + symstroff;
341       *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE);
342
343       /* An N_BINCL symbol indicates the start of the stabs entries
344          for a header file.  We need to scan ahead to the next N_EINCL
345          symbol, ignoring nesting, adding up all the characters in the
346          symbol names, not including the file numbers in types (the
347          first number after an open parenthesis).  */
348       if (type == (int) N_BINCL)
349         {
350           bfd_vma sum_chars;
351           bfd_vma num_chars;
352           bfd_vma buf_len = 0;
353           char * symb;
354           char * symb_rover;
355           int nest;
356           bfd_byte * incl_sym;
357           struct stab_link_includes_entry * incl_entry;
358           struct stab_link_includes_totals * t;
359           struct stab_excl_list * ne;
360
361           symb = symb_rover = NULL;
362           sum_chars = num_chars = 0;
363           nest = 0;
364
365           for (incl_sym = sym + STABSIZE;
366                incl_sym < symend;
367                incl_sym += STABSIZE)
368             {
369               int incl_type;
370
371               incl_type = incl_sym[TYPEOFF];
372               if (incl_type == 0)
373                 break;
374               else if (incl_type == (int) N_EXCL)
375                 continue;
376               else if (incl_type == (int) N_EINCL)
377                 {
378                   if (nest == 0)
379                     break;
380                   --nest;
381                 }
382               else if (incl_type == (int) N_BINCL)
383                 ++nest;
384               else if (nest == 0)
385                 {
386                   const char *str;
387
388                   str = ((char *) stabstrbuf
389                          + stroff
390                          + bfd_get_32 (abfd, incl_sym + STRDXOFF));
391                   for (; *str != '\0'; str++)
392                     {
393                       if (num_chars >= buf_len)
394                         {
395                           buf_len += 32 * 1024;
396                           symb = bfd_realloc (symb, buf_len);
397                           if (symb == NULL)
398                             goto error_return;
399                           symb_rover = symb + num_chars;
400                         }
401                       * symb_rover ++ = * str;
402                       sum_chars += *str;
403                       num_chars ++;
404                       if (*str == '(')
405                         {
406                           /* Skip the file number.  */
407                           ++str;
408                           while (ISDIGIT (*str))
409                             ++str;
410                           --str;
411                         }
412                     }
413                 }
414             }
415
416           BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
417
418           /* If we have already included a header file with the same
419              value, then replaced this one with an N_EXCL symbol.  */
420           incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
421                                                   TRUE, TRUE);
422           if (incl_entry == NULL)
423             goto error_return;
424
425           for (t = incl_entry->totals; t != NULL; t = t->next)
426             if (t->sum_chars == sum_chars
427                 && t->num_chars == num_chars
428                 && memcmp (t->symb, symb, num_chars) == 0)
429               break;
430
431           /* Record this symbol, so that we can set the value
432              correctly.  */
433           amt = sizeof *ne;
434           ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
435           if (ne == NULL)
436             goto error_return;
437           ne->offset = sym - stabbuf;
438           ne->val = sum_chars;
439           ne->type = (int) N_BINCL;
440           ne->next = secinfo->excls;
441           secinfo->excls = ne;
442
443           if (t == NULL)
444             {
445               /* This is the first time we have seen this header file
446                  with this set of stabs strings.  */
447               t = ((struct stab_link_includes_totals *)
448                    bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
449               if (t == NULL)
450                 goto error_return;
451               t->sum_chars = sum_chars;
452               t->num_chars = num_chars;
453               t->symb = bfd_realloc (symb, num_chars); /* Trim data down.  */
454               t->next = incl_entry->totals;
455               incl_entry->totals = t;
456             }
457           else
458             {
459               bfd_size_type *incl_pstridx;
460
461               /* We have seen this header file before.  Tell the final
462                  pass to change the type to N_EXCL.  */
463               ne->type = (int) N_EXCL;
464
465               /* Free off superfluous symbols.  */
466               free (symb);
467
468               /* Mark the skipped symbols.  */
469
470               nest = 0;
471               for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
472                    incl_sym < symend;
473                    incl_sym += STABSIZE, ++incl_pstridx)
474                 {
475                   int incl_type;
476
477                   incl_type = incl_sym[TYPEOFF];
478
479                   if (incl_type == (int) N_EINCL)
480                     {
481                       if (nest == 0)
482                         {
483                           *incl_pstridx = (bfd_size_type) -1;
484                           ++skip;
485                           break;
486                         }
487                       --nest;
488                     }
489                   else if (incl_type == (int) N_BINCL)
490                     ++nest;
491                   else if (incl_type == (int) N_EXCL)
492                     /* Keep existing exclusion marks.  */
493                     continue;   
494                   else if (nest == 0)
495                     {
496                       *incl_pstridx = (bfd_size_type) -1;
497                       ++skip;
498                     }
499                 }
500             }
501         }
502     }
503
504   free (stabbuf);
505   stabbuf = NULL;
506   free (stabstrbuf);
507   stabstrbuf = NULL;
508
509   /* We need to set the section sizes such that the linker will
510      compute the output section sizes correctly.  We set the .stab
511      size to not include the entries we don't want.  We set
512      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
513      from the link.  We record the size of the strtab in the first
514      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
515      for that section.  */
516   stabsec->_cooked_size = (count - skip) * STABSIZE;
517   if (stabsec->_cooked_size == 0)
518     stabsec->flags |= SEC_EXCLUDE;
519   stabstrsec->flags |= SEC_EXCLUDE;
520   sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
521
522   /* Calculate the `cumulative_skips' array now that stabs have been
523      deleted for this section.  */
524
525   if (skip != 0)
526     {
527       bfd_size_type i, offset;
528       bfd_size_type *pskips;
529
530       amt = count * sizeof (bfd_size_type);
531       secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
532       if (secinfo->cumulative_skips == NULL)
533         goto error_return;
534
535       pskips = secinfo->cumulative_skips;
536       pstridx = secinfo->stridxs;
537       offset = 0;
538
539       for (i = 0; i < count; i++, pskips++, pstridx++)
540         {
541           *pskips = offset;
542           if (*pstridx == (bfd_size_type) -1)
543             offset += STABSIZE;
544         }
545
546       BFD_ASSERT (offset != 0);
547     }
548
549   return TRUE;
550
551  error_return:
552   if (stabbuf != NULL)
553     free (stabbuf);
554   if (stabstrbuf != NULL)
555     free (stabstrbuf);
556   return FALSE;
557 }
558
559 \f
560 /* This function is called for each input file before the stab
561    section is relocated.  It discards stab entries for discarded
562    functions and variables.  The function returns TRUE iff
563    any entries have been deleted.
564 */
565
566 bfd_boolean
567 _bfd_discard_section_stabs (abfd, stabsec, psecinfo,
568                             reloc_symbol_deleted_p, cookie)
569      bfd *abfd;
570      asection *stabsec;
571      PTR psecinfo;
572      bfd_boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
573      PTR cookie;
574 {
575   bfd_size_type count, amt;
576   struct stab_section_info *secinfo;
577   bfd_byte *stabbuf = NULL;
578   bfd_byte *sym, *symend;
579   bfd_size_type skip;
580   bfd_size_type *pstridx;
581   int deleting;
582
583   if (stabsec->_raw_size == 0)
584     {
585       /* This file does not contain stabs debugging information.  */
586       return FALSE;
587     }
588
589   if (stabsec->_raw_size % STABSIZE != 0)
590     {
591       /* Something is wrong with the format of these stab symbols.
592          Don't try to optimize them.  */
593       return FALSE;
594     }
595
596   if ((stabsec->output_section != NULL
597        && bfd_is_abs_section (stabsec->output_section)))
598     {
599       /* At least one of the sections is being discarded from the
600          link, so we should just ignore them.  */
601       return FALSE;
602     }
603
604   /* We should have initialized our data in _bfd_link_stab_sections.
605      If there was some bizarre error reading the string sections, though,
606      we might not have.  Bail rather than asserting.  */
607   if (psecinfo == NULL)
608     return FALSE;
609
610   count = stabsec->_raw_size / STABSIZE;
611   secinfo = (struct stab_section_info *) psecinfo;
612
613   /* Read the stabs information from abfd.  */
614
615   stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
616   if (stabbuf == NULL)
617     goto error_return;
618
619   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
620                                   stabsec->_raw_size))
621     goto error_return;
622
623   /* Look through the stabs symbols and discard any information for
624      discarded functions.  */
625
626   skip = 0;
627   deleting = -1;
628
629   symend = stabbuf + stabsec->_raw_size;
630   for (sym = stabbuf, pstridx = secinfo->stridxs;
631        sym < symend;
632        sym += STABSIZE, ++pstridx)
633     {
634       int type;
635
636       if (*pstridx == (bfd_size_type) -1)
637         {
638           /* This stab was deleted in a previous pass.  */
639           continue;
640         }
641
642       type = sym[TYPEOFF];
643
644       if (type == (int) N_FUN)
645         {
646           int strx = bfd_get_32 (abfd, sym + STRDXOFF);
647
648           if (strx == 0)
649             {
650               if (deleting)
651                 {
652                   skip++;
653                   *pstridx = -1;
654                 }
655               deleting = -1;
656               continue;
657             }
658           deleting = 0;
659           if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
660             deleting = 1;
661         }
662
663       if (deleting == 1)
664         {
665           *pstridx = -1;
666           skip++;
667         }
668       else if (deleting == -1)
669         {
670           /* Outside of a function.  Check for deleted variables.  */
671           if (type == (int) N_STSYM || type == (int) N_LCSYM)
672             if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
673               {
674                 *pstridx = -1;
675                 skip ++;
676               }
677           /* We should also check for N_GSYM entries which reference a
678              deleted global, but those are less harmful to debuggers
679              and would require parsing the stab strings.  */
680         }
681     }
682
683   free (stabbuf);
684   stabbuf = NULL;
685
686   /* Shrink the stabsec as needed.  */
687   stabsec->_cooked_size -= skip * STABSIZE;
688   if (stabsec->_cooked_size == 0)
689     stabsec->flags |= SEC_EXCLUDE;
690
691   /* Recalculate the `cumulative_skips' array now that stabs have been
692      deleted for this section.  */
693
694   if (skip != 0)
695     {
696       bfd_size_type i, offset;
697       bfd_size_type *pskips;
698
699       if (secinfo->cumulative_skips == NULL)
700         {
701           amt = count * sizeof (bfd_size_type);
702           secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
703           if (secinfo->cumulative_skips == NULL)
704             goto error_return;
705         }
706
707       pskips = secinfo->cumulative_skips;
708       pstridx = secinfo->stridxs;
709       offset = 0;
710
711       for (i = 0; i < count; i++, pskips++, pstridx++)
712         {
713           *pskips = offset;
714           if (*pstridx == (bfd_size_type) -1)
715             offset += STABSIZE;
716         }
717
718       BFD_ASSERT (offset != 0);
719     }
720
721   return skip > 0;
722
723  error_return:
724   if (stabbuf != NULL)
725     free (stabbuf);
726   return FALSE;
727 }
728
729 /* Write out the stab section.  This is called with the relocated
730    contents.  */
731
732 bfd_boolean
733 _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
734      bfd *output_bfd;
735      PTR *psinfo;
736      asection *stabsec;
737      PTR *psecinfo;
738      bfd_byte *contents;
739 {
740   struct stab_info *sinfo;
741   struct stab_section_info *secinfo;
742   struct stab_excl_list *e;
743   bfd_byte *sym, *tosym, *symend;
744   bfd_size_type *pstridx;
745
746   sinfo = (struct stab_info *) *psinfo;
747   secinfo = (struct stab_section_info *) *psecinfo;
748
749   if (secinfo == NULL)
750     return bfd_set_section_contents (output_bfd, stabsec->output_section,
751                                      contents,
752                                      (file_ptr) stabsec->output_offset,
753                                      stabsec->_raw_size);
754
755   /* Handle each N_BINCL entry.  */
756   for (e = secinfo->excls; e != NULL; e = e->next)
757     {
758       bfd_byte *excl_sym;
759
760       BFD_ASSERT (e->offset < stabsec->_raw_size);
761       excl_sym = contents + e->offset;
762       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
763       excl_sym[TYPEOFF] = e->type;
764     }
765
766   /* Copy over all the stabs symbols, omitting the ones we don't want,
767      and correcting the string indices for those we do want.  */
768   tosym = contents;
769   symend = contents + stabsec->_raw_size;
770   for (sym = contents, pstridx = secinfo->stridxs;
771        sym < symend;
772        sym += STABSIZE, ++pstridx)
773     {
774       if (*pstridx != (bfd_size_type) -1)
775         {
776           if (tosym != sym)
777             memcpy (tosym, sym, STABSIZE);
778           bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
779
780           if (sym[TYPEOFF] == 0)
781             {
782               /* This is the header symbol for the stabs section.  We
783                  don't really need one, since we have merged all the
784                  input stabs sections into one, but we generate one
785                  for the benefit of readers which expect to see one.  */
786               BFD_ASSERT (sym == contents);
787               bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
788                           tosym + VALOFF);
789               bfd_put_16 (output_bfd,
790                           stabsec->output_section->_raw_size / STABSIZE - 1,
791                           tosym + DESCOFF);
792             }
793
794           tosym += STABSIZE;
795         }
796     }
797
798   BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
799
800   return bfd_set_section_contents (output_bfd, stabsec->output_section,
801                                    contents, (file_ptr) stabsec->output_offset,
802                                    stabsec->_cooked_size);
803 }
804
805 /* Write out the .stabstr section.  */
806
807 bfd_boolean
808 _bfd_write_stab_strings (output_bfd, psinfo)
809      bfd *output_bfd;
810      PTR *psinfo;
811 {
812   struct stab_info *sinfo;
813
814   sinfo = (struct stab_info *) *psinfo;
815
816   if (sinfo == NULL)
817     return TRUE;
818
819   if (bfd_is_abs_section (sinfo->stabstr->output_section))
820     {
821       /* The section was discarded from the link.  */
822       return TRUE;
823     }
824
825   BFD_ASSERT ((sinfo->stabstr->output_offset
826                + _bfd_stringtab_size (sinfo->strings))
827               <= sinfo->stabstr->output_section->_raw_size);
828
829   if (bfd_seek (output_bfd,
830                 (file_ptr) (sinfo->stabstr->output_section->filepos
831                             + sinfo->stabstr->output_offset),
832                 SEEK_SET) != 0)
833     return FALSE;
834
835   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
836     return FALSE;
837
838   /* We no longer need the stabs information.  */
839   _bfd_stringtab_free (sinfo->strings);
840   bfd_hash_table_free (&sinfo->includes.root);
841
842   return TRUE;
843 }
844
845 /* Adjust an address in the .stab section.  Given OFFSET within
846    STABSEC, this returns the new offset in the adjusted stab section,
847    or -1 if the address refers to a stab which has been removed.  */
848
849 bfd_vma
850 _bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
851      bfd *output_bfd ATTRIBUTE_UNUSED;
852      PTR *psinfo ATTRIBUTE_UNUSED;
853      asection *stabsec;
854      PTR *psecinfo;
855      bfd_vma offset;
856 {
857   struct stab_section_info *secinfo;
858
859   secinfo = (struct stab_section_info *) *psecinfo;
860
861   if (secinfo == NULL)
862     return offset;
863
864   if (offset >= stabsec->_raw_size)
865     return offset - (stabsec->_cooked_size - stabsec->_raw_size);
866
867   if (secinfo->cumulative_skips)
868     {
869       bfd_vma i;
870
871       i = offset / STABSIZE;
872
873       if (secinfo->stridxs [i] == (bfd_size_type) -1)
874         return (bfd_vma) -1;
875
876       return offset - secinfo->cumulative_skips [i];
877     }
878
879   return offset;
880 }