xref: /NextBSD/contrib/binutils/bfd/stabs.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /* Stabs in sections linking support.
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3    2006, 2007 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21 
22 /* This file contains support for linking stabs in sections, as used
23    on COFF and ELF.  */
24 
25 #include "sysdep.h"
26 #include "bfd.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 linked list of totals that we have found for a particular header
52    file.  A total is a unique identifier for a particular BINCL...EINCL
53    sequence of STABs that can be used to identify duplicate sequences.
54    It consists of three fields, 'sum_chars' which is the sum of all the
55    STABS characters; 'num_chars' which is the number of these charactes
56    and 'symb' which is a buffer of all the symbols in the sequence.  This
57    buffer is only checked as a last resort.  */
58 
59 struct stab_link_includes_totals
60 {
61   struct stab_link_includes_totals *next;
62   bfd_vma sum_chars;  /* Accumulated sum of STABS characters.  */
63   bfd_vma num_chars;  /* Number of STABS characters.  */
64   const char* symb;   /* The STABS characters themselves.  */
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 /* This structure is used to hold a list of N_BINCL symbols, some of
77    which might be converted into N_EXCL symbols.  */
78 
79 struct stab_excl_list
80 {
81   /* The next symbol to convert.  */
82   struct stab_excl_list *next;
83   /* The offset to this symbol in the section contents.  */
84   bfd_size_type offset;
85   /* The value to use for the symbol.  */
86   bfd_vma val;
87   /* The type of this symbol (N_BINCL or N_EXCL).  */
88   int type;
89 };
90 
91 /* This structure is stored with each .stab section.  */
92 
93 struct stab_section_info
94 {
95   /* This is a linked list of N_BINCL symbols which should be
96      converted into N_EXCL symbols.  */
97   struct stab_excl_list *excls;
98 
99   /* This is used to map input stab offsets within their sections
100      to output stab offsets, to take into account stabs that have
101      been deleted.  If it is NULL, the output offsets are the same
102      as the input offsets, because no stabs have been deleted from
103      this section.  Otherwise the i'th entry is the number of
104      bytes of stabs that have been deleted prior to the i'th
105      stab.  */
106   bfd_size_type *cumulative_skips;
107 
108   /* This is an array of string indices.  For each stab symbol, we
109      store the string index here.  If a stab symbol should not be
110      included in the final output, the string index is -1.  */
111   bfd_size_type stridxs[1];
112 };
113 
114 
115 /* The function to create a new entry in the header file hash table.  */
116 
117 static struct bfd_hash_entry *
stab_link_includes_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)118 stab_link_includes_newfunc (struct bfd_hash_entry *entry,
119 			    struct bfd_hash_table *table,
120 			    const char *string)
121 {
122   struct stab_link_includes_entry *ret =
123     (struct stab_link_includes_entry *) entry;
124 
125   /* Allocate the structure if it has not already been allocated by a
126      subclass.  */
127   if (ret == NULL)
128     ret = bfd_hash_allocate (table,
129 			     sizeof (struct stab_link_includes_entry));
130   if (ret == NULL)
131     return NULL;
132 
133   /* Call the allocation method of the superclass.  */
134   ret = ((struct stab_link_includes_entry *)
135 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
136   if (ret)
137     /* Set local fields.  */
138     ret->totals = NULL;
139 
140   return (struct bfd_hash_entry *) ret;
141 }
142 
143 /* This function is called for each input file from the add_symbols
144    pass of the linker.  */
145 
146 bfd_boolean
_bfd_link_section_stabs(bfd * abfd,struct stab_info * sinfo,asection * stabsec,asection * stabstrsec,void ** psecinfo,bfd_size_type * pstring_offset)147 _bfd_link_section_stabs (bfd *abfd,
148 			 struct stab_info *sinfo,
149 			 asection *stabsec,
150 			 asection *stabstrsec,
151 			 void * *psecinfo,
152 			 bfd_size_type *pstring_offset)
153 {
154   bfd_boolean first;
155   bfd_size_type count, amt;
156   struct stab_section_info *secinfo;
157   bfd_byte *stabbuf = NULL;
158   bfd_byte *stabstrbuf = NULL;
159   bfd_byte *sym, *symend;
160   bfd_size_type stroff, next_stroff, skip;
161   bfd_size_type *pstridx;
162 
163   if (stabsec->size == 0
164       || stabstrsec->size == 0)
165     /* This file does not contain stabs debugging information.  */
166     return TRUE;
167 
168   if (stabsec->size % STABSIZE != 0)
169     /* Something is wrong with the format of these stab symbols.
170        Don't try to optimize them.  */
171     return TRUE;
172 
173   if ((stabstrsec->flags & SEC_RELOC) != 0)
174     /* We shouldn't see relocations in the strings, and we aren't
175        prepared to handle them.  */
176     return TRUE;
177 
178   if (bfd_is_abs_section (stabsec->output_section)
179       || bfd_is_abs_section (stabstrsec->output_section))
180     /* At least one of the sections is being discarded from the
181        link, so we should just ignore them.  */
182     return TRUE;
183 
184   first = FALSE;
185 
186   if (sinfo->stabstr == NULL)
187     {
188       flagword flags;
189 
190       /* Initialize the stabs information we need to keep track of.  */
191       first = TRUE;
192       sinfo->strings = _bfd_stringtab_init ();
193       if (sinfo->strings == NULL)
194 	goto error_return;
195       /* Make sure the first byte is zero.  */
196       (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
197       if (! bfd_hash_table_init (&sinfo->includes,
198 				 stab_link_includes_newfunc,
199 				 sizeof (struct stab_link_includes_entry)))
200 	goto error_return;
201       flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING
202 	       | SEC_LINKER_CREATED);
203       sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr",
204 							   flags);
205       if (sinfo->stabstr == NULL)
206 	goto error_return;
207     }
208 
209   /* Initialize the information we are going to store for this .stab
210      section.  */
211   count = stabsec->size / STABSIZE;
212 
213   amt = sizeof (struct stab_section_info);
214   amt += (count - 1) * sizeof (bfd_size_type);
215   *psecinfo = bfd_alloc (abfd, amt);
216   if (*psecinfo == NULL)
217     goto error_return;
218 
219   secinfo = (struct stab_section_info *) *psecinfo;
220   secinfo->excls = NULL;
221   stabsec->rawsize = stabsec->size;
222   secinfo->cumulative_skips = NULL;
223   memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
224 
225   /* Read the stabs information from abfd.  */
226   if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)
227       || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf))
228     goto error_return;
229 
230   /* Look through the stabs symbols, work out the new string indices,
231      and identify N_BINCL symbols which can be eliminated.  */
232   stroff = 0;
233   /* The stabs sections can be split when
234      -split-by-reloc/-split-by-file is used.  We must keep track of
235      each stab section's place in the single concatenated string
236      table.  */
237   next_stroff = pstring_offset ? *pstring_offset : 0;
238   skip = 0;
239 
240   symend = stabbuf + stabsec->size;
241   for (sym = stabbuf, pstridx = secinfo->stridxs;
242        sym < symend;
243        sym += STABSIZE, ++pstridx)
244     {
245       bfd_size_type symstroff;
246       int type;
247       const char *string;
248 
249       if (*pstridx != 0)
250 	/* This symbol has already been handled by an N_BINCL pass.  */
251 	continue;
252 
253       type = sym[TYPEOFF];
254 
255       if (type == 0)
256 	{
257 	  /* Special type 0 stabs indicate the offset to the next
258 	     string table.  We only copy the very first one.  */
259 	  stroff = next_stroff;
260 	  next_stroff += bfd_get_32 (abfd, sym + 8);
261 	  if (pstring_offset)
262 	    *pstring_offset = next_stroff;
263 	  if (! first)
264 	    {
265 	      *pstridx = (bfd_size_type) -1;
266 	      ++skip;
267 	      continue;
268 	    }
269 	  first = FALSE;
270 	}
271 
272       /* Store the string in the hash table, and record the index.  */
273       symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
274       if (symstroff >= stabstrsec->size)
275 	{
276 	  (*_bfd_error_handler)
277 	    (_("%B(%A+0x%lx): Stabs entry has invalid string index."),
278 	     abfd, stabsec, (long) (sym - stabbuf));
279 	  bfd_set_error (bfd_error_bad_value);
280 	  goto error_return;
281 	}
282       string = (char *) stabstrbuf + symstroff;
283       *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE);
284 
285       /* An N_BINCL symbol indicates the start of the stabs entries
286 	 for a header file.  We need to scan ahead to the next N_EINCL
287 	 symbol, ignoring nesting, adding up all the characters in the
288 	 symbol names, not including the file numbers in types (the
289 	 first number after an open parenthesis).  */
290       if (type == (int) N_BINCL)
291 	{
292 	  bfd_vma sum_chars;
293 	  bfd_vma num_chars;
294 	  bfd_vma buf_len = 0;
295 	  char * symb;
296 	  char * symb_rover;
297 	  int nest;
298 	  bfd_byte * incl_sym;
299 	  struct stab_link_includes_entry * incl_entry;
300 	  struct stab_link_includes_totals * t;
301 	  struct stab_excl_list * ne;
302 
303 	  symb = symb_rover = NULL;
304 	  sum_chars = num_chars = 0;
305 	  nest = 0;
306 
307 	  for (incl_sym = sym + STABSIZE;
308 	       incl_sym < symend;
309 	       incl_sym += STABSIZE)
310 	    {
311 	      int incl_type;
312 
313 	      incl_type = incl_sym[TYPEOFF];
314 	      if (incl_type == 0)
315 		break;
316 	      else if (incl_type == (int) N_EXCL)
317 		continue;
318 	      else if (incl_type == (int) N_EINCL)
319 		{
320 		  if (nest == 0)
321 		    break;
322 		  --nest;
323 		}
324 	      else if (incl_type == (int) N_BINCL)
325 		++nest;
326 	      else if (nest == 0)
327 		{
328 		  const char *str;
329 
330 		  str = ((char *) stabstrbuf
331 			 + stroff
332 			 + bfd_get_32 (abfd, incl_sym + STRDXOFF));
333 		  for (; *str != '\0'; str++)
334 		    {
335 		      if (num_chars >= buf_len)
336 			{
337 			  buf_len += 32 * 1024;
338 			  symb = bfd_realloc (symb, buf_len);
339 			  if (symb == NULL)
340 			    goto error_return;
341 			  symb_rover = symb + num_chars;
342 			}
343 		      * symb_rover ++ = * str;
344 		      sum_chars += *str;
345 		      num_chars ++;
346 		      if (*str == '(')
347 			{
348 			  /* Skip the file number.  */
349 			  ++str;
350 			  while (ISDIGIT (*str))
351 			    ++str;
352 			  --str;
353 			}
354 		    }
355 		}
356 	    }
357 
358 	  BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
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 = (struct stab_link_includes_entry * )
363 	    bfd_hash_lookup (&sinfo->includes, string, 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->sum_chars == sum_chars
369 		&& t->num_chars == num_chars
370 		&& memcmp (t->symb, symb, num_chars) == 0)
371 	      break;
372 
373 	  /* Record this symbol, so that we can set the value
374 	     correctly.  */
375 	  amt = sizeof *ne;
376 	  ne = bfd_alloc (abfd, amt);
377 	  if (ne == NULL)
378 	    goto error_return;
379 	  ne->offset = sym - stabbuf;
380 	  ne->val = sum_chars;
381 	  ne->type = (int) N_BINCL;
382 	  ne->next = secinfo->excls;
383 	  secinfo->excls = ne;
384 
385 	  if (t == NULL)
386 	    {
387 	      /* This is the first time we have seen this header file
388 		 with this set of stabs strings.  */
389 	      t = bfd_hash_allocate (&sinfo->includes, sizeof *t);
390 	      if (t == NULL)
391 		goto error_return;
392 	      t->sum_chars = sum_chars;
393 	      t->num_chars = num_chars;
394 	      t->symb = bfd_realloc (symb, num_chars); /* Trim data down.  */
395 	      t->next = incl_entry->totals;
396 	      incl_entry->totals = t;
397 	    }
398 	  else
399 	    {
400 	      bfd_size_type *incl_pstridx;
401 
402 	      /* We have seen this header file before.  Tell the final
403 		 pass to change the type to N_EXCL.  */
404 	      ne->type = (int) N_EXCL;
405 
406 	      /* Free off superfluous symbols.  */
407 	      free (symb);
408 
409 	      /* Mark the skipped symbols.  */
410 
411 	      nest = 0;
412 	      for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
413 		   incl_sym < symend;
414 		   incl_sym += STABSIZE, ++incl_pstridx)
415 		{
416 		  int incl_type;
417 
418 		  incl_type = incl_sym[TYPEOFF];
419 
420 		  if (incl_type == (int) N_EINCL)
421 		    {
422 		      if (nest == 0)
423 			{
424 			  *incl_pstridx = (bfd_size_type) -1;
425 			  ++skip;
426 			  break;
427 			}
428 		      --nest;
429 		    }
430 		  else if (incl_type == (int) N_BINCL)
431 		    ++nest;
432 		  else if (incl_type == (int) N_EXCL)
433 		    /* Keep existing exclusion marks.  */
434 		    continue;
435 		  else if (nest == 0)
436 		    {
437 		      *incl_pstridx = (bfd_size_type) -1;
438 		      ++skip;
439 		    }
440 		}
441 	    }
442 	}
443     }
444 
445   free (stabbuf);
446   stabbuf = NULL;
447   free (stabstrbuf);
448   stabstrbuf = NULL;
449 
450   /* We need to set the section sizes such that the linker will
451      compute the output section sizes correctly.  We set the .stab
452      size to not include the entries we don't want.  We set
453      SEC_EXCLUDE for the .stabstr section, so that it will be dropped
454      from the link.  We record the size of the strtab in the first
455      .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
456      for that section.  */
457   stabsec->size = (count - skip) * STABSIZE;
458   if (stabsec->size == 0)
459     stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
460   stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP;
461   sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings);
462 
463   /* Calculate the `cumulative_skips' array now that stabs have been
464      deleted for this section.  */
465 
466   if (skip != 0)
467     {
468       bfd_size_type i, offset;
469       bfd_size_type *pskips;
470 
471       amt = count * sizeof (bfd_size_type);
472       secinfo->cumulative_skips = bfd_alloc (abfd, amt);
473       if (secinfo->cumulative_skips == NULL)
474 	goto error_return;
475 
476       pskips = secinfo->cumulative_skips;
477       pstridx = secinfo->stridxs;
478       offset = 0;
479 
480       for (i = 0; i < count; i++, pskips++, pstridx++)
481 	{
482 	  *pskips = offset;
483 	  if (*pstridx == (bfd_size_type) -1)
484 	    offset += STABSIZE;
485 	}
486 
487       BFD_ASSERT (offset != 0);
488     }
489 
490   return TRUE;
491 
492  error_return:
493   if (stabbuf != NULL)
494     free (stabbuf);
495   if (stabstrbuf != NULL)
496     free (stabstrbuf);
497   return FALSE;
498 }
499 
500 /* This function is called for each input file before the stab
501    section is relocated.  It discards stab entries for discarded
502    functions and variables.  The function returns TRUE iff
503    any entries have been deleted.
504 */
505 
506 bfd_boolean
_bfd_discard_section_stabs(bfd * abfd,asection * stabsec,void * psecinfo,bfd_boolean (* reloc_symbol_deleted_p)(bfd_vma,void *),void * cookie)507 _bfd_discard_section_stabs (bfd *abfd,
508 			    asection *stabsec,
509 			    void * psecinfo,
510 			    bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
511 			    void * cookie)
512 {
513   bfd_size_type count, amt;
514   struct stab_section_info *secinfo;
515   bfd_byte *stabbuf = NULL;
516   bfd_byte *sym, *symend;
517   bfd_size_type skip;
518   bfd_size_type *pstridx;
519   int deleting;
520 
521   if (stabsec->size == 0)
522     /* This file does not contain stabs debugging information.  */
523     return FALSE;
524 
525   if (stabsec->size % STABSIZE != 0)
526     /* Something is wrong with the format of these stab symbols.
527        Don't try to optimize them.  */
528     return FALSE;
529 
530   if ((stabsec->output_section != NULL
531        && bfd_is_abs_section (stabsec->output_section)))
532     /* At least one of the sections is being discarded from the
533        link, so we should just ignore them.  */
534     return FALSE;
535 
536   /* We should have initialized our data in _bfd_link_stab_sections.
537      If there was some bizarre error reading the string sections, though,
538      we might not have.  Bail rather than asserting.  */
539   if (psecinfo == NULL)
540     return FALSE;
541 
542   count = stabsec->rawsize / STABSIZE;
543   secinfo = (struct stab_section_info *) psecinfo;
544 
545   /* Read the stabs information from abfd.  */
546   if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf))
547     goto error_return;
548 
549   /* Look through the stabs symbols and discard any information for
550      discarded functions.  */
551   skip = 0;
552   deleting = -1;
553 
554   symend = stabbuf + stabsec->rawsize;
555   for (sym = stabbuf, pstridx = secinfo->stridxs;
556        sym < symend;
557        sym += STABSIZE, ++pstridx)
558     {
559       int type;
560 
561       if (*pstridx == (bfd_size_type) -1)
562 	/* This stab was deleted in a previous pass.  */
563 	continue;
564 
565       type = sym[TYPEOFF];
566 
567       if (type == (int) N_FUN)
568 	{
569 	  int strx = bfd_get_32 (abfd, sym + STRDXOFF);
570 
571 	  if (strx == 0)
572 	    {
573 	      if (deleting)
574 		{
575 		  skip++;
576 		  *pstridx = -1;
577 		}
578 	      deleting = -1;
579 	      continue;
580 	    }
581 	  deleting = 0;
582 	  if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
583 	    deleting = 1;
584 	}
585 
586       if (deleting == 1)
587 	{
588 	  *pstridx = -1;
589 	  skip++;
590 	}
591       else if (deleting == -1)
592 	{
593 	  /* Outside of a function.  Check for deleted variables.  */
594 	  if (type == (int) N_STSYM || type == (int) N_LCSYM)
595 	    if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
596 	      {
597 		*pstridx = -1;
598 		skip ++;
599 	      }
600 	  /* We should also check for N_GSYM entries which reference a
601 	     deleted global, but those are less harmful to debuggers
602 	     and would require parsing the stab strings.  */
603 	}
604     }
605 
606   free (stabbuf);
607   stabbuf = NULL;
608 
609   /* Shrink the stabsec as needed.  */
610   stabsec->size -= skip * STABSIZE;
611   if (stabsec->size == 0)
612     stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
613 
614   /* Recalculate the `cumulative_skips' array now that stabs have been
615      deleted for this section.  */
616 
617   if (skip != 0)
618     {
619       bfd_size_type i, offset;
620       bfd_size_type *pskips;
621 
622       if (secinfo->cumulative_skips == NULL)
623 	{
624 	  amt = count * sizeof (bfd_size_type);
625 	  secinfo->cumulative_skips = bfd_alloc (abfd, amt);
626 	  if (secinfo->cumulative_skips == NULL)
627 	    goto error_return;
628 	}
629 
630       pskips = secinfo->cumulative_skips;
631       pstridx = secinfo->stridxs;
632       offset = 0;
633 
634       for (i = 0; i < count; i++, pskips++, pstridx++)
635 	{
636 	  *pskips = offset;
637 	  if (*pstridx == (bfd_size_type) -1)
638 	    offset += STABSIZE;
639 	}
640 
641       BFD_ASSERT (offset != 0);
642     }
643 
644   return skip > 0;
645 
646  error_return:
647   if (stabbuf != NULL)
648     free (stabbuf);
649   return FALSE;
650 }
651 
652 /* Write out the stab section.  This is called with the relocated
653    contents.  */
654 
655 bfd_boolean
_bfd_write_section_stabs(bfd * output_bfd,struct stab_info * sinfo,asection * stabsec,void ** psecinfo,bfd_byte * contents)656 _bfd_write_section_stabs (bfd *output_bfd,
657 			  struct stab_info *sinfo,
658 			  asection *stabsec,
659 			  void * *psecinfo,
660 			  bfd_byte *contents)
661 {
662   struct stab_section_info *secinfo;
663   struct stab_excl_list *e;
664   bfd_byte *sym, *tosym, *symend;
665   bfd_size_type *pstridx;
666 
667   secinfo = (struct stab_section_info *) *psecinfo;
668 
669   if (secinfo == NULL)
670     return bfd_set_section_contents (output_bfd, stabsec->output_section,
671 				     contents, stabsec->output_offset,
672 				     stabsec->size);
673 
674   /* Handle each N_BINCL entry.  */
675   for (e = secinfo->excls; e != NULL; e = e->next)
676     {
677       bfd_byte *excl_sym;
678 
679       BFD_ASSERT (e->offset < stabsec->rawsize);
680       excl_sym = contents + e->offset;
681       bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
682       excl_sym[TYPEOFF] = e->type;
683     }
684 
685   /* Copy over all the stabs symbols, omitting the ones we don't want,
686      and correcting the string indices for those we do want.  */
687   tosym = contents;
688   symend = contents + stabsec->rawsize;
689   for (sym = contents, pstridx = secinfo->stridxs;
690        sym < symend;
691        sym += STABSIZE, ++pstridx)
692     {
693       if (*pstridx != (bfd_size_type) -1)
694 	{
695 	  if (tosym != sym)
696 	    memcpy (tosym, sym, STABSIZE);
697 	  bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
698 
699 	  if (sym[TYPEOFF] == 0)
700 	    {
701 	      /* This is the header symbol for the stabs section.  We
702 		 don't really need one, since we have merged all the
703 		 input stabs sections into one, but we generate one
704 		 for the benefit of readers which expect to see one.  */
705 	      BFD_ASSERT (sym == contents);
706 	      bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
707 			  tosym + VALOFF);
708 	      bfd_put_16 (output_bfd,
709 			  stabsec->output_section->size / STABSIZE - 1,
710 			  tosym + DESCOFF);
711 	    }
712 
713 	  tosym += STABSIZE;
714 	}
715     }
716 
717   BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);
718 
719   return bfd_set_section_contents (output_bfd, stabsec->output_section,
720 				   contents, (file_ptr) stabsec->output_offset,
721 				   stabsec->size);
722 }
723 
724 /* Write out the .stabstr section.  */
725 
726 bfd_boolean
_bfd_write_stab_strings(bfd * output_bfd,struct stab_info * sinfo)727 _bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo)
728 {
729   if (bfd_is_abs_section (sinfo->stabstr->output_section))
730     /* The section was discarded from the link.  */
731     return TRUE;
732 
733   BFD_ASSERT ((sinfo->stabstr->output_offset
734 	       + _bfd_stringtab_size (sinfo->strings))
735 	      <= sinfo->stabstr->output_section->size);
736 
737   if (bfd_seek (output_bfd,
738 		(file_ptr) (sinfo->stabstr->output_section->filepos
739 			    + sinfo->stabstr->output_offset),
740 		SEEK_SET) != 0)
741     return FALSE;
742 
743   if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
744     return FALSE;
745 
746   /* We no longer need the stabs information.  */
747   _bfd_stringtab_free (sinfo->strings);
748   bfd_hash_table_free (&sinfo->includes);
749 
750   return TRUE;
751 }
752 
753 /* Adjust an address in the .stab section.  Given OFFSET within
754    STABSEC, this returns the new offset in the adjusted stab section,
755    or -1 if the address refers to a stab which has been removed.  */
756 
757 bfd_vma
_bfd_stab_section_offset(asection * stabsec,void * psecinfo,bfd_vma offset)758 _bfd_stab_section_offset (asection *stabsec,
759 			  void * psecinfo,
760 			  bfd_vma offset)
761 {
762   struct stab_section_info *secinfo;
763 
764   secinfo = (struct stab_section_info *) psecinfo;
765 
766   if (secinfo == NULL)
767     return offset;
768 
769   if (offset >= stabsec->rawsize)
770     return offset - stabsec->rawsize + stabsec->size;
771 
772   if (secinfo->cumulative_skips)
773     {
774       bfd_vma i;
775 
776       i = offset / STABSIZE;
777 
778       if (secinfo->stridxs [i] == (bfd_size_type) -1)
779 	return (bfd_vma) -1;
780 
781       return offset - secinfo->cumulative_skips [i];
782     }
783 
784   return offset;
785 }
786