OSDN Git Service

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