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