OSDN Git Service

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