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 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   /* This is an array of string indices.  For each stab symbol, we
105      store the string index here.  If a stab symbol should not be
106      included in the final output, the string index is -1.  */
107   bfd_size_type stridxs[1];
108 };
109
110 /* This structure is used to keep track of stabs in sections
111    information while linking.  */
112
113 struct stab_info
114 {
115   /* A hash table used to hold stabs strings.  */
116   struct bfd_strtab_hash *strings;
117   /* The header file hash table.  */
118   struct stab_link_includes_table includes;
119   /* The first .stabstr section.  */
120   asection *stabstr;
121 };
122
123 static struct bfd_hash_entry *stab_link_includes_newfunc
124   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
125 \f
126 /* The function to create a new entry in the header file hash table.  */
127
128 static struct bfd_hash_entry *
129 stab_link_includes_newfunc (entry, table, string)
130      struct bfd_hash_entry *entry;
131      struct bfd_hash_table *table;
132      const char *string;
133 {
134   struct stab_link_includes_entry *ret =
135     (struct stab_link_includes_entry *) entry;
136
137   /* Allocate the structure if it has not already been allocated by a
138      subclass.  */
139   if (ret == (struct stab_link_includes_entry *) NULL)
140     ret = ((struct stab_link_includes_entry *)
141            bfd_hash_allocate (table,
142                               sizeof (struct stab_link_includes_entry)));
143   if (ret == (struct stab_link_includes_entry *) NULL)
144     return (struct bfd_hash_entry *) ret;
145
146   /* Call the allocation method of the superclass.  */
147   ret = ((struct stab_link_includes_entry *)
148          bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
149   if (ret)
150     {
151       /* Set local fields.  */
152       ret->totals = NULL;
153     }
154
155   return (struct bfd_hash_entry *) ret;
156 }
157 \f
158 /* This function is called for each input file from the add_symbols
159    pass of the linker.  */
160
161 boolean
162 _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
163      bfd *abfd;
164      PTR *psinfo;
165      asection *stabsec;
166      asection *stabstrsec;
167      PTR *psecinfo;
168 {
169   boolean first;
170   struct stab_info *sinfo;
171   bfd_size_type count;
172   struct stab_section_info *secinfo;
173   bfd_byte *stabbuf = NULL;
174   bfd_byte *stabstrbuf = NULL;
175   bfd_byte *sym, *symend;
176   bfd_size_type stroff, next_stroff, skip;
177   bfd_size_type *pstridx;
178
179   if (stabsec->_raw_size == 0
180       || stabstrsec->_raw_size == 0)
181     {
182       /* This file does not contain stabs debugging information.  */
183       return true;
184     }
185
186   if (stabsec->_raw_size % STABSIZE != 0)
187     {
188       /* Something is wrong with the format of these stab symbols.
189          Don't try to optimize them.  */
190       return true;
191     }
192
193   if ((stabstrsec->flags & SEC_RELOC) != 0)
194     {
195       /* We shouldn't see relocations in the strings, and we aren't
196          prepared to handle them.  */
197       return true;
198     }
199
200   if ((stabsec->output_section != NULL
201        && bfd_is_abs_section (stabsec->output_section))
202       || (stabstrsec->output_section != NULL
203           && bfd_is_abs_section (stabstrsec->output_section)))
204     {
205       /* At least one of the sections is being discarded from the
206          link, so we should just ignore them.  */
207       return true;
208     }
209
210   first = false;
211
212   if (*psinfo == NULL)
213     {
214       /* Initialize the stabs information we need to keep track of.  */
215       first = true;
216       *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info));
217       if (*psinfo == NULL)
218         goto error_return;
219       sinfo = (struct stab_info *) *psinfo;
220       sinfo->strings = _bfd_stringtab_init ();
221       if (sinfo->strings == NULL)
222         goto error_return;
223       if (! bfd_hash_table_init_n (&sinfo->includes.root,
224                                    stab_link_includes_newfunc,
225                                    251))
226         goto error_return;
227       sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
228       sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
229     }
230
231   sinfo = (struct stab_info *) *psinfo;
232
233   /* Initialize the information we are going to store for this .stab
234      section.  */
235
236   count = stabsec->_raw_size / STABSIZE;
237
238   *psecinfo = bfd_alloc (abfd,
239                          (sizeof (struct stab_section_info)
240                           + (count - 1) * sizeof (bfd_size_type)));
241   if (*psecinfo == NULL)
242     goto error_return;
243
244   secinfo = (struct stab_section_info *) *psecinfo;
245   secinfo->excls = NULL;
246   memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type));
247
248   /* Read the stabs information from abfd.  */
249
250   stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
251   stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
252   if (stabbuf == NULL || stabstrbuf == NULL)
253     goto error_return;
254
255   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, 0,
256                                   stabsec->_raw_size)
257       || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, 0,
258                                      stabstrsec->_raw_size))
259     goto error_return;
260
261   /* Look through the stabs symbols, work out the new string indices,
262      and identify N_BINCL symbols which can be eliminated.  */
263
264   stroff = 0;
265   next_stroff = 0;
266   skip = 0;
267
268   symend = stabbuf + stabsec->_raw_size;
269   for (sym = stabbuf, pstridx = secinfo->stridxs;
270        sym < symend;
271        sym += STABSIZE, ++pstridx)
272     {
273       int type;
274       const char *string;
275
276       if (*pstridx != 0)
277         {
278           /* This symbol has already been handled by an N_BINCL pass.  */
279           continue;
280         }
281
282       type = sym[TYPEOFF];
283
284       if (type == 0)
285         {
286           /* Special type 0 stabs indicate the offset to the next
287              string table.  We only copy the very first one.  */
288           stroff = next_stroff;
289           next_stroff += bfd_get_32 (abfd, sym + 8);
290           if (! first)
291             {
292               *pstridx = (bfd_size_type) -1;
293               ++skip;
294               continue;
295             }
296           first = false;
297         }
298
299       /* Store the string in the hash table, and record the index.  */
300       string = ((char *) stabstrbuf
301                 + stroff
302                 + bfd_get_32 (abfd, sym + STRDXOFF));
303       *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
304
305       /* An N_BINCL symbol indicates the start of the stabs entries
306          for a header file.  We need to scan ahead to the next N_EINCL
307          symbol, ignoring nesting, adding up all the characters in the
308          symbol names, not including the file numbers in types (the
309          first number after an open parenthesis).  */
310       if (type == N_BINCL)
311         {
312           bfd_vma val;
313           int nest;
314           bfd_byte *incl_sym;
315           struct stab_link_includes_entry *incl_entry;
316           struct stab_link_includes_totals *t;
317           struct stab_excl_list *ne;
318
319           val = 0;
320           nest = 0;
321           for (incl_sym = sym + STABSIZE;
322                incl_sym < symend;
323                incl_sym += STABSIZE)
324             {
325               int incl_type;
326
327               incl_type = incl_sym[TYPEOFF];
328               if (incl_type == 0)
329                 break;
330               else if (incl_type == N_EINCL)
331                 {
332                   if (nest == 0)
333                     break;
334                   --nest;
335                 }
336               else if (incl_type == N_BINCL)
337                 ++nest;
338               else if (nest == 0)
339                 {
340                   const char *str;
341
342                   str = ((char *) stabstrbuf
343                          + stroff
344                          + bfd_get_32 (abfd, incl_sym + STRDXOFF));
345                   for (; *str != '\0'; str++)
346                     {
347                       val += *str;
348                       if (*str == '(')
349                         {
350                           /* Skip the file number.  */
351                           ++str;
352                           while (isdigit ((unsigned char) *str))
353                             ++str;
354                           --str;
355                         }
356                     }
357                 }
358             }
359
360           /* If we have already included a header file with the same
361              value, then replaced this one with an N_EXCL symbol.  */
362           incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
363                                                   true, true);
364           if (incl_entry == NULL)
365             goto error_return;
366
367           for (t = incl_entry->totals; t != NULL; t = t->next)
368             if (t->total == val)
369               break;
370
371           /* Record this symbol, so that we can set the value
372              correctly.  */
373           ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne);
374           ne->offset = sym - stabbuf;
375           ne->val = val;
376           ne->type = N_BINCL;
377           ne->next = secinfo->excls;
378           secinfo->excls = ne;
379
380           if (t == NULL)
381             {
382               /* This is the first time we have seen this header file
383                  with this set of stabs strings.  */
384               t = ((struct stab_link_includes_totals *)
385                    bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
386               if (t == NULL)
387                 goto error_return;
388               t->total = val;
389               t->next = incl_entry->totals;
390               incl_entry->totals = t;
391             }
392           else
393             {
394               bfd_size_type *incl_pstridx;
395
396               /* We have seen this header file before.  Tell the final
397                  pass to change the type to N_EXCL.  */
398               ne->type = N_EXCL;
399
400               /* Mark the skipped symbols.  */
401
402               nest = 0;
403               for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
404                    incl_sym < symend;
405                    incl_sym += STABSIZE, ++incl_pstridx)
406                 {
407                   int incl_type;
408
409                   incl_type = incl_sym[TYPEOFF];
410
411                   if (incl_type == N_EINCL)
412                     {
413                       if (nest == 0)
414                         {
415                           *incl_pstridx = (bfd_size_type) -1;
416                           ++skip;
417                           break;
418                         }
419                       --nest;
420                     }
421                   else if (incl_type == N_BINCL)
422                     ++nest;
423                   else if (nest == 0)
424                     {
425                       *incl_pstridx = (bfd_size_type) -1;
426                       ++skip;
427                     }
428                 }
429             }
430         }
431     }
432
433   free (stabbuf);
434   free (stabstrbuf);
435
436   /* We need to set the section sizes such that the linker will
437      compute the output section sizes correctly.  We set the .stab
438      size to not include the entries we don't want.  We set
439      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
440      from the link.  We record the size of the strtab in the first
441      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
442      for that section.  */
443   stabsec->_cooked_size = (count - skip) * STABSIZE;
444   if (stabsec->_cooked_size == 0)
445     stabsec->flags |= SEC_EXCLUDE;
446   stabstrsec->flags |= SEC_EXCLUDE;
447   sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
448
449   return true;
450
451  error_return:
452   if (stabbuf != NULL)
453     free (stabbuf);
454   if (stabstrbuf != NULL)
455     free (stabstrbuf);
456   return false;
457 }
458
459 /* Write out the stab section.  This is called with the relocated
460    contents.  */
461
462 boolean
463 _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
464      bfd *output_bfd;
465      PTR *psinfo;
466      asection *stabsec;
467      PTR *psecinfo;
468      bfd_byte *contents;
469 {
470   struct stab_info *sinfo;
471   struct stab_section_info *secinfo;
472   struct stab_excl_list *e;
473   bfd_byte *sym, *tosym, *symend;
474   bfd_size_type *pstridx;
475
476   sinfo = (struct stab_info *) *psinfo;
477   secinfo = (struct stab_section_info *) *psecinfo;
478
479   if (secinfo == NULL)
480     return bfd_set_section_contents (output_bfd, stabsec->output_section,
481                                      contents, stabsec->output_offset,
482                                      stabsec->_raw_size);
483
484   /* Handle each N_BINCL entry.  */
485   for (e = secinfo->excls; e != NULL; e = e->next)
486     {
487       bfd_byte *excl_sym;
488
489       BFD_ASSERT (e->offset < stabsec->_raw_size);
490       excl_sym = contents + e->offset;
491       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
492       excl_sym[TYPEOFF] = e->type;
493     }
494
495   /* Copy over all the stabs symbols, omitting the ones we don't want,
496      and correcting the string indices for those we do want.  */
497   tosym = contents;
498   symend = contents + stabsec->_raw_size;
499   for (sym = contents, pstridx = secinfo->stridxs;
500        sym < symend;
501        sym += STABSIZE, ++pstridx)
502     {
503       if (*pstridx != (bfd_size_type) -1)
504         {
505           if (tosym != sym)
506             memcpy (tosym, sym, STABSIZE);
507           bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
508
509           if (sym[TYPEOFF] == 0)
510             {
511               /* This is the header symbol for the stabs section.  We
512                  don't really need one, since we have merged all the
513                  input stabs sections into one, but we generate one
514                  for the benefit of readers which expect to see one.  */
515               BFD_ASSERT (sym == contents);
516               bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
517                           tosym + VALOFF);
518               bfd_put_16 (output_bfd,
519                           stabsec->output_section->_raw_size / STABSIZE - 1,
520                           tosym + DESCOFF);
521             }
522
523           tosym += STABSIZE;
524         }
525     }
526
527   BFD_ASSERT (tosym - contents == stabsec->_cooked_size);
528
529   return bfd_set_section_contents (output_bfd, stabsec->output_section,
530                                    contents, stabsec->output_offset,
531                                    stabsec->_cooked_size);
532 }
533
534 /* Write out the .stabstr section.  */
535
536 boolean
537 _bfd_write_stab_strings (output_bfd, psinfo)
538      bfd *output_bfd;
539      PTR *psinfo;
540 {
541   struct stab_info *sinfo;
542
543   sinfo = (struct stab_info *) *psinfo;
544
545   if (sinfo == NULL)
546     return true;
547
548   BFD_ASSERT ((sinfo->stabstr->output_offset
549                + _bfd_stringtab_size (sinfo->strings))
550               <= sinfo->stabstr->output_section->_raw_size);
551
552   if (bfd_seek (output_bfd,
553                 (sinfo->stabstr->output_section->filepos
554                  + sinfo->stabstr->output_offset),
555                 SEEK_SET) != 0)
556     return false;
557
558   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
559     return false;
560
561   /* We no longer need the stabs information.  */
562   _bfd_stringtab_free (sinfo->strings);
563   bfd_hash_table_free (&sinfo->includes.root);
564
565   return true;
566 }