1377e23a2Schristos /* Stabs in sections linking support.
2*1424dfb3Schristos Copyright (C) 1996-2020 Free Software Foundation, Inc.
3377e23a2Schristos Written by Ian Lance Taylor, Cygnus Support.
4377e23a2Schristos
5377e23a2Schristos This file is part of BFD, the Binary File Descriptor library.
6377e23a2Schristos
7377e23a2Schristos This program is free software; you can redistribute it and/or modify
8377e23a2Schristos it under the terms of the GNU General Public License as published by
9377e23a2Schristos the Free Software Foundation; either version 3 of the License, or
10377e23a2Schristos (at your option) any later version.
11377e23a2Schristos
12377e23a2Schristos This program is distributed in the hope that it will be useful,
13377e23a2Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
14377e23a2Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15377e23a2Schristos GNU General Public License for more details.
16377e23a2Schristos
17377e23a2Schristos You should have received a copy of the GNU General Public License
18377e23a2Schristos along with this program; if not, write to the Free Software
19377e23a2Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20377e23a2Schristos MA 02110-1301, USA. */
21377e23a2Schristos
22377e23a2Schristos
23377e23a2Schristos /* This file contains support for linking stabs in sections, as used
24377e23a2Schristos on COFF and ELF. */
25377e23a2Schristos
26377e23a2Schristos #include "sysdep.h"
27377e23a2Schristos #include "bfd.h"
28377e23a2Schristos #include "libbfd.h"
29377e23a2Schristos #include "aout/stab_gnu.h"
30377e23a2Schristos #include "safe-ctype.h"
31377e23a2Schristos
32377e23a2Schristos /* Stabs entries use a 12 byte format:
33377e23a2Schristos 4 byte string table index
34377e23a2Schristos 1 byte stab type
35377e23a2Schristos 1 byte stab other field
36377e23a2Schristos 2 byte stab desc field
37377e23a2Schristos 4 byte stab value
38377e23a2Schristos FIXME: This will have to change for a 64 bit object format.
39377e23a2Schristos
40377e23a2Schristos The stabs symbols are divided into compilation units. For the
41377e23a2Schristos first entry in each unit, the type of 0, the value is the length of
42377e23a2Schristos the string table for this unit, and the desc field is the number of
43377e23a2Schristos stabs symbols for this unit. */
44377e23a2Schristos
45377e23a2Schristos #define STRDXOFF 0
46377e23a2Schristos #define TYPEOFF 4
47377e23a2Schristos #define OTHEROFF 5
48377e23a2Schristos #define DESCOFF 6
49377e23a2Schristos #define VALOFF 8
50377e23a2Schristos #define STABSIZE 12
51377e23a2Schristos
52377e23a2Schristos /* A linked list of totals that we have found for a particular header
53377e23a2Schristos file. A total is a unique identifier for a particular BINCL...EINCL
54377e23a2Schristos sequence of STABs that can be used to identify duplicate sequences.
55377e23a2Schristos It consists of three fields, 'sum_chars' which is the sum of all the
56377e23a2Schristos STABS characters; 'num_chars' which is the number of these charactes
57377e23a2Schristos and 'symb' which is a buffer of all the symbols in the sequence. This
58377e23a2Schristos buffer is only checked as a last resort. */
59377e23a2Schristos
60377e23a2Schristos struct stab_link_includes_totals
61377e23a2Schristos {
62377e23a2Schristos struct stab_link_includes_totals *next;
63377e23a2Schristos bfd_vma sum_chars; /* Accumulated sum of STABS characters. */
64377e23a2Schristos bfd_vma num_chars; /* Number of STABS characters. */
65377e23a2Schristos const char* symb; /* The STABS characters themselves. */
66377e23a2Schristos };
67377e23a2Schristos
68377e23a2Schristos /* An entry in the header file hash table. */
69377e23a2Schristos
70377e23a2Schristos struct stab_link_includes_entry
71377e23a2Schristos {
72377e23a2Schristos struct bfd_hash_entry root;
73377e23a2Schristos /* List of totals we have found for this file. */
74377e23a2Schristos struct stab_link_includes_totals *totals;
75377e23a2Schristos };
76377e23a2Schristos
77377e23a2Schristos /* This structure is used to hold a list of N_BINCL symbols, some of
78377e23a2Schristos which might be converted into N_EXCL symbols. */
79377e23a2Schristos
80377e23a2Schristos struct stab_excl_list
81377e23a2Schristos {
82377e23a2Schristos /* The next symbol to convert. */
83377e23a2Schristos struct stab_excl_list *next;
84377e23a2Schristos /* The offset to this symbol in the section contents. */
85377e23a2Schristos bfd_size_type offset;
86377e23a2Schristos /* The value to use for the symbol. */
87377e23a2Schristos bfd_vma val;
88377e23a2Schristos /* The type of this symbol (N_BINCL or N_EXCL). */
89377e23a2Schristos int type;
90377e23a2Schristos };
91377e23a2Schristos
92377e23a2Schristos /* This structure is stored with each .stab section. */
93377e23a2Schristos
94377e23a2Schristos struct stab_section_info
95377e23a2Schristos {
96377e23a2Schristos /* This is a linked list of N_BINCL symbols which should be
97377e23a2Schristos converted into N_EXCL symbols. */
98377e23a2Schristos struct stab_excl_list *excls;
99377e23a2Schristos
100377e23a2Schristos /* This is used to map input stab offsets within their sections
101377e23a2Schristos to output stab offsets, to take into account stabs that have
102377e23a2Schristos been deleted. If it is NULL, the output offsets are the same
103377e23a2Schristos as the input offsets, because no stabs have been deleted from
104377e23a2Schristos this section. Otherwise the i'th entry is the number of
105377e23a2Schristos bytes of stabs that have been deleted prior to the i'th
106377e23a2Schristos stab. */
107377e23a2Schristos bfd_size_type *cumulative_skips;
108377e23a2Schristos
109377e23a2Schristos /* This is an array of string indices. For each stab symbol, we
110377e23a2Schristos store the string index here. If a stab symbol should not be
111377e23a2Schristos included in the final output, the string index is -1. */
112377e23a2Schristos bfd_size_type stridxs[1];
113377e23a2Schristos };
114377e23a2Schristos
115377e23a2Schristos
116377e23a2Schristos /* The function to create a new entry in the header file hash table. */
117377e23a2Schristos
118377e23a2Schristos static struct bfd_hash_entry *
stab_link_includes_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)119377e23a2Schristos stab_link_includes_newfunc (struct bfd_hash_entry *entry,
120377e23a2Schristos struct bfd_hash_table *table,
121377e23a2Schristos const char *string)
122377e23a2Schristos {
123377e23a2Schristos struct stab_link_includes_entry *ret =
124377e23a2Schristos (struct stab_link_includes_entry *) entry;
125377e23a2Schristos
126377e23a2Schristos /* Allocate the structure if it has not already been allocated by a
127377e23a2Schristos subclass. */
128377e23a2Schristos if (ret == NULL)
129377e23a2Schristos ret = (struct stab_link_includes_entry *)
130377e23a2Schristos bfd_hash_allocate (table, sizeof (struct stab_link_includes_entry));
131377e23a2Schristos if (ret == NULL)
132377e23a2Schristos return NULL;
133377e23a2Schristos
134377e23a2Schristos /* Call the allocation method of the superclass. */
135377e23a2Schristos ret = ((struct stab_link_includes_entry *)
136377e23a2Schristos bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
137377e23a2Schristos if (ret)
138377e23a2Schristos /* Set local fields. */
139377e23a2Schristos ret->totals = NULL;
140377e23a2Schristos
141377e23a2Schristos return (struct bfd_hash_entry *) ret;
142377e23a2Schristos }
143377e23a2Schristos
144377e23a2Schristos /* This function is called for each input file from the add_symbols
145377e23a2Schristos pass of the linker. */
146377e23a2Schristos
147377e23a2Schristos bfd_boolean
_bfd_link_section_stabs(bfd * abfd,struct stab_info * sinfo,asection * stabsec,asection * stabstrsec,void ** psecinfo,bfd_size_type * pstring_offset)148377e23a2Schristos _bfd_link_section_stabs (bfd *abfd,
149377e23a2Schristos struct stab_info *sinfo,
150377e23a2Schristos asection *stabsec,
151377e23a2Schristos asection *stabstrsec,
152377e23a2Schristos void * *psecinfo,
153377e23a2Schristos bfd_size_type *pstring_offset)
154377e23a2Schristos {
155377e23a2Schristos bfd_boolean first;
156377e23a2Schristos bfd_size_type count, amt;
157377e23a2Schristos struct stab_section_info *secinfo;
158377e23a2Schristos bfd_byte *stabbuf = NULL;
159377e23a2Schristos bfd_byte *stabstrbuf = NULL;
160377e23a2Schristos bfd_byte *sym, *symend;
161377e23a2Schristos bfd_size_type stroff, next_stroff, skip;
162377e23a2Schristos bfd_size_type *pstridx;
163377e23a2Schristos
164377e23a2Schristos if (stabsec->size == 0
165377e23a2Schristos || stabstrsec->size == 0)
166377e23a2Schristos /* This file does not contain stabs debugging information. */
167377e23a2Schristos return TRUE;
168377e23a2Schristos
169377e23a2Schristos if (stabsec->size % STABSIZE != 0)
170377e23a2Schristos /* Something is wrong with the format of these stab symbols.
171377e23a2Schristos Don't try to optimize them. */
172377e23a2Schristos return TRUE;
173377e23a2Schristos
174377e23a2Schristos if ((stabstrsec->flags & SEC_RELOC) != 0)
175377e23a2Schristos /* We shouldn't see relocations in the strings, and we aren't
176377e23a2Schristos prepared to handle them. */
177377e23a2Schristos return TRUE;
178377e23a2Schristos
179377e23a2Schristos if (bfd_is_abs_section (stabsec->output_section)
180377e23a2Schristos || bfd_is_abs_section (stabstrsec->output_section))
181377e23a2Schristos /* At least one of the sections is being discarded from the
182377e23a2Schristos link, so we should just ignore them. */
183377e23a2Schristos return TRUE;
184377e23a2Schristos
185377e23a2Schristos first = FALSE;
186377e23a2Schristos
187377e23a2Schristos if (sinfo->stabstr == NULL)
188377e23a2Schristos {
189377e23a2Schristos flagword flags;
190377e23a2Schristos
191377e23a2Schristos /* Initialize the stabs information we need to keep track of. */
192377e23a2Schristos first = TRUE;
193377e23a2Schristos sinfo->strings = _bfd_stringtab_init ();
194377e23a2Schristos if (sinfo->strings == NULL)
195377e23a2Schristos goto error_return;
196377e23a2Schristos /* Make sure the first byte is zero. */
197377e23a2Schristos (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
198377e23a2Schristos if (! bfd_hash_table_init (&sinfo->includes,
199377e23a2Schristos stab_link_includes_newfunc,
200377e23a2Schristos sizeof (struct stab_link_includes_entry)))
201377e23a2Schristos goto error_return;
202377e23a2Schristos flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING
203377e23a2Schristos | SEC_LINKER_CREATED);
204377e23a2Schristos sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr",
205377e23a2Schristos flags);
206377e23a2Schristos if (sinfo->stabstr == NULL)
207377e23a2Schristos goto error_return;
208377e23a2Schristos }
209377e23a2Schristos
210377e23a2Schristos /* Initialize the information we are going to store for this .stab
211377e23a2Schristos section. */
212377e23a2Schristos count = stabsec->size / STABSIZE;
213377e23a2Schristos
214377e23a2Schristos amt = sizeof (struct stab_section_info);
215377e23a2Schristos amt += (count - 1) * sizeof (bfd_size_type);
216377e23a2Schristos *psecinfo = bfd_alloc (abfd, amt);
217377e23a2Schristos if (*psecinfo == NULL)
218377e23a2Schristos goto error_return;
219377e23a2Schristos
220377e23a2Schristos secinfo = (struct stab_section_info *) *psecinfo;
221377e23a2Schristos secinfo->excls = NULL;
222377e23a2Schristos stabsec->rawsize = stabsec->size;
223377e23a2Schristos secinfo->cumulative_skips = NULL;
224377e23a2Schristos memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
225377e23a2Schristos
226377e23a2Schristos /* Read the stabs information from abfd. */
227377e23a2Schristos if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)
228377e23a2Schristos || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf))
229377e23a2Schristos goto error_return;
230377e23a2Schristos
231377e23a2Schristos /* Look through the stabs symbols, work out the new string indices,
232377e23a2Schristos and identify N_BINCL symbols which can be eliminated. */
233377e23a2Schristos stroff = 0;
234377e23a2Schristos /* The stabs sections can be split when
235377e23a2Schristos -split-by-reloc/-split-by-file is used. We must keep track of
236377e23a2Schristos each stab section's place in the single concatenated string
237377e23a2Schristos table. */
238377e23a2Schristos next_stroff = pstring_offset ? *pstring_offset : 0;
239377e23a2Schristos skip = 0;
240377e23a2Schristos
241377e23a2Schristos symend = stabbuf + stabsec->size;
242377e23a2Schristos for (sym = stabbuf, pstridx = secinfo->stridxs;
243377e23a2Schristos sym < symend;
244377e23a2Schristos sym += STABSIZE, ++pstridx)
245377e23a2Schristos {
246377e23a2Schristos bfd_size_type symstroff;
247377e23a2Schristos int type;
248377e23a2Schristos const char *string;
249377e23a2Schristos
250377e23a2Schristos if (*pstridx != 0)
251377e23a2Schristos /* This symbol has already been handled by an N_BINCL pass. */
252377e23a2Schristos continue;
253377e23a2Schristos
254377e23a2Schristos type = sym[TYPEOFF];
255377e23a2Schristos
256377e23a2Schristos if (type == 0)
257377e23a2Schristos {
258377e23a2Schristos /* Special type 0 stabs indicate the offset to the next
259377e23a2Schristos string table. We only copy the very first one. */
260377e23a2Schristos stroff = next_stroff;
261377e23a2Schristos next_stroff += bfd_get_32 (abfd, sym + 8);
262377e23a2Schristos if (pstring_offset)
263377e23a2Schristos *pstring_offset = next_stroff;
264377e23a2Schristos if (! first)
265377e23a2Schristos {
266377e23a2Schristos *pstridx = (bfd_size_type) -1;
267377e23a2Schristos ++skip;
268377e23a2Schristos continue;
269377e23a2Schristos }
270377e23a2Schristos first = FALSE;
271377e23a2Schristos }
272377e23a2Schristos
273377e23a2Schristos /* Store the string in the hash table, and record the index. */
274377e23a2Schristos symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
275377e23a2Schristos if (symstroff >= stabstrsec->size)
276377e23a2Schristos {
2771c468f90Schristos _bfd_error_handler
2781c468f90Schristos /* xgettext:c-format */
27907163879Schristos (_("%pB(%pA+%#lx): stabs entry has invalid string index"),
280377e23a2Schristos abfd, stabsec, (long) (sym - stabbuf));
281377e23a2Schristos bfd_set_error (bfd_error_bad_value);
282377e23a2Schristos goto error_return;
283377e23a2Schristos }
284377e23a2Schristos string = (char *) stabstrbuf + symstroff;
285377e23a2Schristos *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE);
286377e23a2Schristos
287377e23a2Schristos /* An N_BINCL symbol indicates the start of the stabs entries
288377e23a2Schristos for a header file. We need to scan ahead to the next N_EINCL
289377e23a2Schristos symbol, ignoring nesting, adding up all the characters in the
290377e23a2Schristos symbol names, not including the file numbers in types (the
291377e23a2Schristos first number after an open parenthesis). */
292377e23a2Schristos if (type == (int) N_BINCL)
293377e23a2Schristos {
294377e23a2Schristos bfd_vma sum_chars;
295377e23a2Schristos bfd_vma num_chars;
296377e23a2Schristos bfd_vma buf_len = 0;
297377e23a2Schristos char * symb;
298377e23a2Schristos char * symb_rover;
299377e23a2Schristos int nest;
300377e23a2Schristos bfd_byte * incl_sym;
301377e23a2Schristos struct stab_link_includes_entry * incl_entry;
302377e23a2Schristos struct stab_link_includes_totals * t;
303377e23a2Schristos struct stab_excl_list * ne;
304377e23a2Schristos
305377e23a2Schristos symb = symb_rover = NULL;
306377e23a2Schristos sum_chars = num_chars = 0;
307377e23a2Schristos nest = 0;
308377e23a2Schristos
309377e23a2Schristos for (incl_sym = sym + STABSIZE;
310377e23a2Schristos incl_sym < symend;
311377e23a2Schristos incl_sym += STABSIZE)
312377e23a2Schristos {
313377e23a2Schristos int incl_type;
314377e23a2Schristos
315377e23a2Schristos incl_type = incl_sym[TYPEOFF];
316377e23a2Schristos if (incl_type == 0)
317377e23a2Schristos break;
318377e23a2Schristos else if (incl_type == (int) N_EXCL)
319377e23a2Schristos continue;
320377e23a2Schristos else if (incl_type == (int) N_EINCL)
321377e23a2Schristos {
322377e23a2Schristos if (nest == 0)
323377e23a2Schristos break;
324377e23a2Schristos --nest;
325377e23a2Schristos }
326377e23a2Schristos else if (incl_type == (int) N_BINCL)
327377e23a2Schristos ++nest;
328377e23a2Schristos else if (nest == 0)
329377e23a2Schristos {
330377e23a2Schristos const char *str;
331377e23a2Schristos
332377e23a2Schristos str = ((char *) stabstrbuf
333377e23a2Schristos + stroff
334377e23a2Schristos + bfd_get_32 (abfd, incl_sym + STRDXOFF));
335377e23a2Schristos for (; *str != '\0'; str++)
336377e23a2Schristos {
337377e23a2Schristos if (num_chars >= buf_len)
338377e23a2Schristos {
339377e23a2Schristos buf_len += 32 * 1024;
340377e23a2Schristos symb = (char *) bfd_realloc_or_free (symb, buf_len);
341377e23a2Schristos if (symb == NULL)
342377e23a2Schristos goto error_return;
343377e23a2Schristos symb_rover = symb + num_chars;
344377e23a2Schristos }
345377e23a2Schristos * symb_rover ++ = * str;
346377e23a2Schristos sum_chars += *str;
347377e23a2Schristos num_chars ++;
348377e23a2Schristos if (*str == '(')
349377e23a2Schristos {
350377e23a2Schristos /* Skip the file number. */
351377e23a2Schristos ++str;
352377e23a2Schristos while (ISDIGIT (*str))
353377e23a2Schristos ++str;
354377e23a2Schristos --str;
355377e23a2Schristos }
356377e23a2Schristos }
357377e23a2Schristos }
358377e23a2Schristos }
359377e23a2Schristos
360377e23a2Schristos BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
361377e23a2Schristos
362377e23a2Schristos /* If we have already included a header file with the same
363377e23a2Schristos value, then replaced this one with an N_EXCL symbol. */
364377e23a2Schristos incl_entry = (struct stab_link_includes_entry * )
365377e23a2Schristos bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE);
366377e23a2Schristos if (incl_entry == NULL)
367377e23a2Schristos goto error_return;
368377e23a2Schristos
369377e23a2Schristos for (t = incl_entry->totals; t != NULL; t = t->next)
370377e23a2Schristos if (t->sum_chars == sum_chars
371377e23a2Schristos && t->num_chars == num_chars
372377e23a2Schristos && memcmp (t->symb, symb, num_chars) == 0)
373377e23a2Schristos break;
374377e23a2Schristos
375377e23a2Schristos /* Record this symbol, so that we can set the value
376377e23a2Schristos correctly. */
377377e23a2Schristos amt = sizeof *ne;
378377e23a2Schristos ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
379377e23a2Schristos if (ne == NULL)
380377e23a2Schristos goto error_return;
381377e23a2Schristos ne->offset = sym - stabbuf;
382377e23a2Schristos ne->val = sum_chars;
383377e23a2Schristos ne->type = (int) N_BINCL;
384377e23a2Schristos ne->next = secinfo->excls;
385377e23a2Schristos secinfo->excls = ne;
386377e23a2Schristos
387377e23a2Schristos if (t == NULL)
388377e23a2Schristos {
389377e23a2Schristos /* This is the first time we have seen this header file
390377e23a2Schristos with this set of stabs strings. */
391377e23a2Schristos t = (struct stab_link_includes_totals *)
392377e23a2Schristos bfd_hash_allocate (&sinfo->includes, sizeof *t);
393377e23a2Schristos if (t == NULL)
394377e23a2Schristos goto error_return;
395377e23a2Schristos t->sum_chars = sum_chars;
396377e23a2Schristos t->num_chars = num_chars;
397377e23a2Schristos /* Trim data down. */
398377e23a2Schristos t->symb = symb = (char *) bfd_realloc_or_free (symb, num_chars);
399377e23a2Schristos t->next = incl_entry->totals;
400377e23a2Schristos incl_entry->totals = t;
401377e23a2Schristos }
402377e23a2Schristos else
403377e23a2Schristos {
404377e23a2Schristos bfd_size_type *incl_pstridx;
405377e23a2Schristos
406377e23a2Schristos /* We have seen this header file before. Tell the final
407377e23a2Schristos pass to change the type to N_EXCL. */
408377e23a2Schristos ne->type = (int) N_EXCL;
409377e23a2Schristos
410377e23a2Schristos /* Free off superfluous symbols. */
411377e23a2Schristos free (symb);
412377e23a2Schristos
413377e23a2Schristos /* Mark the skipped symbols. */
414377e23a2Schristos
415377e23a2Schristos nest = 0;
416377e23a2Schristos for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
417377e23a2Schristos incl_sym < symend;
418377e23a2Schristos incl_sym += STABSIZE, ++incl_pstridx)
419377e23a2Schristos {
420377e23a2Schristos int incl_type;
421377e23a2Schristos
422377e23a2Schristos incl_type = incl_sym[TYPEOFF];
423377e23a2Schristos
424377e23a2Schristos if (incl_type == (int) N_EINCL)
425377e23a2Schristos {
426377e23a2Schristos if (nest == 0)
427377e23a2Schristos {
428377e23a2Schristos *incl_pstridx = (bfd_size_type) -1;
429377e23a2Schristos ++skip;
430377e23a2Schristos break;
431377e23a2Schristos }
432377e23a2Schristos --nest;
433377e23a2Schristos }
434377e23a2Schristos else if (incl_type == (int) N_BINCL)
435377e23a2Schristos ++nest;
436377e23a2Schristos else if (incl_type == (int) N_EXCL)
437377e23a2Schristos /* Keep existing exclusion marks. */
438377e23a2Schristos continue;
439377e23a2Schristos else if (nest == 0)
440377e23a2Schristos {
441377e23a2Schristos *incl_pstridx = (bfd_size_type) -1;
442377e23a2Schristos ++skip;
443377e23a2Schristos }
444377e23a2Schristos }
445377e23a2Schristos }
446377e23a2Schristos }
447377e23a2Schristos }
448377e23a2Schristos
449377e23a2Schristos free (stabbuf);
450377e23a2Schristos stabbuf = NULL;
451377e23a2Schristos free (stabstrbuf);
452377e23a2Schristos stabstrbuf = NULL;
453377e23a2Schristos
454377e23a2Schristos /* We need to set the section sizes such that the linker will
455377e23a2Schristos compute the output section sizes correctly. We set the .stab
456377e23a2Schristos size to not include the entries we don't want. We set
457377e23a2Schristos SEC_EXCLUDE for the .stabstr section, so that it will be dropped
458377e23a2Schristos from the link. We record the size of the strtab in the first
459377e23a2Schristos .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
460377e23a2Schristos for that section. */
461377e23a2Schristos stabsec->size = (count - skip) * STABSIZE;
462377e23a2Schristos if (stabsec->size == 0)
463377e23a2Schristos stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
464377e23a2Schristos stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP;
465377e23a2Schristos sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings);
466377e23a2Schristos
467377e23a2Schristos /* Calculate the `cumulative_skips' array now that stabs have been
468377e23a2Schristos deleted for this section. */
469377e23a2Schristos
470377e23a2Schristos if (skip != 0)
471377e23a2Schristos {
472377e23a2Schristos bfd_size_type i, offset;
473377e23a2Schristos bfd_size_type *pskips;
474377e23a2Schristos
475377e23a2Schristos amt = count * sizeof (bfd_size_type);
476377e23a2Schristos secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
477377e23a2Schristos if (secinfo->cumulative_skips == NULL)
478377e23a2Schristos goto error_return;
479377e23a2Schristos
480377e23a2Schristos pskips = secinfo->cumulative_skips;
481377e23a2Schristos pstridx = secinfo->stridxs;
482377e23a2Schristos offset = 0;
483377e23a2Schristos
484377e23a2Schristos for (i = 0; i < count; i++, pskips++, pstridx++)
485377e23a2Schristos {
486377e23a2Schristos *pskips = offset;
487377e23a2Schristos if (*pstridx == (bfd_size_type) -1)
488377e23a2Schristos offset += STABSIZE;
489377e23a2Schristos }
490377e23a2Schristos
491377e23a2Schristos BFD_ASSERT (offset != 0);
492377e23a2Schristos }
493377e23a2Schristos
494377e23a2Schristos return TRUE;
495377e23a2Schristos
496377e23a2Schristos error_return:
497377e23a2Schristos free (stabbuf);
498377e23a2Schristos free (stabstrbuf);
499377e23a2Schristos return FALSE;
500377e23a2Schristos }
501377e23a2Schristos
502377e23a2Schristos /* This function is called for each input file before the stab
503377e23a2Schristos section is relocated. It discards stab entries for discarded
504377e23a2Schristos functions and variables. The function returns TRUE iff
505377e23a2Schristos any entries have been deleted.
506377e23a2Schristos */
507377e23a2Schristos
508377e23a2Schristos bfd_boolean
_bfd_discard_section_stabs(bfd * abfd,asection * stabsec,void * psecinfo,bfd_boolean (* reloc_symbol_deleted_p)(bfd_vma,void *),void * cookie)509377e23a2Schristos _bfd_discard_section_stabs (bfd *abfd,
510377e23a2Schristos asection *stabsec,
511377e23a2Schristos void * psecinfo,
512377e23a2Schristos bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
513377e23a2Schristos void * cookie)
514377e23a2Schristos {
515377e23a2Schristos bfd_size_type count, amt;
516377e23a2Schristos struct stab_section_info *secinfo;
517377e23a2Schristos bfd_byte *stabbuf = NULL;
518377e23a2Schristos bfd_byte *sym, *symend;
519377e23a2Schristos bfd_size_type skip;
520377e23a2Schristos bfd_size_type *pstridx;
521377e23a2Schristos int deleting;
522377e23a2Schristos
523377e23a2Schristos if (stabsec->size == 0)
524377e23a2Schristos /* This file does not contain stabs debugging information. */
525377e23a2Schristos return FALSE;
526377e23a2Schristos
527377e23a2Schristos if (stabsec->size % STABSIZE != 0)
528377e23a2Schristos /* Something is wrong with the format of these stab symbols.
529377e23a2Schristos Don't try to optimize them. */
530377e23a2Schristos return FALSE;
531377e23a2Schristos
532377e23a2Schristos if ((stabsec->output_section != NULL
533377e23a2Schristos && bfd_is_abs_section (stabsec->output_section)))
534377e23a2Schristos /* At least one of the sections is being discarded from the
535377e23a2Schristos link, so we should just ignore them. */
536377e23a2Schristos return FALSE;
537377e23a2Schristos
5385e098073Schristos /* We should have initialized our data in _bfd_link_section_stabs.
539377e23a2Schristos If there was some bizarre error reading the string sections, though,
540377e23a2Schristos we might not have. Bail rather than asserting. */
541377e23a2Schristos if (psecinfo == NULL)
542377e23a2Schristos return FALSE;
543377e23a2Schristos
544377e23a2Schristos count = stabsec->rawsize / STABSIZE;
545377e23a2Schristos secinfo = (struct stab_section_info *) psecinfo;
546377e23a2Schristos
547377e23a2Schristos /* Read the stabs information from abfd. */
548377e23a2Schristos if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf))
549377e23a2Schristos goto error_return;
550377e23a2Schristos
551377e23a2Schristos /* Look through the stabs symbols and discard any information for
552377e23a2Schristos discarded functions. */
553377e23a2Schristos skip = 0;
554377e23a2Schristos deleting = -1;
555377e23a2Schristos
556377e23a2Schristos symend = stabbuf + stabsec->rawsize;
557377e23a2Schristos for (sym = stabbuf, pstridx = secinfo->stridxs;
558377e23a2Schristos sym < symend;
559377e23a2Schristos sym += STABSIZE, ++pstridx)
560377e23a2Schristos {
561377e23a2Schristos int type;
562377e23a2Schristos
563377e23a2Schristos if (*pstridx == (bfd_size_type) -1)
564377e23a2Schristos /* This stab was deleted in a previous pass. */
565377e23a2Schristos continue;
566377e23a2Schristos
567377e23a2Schristos type = sym[TYPEOFF];
568377e23a2Schristos
569377e23a2Schristos if (type == (int) N_FUN)
570377e23a2Schristos {
571377e23a2Schristos int strx = bfd_get_32 (abfd, sym + STRDXOFF);
572377e23a2Schristos
573377e23a2Schristos if (strx == 0)
574377e23a2Schristos {
575377e23a2Schristos if (deleting)
576377e23a2Schristos {
577377e23a2Schristos skip++;
578377e23a2Schristos *pstridx = -1;
579377e23a2Schristos }
580377e23a2Schristos deleting = -1;
581377e23a2Schristos continue;
582377e23a2Schristos }
583377e23a2Schristos deleting = 0;
584377e23a2Schristos if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
585377e23a2Schristos deleting = 1;
586377e23a2Schristos }
587377e23a2Schristos
588377e23a2Schristos if (deleting == 1)
589377e23a2Schristos {
590377e23a2Schristos *pstridx = -1;
591377e23a2Schristos skip++;
592377e23a2Schristos }
593377e23a2Schristos else if (deleting == -1)
594377e23a2Schristos {
595377e23a2Schristos /* Outside of a function. Check for deleted variables. */
596377e23a2Schristos if (type == (int) N_STSYM || type == (int) N_LCSYM)
597377e23a2Schristos if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
598377e23a2Schristos {
599377e23a2Schristos *pstridx = -1;
600377e23a2Schristos skip ++;
601377e23a2Schristos }
602377e23a2Schristos /* We should also check for N_GSYM entries which reference a
603377e23a2Schristos deleted global, but those are less harmful to debuggers
604377e23a2Schristos and would require parsing the stab strings. */
605377e23a2Schristos }
606377e23a2Schristos }
607377e23a2Schristos
608377e23a2Schristos free (stabbuf);
609377e23a2Schristos stabbuf = NULL;
610377e23a2Schristos
611377e23a2Schristos /* Shrink the stabsec as needed. */
612377e23a2Schristos stabsec->size -= skip * STABSIZE;
613377e23a2Schristos if (stabsec->size == 0)
614377e23a2Schristos stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
615377e23a2Schristos
616377e23a2Schristos /* Recalculate the `cumulative_skips' array now that stabs have been
617377e23a2Schristos deleted for this section. */
618377e23a2Schristos
619377e23a2Schristos if (skip != 0)
620377e23a2Schristos {
621377e23a2Schristos bfd_size_type i, offset;
622377e23a2Schristos bfd_size_type *pskips;
623377e23a2Schristos
624377e23a2Schristos if (secinfo->cumulative_skips == NULL)
625377e23a2Schristos {
626377e23a2Schristos amt = count * sizeof (bfd_size_type);
627377e23a2Schristos secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
628377e23a2Schristos if (secinfo->cumulative_skips == NULL)
629377e23a2Schristos goto error_return;
630377e23a2Schristos }
631377e23a2Schristos
632377e23a2Schristos pskips = secinfo->cumulative_skips;
633377e23a2Schristos pstridx = secinfo->stridxs;
634377e23a2Schristos offset = 0;
635377e23a2Schristos
636377e23a2Schristos for (i = 0; i < count; i++, pskips++, pstridx++)
637377e23a2Schristos {
638377e23a2Schristos *pskips = offset;
639377e23a2Schristos if (*pstridx == (bfd_size_type) -1)
640377e23a2Schristos offset += STABSIZE;
641377e23a2Schristos }
642377e23a2Schristos
643377e23a2Schristos BFD_ASSERT (offset != 0);
644377e23a2Schristos }
645377e23a2Schristos
646377e23a2Schristos return skip > 0;
647377e23a2Schristos
648377e23a2Schristos error_return:
649377e23a2Schristos free (stabbuf);
650377e23a2Schristos return FALSE;
651377e23a2Schristos }
652377e23a2Schristos
653377e23a2Schristos /* Write out the stab section. This is called with the relocated
654377e23a2Schristos contents. */
655377e23a2Schristos
656377e23a2Schristos bfd_boolean
_bfd_write_section_stabs(bfd * output_bfd,struct stab_info * sinfo,asection * stabsec,void ** psecinfo,bfd_byte * contents)657377e23a2Schristos _bfd_write_section_stabs (bfd *output_bfd,
658377e23a2Schristos struct stab_info *sinfo,
659377e23a2Schristos asection *stabsec,
660377e23a2Schristos void * *psecinfo,
661377e23a2Schristos bfd_byte *contents)
662377e23a2Schristos {
663377e23a2Schristos struct stab_section_info *secinfo;
664377e23a2Schristos struct stab_excl_list *e;
665377e23a2Schristos bfd_byte *sym, *tosym, *symend;
666377e23a2Schristos bfd_size_type *pstridx;
667377e23a2Schristos
668377e23a2Schristos secinfo = (struct stab_section_info *) *psecinfo;
669377e23a2Schristos
670377e23a2Schristos if (secinfo == NULL)
671377e23a2Schristos return bfd_set_section_contents (output_bfd, stabsec->output_section,
672377e23a2Schristos contents, stabsec->output_offset,
673377e23a2Schristos stabsec->size);
674377e23a2Schristos
675377e23a2Schristos /* Handle each N_BINCL entry. */
676377e23a2Schristos for (e = secinfo->excls; e != NULL; e = e->next)
677377e23a2Schristos {
678377e23a2Schristos bfd_byte *excl_sym;
679377e23a2Schristos
680377e23a2Schristos BFD_ASSERT (e->offset < stabsec->rawsize);
681377e23a2Schristos excl_sym = contents + e->offset;
682377e23a2Schristos bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
683377e23a2Schristos excl_sym[TYPEOFF] = e->type;
684377e23a2Schristos }
685377e23a2Schristos
686377e23a2Schristos /* Copy over all the stabs symbols, omitting the ones we don't want,
687377e23a2Schristos and correcting the string indices for those we do want. */
688377e23a2Schristos tosym = contents;
689377e23a2Schristos symend = contents + stabsec->rawsize;
690377e23a2Schristos for (sym = contents, pstridx = secinfo->stridxs;
691377e23a2Schristos sym < symend;
692377e23a2Schristos sym += STABSIZE, ++pstridx)
693377e23a2Schristos {
694377e23a2Schristos if (*pstridx != (bfd_size_type) -1)
695377e23a2Schristos {
696377e23a2Schristos if (tosym != sym)
697377e23a2Schristos memcpy (tosym, sym, STABSIZE);
698377e23a2Schristos bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
699377e23a2Schristos
700377e23a2Schristos if (sym[TYPEOFF] == 0)
701377e23a2Schristos {
702377e23a2Schristos /* This is the header symbol for the stabs section. We
703377e23a2Schristos don't really need one, since we have merged all the
704377e23a2Schristos input stabs sections into one, but we generate one
705377e23a2Schristos for the benefit of readers which expect to see one. */
706377e23a2Schristos BFD_ASSERT (sym == contents);
707377e23a2Schristos bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
708377e23a2Schristos tosym + VALOFF);
709377e23a2Schristos bfd_put_16 (output_bfd,
710377e23a2Schristos stabsec->output_section->size / STABSIZE - 1,
711377e23a2Schristos tosym + DESCOFF);
712377e23a2Schristos }
713377e23a2Schristos
714377e23a2Schristos tosym += STABSIZE;
715377e23a2Schristos }
716377e23a2Schristos }
717377e23a2Schristos
718377e23a2Schristos BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);
719377e23a2Schristos
720377e23a2Schristos return bfd_set_section_contents (output_bfd, stabsec->output_section,
721377e23a2Schristos contents, (file_ptr) stabsec->output_offset,
722377e23a2Schristos stabsec->size);
723377e23a2Schristos }
724377e23a2Schristos
725377e23a2Schristos /* Write out the .stabstr section. */
726377e23a2Schristos
727377e23a2Schristos bfd_boolean
_bfd_write_stab_strings(bfd * output_bfd,struct stab_info * sinfo)728377e23a2Schristos _bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo)
729377e23a2Schristos {
730377e23a2Schristos if (bfd_is_abs_section (sinfo->stabstr->output_section))
731377e23a2Schristos /* The section was discarded from the link. */
732377e23a2Schristos return TRUE;
733377e23a2Schristos
734377e23a2Schristos BFD_ASSERT ((sinfo->stabstr->output_offset
735377e23a2Schristos + _bfd_stringtab_size (sinfo->strings))
736377e23a2Schristos <= sinfo->stabstr->output_section->size);
737377e23a2Schristos
738377e23a2Schristos if (bfd_seek (output_bfd,
739377e23a2Schristos (file_ptr) (sinfo->stabstr->output_section->filepos
740377e23a2Schristos + sinfo->stabstr->output_offset),
741377e23a2Schristos SEEK_SET) != 0)
742377e23a2Schristos return FALSE;
743377e23a2Schristos
744377e23a2Schristos if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
745377e23a2Schristos return FALSE;
746377e23a2Schristos
747377e23a2Schristos /* We no longer need the stabs information. */
748377e23a2Schristos _bfd_stringtab_free (sinfo->strings);
749377e23a2Schristos bfd_hash_table_free (&sinfo->includes);
750377e23a2Schristos
751377e23a2Schristos return TRUE;
752377e23a2Schristos }
753377e23a2Schristos
754377e23a2Schristos /* Adjust an address in the .stab section. Given OFFSET within
755377e23a2Schristos STABSEC, this returns the new offset in the adjusted stab section,
756377e23a2Schristos or -1 if the address refers to a stab which has been removed. */
757377e23a2Schristos
758377e23a2Schristos bfd_vma
_bfd_stab_section_offset(asection * stabsec,void * psecinfo,bfd_vma offset)759377e23a2Schristos _bfd_stab_section_offset (asection *stabsec,
760377e23a2Schristos void * psecinfo,
761377e23a2Schristos bfd_vma offset)
762377e23a2Schristos {
763377e23a2Schristos struct stab_section_info *secinfo;
764377e23a2Schristos
765377e23a2Schristos secinfo = (struct stab_section_info *) psecinfo;
766377e23a2Schristos
767377e23a2Schristos if (secinfo == NULL)
768377e23a2Schristos return offset;
769377e23a2Schristos
770377e23a2Schristos if (offset >= stabsec->rawsize)
771377e23a2Schristos return offset - stabsec->rawsize + stabsec->size;
772377e23a2Schristos
773377e23a2Schristos if (secinfo->cumulative_skips)
774377e23a2Schristos {
775377e23a2Schristos bfd_vma i;
776377e23a2Schristos
777377e23a2Schristos i = offset / STABSIZE;
778377e23a2Schristos
779377e23a2Schristos if (secinfo->stridxs [i] == (bfd_size_type) -1)
780377e23a2Schristos return (bfd_vma) -1;
781377e23a2Schristos
782377e23a2Schristos return offset - secinfo->cumulative_skips [i];
783377e23a2Schristos }
784377e23a2Schristos
785377e23a2Schristos return offset;
786377e23a2Schristos }
787