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