source: branches/libc-0.6/src/binutils/bfd/stabs.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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