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
59struct 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
69struct 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
79struct 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
93struct 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
114static 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
119static struct bfd_hash_entry *
120stab_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
152bfd_boolean
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
526bfd_boolean
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
687bfd_boolean
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
759bfd_boolean
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
794bfd_vma
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