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