OSDN Git Service

ea7e486c14787207b99bbc68af655bdd52e41661
[pf3gnuchains/pf3gnuchains3x.git] / bfd / stabs.c
1 /* Stabs in sections linking support.
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001
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
30 #include <ctype.h>
31
32 /* Stabs entries use a 12 byte format:
33      4 byte string table index
34      1 byte stab type
35      1 byte stab other field
36      2 byte stab desc field
37      4 byte stab value
38    FIXME: This will have to change for a 64 bit object format.
39
40    The stabs symbols are divided into compilation units.  For the
41    first entry in each unit, the type of 0, the value is the length of
42    the string table for this unit, and the desc field is the number of
43    stabs symbols for this unit.  */
44
45 #define STRDXOFF (0)
46 #define TYPEOFF (4)
47 #define OTHEROFF (5)
48 #define DESCOFF (6)
49 #define VALOFF (8)
50 #define STABSIZE (12)
51
52 /* A hash table used for header files with N_BINCL entries.  */
53
54 struct stab_link_includes_table
55 {
56   struct bfd_hash_table root;
57 };
58
59 /* A linked list of totals that we have found for a particular header
60    file.  */
61
62 struct stab_link_includes_totals
63 {
64   struct stab_link_includes_totals *next;
65   bfd_vma total;
66 };
67
68 /* An entry in the header file hash table.  */
69
70 struct stab_link_includes_entry
71 {
72   struct bfd_hash_entry root;
73   /* List of totals we have found for this file.  */
74   struct stab_link_includes_totals *totals;
75 };
76
77 /* Look up an entry in an the header file hash table.  */
78
79 #define stab_link_includes_lookup(table, string, create, copy) \
80   ((struct stab_link_includes_entry *) \
81    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
82
83 /* This structure is used to hold a list of N_BINCL symbols, some of
84    which might be converted into N_EXCL symbols.  */
85
86 struct stab_excl_list
87 {
88   /* The next symbol to convert.  */
89   struct stab_excl_list *next;
90   /* The offset to this symbol in the section contents.  */
91   bfd_size_type offset;
92   /* The value to use for the symbol.  */
93   bfd_vma val;
94   /* The type of this symbol (N_BINCL or N_EXCL).  */
95   int type;
96 };
97
98 /* This structure is stored with each .stab section.  */
99
100 struct stab_section_info
101 {
102   /* This is a linked list of N_BINCL symbols which should be
103      converted into N_EXCL symbols.  */
104   struct stab_excl_list *excls;
105
106   /* This is used to map input stab offsets within their sections
107      to output stab offsets, to take into account stabs that have
108      been deleted.  If it is NULL, the output offsets are the same
109      as the input offsets, because no stabs have been deleted from
110      this section.  Otherwise the i'th entry is the number of
111      bytes of stabs that have been deleted prior to the i'th
112      stab.  */
113   bfd_size_type *cumulative_skips;
114
115   /* This is an array of string indices.  For each stab symbol, we
116      store the string index here.  If a stab symbol should not be
117      included in the final output, the string index is -1.  */
118   bfd_size_type stridxs[1];
119 };
120
121 /* This structure is used to keep track of stabs in sections
122    information while linking.  */
123
124 struct stab_info
125 {
126   /* A hash table used to hold stabs strings.  */
127   struct bfd_strtab_hash *strings;
128   /* The header file hash table.  */
129   struct stab_link_includes_table includes;
130   /* The first .stabstr section.  */
131   asection *stabstr;
132 };
133
134 static struct bfd_hash_entry *stab_link_includes_newfunc
135   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
136 \f
137 /* The function to create a new entry in the header file hash table.  */
138
139 static struct bfd_hash_entry *
140 stab_link_includes_newfunc (entry, table, string)
141      struct bfd_hash_entry *entry;
142      struct bfd_hash_table *table;
143      const char *string;
144 {
145   struct stab_link_includes_entry *ret =
146     (struct stab_link_includes_entry *) entry;
147
148   /* Allocate the structure if it has not already been allocated by a
149      subclass.  */
150   if (ret == (struct stab_link_includes_entry *) NULL)
151     ret = ((struct stab_link_includes_entry *)
152            bfd_hash_allocate (table,
153                               sizeof (struct stab_link_includes_entry)));
154   if (ret == (struct stab_link_includes_entry *) NULL)
155     return (struct bfd_hash_entry *) ret;
156
157   /* Call the allocation method of the superclass.  */
158   ret = ((struct stab_link_includes_entry *)
159          bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
160   if (ret)
161     {
162       /* Set local fields.  */
163       ret->totals = NULL;
164     }
165
166   return (struct bfd_hash_entry *) ret;
167 }
168 \f
169 /* This function is called for each input file from the add_symbols
170    pass of the linker.  */
171
172 boolean
173 _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
174      bfd *abfd;
175      PTR *psinfo;
176      asection *stabsec;
177      asection *stabstrsec;
178      PTR *psecinfo;
179 {
180   boolean first;
181   struct stab_info *sinfo;
182   bfd_size_type count, amt;
183   struct stab_section_info *secinfo;
184   bfd_byte *stabbuf = NULL;
185   bfd_byte *stabstrbuf = NULL;
186   bfd_byte *sym, *symend;
187   bfd_size_type stroff, next_stroff, skip;
188   bfd_size_type *pstridx;
189
190   if (stabsec->_raw_size == 0
191       || stabstrsec->_raw_size == 0)
192     {
193       /* This file does not contain stabs debugging information.  */
194       return true;
195     }
196
197   if (stabsec->_raw_size % STABSIZE != 0)
198     {
199       /* Something is wrong with the format of these stab symbols.
200          Don't try to optimize them.  */
201       return true;
202     }
203
204   if ((stabstrsec->flags & SEC_RELOC) != 0)
205     {
206       /* We shouldn't see relocations in the strings, and we aren't
207          prepared to handle them.  */
208       return true;
209     }
210
211   if ((stabsec->output_section != NULL
212        && bfd_is_abs_section (stabsec->output_section))
213       || (stabstrsec->output_section != NULL
214           && bfd_is_abs_section (stabstrsec->output_section)))
215     {
216       /* At least one of the sections is being discarded from the
217          link, so we should just ignore them.  */
218       return true;
219     }
220
221   first = false;
222
223   if (*psinfo == NULL)
224     {
225       /* Initialize the stabs information we need to keep track of.  */
226       first = true;
227       amt = sizeof (struct stab_info);
228       *psinfo = (PTR) bfd_alloc (abfd, amt);
229       if (*psinfo == NULL)
230         goto error_return;
231       sinfo = (struct stab_info *) *psinfo;
232       sinfo->strings = _bfd_stringtab_init ();
233       if (sinfo->strings == NULL)
234         goto error_return;
235       /* Make sure the first byte is zero.  */
236       (void) _bfd_stringtab_add (sinfo->strings, "", true, true);
237       if (! bfd_hash_table_init_n (&sinfo->includes.root,
238                                    stab_link_includes_newfunc,
239                                    251))
240         goto error_return;
241       sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
242       sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
243     }
244
245   sinfo = (struct stab_info *) *psinfo;
246
247   /* Initialize the information we are going to store for this .stab
248      section.  */
249
250   count = stabsec->_raw_size / STABSIZE;
251
252   amt = sizeof (struct stab_section_info);
253   amt += (count - 1) * sizeof (bfd_size_type);
254   *psecinfo = bfd_alloc (abfd, amt);
255   if (*psecinfo == NULL)
256     goto error_return;
257
258   secinfo = (struct stab_section_info *) *psecinfo;
259   secinfo->excls = NULL;
260   secinfo->cumulative_skips = NULL;
261   memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
262
263   /* Read the stabs information from abfd.  */
264
265   stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
266   stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
267   if (stabbuf == NULL || stabstrbuf == NULL)
268     goto error_return;
269
270   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
271                                   stabsec->_raw_size)
272       || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, (bfd_vma) 0,
273                                      stabstrsec->_raw_size))
274     goto error_return;
275
276   /* Look through the stabs symbols, work out the new string indices,
277      and identify N_BINCL symbols which can be eliminated.  */
278
279   stroff = 0;
280   next_stroff = 0;
281   skip = 0;
282
283   symend = stabbuf + stabsec->_raw_size;
284   for (sym = stabbuf, pstridx = secinfo->stridxs;
285        sym < symend;
286        sym += STABSIZE, ++pstridx)
287     {
288       int type;
289       const char *string;
290
291       if (*pstridx != 0)
292         {
293           /* This symbol has already been handled by an N_BINCL pass.  */
294           continue;
295         }
296
297       type = sym[TYPEOFF];
298
299       if (type == 0)
300         {
301           /* Special type 0 stabs indicate the offset to the next
302              string table.  We only copy the very first one.  */
303           stroff = next_stroff;
304           next_stroff += bfd_get_32 (abfd, sym + 8);
305           if (! first)
306             {
307               *pstridx = (bfd_size_type) -1;
308               ++skip;
309               continue;
310             }
311           first = false;
312         }
313
314       /* Store the string in the hash table, and record the index.  */
315       string = ((char *) stabstrbuf
316                 + stroff
317                 + bfd_get_32 (abfd, sym + STRDXOFF));
318       *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
319
320       /* An N_BINCL symbol indicates the start of the stabs entries
321          for a header file.  We need to scan ahead to the next N_EINCL
322          symbol, ignoring nesting, adding up all the characters in the
323          symbol names, not including the file numbers in types (the
324          first number after an open parenthesis).  */
325       if (type == N_BINCL)
326         {
327           bfd_vma val;
328           int nest;
329           bfd_byte *incl_sym;
330           struct stab_link_includes_entry *incl_entry;
331           struct stab_link_includes_totals *t;
332           struct stab_excl_list *ne;
333
334           val = 0;
335           nest = 0;
336           for (incl_sym = sym + STABSIZE;
337                incl_sym < symend;
338                incl_sym += STABSIZE)
339             {
340               int incl_type;
341
342               incl_type = incl_sym[TYPEOFF];
343               if (incl_type == 0)
344                 break;
345               else if (incl_type == N_EINCL)
346                 {
347                   if (nest == 0)
348                     break;
349                   --nest;
350                 }
351               else if (incl_type == N_BINCL)
352                 ++nest;
353               else if (nest == 0)
354                 {
355                   const char *str;
356
357                   str = ((char *) stabstrbuf
358                          + stroff
359                          + bfd_get_32 (abfd, incl_sym + STRDXOFF));
360                   for (; *str != '\0'; str++)
361                     {
362                       val += *str;
363                       if (*str == '(')
364                         {
365                           /* Skip the file number.  */
366                           ++str;
367                           while (isdigit ((unsigned char) *str))
368                             ++str;
369                           --str;
370                         }
371                     }
372                 }
373             }
374
375           /* If we have already included a header file with the same
376              value, then replaced this one with an N_EXCL symbol.  */
377           incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
378                                                   true, true);
379           if (incl_entry == NULL)
380             goto error_return;
381
382           for (t = incl_entry->totals; t != NULL; t = t->next)
383             if (t->total == val)
384               break;
385
386           /* Record this symbol, so that we can set the value
387              correctly.  */
388           amt = sizeof *ne;
389           ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
390           if (ne == NULL)
391             goto error_return;
392           ne->offset = sym - stabbuf;
393           ne->val = val;
394           ne->type = N_BINCL;
395           ne->next = secinfo->excls;
396           secinfo->excls = ne;
397
398           if (t == NULL)
399             {
400               /* This is the first time we have seen this header file
401                  with this set of stabs strings.  */
402               t = ((struct stab_link_includes_totals *)
403                    bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
404               if (t == NULL)
405                 goto error_return;
406               t->total = val;
407               t->next = incl_entry->totals;
408               incl_entry->totals = t;
409             }
410           else
411             {
412               bfd_size_type *incl_pstridx;
413
414               /* We have seen this header file before.  Tell the final
415                  pass to change the type to N_EXCL.  */
416               ne->type = N_EXCL;
417
418               /* Mark the skipped symbols.  */
419
420               nest = 0;
421               for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
422                    incl_sym < symend;
423                    incl_sym += STABSIZE, ++incl_pstridx)
424                 {
425                   int incl_type;
426
427                   incl_type = incl_sym[TYPEOFF];
428
429                   if (incl_type == N_EINCL)
430                     {
431                       if (nest == 0)
432                         {
433                           *incl_pstridx = (bfd_size_type) -1;
434                           ++skip;
435                           break;
436                         }
437                       --nest;
438                     }
439                   else if (incl_type == N_BINCL)
440                     ++nest;
441                   else if (nest == 0)
442                     {
443                       *incl_pstridx = (bfd_size_type) -1;
444                       ++skip;
445                     }
446                 }
447             }
448         }
449     }
450
451   free (stabbuf);
452   stabbuf = NULL;
453   free (stabstrbuf);
454   stabstrbuf = NULL;
455
456   /* We need to set the section sizes such that the linker will
457      compute the output section sizes correctly.  We set the .stab
458      size to not include the entries we don't want.  We set
459      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
460      from the link.  We record the size of the strtab in the first
461      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
462      for that section.  */
463   stabsec->_cooked_size = (count - skip) * STABSIZE;
464   if (stabsec->_cooked_size == 0)
465     stabsec->flags |= SEC_EXCLUDE;
466   stabstrsec->flags |= SEC_EXCLUDE;
467   sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
468
469   /* Calculate the `cumulative_skips' array now that stabs have been
470      deleted for this section.  */
471
472   if (skip != 0)
473     {
474       bfd_size_type i, offset;
475       bfd_size_type *pskips;
476
477       amt = count * sizeof (bfd_size_type);
478       secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
479       if (secinfo->cumulative_skips == NULL)
480         goto error_return;
481
482       pskips = secinfo->cumulative_skips;
483       pstridx = secinfo->stridxs;
484       offset = 0;
485
486       for (i = 0; i < count; i++, pskips++, pstridx++)
487         {
488           *pskips = offset;
489           if (*pstridx == (bfd_size_type) -1)
490             offset += STABSIZE;
491         }
492
493       BFD_ASSERT (offset != 0);
494     }
495
496   return true;
497
498  error_return:
499   if (stabbuf != NULL)
500     free (stabbuf);
501   if (stabstrbuf != NULL)
502     free (stabstrbuf);
503   return false;
504 }
505
506 /* Write out the stab section.  This is called with the relocated
507    contents.  */
508
509 boolean
510 _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
511      bfd *output_bfd;
512      PTR *psinfo;
513      asection *stabsec;
514      PTR *psecinfo;
515      bfd_byte *contents;
516 {
517   struct stab_info *sinfo;
518   struct stab_section_info *secinfo;
519   struct stab_excl_list *e;
520   bfd_byte *sym, *tosym, *symend;
521   bfd_size_type *pstridx;
522
523   sinfo = (struct stab_info *) *psinfo;
524   secinfo = (struct stab_section_info *) *psecinfo;
525
526   if (secinfo == NULL)
527     return bfd_set_section_contents (output_bfd, stabsec->output_section,
528                                      contents,
529                                      (file_ptr) stabsec->output_offset,
530                                      stabsec->_raw_size);
531
532   /* Handle each N_BINCL entry.  */
533   for (e = secinfo->excls; e != NULL; e = e->next)
534     {
535       bfd_byte *excl_sym;
536
537       BFD_ASSERT (e->offset < stabsec->_raw_size);
538       excl_sym = contents + e->offset;
539       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
540       excl_sym[TYPEOFF] = e->type;
541     }
542
543   /* Copy over all the stabs symbols, omitting the ones we don't want,
544      and correcting the string indices for those we do want.  */
545   tosym = contents;
546   symend = contents + stabsec->_raw_size;
547   for (sym = contents, pstridx = secinfo->stridxs;
548        sym < symend;
549        sym += STABSIZE, ++pstridx)
550     {
551       if (*pstridx != (bfd_size_type) -1)
552         {
553           if (tosym != sym)
554             memcpy (tosym, sym, STABSIZE);
555           bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
556
557           if (sym[TYPEOFF] == 0)
558             {
559               /* This is the header symbol for the stabs section.  We
560                  don't really need one, since we have merged all the
561                  input stabs sections into one, but we generate one
562                  for the benefit of readers which expect to see one.  */
563               BFD_ASSERT (sym == contents);
564               bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
565                           tosym + VALOFF);
566               bfd_put_16 (output_bfd,
567                           stabsec->output_section->_raw_size / STABSIZE - 1,
568                           tosym + DESCOFF);
569             }
570
571           tosym += STABSIZE;
572         }
573     }
574
575   BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
576
577   return bfd_set_section_contents (output_bfd, stabsec->output_section,
578                                    contents, (file_ptr) stabsec->output_offset,
579                                    stabsec->_cooked_size);
580 }
581
582 /* Write out the .stabstr section.  */
583
584 boolean
585 _bfd_write_stab_strings (output_bfd, psinfo)
586      bfd *output_bfd;
587      PTR *psinfo;
588 {
589   struct stab_info *sinfo;
590
591   sinfo = (struct stab_info *) *psinfo;
592
593   if (sinfo == NULL)
594     return true;
595
596   if (bfd_is_abs_section (sinfo->stabstr->output_section))
597     {
598       /* The section was discarded from the link.  */
599       return true;
600     }
601
602   BFD_ASSERT ((sinfo->stabstr->output_offset
603                + _bfd_stringtab_size (sinfo->strings))
604               <= sinfo->stabstr->output_section->_raw_size);
605
606   if (bfd_seek (output_bfd,
607                 (file_ptr) (sinfo->stabstr->output_section->filepos
608                             + sinfo->stabstr->output_offset),
609                 SEEK_SET) != 0)
610     return false;
611
612   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
613     return false;
614
615   /* We no longer need the stabs information.  */
616   _bfd_stringtab_free (sinfo->strings);
617   bfd_hash_table_free (&sinfo->includes.root);
618
619   return true;
620 }
621
622 /* Adjust an address in the .stab section.  Given OFFSET within
623    STABSEC, this returns the new offset in the adjusted stab section,
624    or -1 if the address refers to a stab which has been removed.  */
625
626 bfd_vma
627 _bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
628      bfd *output_bfd ATTRIBUTE_UNUSED;
629      PTR *psinfo ATTRIBUTE_UNUSED;
630      asection *stabsec;
631      PTR *psecinfo;
632      bfd_vma offset;
633 {
634   struct stab_section_info *secinfo;
635
636   secinfo = (struct stab_section_info *) *psecinfo;
637
638   if (secinfo == NULL)
639     return offset;
640
641   if (offset >= stabsec->_raw_size)
642     return offset - (stabsec->_cooked_size - stabsec->_raw_size);
643
644   if (secinfo->cumulative_skips)
645     {
646       bfd_vma i;
647
648       i = offset / STABSIZE;
649
650       if (secinfo->stridxs [i] == (bfd_size_type) -1)
651         return (bfd_vma) -1;
652
653       return offset - secinfo->cumulative_skips [i];
654     }
655
656   return offset;
657 }