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