1 /* Stabs in sections linking support.
2 Copyright 1996, 1997 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
21 /* This file contains support for linking stabs in sections, as used
27 #include "aout/stab_gnu.h"
31 /* Stabs entries use a 12 byte format:
32 4 byte string table index
34 1 byte stab other field
35 2 byte stab desc field
37 FIXME: This will have to change for a 64 bit object format.
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. */
51 /* A hash table used for header files with N_BINCL entries. */
53 struct stab_link_includes_table
55 struct bfd_hash_table root;
58 /* A linked list of totals that we have found for a particular header
61 struct stab_link_includes_totals
63 struct stab_link_includes_totals *next;
67 /* An entry in the header file hash table. */
69 struct stab_link_includes_entry
71 struct bfd_hash_entry root;
72 /* List of totals we have found for this file. */
73 struct stab_link_includes_totals *totals;
76 /* Look up an entry in an the header file hash table. */
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)))
82 /* This structure is used to hold a list of N_BINCL symbols, some of
83 which might be converted into N_EXCL symbols. */
87 /* The next symbol to convert. */
88 struct stab_excl_list *next;
89 /* The offset to this symbol in the section contents. */
91 /* The value to use for the symbol. */
93 /* The type of this symbol (N_BINCL or N_EXCL). */
97 /* This structure is stored with each .stab section. */
99 struct stab_section_info
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];
110 /* This structure is used to keep track of stabs in sections
111 information while linking. */
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. */
123 static struct bfd_hash_entry *stab_link_includes_newfunc
124 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
126 /* The function to create a new entry in the header file hash table. */
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;
134 struct stab_link_includes_entry *ret =
135 (struct stab_link_includes_entry *) entry;
137 /* Allocate the structure if it has not already been allocated by a
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;
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));
151 /* Set local fields. */
155 return (struct bfd_hash_entry *) ret;
158 /* This function is called for each input file from the add_symbols
159 pass of the linker. */
162 _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
166 asection *stabstrsec;
170 struct stab_info *sinfo;
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;
179 if (stabsec->_raw_size == 0
180 || stabstrsec->_raw_size == 0)
182 /* This file does not contain stabs debugging information. */
186 if (stabsec->_raw_size % STABSIZE != 0)
188 /* Something is wrong with the format of these stab symbols.
189 Don't try to optimize them. */
193 if ((stabstrsec->flags & SEC_RELOC) != 0)
195 /* We shouldn't see relocations in the strings, and we aren't
196 prepared to handle them. */
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)))
205 /* At least one of the sections is being discarded from the
206 link, so we should just ignore them. */
214 /* Initialize the stabs information we need to keep track of. */
216 *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info));
219 sinfo = (struct stab_info *) *psinfo;
220 sinfo->strings = _bfd_stringtab_init ();
221 if (sinfo->strings == NULL)
223 if (! bfd_hash_table_init_n (&sinfo->includes.root,
224 stab_link_includes_newfunc,
227 sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
228 sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
231 sinfo = (struct stab_info *) *psinfo;
233 /* Initialize the information we are going to store for this .stab
236 count = stabsec->_raw_size / STABSIZE;
238 *psecinfo = bfd_alloc (abfd,
239 (sizeof (struct stab_section_info)
240 + (count - 1) * sizeof (bfd_size_type)));
241 if (*psecinfo == NULL)
244 secinfo = (struct stab_section_info *) *psecinfo;
245 secinfo->excls = NULL;
246 memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type));
248 /* Read the stabs information from abfd. */
250 stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
251 stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
252 if (stabbuf == NULL || stabstrbuf == NULL)
255 if (! bfd_get_section_contents (abfd, stabsec, stabbuf, 0,
257 || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, 0,
258 stabstrsec->_raw_size))
261 /* Look through the stabs symbols, work out the new string indices,
262 and identify N_BINCL symbols which can be eliminated. */
268 symend = stabbuf + stabsec->_raw_size;
269 for (sym = stabbuf, pstridx = secinfo->stridxs;
271 sym += STABSIZE, ++pstridx)
278 /* This symbol has already been handled by an N_BINCL pass. */
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);
292 *pstridx = (bfd_size_type) -1;
299 /* Store the string in the hash table, and record the index. */
300 string = ((char *) stabstrbuf
302 + bfd_get_32 (abfd, sym + STRDXOFF));
303 *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
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). */
315 struct stab_link_includes_entry *incl_entry;
316 struct stab_link_includes_totals *t;
317 struct stab_excl_list *ne;
321 for (incl_sym = sym + STABSIZE;
323 incl_sym += STABSIZE)
327 incl_type = incl_sym[TYPEOFF];
330 else if (incl_type == N_EINCL)
336 else if (incl_type == N_BINCL)
342 str = ((char *) stabstrbuf
344 + bfd_get_32 (abfd, incl_sym + STRDXOFF));
345 for (; *str != '\0'; str++)
350 /* Skip the file number. */
352 while (isdigit ((unsigned char) *str))
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,
364 if (incl_entry == NULL)
367 for (t = incl_entry->totals; t != NULL; t = t->next)
371 /* Record this symbol, so that we can set the value
373 ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne);
374 ne->offset = sym - stabbuf;
377 ne->next = secinfo->excls;
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));
389 t->next = incl_entry->totals;
390 incl_entry->totals = t;
394 bfd_size_type *incl_pstridx;
396 /* We have seen this header file before. Tell the final
397 pass to change the type to N_EXCL. */
400 /* Mark the skipped symbols. */
403 for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
405 incl_sym += STABSIZE, ++incl_pstridx)
409 incl_type = incl_sym[TYPEOFF];
411 if (incl_type == N_EINCL)
415 *incl_pstridx = (bfd_size_type) -1;
421 else if (incl_type == N_BINCL)
425 *incl_pstridx = (bfd_size_type) -1;
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
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);
454 if (stabstrbuf != NULL)
459 /* Write out the stab section. This is called with the relocated
463 _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
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;
476 sinfo = (struct stab_info *) *psinfo;
477 secinfo = (struct stab_section_info *) *psecinfo;
480 return bfd_set_section_contents (output_bfd, stabsec->output_section,
481 contents, stabsec->output_offset,
484 /* Handle each N_BINCL entry. */
485 for (e = secinfo->excls; e != NULL; e = e->next)
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;
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. */
498 symend = contents + stabsec->_raw_size;
499 for (sym = contents, pstridx = secinfo->stridxs;
501 sym += STABSIZE, ++pstridx)
503 if (*pstridx != (bfd_size_type) -1)
506 memcpy (tosym, sym, STABSIZE);
507 bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
509 if (sym[TYPEOFF] == 0)
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),
518 bfd_put_16 (output_bfd,
519 stabsec->output_section->_raw_size / STABSIZE - 1,
527 BFD_ASSERT (tosym - contents == stabsec->_cooked_size);
529 return bfd_set_section_contents (output_bfd, stabsec->output_section,
530 contents, stabsec->output_offset,
531 stabsec->_cooked_size);
534 /* Write out the .stabstr section. */
537 _bfd_write_stab_strings (output_bfd, psinfo)
541 struct stab_info *sinfo;
543 sinfo = (struct stab_info *) *psinfo;
548 BFD_ASSERT ((sinfo->stabstr->output_offset
549 + _bfd_stringtab_size (sinfo->strings))
550 <= sinfo->stabstr->output_section->_raw_size);
552 if (bfd_seek (output_bfd,
553 (sinfo->stabstr->output_section->filepos
554 + sinfo->stabstr->output_offset),
558 if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
561 /* We no longer need the stabs information. */
562 _bfd_stringtab_free (sinfo->strings);
563 bfd_hash_table_free (&sinfo->includes.root);