This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / stabs.c
1 /* Stabs in sections linking support.
2    Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor, Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* This file contains support for linking stabs in sections, as used
22    on COFF and ELF.  */
23
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "libbfd.h"
27 #include "aout/stab_gnu.h"
28
29 #include <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 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   boolean first;
180   struct stab_info *sinfo;
181   bfd_size_type count;
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       *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info));
227       if (*psinfo == NULL)
228         goto error_return;
229       sinfo = (struct stab_info *) *psinfo;
230       sinfo->strings = _bfd_stringtab_init ();
231       if (sinfo->strings == NULL)
232         goto error_return;
233       if (! bfd_hash_table_init_n (&sinfo->includes.root,
234                                    stab_link_includes_newfunc,
235                                    251))
236         goto error_return;
237       sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
238       sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
239     }
240
241   sinfo = (struct stab_info *) *psinfo;
242
243   /* Initialize the information we are going to store for this .stab
244      section.  */
245
246   count = stabsec->_raw_size / STABSIZE;
247
248   *psecinfo = bfd_alloc (abfd,
249                          (sizeof (struct stab_section_info)
250                           + (count - 1) * sizeof (bfd_size_type)));
251   if (*psecinfo == NULL)
252     goto error_return;
253
254   secinfo = (struct stab_section_info *) *psecinfo;
255   secinfo->excls = NULL;
256   secinfo->cumulative_skips = NULL;
257   memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type));
258
259   /* Read the stabs information from abfd.  */
260
261   stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
262   stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
263   if (stabbuf == NULL || stabstrbuf == NULL)
264     goto error_return;
265
266   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, 0,
267                                   stabsec->_raw_size)
268       || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, 0,
269                                      stabstrsec->_raw_size))
270     goto error_return;
271
272   /* Look through the stabs symbols, work out the new string indices,
273      and identify N_BINCL symbols which can be eliminated.  */
274
275   stroff = 0;
276   next_stroff = 0;
277   skip = 0;
278
279   symend = stabbuf + stabsec->_raw_size;
280   for (sym = stabbuf, pstridx = secinfo->stridxs;
281        sym < symend;
282        sym += STABSIZE, ++pstridx)
283     {
284       int type;
285       const char *string;
286
287       if (*pstridx != 0)
288         {
289           /* This symbol has already been handled by an N_BINCL pass.  */
290           continue;
291         }
292
293       type = sym[TYPEOFF];
294
295       if (type == 0)
296         {
297           /* Special type 0 stabs indicate the offset to the next
298              string table.  We only copy the very first one.  */
299           stroff = next_stroff;
300           next_stroff += bfd_get_32 (abfd, sym + 8);
301           if (! first)
302             {
303               *pstridx = (bfd_size_type) -1;
304               ++skip;
305               continue;
306             }
307           first = false;
308         }
309
310       /* Store the string in the hash table, and record the index.  */
311       string = ((char *) stabstrbuf
312                 + stroff
313                 + bfd_get_32 (abfd, sym + STRDXOFF));
314       *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
315
316       /* An N_BINCL symbol indicates the start of the stabs entries
317          for a header file.  We need to scan ahead to the next N_EINCL
318          symbol, ignoring nesting, adding up all the characters in the
319          symbol names, not including the file numbers in types (the
320          first number after an open parenthesis).  */
321       if (type == N_BINCL)
322         {
323           bfd_vma val;
324           int nest;
325           bfd_byte *incl_sym;
326           struct stab_link_includes_entry *incl_entry;
327           struct stab_link_includes_totals *t;
328           struct stab_excl_list *ne;
329
330           val = 0;
331           nest = 0;
332           for (incl_sym = sym + STABSIZE;
333                incl_sym < symend;
334                incl_sym += STABSIZE)
335             {
336               int incl_type;
337
338               incl_type = incl_sym[TYPEOFF];
339               if (incl_type == 0)
340                 break;
341               else if (incl_type == N_EINCL)
342                 {
343                   if (nest == 0)
344                     break;
345                   --nest;
346                 }
347               else if (incl_type == N_BINCL)
348                 ++nest;
349               else if (nest == 0)
350                 {
351                   const char *str;
352
353                   str = ((char *) stabstrbuf
354                          + stroff
355                          + bfd_get_32 (abfd, incl_sym + STRDXOFF));
356                   for (; *str != '\0'; str++)
357                     {
358                       val += *str;
359                       if (*str == '(')
360                         {
361                           /* Skip the file number.  */
362                           ++str;
363                           while (isdigit ((unsigned char) *str))
364                             ++str;
365                           --str;
366                         }
367                     }
368                 }
369             }
370
371           /* If we have already included a header file with the same
372              value, then replaced this one with an N_EXCL symbol.  */
373           incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
374                                                   true, true);
375           if (incl_entry == NULL)
376             goto error_return;
377
378           for (t = incl_entry->totals; t != NULL; t = t->next)
379             if (t->total == val)
380               break;
381
382           /* Record this symbol, so that we can set the value
383              correctly.  */
384           ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne);
385           if (ne == NULL)
386             goto error_return;
387           ne->offset = sym - stabbuf;
388           ne->val = val;
389           ne->type = N_BINCL;
390           ne->next = secinfo->excls;
391           secinfo->excls = ne;
392
393           if (t == NULL)
394             {
395               /* This is the first time we have seen this header file
396                  with this set of stabs strings.  */
397               t = ((struct stab_link_includes_totals *)
398                    bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
399               if (t == NULL)
400                 goto error_return;
401               t->total = val;
402               t->next = incl_entry->totals;
403               incl_entry->totals = t;
404             }
405           else
406             {
407               bfd_size_type *incl_pstridx;
408
409               /* We have seen this header file before.  Tell the final
410                  pass to change the type to N_EXCL.  */
411               ne->type = N_EXCL;
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 == 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 == N_BINCL)
435                     ++nest;
436                   else if (nest == 0)
437                     {
438                       *incl_pstridx = (bfd_size_type) -1;
439                       ++skip;
440                     }
441                 }
442             }
443         }
444     }
445
446   free (stabbuf);
447   stabbuf = NULL;
448   free (stabstrbuf);
449   stabstrbuf = NULL;
450
451   /* We need to set the section sizes such that the linker will
452      compute the output section sizes correctly.  We set the .stab
453      size to not include the entries we don't want.  We set
454      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
455      from the link.  We record the size of the strtab in the first
456      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
457      for that section.  */
458   stabsec->_cooked_size = (count - skip) * STABSIZE;
459   if (stabsec->_cooked_size == 0)
460     stabsec->flags |= SEC_EXCLUDE;
461   stabstrsec->flags |= SEC_EXCLUDE;
462   sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
463
464   /* Calculate the `cumulative_skips' array now that stabs have been
465      deleted for this section. */
466
467   if (skip != 0)
468     {
469       bfd_size_type i, offset;
470       bfd_size_type *pskips;
471
472       secinfo->cumulative_skips =
473         (bfd_size_type *) bfd_alloc (abfd, count * sizeof (bfd_size_type));
474       if (secinfo->cumulative_skips == NULL)
475         goto error_return;
476
477       pskips = secinfo->cumulative_skips;
478       pstridx = secinfo->stridxs;
479       offset = 0;
480
481       for (i = 0; i < count; i++, pskips++, pstridx++)
482         {
483           *pskips = offset;
484           if (*pstridx == (bfd_size_type) -1)
485             offset += STABSIZE;
486         }
487
488       BFD_ASSERT (offset != 0);
489     }
490
491   return true;
492
493  error_return:
494   if (stabbuf != NULL)
495     free (stabbuf);
496   if (stabstrbuf != NULL)
497     free (stabstrbuf);
498   return false;
499 }
500
501 /* Write out the stab section.  This is called with the relocated
502    contents.  */
503
504 boolean
505 _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
506      bfd *output_bfd;
507      PTR *psinfo;
508      asection *stabsec;
509      PTR *psecinfo;
510      bfd_byte *contents;
511 {
512   struct stab_info *sinfo;
513   struct stab_section_info *secinfo;
514   struct stab_excl_list *e;
515   bfd_byte *sym, *tosym, *symend;
516   bfd_size_type *pstridx;
517
518   sinfo = (struct stab_info *) *psinfo;
519   secinfo = (struct stab_section_info *) *psecinfo;
520
521   if (secinfo == NULL)
522     return bfd_set_section_contents (output_bfd, stabsec->output_section,
523                                      contents, stabsec->output_offset,
524                                      stabsec->_raw_size);
525
526   /* Handle each N_BINCL entry.  */
527   for (e = secinfo->excls; e != NULL; e = e->next)
528     {
529       bfd_byte *excl_sym;
530
531       BFD_ASSERT (e->offset < stabsec->_raw_size);
532       excl_sym = contents + e->offset;
533       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
534       excl_sym[TYPEOFF] = e->type;
535     }
536
537   /* Copy over all the stabs symbols, omitting the ones we don't want,
538      and correcting the string indices for those we do want.  */
539   tosym = contents;
540   symend = contents + stabsec->_raw_size;
541   for (sym = contents, pstridx = secinfo->stridxs;
542        sym < symend;
543        sym += STABSIZE, ++pstridx)
544     {
545       if (*pstridx != (bfd_size_type) -1)
546         {
547           if (tosym != sym)
548             memcpy (tosym, sym, STABSIZE);
549           bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
550
551           if (sym[TYPEOFF] == 0)
552             {
553               /* This is the header symbol for the stabs section.  We
554                  don't really need one, since we have merged all the
555                  input stabs sections into one, but we generate one
556                  for the benefit of readers which expect to see one.  */
557               BFD_ASSERT (sym == contents);
558               bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
559                           tosym + VALOFF);
560               bfd_put_16 (output_bfd,
561                           stabsec->output_section->_raw_size / STABSIZE - 1,
562                           tosym + DESCOFF);
563             }
564
565           tosym += STABSIZE;
566         }
567     }
568
569   BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
570
571   return bfd_set_section_contents (output_bfd, stabsec->output_section,
572                                    contents, stabsec->output_offset,
573                                    stabsec->_cooked_size);
574 }
575
576 /* Write out the .stabstr section.  */
577
578 boolean
579 _bfd_write_stab_strings (output_bfd, psinfo)
580      bfd *output_bfd;
581      PTR *psinfo;
582 {
583   struct stab_info *sinfo;
584
585   sinfo = (struct stab_info *) *psinfo;
586
587   if (sinfo == NULL)
588     return true;
589
590   if (bfd_is_abs_section (sinfo->stabstr->output_section))
591     {
592       /* The section was discarded from the link.  */
593       return true;
594     }
595
596   BFD_ASSERT ((sinfo->stabstr->output_offset
597                + _bfd_stringtab_size (sinfo->strings))
598               <= sinfo->stabstr->output_section->_raw_size);
599
600   if (bfd_seek (output_bfd,
601                 (sinfo->stabstr->output_section->filepos
602                  + sinfo->stabstr->output_offset),
603                 SEEK_SET) != 0)
604     return false;
605
606   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
607     return false;
608
609   /* We no longer need the stabs information.  */
610   _bfd_stringtab_free (sinfo->strings);
611   bfd_hash_table_free (&sinfo->includes.root);
612
613   return true;
614 }
615
616 /* Adjust an address in the .stab section.  Given OFFSET within
617    STABSEC, this returns the new offset in the adjusted stab section,
618    or -1 if the address refers to a stab which has been removed.  */
619
620 bfd_vma
621 _bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
622      bfd *output_bfd;
623      PTR *psinfo;
624      asection *stabsec;
625      PTR *psecinfo;
626      bfd_vma offset;
627 {
628   struct stab_section_info *secinfo;
629
630   secinfo = (struct stab_section_info *) *psecinfo;
631
632   if (secinfo == NULL)
633     return offset;
634
635   if (offset >= stabsec->_raw_size)
636     return offset - (stabsec->_cooked_size - stabsec->_raw_size);
637
638   if (secinfo->cumulative_skips)
639     {
640       bfd_vma i;
641
642       i = offset / STABSIZE;
643
644       if (secinfo->stridxs [i] == (bfd_size_type) -1)
645         return (bfd_vma) -1;
646
647       return offset - secinfo->cumulative_skips [i];
648     }
649
650   return offset;
651 }