xref: /openbsd/gnu/usr.bin/binutils/bfd/stabs.c (revision 78b63d65)
1 /* Stabs in sections linking support.
2    Copyright 1996, 1997, 1998, 1999 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 
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 
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 }
654