ecofflink.c revision 1.1.1.10 1 1.1 skrll /* Routines to link ECOFF debugging information.
2 1.1.1.10 christos Copyright (C) 1993-2025 Free Software Foundation, Inc.
3 1.1 skrll Written by Ian Lance Taylor, Cygnus Support, <ian (at) cygnus.com>.
4 1.1 skrll
5 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
6 1.1 skrll
7 1.1 skrll This program is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3 of the License, or
10 1.1 skrll (at your option) any later version.
11 1.1 skrll
12 1.1 skrll This program is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with this program; if not, write to the Free Software
19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 skrll MA 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1 skrll #include "bfd.h"
24 1.1 skrll #include "bfdlink.h"
25 1.1 skrll #include "libbfd.h"
26 1.1.1.7 christos #include "ecoff-bfd.h"
27 1.1 skrll #include "objalloc.h"
28 1.1 skrll #include "aout/stab_gnu.h"
29 1.1 skrll #include "coff/internal.h"
30 1.1 skrll #include "coff/sym.h"
31 1.1 skrll #include "coff/symconst.h"
32 1.1 skrll #include "coff/ecoff.h"
33 1.1 skrll #include "libcoff.h"
34 1.1 skrll #include "libecoff.h"
35 1.1.1.10 christos
36 1.1.1.10 christos /* ECOFF uses two common sections. One is the usual one, and the
37 1.1.1.10 christos other is for small objects. All the small objects are kept
38 1.1.1.10 christos together, and then referenced via the gp pointer, which yields
39 1.1.1.10 christos faster assembler code. This is what we use for the small common
40 1.1.1.10 christos section. */
41 1.1.1.10 christos static const asymbol ecoff_scom_symbol =
42 1.1.1.10 christos GLOBAL_SYM_INIT (SCOMMON, &_bfd_ecoff_scom_section);
43 1.1.1.10 christos asection _bfd_ecoff_scom_section =
44 1.1.1.10 christos BFD_FAKE_SECTION (_bfd_ecoff_scom_section, &ecoff_scom_symbol,
45 1.1.1.10 christos SCOMMON, 0, SEC_IS_COMMON | SEC_SMALL_DATA);
46 1.1.1.10 christos
47 1.1 skrll /* Routines to swap auxiliary information in and out. I am assuming
48 1.1 skrll that the auxiliary information format is always going to be target
49 1.1 skrll independent. */
50 1.1 skrll
51 1.1 skrll /* Swap in a type information record.
52 1.1 skrll BIGEND says whether AUX symbols are big-endian or little-endian; this
53 1.1 skrll info comes from the file header record (fh-fBigendian). */
54 1.1 skrll
55 1.1 skrll void
56 1.1.1.3 christos _bfd_ecoff_swap_tir_in (int bigend, const struct tir_ext *ext_copy,
57 1.1.1.3 christos TIR *intern)
58 1.1 skrll {
59 1.1 skrll struct tir_ext ext[1];
60 1.1 skrll
61 1.1 skrll *ext = *ext_copy; /* Make it reasonable to do in-place. */
62 1.1 skrll
63 1.1 skrll /* now the fun stuff... */
64 1.1.1.3 christos if (bigend)
65 1.1.1.3 christos {
66 1.1.1.6 christos intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
67 1.1.1.6 christos intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
68 1.1.1.6 christos intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
69 1.1.1.6 christos >> TIR_BITS1_BT_SH_BIG;
70 1.1.1.6 christos intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
71 1.1.1.3 christos >> TIR_BITS_TQ4_SH_BIG;
72 1.1.1.6 christos intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
73 1.1.1.3 christos >> TIR_BITS_TQ5_SH_BIG;
74 1.1.1.6 christos intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
75 1.1.1.3 christos >> TIR_BITS_TQ0_SH_BIG;
76 1.1.1.6 christos intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
77 1.1.1.3 christos >> TIR_BITS_TQ1_SH_BIG;
78 1.1.1.6 christos intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
79 1.1.1.3 christos >> TIR_BITS_TQ2_SH_BIG;
80 1.1.1.6 christos intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
81 1.1.1.3 christos >> TIR_BITS_TQ3_SH_BIG;
82 1.1.1.3 christos }
83 1.1.1.3 christos else
84 1.1.1.3 christos {
85 1.1.1.6 christos intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
86 1.1.1.6 christos intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
87 1.1.1.6 christos intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
88 1.1.1.3 christos >> TIR_BITS1_BT_SH_LITTLE;
89 1.1.1.6 christos intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
90 1.1.1.3 christos >> TIR_BITS_TQ4_SH_LITTLE;
91 1.1.1.6 christos intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
92 1.1.1.3 christos >> TIR_BITS_TQ5_SH_LITTLE;
93 1.1.1.6 christos intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
94 1.1.1.3 christos >> TIR_BITS_TQ0_SH_LITTLE;
95 1.1.1.6 christos intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
96 1.1.1.3 christos >> TIR_BITS_TQ1_SH_LITTLE;
97 1.1.1.6 christos intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
98 1.1.1.3 christos >> TIR_BITS_TQ2_SH_LITTLE;
99 1.1.1.6 christos intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
100 1.1.1.3 christos >> TIR_BITS_TQ3_SH_LITTLE;
101 1.1.1.3 christos }
102 1.1 skrll
103 1.1 skrll #ifdef TEST
104 1.1 skrll if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
105 1.1 skrll abort ();
106 1.1 skrll #endif
107 1.1 skrll }
108 1.1 skrll
109 1.1 skrll /* Swap out a type information record.
110 1.1 skrll BIGEND says whether AUX symbols are big-endian or little-endian; this
111 1.1 skrll info comes from the file header record (fh-fBigendian). */
112 1.1 skrll
113 1.1 skrll void
114 1.1.1.3 christos _bfd_ecoff_swap_tir_out (int bigend,
115 1.1.1.3 christos const TIR *intern_copy,
116 1.1.1.3 christos struct tir_ext *ext)
117 1.1 skrll {
118 1.1 skrll TIR intern[1];
119 1.1 skrll
120 1.1 skrll *intern = *intern_copy; /* Make it reasonable to do in-place. */
121 1.1 skrll
122 1.1 skrll /* now the fun stuff... */
123 1.1.1.3 christos if (bigend)
124 1.1.1.3 christos {
125 1.1.1.3 christos ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
126 1.1 skrll | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
127 1.1 skrll | ((intern->bt << TIR_BITS1_BT_SH_BIG)
128 1.1 skrll & TIR_BITS1_BT_BIG));
129 1.1.1.3 christos ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
130 1.1 skrll & TIR_BITS_TQ4_BIG)
131 1.1 skrll | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
132 1.1 skrll & TIR_BITS_TQ5_BIG));
133 1.1.1.3 christos ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
134 1.1 skrll & TIR_BITS_TQ0_BIG)
135 1.1 skrll | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
136 1.1 skrll & TIR_BITS_TQ1_BIG));
137 1.1.1.3 christos ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
138 1.1 skrll & TIR_BITS_TQ2_BIG)
139 1.1 skrll | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
140 1.1 skrll & TIR_BITS_TQ3_BIG));
141 1.1.1.3 christos }
142 1.1.1.3 christos else
143 1.1.1.3 christos {
144 1.1.1.3 christos ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
145 1.1 skrll | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
146 1.1 skrll | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
147 1.1 skrll & TIR_BITS1_BT_LITTLE));
148 1.1.1.3 christos ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
149 1.1 skrll & TIR_BITS_TQ4_LITTLE)
150 1.1 skrll | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
151 1.1 skrll & TIR_BITS_TQ5_LITTLE));
152 1.1.1.3 christos ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
153 1.1 skrll & TIR_BITS_TQ0_LITTLE)
154 1.1 skrll | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
155 1.1 skrll & TIR_BITS_TQ1_LITTLE));
156 1.1.1.3 christos ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
157 1.1 skrll & TIR_BITS_TQ2_LITTLE)
158 1.1 skrll | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
159 1.1 skrll & TIR_BITS_TQ3_LITTLE));
160 1.1.1.3 christos }
161 1.1 skrll
162 1.1 skrll #ifdef TEST
163 1.1 skrll if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
164 1.1 skrll abort ();
165 1.1 skrll #endif
166 1.1 skrll }
167 1.1 skrll
168 1.1 skrll /* Swap in a relative symbol record. BIGEND says whether it is in
169 1.1 skrll big-endian or little-endian format.*/
170 1.1 skrll
171 1.1 skrll void
172 1.1.1.3 christos _bfd_ecoff_swap_rndx_in (int bigend,
173 1.1.1.3 christos const struct rndx_ext *ext_copy,
174 1.1.1.3 christos RNDXR *intern)
175 1.1 skrll {
176 1.1 skrll struct rndx_ext ext[1];
177 1.1 skrll
178 1.1 skrll *ext = *ext_copy; /* Make it reasonable to do in-place. */
179 1.1 skrll
180 1.1 skrll /* now the fun stuff... */
181 1.1.1.3 christos if (bigend)
182 1.1.1.3 christos {
183 1.1.1.3 christos intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
184 1.1 skrll | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
185 1.1.1.6 christos >> RNDX_BITS1_RFD_SH_BIG);
186 1.1.1.3 christos intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
187 1.1.1.6 christos << RNDX_BITS1_INDEX_SH_LEFT_BIG)
188 1.1 skrll | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
189 1.1 skrll | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
190 1.1.1.3 christos }
191 1.1.1.3 christos else
192 1.1.1.3 christos {
193 1.1.1.3 christos intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
194 1.1 skrll | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
195 1.1.1.6 christos << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
196 1.1.1.3 christos intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
197 1.1.1.6 christos >> RNDX_BITS1_INDEX_SH_LITTLE)
198 1.1 skrll | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
199 1.1 skrll | ((unsigned int) ext->r_bits[3]
200 1.1 skrll << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
201 1.1.1.3 christos }
202 1.1 skrll
203 1.1 skrll #ifdef TEST
204 1.1 skrll if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
205 1.1 skrll abort ();
206 1.1 skrll #endif
207 1.1 skrll }
208 1.1 skrll
209 1.1 skrll /* Swap out a relative symbol record. BIGEND says whether it is in
210 1.1 skrll big-endian or little-endian format.*/
211 1.1 skrll
212 1.1 skrll void
213 1.1.1.3 christos _bfd_ecoff_swap_rndx_out (int bigend,
214 1.1.1.3 christos const RNDXR *intern_copy,
215 1.1.1.3 christos struct rndx_ext *ext)
216 1.1 skrll {
217 1.1 skrll RNDXR intern[1];
218 1.1 skrll
219 1.1 skrll *intern = *intern_copy; /* Make it reasonable to do in-place. */
220 1.1 skrll
221 1.1 skrll /* now the fun stuff... */
222 1.1.1.3 christos if (bigend)
223 1.1.1.3 christos {
224 1.1.1.3 christos ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
225 1.1.1.3 christos ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
226 1.1 skrll & RNDX_BITS1_RFD_BIG)
227 1.1 skrll | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
228 1.1 skrll & RNDX_BITS1_INDEX_BIG));
229 1.1.1.3 christos ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
230 1.1.1.3 christos ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
231 1.1.1.3 christos }
232 1.1.1.3 christos else
233 1.1.1.3 christos {
234 1.1.1.3 christos ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
235 1.1.1.3 christos ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
236 1.1 skrll & RNDX_BITS1_RFD_LITTLE)
237 1.1 skrll | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
238 1.1 skrll & RNDX_BITS1_INDEX_LITTLE));
239 1.1.1.3 christos ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
240 1.1.1.3 christos ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
241 1.1.1.3 christos }
242 1.1 skrll
243 1.1 skrll #ifdef TEST
244 1.1 skrll if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
245 1.1 skrll abort ();
246 1.1 skrll #endif
247 1.1 skrll }
248 1.1 skrll
249 1.1 skrll /* The minimum amount of data to allocate. */
251 1.1 skrll #define ALLOC_SIZE (4064)
252 1.1 skrll
253 1.1 skrll /* Add bytes to a buffer. Return success. */
254 1.1.1.8 christos
255 1.1.1.3 christos static bool
256 1.1 skrll ecoff_add_bytes (char **buf, char **bufend, size_t need)
257 1.1 skrll {
258 1.1 skrll size_t have;
259 1.1 skrll size_t want;
260 1.1 skrll char *newbuf;
261 1.1 skrll
262 1.1 skrll have = *bufend - *buf;
263 1.1 skrll if (have > need)
264 1.1 skrll want = ALLOC_SIZE;
265 1.1 skrll else
266 1.1 skrll {
267 1.1 skrll want = need - have;
268 1.1 skrll if (want < ALLOC_SIZE)
269 1.1 skrll want = ALLOC_SIZE;
270 1.1 skrll }
271 1.1 skrll newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
272 1.1.1.8 christos if (newbuf == NULL)
273 1.1 skrll return false;
274 1.1 skrll *buf = newbuf;
275 1.1.1.8 christos *bufend = *buf + have + want;
276 1.1 skrll return true;
277 1.1 skrll }
278 1.1 skrll
279 1.1 skrll /* We keep a hash table which maps strings to numbers. We use it to
280 1.1 skrll map FDR names to indices in the output file, and to map local
281 1.1 skrll strings when combining stabs debugging information. */
282 1.1 skrll
283 1.1 skrll struct string_hash_entry
284 1.1 skrll {
285 1.1 skrll struct bfd_hash_entry root;
286 1.1 skrll /* FDR index or string table offset. */
287 1.1 skrll long val;
288 1.1 skrll /* Next entry in string table. */
289 1.1 skrll struct string_hash_entry *next;
290 1.1 skrll };
291 1.1 skrll
292 1.1 skrll struct string_hash_table
293 1.1 skrll {
294 1.1 skrll struct bfd_hash_table table;
295 1.1 skrll };
296 1.1 skrll
297 1.1 skrll /* Routine to create an entry in a string hash table. */
298 1.1 skrll
299 1.1.1.3 christos static struct bfd_hash_entry *
300 1.1.1.3 christos string_hash_newfunc (struct bfd_hash_entry *entry,
301 1.1.1.3 christos struct bfd_hash_table *table,
302 1.1 skrll const char *string)
303 1.1 skrll {
304 1.1 skrll struct string_hash_entry *ret = (struct string_hash_entry *) entry;
305 1.1 skrll
306 1.1 skrll /* Allocate the structure if it has not already been allocated by a
307 1.1 skrll subclass. */
308 1.1 skrll if (ret == (struct string_hash_entry *) NULL)
309 1.1 skrll ret = ((struct string_hash_entry *)
310 1.1 skrll bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
311 1.1 skrll if (ret == (struct string_hash_entry *) NULL)
312 1.1 skrll return NULL;
313 1.1 skrll
314 1.1 skrll /* Call the allocation method of the superclass. */
315 1.1 skrll ret = ((struct string_hash_entry *)
316 1.1 skrll bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
317 1.1 skrll
318 1.1 skrll if (ret)
319 1.1 skrll {
320 1.1 skrll /* Initialize the local fields. */
321 1.1 skrll ret->val = -1;
322 1.1 skrll ret->next = NULL;
323 1.1 skrll }
324 1.1 skrll
325 1.1 skrll return (struct bfd_hash_entry *) ret;
326 1.1 skrll }
327 1.1 skrll
328 1.1 skrll /* Look up an entry in an string hash table. */
329 1.1 skrll
330 1.1 skrll #define string_hash_lookup(t, string, create, copy) \
331 1.1 skrll ((struct string_hash_entry *) \
332 1.1 skrll bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
333 1.1 skrll
334 1.1 skrll /* We can't afford to read in all the debugging information when we do
335 1.1 skrll a link. Instead, we build a list of these structures to show how
336 1.1 skrll different parts of the input file map to the output file. */
337 1.1 skrll
338 1.1 skrll struct shuffle
339 1.1 skrll {
340 1.1 skrll /* The next entry in this linked list. */
341 1.1 skrll struct shuffle *next;
342 1.1 skrll /* The length of the information. */
343 1.1 skrll unsigned long size;
344 1.1.1.8 christos /* Whether this information comes from a file or not. */
345 1.1 skrll bool filep;
346 1.1 skrll union
347 1.1 skrll {
348 1.1 skrll struct
349 1.1 skrll {
350 1.1 skrll /* The BFD the data comes from. */
351 1.1 skrll bfd *input_bfd;
352 1.1 skrll /* The offset within input_bfd. */
353 1.1 skrll file_ptr offset;
354 1.1 skrll } file;
355 1.1.1.3 christos /* The data to be written out. */
356 1.1 skrll void * memory;
357 1.1 skrll } u;
358 1.1 skrll };
359 1.1 skrll
360 1.1 skrll /* This structure holds information across calls to
361 1.1 skrll bfd_ecoff_debug_accumulate. */
362 1.1 skrll
363 1.1 skrll struct accumulate
364 1.1 skrll {
365 1.1 skrll /* The FDR hash table. */
366 1.1 skrll struct string_hash_table fdr_hash;
367 1.1 skrll /* The strings hash table. */
368 1.1 skrll struct string_hash_table str_hash;
369 1.1 skrll /* Linked lists describing how to shuffle the input debug
370 1.1 skrll information into the output file. We keep a pointer to both the
371 1.1 skrll head and the tail. */
372 1.1 skrll struct shuffle *line;
373 1.1 skrll struct shuffle *line_end;
374 1.1 skrll struct shuffle *pdr;
375 1.1 skrll struct shuffle *pdr_end;
376 1.1 skrll struct shuffle *sym;
377 1.1 skrll struct shuffle *sym_end;
378 1.1 skrll struct shuffle *opt;
379 1.1 skrll struct shuffle *opt_end;
380 1.1 skrll struct shuffle *aux;
381 1.1 skrll struct shuffle *aux_end;
382 1.1 skrll struct shuffle *ss;
383 1.1 skrll struct shuffle *ss_end;
384 1.1 skrll struct string_hash_entry *ss_hash;
385 1.1 skrll struct string_hash_entry *ss_hash_end;
386 1.1 skrll struct shuffle *fdr;
387 1.1 skrll struct shuffle *fdr_end;
388 1.1 skrll struct shuffle *rfd;
389 1.1 skrll struct shuffle *rfd_end;
390 1.1 skrll /* The size of the largest file shuffle. */
391 1.1 skrll unsigned long largest_file_shuffle;
392 1.1 skrll /* An objalloc for debugging information. */
393 1.1 skrll struct objalloc *memory;
394 1.1 skrll };
395 1.1 skrll
396 1.1 skrll /* Add a file entry to a shuffle list. */
397 1.1.1.8 christos
398 1.1.1.3 christos static bool
399 1.1.1.3 christos add_file_shuffle (struct accumulate *ainfo,
400 1.1.1.3 christos struct shuffle **head,
401 1.1.1.3 christos struct shuffle **tail,
402 1.1.1.3 christos bfd *input_bfd,
403 1.1.1.3 christos file_ptr offset,
404 1.1 skrll unsigned long size)
405 1.1 skrll {
406 1.1 skrll struct shuffle *n;
407 1.1 skrll
408 1.1 skrll if (*tail != (struct shuffle *) NULL
409 1.1 skrll && (*tail)->filep
410 1.1 skrll && (*tail)->u.file.input_bfd == input_bfd
411 1.1 skrll && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
412 1.1 skrll {
413 1.1 skrll /* Just merge this entry onto the existing one. */
414 1.1 skrll (*tail)->size += size;
415 1.1 skrll if ((*tail)->size > ainfo->largest_file_shuffle)
416 1.1.1.8 christos ainfo->largest_file_shuffle = (*tail)->size;
417 1.1 skrll return true;
418 1.1 skrll }
419 1.1 skrll
420 1.1 skrll n = (struct shuffle *) objalloc_alloc (ainfo->memory,
421 1.1 skrll sizeof (struct shuffle));
422 1.1 skrll if (!n)
423 1.1 skrll {
424 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
425 1.1 skrll return false;
426 1.1 skrll }
427 1.1 skrll n->next = NULL;
428 1.1.1.8 christos n->size = size;
429 1.1 skrll n->filep = true;
430 1.1 skrll n->u.file.input_bfd = input_bfd;
431 1.1 skrll n->u.file.offset = offset;
432 1.1 skrll if (*head == (struct shuffle *) NULL)
433 1.1 skrll *head = n;
434 1.1 skrll if (*tail != (struct shuffle *) NULL)
435 1.1 skrll (*tail)->next = n;
436 1.1 skrll *tail = n;
437 1.1 skrll if (size > ainfo->largest_file_shuffle)
438 1.1.1.8 christos ainfo->largest_file_shuffle = size;
439 1.1 skrll return true;
440 1.1 skrll }
441 1.1 skrll
442 1.1 skrll /* Add a memory entry to a shuffle list. */
443 1.1.1.8 christos
444 1.1.1.3 christos static bool
445 1.1.1.3 christos add_memory_shuffle (struct accumulate *ainfo,
446 1.1.1.3 christos struct shuffle **head,
447 1.1.1.3 christos struct shuffle **tail,
448 1.1.1.3 christos bfd_byte *data,
449 1.1 skrll unsigned long size)
450 1.1 skrll {
451 1.1 skrll struct shuffle *n;
452 1.1 skrll
453 1.1 skrll n = (struct shuffle *) objalloc_alloc (ainfo->memory,
454 1.1 skrll sizeof (struct shuffle));
455 1.1 skrll if (!n)
456 1.1 skrll {
457 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
458 1.1 skrll return false;
459 1.1 skrll }
460 1.1 skrll n->next = NULL;
461 1.1.1.8 christos n->size = size;
462 1.1.1.3 christos n->filep = false;
463 1.1 skrll n->u.memory = data;
464 1.1 skrll if (*head == (struct shuffle *) NULL)
465 1.1 skrll *head = n;
466 1.1 skrll if (*tail != (struct shuffle *) NULL)
467 1.1 skrll (*tail)->next = n;
468 1.1.1.8 christos *tail = n;
469 1.1 skrll return true;
470 1.1 skrll }
471 1.1 skrll
472 1.1 skrll /* Initialize the FDR hash table. This returns a handle which is then
473 1.1 skrll passed in to bfd_ecoff_debug_accumulate, et. al. */
474 1.1.1.3 christos
475 1.1.1.3 christos void *
476 1.1.1.3 christos bfd_ecoff_debug_init (bfd *output_bfd ATTRIBUTE_UNUSED,
477 1.1.1.3 christos struct ecoff_debug_info *output_debug,
478 1.1.1.3 christos const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
479 1.1 skrll struct bfd_link_info *info)
480 1.1 skrll {
481 1.1.1.8 christos struct accumulate *ainfo;
482 1.1 skrll size_t amt = sizeof (struct accumulate);
483 1.1 skrll
484 1.1 skrll ainfo = (struct accumulate *) bfd_malloc (amt);
485 1.1 skrll if (!ainfo)
486 1.1 skrll return NULL;
487 1.1 skrll if (!bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
488 1.1 skrll sizeof (struct string_hash_entry), 1021))
489 1.1 skrll return NULL;
490 1.1 skrll
491 1.1 skrll ainfo->line = NULL;
492 1.1 skrll ainfo->line_end = NULL;
493 1.1 skrll ainfo->pdr = NULL;
494 1.1 skrll ainfo->pdr_end = NULL;
495 1.1 skrll ainfo->sym = NULL;
496 1.1 skrll ainfo->sym_end = NULL;
497 1.1 skrll ainfo->opt = NULL;
498 1.1 skrll ainfo->opt_end = NULL;
499 1.1 skrll ainfo->aux = NULL;
500 1.1 skrll ainfo->aux_end = NULL;
501 1.1 skrll ainfo->ss = NULL;
502 1.1 skrll ainfo->ss_end = NULL;
503 1.1 skrll ainfo->ss_hash = NULL;
504 1.1 skrll ainfo->ss_hash_end = NULL;
505 1.1 skrll ainfo->fdr = NULL;
506 1.1 skrll ainfo->fdr_end = NULL;
507 1.1 skrll ainfo->rfd = NULL;
508 1.1 skrll ainfo->rfd_end = NULL;
509 1.1 skrll
510 1.1 skrll ainfo->largest_file_shuffle = 0;
511 1.1.1.4 christos
512 1.1 skrll if (! bfd_link_relocatable (info))
513 1.1 skrll {
514 1.1 skrll if (!bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc,
515 1.1 skrll sizeof (struct string_hash_entry)))
516 1.1 skrll return NULL;
517 1.1 skrll
518 1.1 skrll /* The first entry in the string table is the empty string. */
519 1.1 skrll output_debug->symbolic_header.issMax = 1;
520 1.1 skrll }
521 1.1 skrll
522 1.1 skrll ainfo->memory = objalloc_create ();
523 1.1 skrll if (ainfo->memory == NULL)
524 1.1 skrll {
525 1.1 skrll bfd_set_error (bfd_error_no_memory);
526 1.1 skrll return NULL;
527 1.1 skrll }
528 1.1.1.3 christos
529 1.1 skrll return ainfo;
530 1.1 skrll }
531 1.1 skrll
532 1.1 skrll /* Free the accumulated debugging information. */
533 1.1 skrll
534 1.1.1.3 christos void
535 1.1.1.3 christos bfd_ecoff_debug_free (void * handle,
536 1.1.1.3 christos bfd *output_bfd ATTRIBUTE_UNUSED,
537 1.1.1.3 christos struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED,
538 1.1.1.3 christos const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
539 1.1 skrll struct bfd_link_info *info)
540 1.1 skrll {
541 1.1 skrll struct accumulate *ainfo = (struct accumulate *) handle;
542 1.1 skrll
543 1.1 skrll bfd_hash_table_free (&ainfo->fdr_hash.table);
544 1.1.1.4 christos
545 1.1 skrll if (! bfd_link_relocatable (info))
546 1.1 skrll bfd_hash_table_free (&ainfo->str_hash.table);
547 1.1 skrll
548 1.1 skrll objalloc_free (ainfo->memory);
549 1.1 skrll
550 1.1 skrll free (ainfo);
551 1.1 skrll }
552 1.1 skrll
553 1.1 skrll /* Accumulate the debugging information from INPUT_BFD into
554 1.1 skrll OUTPUT_BFD. The INPUT_DEBUG argument points to some ECOFF
555 1.1 skrll debugging information which we want to link into the information
556 1.1 skrll pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
557 1.1 skrll INPUT_SWAP point to the swapping information needed. INFO is the
558 1.1 skrll linker information structure. HANDLE is returned by
559 1.1 skrll bfd_ecoff_debug_init. */
560 1.1.1.8 christos
561 1.1.1.3 christos bool
562 1.1.1.3 christos bfd_ecoff_debug_accumulate (void * handle,
563 1.1.1.3 christos bfd *output_bfd,
564 1.1.1.3 christos struct ecoff_debug_info *output_debug,
565 1.1.1.3 christos const struct ecoff_debug_swap *output_swap,
566 1.1.1.3 christos bfd *input_bfd,
567 1.1.1.3 christos struct ecoff_debug_info *input_debug,
568 1.1.1.3 christos const struct ecoff_debug_swap *input_swap,
569 1.1 skrll struct bfd_link_info *info)
570 1.1 skrll {
571 1.1.1.3 christos struct accumulate *ainfo = (struct accumulate *) handle;
572 1.1 skrll void (* const swap_sym_in) (bfd *, void *, SYMR *)
573 1.1.1.3 christos = input_swap->swap_sym_in;
574 1.1 skrll void (* const swap_rfd_in) (bfd *, void *, RFDT *)
575 1.1.1.3 christos = input_swap->swap_rfd_in;
576 1.1 skrll void (* const swap_sym_out) (bfd *, const SYMR *, void *)
577 1.1.1.3 christos = output_swap->swap_sym_out;
578 1.1 skrll void (* const swap_fdr_out) (bfd *, const FDR *, void *)
579 1.1.1.3 christos = output_swap->swap_fdr_out;
580 1.1 skrll void (* const swap_rfd_out) (bfd *, const RFDT *, void *)
581 1.1 skrll = output_swap->swap_rfd_out;
582 1.1 skrll bfd_size_type external_pdr_size = output_swap->external_pdr_size;
583 1.1 skrll bfd_size_type external_sym_size = output_swap->external_sym_size;
584 1.1 skrll bfd_size_type external_opt_size = output_swap->external_opt_size;
585 1.1 skrll bfd_size_type external_fdr_size = output_swap->external_fdr_size;
586 1.1 skrll bfd_size_type external_rfd_size = output_swap->external_rfd_size;
587 1.1 skrll HDRR * const output_symhdr = &output_debug->symbolic_header;
588 1.1 skrll HDRR * const input_symhdr = &input_debug->symbolic_header;
589 1.1 skrll bfd_vma section_adjust[scMax];
590 1.1 skrll asection *sec;
591 1.1 skrll bfd_byte *fdr_start;
592 1.1 skrll bfd_byte *fdr_ptr;
593 1.1 skrll bfd_byte *fdr_end;
594 1.1 skrll bfd_size_type fdr_add;
595 1.1 skrll unsigned int copied;
596 1.1 skrll RFDT i;
597 1.1 skrll unsigned long sz;
598 1.1 skrll bfd_byte *rfd_out;
599 1.1 skrll bfd_byte *rfd_in;
600 1.1 skrll bfd_byte *rfd_end;
601 1.1 skrll long newrfdbase = 0;
602 1.1 skrll long oldrfdbase = 0;
603 1.1 skrll bfd_byte *fdr_out;
604 1.1 skrll bfd_size_type amt;
605 1.1 skrll
606 1.1 skrll /* Use section_adjust to hold the value to add to a symbol in a
607 1.1.1.3 christos particular section. */
608 1.1 skrll memset (section_adjust, 0, sizeof section_adjust);
609 1.1 skrll
610 1.1 skrll #define SET(name, indx) \
611 1.1 skrll sec = bfd_get_section_by_name (input_bfd, name); \
612 1.1 skrll if (sec != NULL) \
613 1.1 skrll section_adjust[indx] = (sec->output_section->vma \
614 1.1 skrll + sec->output_offset \
615 1.1 skrll - sec->vma);
616 1.1 skrll
617 1.1 skrll SET (".text", scText);
618 1.1 skrll SET (".data", scData);
619 1.1 skrll SET (".bss", scBss);
620 1.1 skrll SET (".sdata", scSData);
621 1.1 skrll SET (".sbss", scSBss);
622 1.1 skrll /* scRdata section may be either .rdata or .rodata. */
623 1.1 skrll SET (".rdata", scRData);
624 1.1 skrll SET (".rodata", scRData);
625 1.1 skrll SET (".init", scInit);
626 1.1 skrll SET (".fini", scFini);
627 1.1 skrll SET (".rconst", scRConst);
628 1.1 skrll
629 1.1 skrll #undef SET
630 1.1 skrll
631 1.1 skrll /* Find all the debugging information based on the FDR's. We need
632 1.1 skrll to handle them whether they are swapped or not. */
633 1.1 skrll if (input_debug->fdr != (FDR *) NULL)
634 1.1 skrll {
635 1.1 skrll fdr_start = (bfd_byte *) input_debug->fdr;
636 1.1 skrll fdr_add = sizeof (FDR);
637 1.1 skrll }
638 1.1 skrll else
639 1.1 skrll {
640 1.1 skrll fdr_start = (bfd_byte *) input_debug->external_fdr;
641 1.1 skrll fdr_add = input_swap->external_fdr_size;
642 1.1 skrll }
643 1.1 skrll fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
644 1.1 skrll
645 1.1 skrll amt = input_symhdr->ifdMax;
646 1.1 skrll amt *= sizeof (RFDT);
647 1.1 skrll input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
648 1.1 skrll
649 1.1 skrll sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
650 1.1 skrll rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
651 1.1 skrll if (!input_debug->ifdmap || !rfd_out)
652 1.1 skrll {
653 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
654 1.1 skrll return false;
655 1.1 skrll }
656 1.1.1.8 christos if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
657 1.1 skrll return false;
658 1.1 skrll
659 1.1 skrll copied = 0;
660 1.1 skrll
661 1.1 skrll /* Look through the FDR's to see which ones we are going to include
662 1.1 skrll in the final output. We do not want duplicate FDR information
663 1.1 skrll for header files, because ECOFF debugging is often very large.
664 1.1 skrll When we find an FDR with no line information which can be merged,
665 1.1 skrll we look it up in a hash table to ensure that we only include it
666 1.1 skrll once. We keep a table mapping FDR numbers to the final number
667 1.1 skrll they get with the BFD, so that we can refer to it when we write
668 1.1 skrll out the external symbols. */
669 1.1 skrll for (fdr_ptr = fdr_start, i = 0;
670 1.1 skrll fdr_ptr < fdr_end;
671 1.1 skrll fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
672 1.1 skrll {
673 1.1 skrll FDR fdr;
674 1.1 skrll
675 1.1 skrll if (input_debug->fdr != (FDR *) NULL)
676 1.1 skrll fdr = *(FDR *) fdr_ptr;
677 1.1.1.3 christos else
678 1.1 skrll (*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);
679 1.1 skrll
680 1.1 skrll /* See if this FDR can be merged with an existing one. */
681 1.1 skrll if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
682 1.1 skrll {
683 1.1 skrll const char *name;
684 1.1 skrll char *lookup;
685 1.1 skrll struct string_hash_entry *fh;
686 1.1 skrll
687 1.1 skrll /* We look up a string formed from the file name and the
688 1.1 skrll number of symbols and aux entries. Sometimes an include
689 1.1 skrll file will conditionally define a typedef or something
690 1.1 skrll based on the order of include files. Using the number of
691 1.1 skrll symbols and aux entries as a hash reduces the chance that
692 1.1 skrll we will merge symbol information that should not be
693 1.1 skrll merged. */
694 1.1 skrll name = input_debug->ss + fdr.issBase + fdr.rss;
695 1.1 skrll
696 1.1 skrll lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
697 1.1.1.8 christos if (lookup == NULL)
698 1.1 skrll return false;
699 1.1 skrll sprintf (lookup, "%s %lx %lx", name, (unsigned long) fdr.csym,
700 1.1 skrll (unsigned long) fdr.caux);
701 1.1.1.8 christos
702 1.1 skrll fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
703 1.1 skrll free (lookup);
704 1.1.1.8 christos if (fh == (struct string_hash_entry *) NULL)
705 1.1 skrll return false;
706 1.1 skrll
707 1.1 skrll if (fh->val != -1)
708 1.1 skrll {
709 1.1.1.3 christos input_debug->ifdmap[i] = fh->val;
710 1.1 skrll (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);
711 1.1 skrll
712 1.1 skrll /* Don't copy this FDR. */
713 1.1 skrll continue;
714 1.1 skrll }
715 1.1 skrll
716 1.1 skrll fh->val = output_symhdr->ifdMax + copied;
717 1.1 skrll }
718 1.1 skrll
719 1.1.1.3 christos input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
720 1.1 skrll (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);
721 1.1 skrll ++copied;
722 1.1 skrll }
723 1.1 skrll
724 1.1 skrll newrfdbase = output_symhdr->crfd;
725 1.1 skrll output_symhdr->crfd += input_symhdr->ifdMax;
726 1.1 skrll
727 1.1 skrll /* Copy over any existing RFD's. RFD's are only created by the
728 1.1 skrll linker, so this will only happen for input files which are the
729 1.1 skrll result of a partial link. */
730 1.1 skrll rfd_in = (bfd_byte *) input_debug->external_rfd;
731 1.1 skrll rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
732 1.1 skrll for (;
733 1.1 skrll rfd_in < rfd_end;
734 1.1 skrll rfd_in += input_swap->external_rfd_size)
735 1.1 skrll {
736 1.1 skrll RFDT rfd;
737 1.1.1.3 christos
738 1.1 skrll (*swap_rfd_in) (input_bfd, rfd_in, &rfd);
739 1.1 skrll BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
740 1.1.1.3 christos rfd = input_debug->ifdmap[rfd];
741 1.1 skrll (*swap_rfd_out) (output_bfd, &rfd, rfd_out);
742 1.1 skrll rfd_out += external_rfd_size;
743 1.1 skrll }
744 1.1 skrll
745 1.1 skrll oldrfdbase = output_symhdr->crfd;
746 1.1 skrll output_symhdr->crfd += input_symhdr->crfd;
747 1.1 skrll
748 1.1 skrll /* Look through the FDR's and copy over all associated debugging
749 1.1 skrll information. */
750 1.1 skrll sz = copied * external_fdr_size;
751 1.1 skrll fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
752 1.1 skrll if (!fdr_out)
753 1.1 skrll {
754 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
755 1.1 skrll return false;
756 1.1 skrll }
757 1.1.1.8 christos if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
758 1.1 skrll return false;
759 1.1 skrll for (fdr_ptr = fdr_start, i = 0;
760 1.1 skrll fdr_ptr < fdr_end;
761 1.1 skrll fdr_ptr += fdr_add, i++)
762 1.1 skrll {
763 1.1 skrll FDR fdr;
764 1.1 skrll bfd_byte *sym_out;
765 1.1 skrll bfd_byte *lraw_src;
766 1.1.1.8 christos bfd_byte *lraw_end;
767 1.1 skrll bool fgotfilename;
768 1.1 skrll
769 1.1 skrll if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
770 1.1 skrll {
771 1.1 skrll /* We are not copying this FDR. */
772 1.1 skrll continue;
773 1.1 skrll }
774 1.1 skrll
775 1.1 skrll if (input_debug->fdr != (FDR *) NULL)
776 1.1 skrll fdr = *(FDR *) fdr_ptr;
777 1.1.1.3 christos else
778 1.1 skrll (*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);
779 1.1 skrll
780 1.1 skrll /* FIXME: It is conceivable that this FDR points to the .init or
781 1.1 skrll .fini section, in which case this will not do the right
782 1.1 skrll thing. */
783 1.1 skrll fdr.adr += section_adjust[scText];
784 1.1 skrll
785 1.1 skrll /* Swap in the local symbols, adjust their values, and swap them
786 1.1.1.8 christos out again. */
787 1.1 skrll fgotfilename = false;
788 1.1 skrll sz = fdr.csym * external_sym_size;
789 1.1 skrll sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
790 1.1 skrll if (!sym_out)
791 1.1 skrll {
792 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
793 1.1 skrll return false;
794 1.1 skrll }
795 1.1 skrll if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
796 1.1.1.8 christos sz))
797 1.1 skrll return false;
798 1.1 skrll lraw_src = ((bfd_byte *) input_debug->external_sym
799 1.1 skrll + fdr.isymBase * input_swap->external_sym_size);
800 1.1 skrll lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
801 1.1 skrll for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size)
802 1.1 skrll {
803 1.1 skrll SYMR internal_sym;
804 1.1.1.3 christos
805 1.1 skrll (*swap_sym_in) (input_bfd, lraw_src, &internal_sym);
806 1.1 skrll
807 1.1 skrll BFD_ASSERT (internal_sym.sc != scCommon
808 1.1 skrll && internal_sym.sc != scSCommon);
809 1.1 skrll
810 1.1 skrll /* Adjust the symbol value if appropriate. */
811 1.1 skrll switch (internal_sym.st)
812 1.1 skrll {
813 1.1 skrll case stNil:
814 1.1 skrll if (ECOFF_IS_STAB (&internal_sym))
815 1.1 skrll break;
816 1.1 skrll /* Fall through. */
817 1.1 skrll case stGlobal:
818 1.1 skrll case stStatic:
819 1.1 skrll case stLabel:
820 1.1 skrll case stProc:
821 1.1 skrll case stStaticProc:
822 1.1 skrll internal_sym.value += section_adjust[internal_sym.sc];
823 1.1 skrll break;
824 1.1 skrll
825 1.1 skrll default:
826 1.1 skrll break;
827 1.1 skrll }
828 1.1 skrll
829 1.1 skrll /* If we are doing a final link, we hash all the strings in
830 1.1 skrll the local symbol table together. This reduces the amount
831 1.1 skrll of space required by debugging information. We don't do
832 1.1 skrll this when performing a relocatable link because it would
833 1.1.1.4 christos prevent us from easily merging different FDR's. */
834 1.1 skrll if (! bfd_link_relocatable (info))
835 1.1.1.8 christos {
836 1.1 skrll bool ffilename;
837 1.1 skrll const char *name;
838 1.1 skrll
839 1.1.1.8 christos if (! fgotfilename && internal_sym.iss == fdr.rss)
840 1.1 skrll ffilename = true;
841 1.1.1.8 christos else
842 1.1 skrll ffilename = false;
843 1.1 skrll
844 1.1 skrll /* Hash the name into the string table. */
845 1.1 skrll name = input_debug->ss + fdr.issBase + internal_sym.iss;
846 1.1 skrll if (*name == '\0')
847 1.1 skrll internal_sym.iss = 0;
848 1.1 skrll else
849 1.1 skrll {
850 1.1 skrll struct string_hash_entry *sh;
851 1.1.1.8 christos
852 1.1 skrll sh = string_hash_lookup (&ainfo->str_hash, name, true, true);
853 1.1.1.8 christos if (sh == (struct string_hash_entry *) NULL)
854 1.1 skrll return false;
855 1.1 skrll if (sh->val == -1)
856 1.1 skrll {
857 1.1 skrll sh->val = output_symhdr->issMax;
858 1.1 skrll output_symhdr->issMax += strlen (name) + 1;
859 1.1 skrll if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
860 1.1 skrll ainfo->ss_hash = sh;
861 1.1 skrll if (ainfo->ss_hash_end
862 1.1 skrll != (struct string_hash_entry *) NULL)
863 1.1 skrll ainfo->ss_hash_end->next = sh;
864 1.1 skrll ainfo->ss_hash_end = sh;
865 1.1 skrll }
866 1.1 skrll internal_sym.iss = sh->val;
867 1.1 skrll }
868 1.1 skrll
869 1.1 skrll if (ffilename)
870 1.1 skrll {
871 1.1.1.8 christos fdr.rss = internal_sym.iss;
872 1.1 skrll fgotfilename = true;
873 1.1 skrll }
874 1.1 skrll }
875 1.1 skrll
876 1.1 skrll (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
877 1.1 skrll sym_out += external_sym_size;
878 1.1 skrll }
879 1.1 skrll
880 1.1 skrll fdr.isymBase = output_symhdr->isymMax;
881 1.1 skrll output_symhdr->isymMax += fdr.csym;
882 1.1 skrll
883 1.1 skrll /* Copy the information that does not need swapping. */
884 1.1 skrll
885 1.1 skrll /* FIXME: If we are relaxing, we need to adjust the line
886 1.1 skrll numbers. Frankly, forget it. Anybody using stabs debugging
887 1.1 skrll information will not use this line number information, and
888 1.1 skrll stabs are adjusted correctly. */
889 1.1 skrll if (fdr.cbLine > 0)
890 1.1 skrll {
891 1.1 skrll file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
892 1.1 skrll if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
893 1.1.1.8 christos input_bfd, pos, (unsigned long) fdr.cbLine))
894 1.1 skrll return false;
895 1.1 skrll fdr.ilineBase = output_symhdr->ilineMax;
896 1.1 skrll fdr.cbLineOffset = output_symhdr->cbLine;
897 1.1 skrll output_symhdr->ilineMax += fdr.cline;
898 1.1 skrll output_symhdr->cbLine += fdr.cbLine;
899 1.1 skrll }
900 1.1 skrll if (fdr.caux > 0)
901 1.1 skrll {
902 1.1 skrll file_ptr pos = (input_symhdr->cbAuxOffset
903 1.1 skrll + fdr.iauxBase * sizeof (union aux_ext));
904 1.1 skrll if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
905 1.1 skrll input_bfd, pos,
906 1.1.1.8 christos fdr.caux * sizeof (union aux_ext)))
907 1.1 skrll return false;
908 1.1 skrll fdr.iauxBase = output_symhdr->iauxMax;
909 1.1 skrll output_symhdr->iauxMax += fdr.caux;
910 1.1.1.4 christos }
911 1.1 skrll if (! bfd_link_relocatable (info))
912 1.1 skrll {
913 1.1.1.6 christos
914 1.1 skrll /* When we are hashing strings, we lie about the number of
915 1.1 skrll strings attached to each FDR. We need to set cbSs
916 1.1 skrll because some versions of dbx apparently use it to decide
917 1.1 skrll how much of the string table to read in. */
918 1.1 skrll fdr.issBase = 0;
919 1.1 skrll fdr.cbSs = output_symhdr->issMax;
920 1.1 skrll }
921 1.1 skrll else if (fdr.cbSs > 0)
922 1.1 skrll {
923 1.1 skrll file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
924 1.1 skrll if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
925 1.1.1.8 christos input_bfd, pos, (unsigned long) fdr.cbSs))
926 1.1 skrll return false;
927 1.1 skrll fdr.issBase = output_symhdr->issMax;
928 1.1 skrll output_symhdr->issMax += fdr.cbSs;
929 1.1 skrll }
930 1.1 skrll
931 1.1 skrll if (output_bfd->xvec->header_byteorder
932 1.1 skrll == input_bfd->xvec->header_byteorder)
933 1.1 skrll {
934 1.1 skrll /* The two BFD's have the same endianness, and we don't have
935 1.1 skrll to adjust the PDR addresses, so simply copying the
936 1.1 skrll information will suffice. */
937 1.1 skrll BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
938 1.1 skrll if (fdr.cpd > 0)
939 1.1 skrll {
940 1.1 skrll file_ptr pos = (input_symhdr->cbPdOffset
941 1.1 skrll + fdr.ipdFirst * external_pdr_size);
942 1.1 skrll unsigned long size = fdr.cpd * external_pdr_size;
943 1.1 skrll if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
944 1.1.1.8 christos input_bfd, pos, size))
945 1.1 skrll return false;
946 1.1 skrll }
947 1.1 skrll BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
948 1.1 skrll if (fdr.copt > 0)
949 1.1 skrll {
950 1.1 skrll file_ptr pos = (input_symhdr->cbOptOffset
951 1.1 skrll + fdr.ioptBase * external_opt_size);
952 1.1 skrll unsigned long size = fdr.copt * external_opt_size;
953 1.1 skrll if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
954 1.1.1.8 christos input_bfd, pos, size))
955 1.1 skrll return false;
956 1.1 skrll }
957 1.1 skrll }
958 1.1 skrll else
959 1.1 skrll {
960 1.1 skrll bfd_size_type outsz, insz;
961 1.1 skrll bfd_byte *in;
962 1.1 skrll bfd_byte *end;
963 1.1 skrll bfd_byte *out;
964 1.1 skrll
965 1.1 skrll /* The two BFD's have different endianness, so we must swap
966 1.1 skrll everything in and out. This code would always work, but
967 1.1 skrll it would be unnecessarily slow in the normal case. */
968 1.1 skrll outsz = external_pdr_size;
969 1.1 skrll insz = input_swap->external_pdr_size;
970 1.1 skrll in = ((bfd_byte *) input_debug->external_pdr
971 1.1 skrll + fdr.ipdFirst * insz);
972 1.1 skrll end = in + fdr.cpd * insz;
973 1.1 skrll sz = fdr.cpd * outsz;
974 1.1 skrll out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
975 1.1 skrll if (!out)
976 1.1 skrll {
977 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
978 1.1 skrll return false;
979 1.1 skrll }
980 1.1 skrll if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
981 1.1.1.8 christos sz))
982 1.1 skrll return false;
983 1.1 skrll for (; in < end; in += insz, out += outsz)
984 1.1 skrll {
985 1.1 skrll PDR pdr;
986 1.1.1.3 christos
987 1.1.1.3 christos (*input_swap->swap_pdr_in) (input_bfd, in, &pdr);
988 1.1 skrll (*output_swap->swap_pdr_out) (output_bfd, &pdr, out);
989 1.1 skrll }
990 1.1 skrll
991 1.1 skrll /* Swap over the optimization information. */
992 1.1 skrll outsz = external_opt_size;
993 1.1 skrll insz = input_swap->external_opt_size;
994 1.1 skrll in = ((bfd_byte *) input_debug->external_opt
995 1.1 skrll + fdr.ioptBase * insz);
996 1.1 skrll end = in + fdr.copt * insz;
997 1.1 skrll sz = fdr.copt * outsz;
998 1.1 skrll out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
999 1.1 skrll if (!out)
1000 1.1 skrll {
1001 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
1002 1.1 skrll return false;
1003 1.1 skrll }
1004 1.1 skrll if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
1005 1.1.1.8 christos sz))
1006 1.1 skrll return false;
1007 1.1 skrll for (; in < end; in += insz, out += outsz)
1008 1.1 skrll {
1009 1.1 skrll OPTR opt;
1010 1.1.1.3 christos
1011 1.1.1.3 christos (*input_swap->swap_opt_in) (input_bfd, in, &opt);
1012 1.1 skrll (*output_swap->swap_opt_out) (output_bfd, &opt, out);
1013 1.1 skrll }
1014 1.1 skrll }
1015 1.1 skrll
1016 1.1 skrll fdr.ipdFirst = output_symhdr->ipdMax;
1017 1.1 skrll output_symhdr->ipdMax += fdr.cpd;
1018 1.1 skrll fdr.ioptBase = output_symhdr->ioptMax;
1019 1.1 skrll output_symhdr->ioptMax += fdr.copt;
1020 1.1 skrll
1021 1.1 skrll if (fdr.crfd <= 0)
1022 1.1 skrll {
1023 1.1 skrll /* Point this FDR at the table of RFD's we created. */
1024 1.1 skrll fdr.rfdBase = newrfdbase;
1025 1.1 skrll fdr.crfd = input_symhdr->ifdMax;
1026 1.1 skrll }
1027 1.1 skrll else
1028 1.1 skrll {
1029 1.1 skrll /* Point this FDR at the remapped RFD's. */
1030 1.1 skrll fdr.rfdBase += oldrfdbase;
1031 1.1 skrll }
1032 1.1 skrll
1033 1.1 skrll (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
1034 1.1 skrll fdr_out += external_fdr_size;
1035 1.1 skrll ++output_symhdr->ifdMax;
1036 1.1 skrll }
1037 1.1.1.8 christos
1038 1.1 skrll return true;
1039 1.1 skrll }
1040 1.1 skrll
1041 1.1 skrll /* Add a string to the debugging information we are accumulating.
1042 1.1 skrll Return the offset from the fdr string base. */
1043 1.1 skrll
1044 1.1.1.3 christos static long
1045 1.1.1.3 christos ecoff_add_string (struct accumulate *ainfo,
1046 1.1.1.3 christos struct bfd_link_info *info,
1047 1.1.1.3 christos struct ecoff_debug_info *debug,
1048 1.1.1.3 christos FDR *fdr,
1049 1.1 skrll const char *string)
1050 1.1 skrll {
1051 1.1 skrll HDRR *symhdr;
1052 1.1 skrll size_t len;
1053 1.1 skrll bfd_size_type ret;
1054 1.1 skrll
1055 1.1 skrll symhdr = &debug->symbolic_header;
1056 1.1.1.4 christos len = strlen (string);
1057 1.1 skrll if (bfd_link_relocatable (info))
1058 1.1.1.2 christos {
1059 1.1.1.6 christos if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
1060 1.1 skrll (bfd_byte *) string, len + 1))
1061 1.1 skrll return -1;
1062 1.1 skrll ret = symhdr->issMax;
1063 1.1 skrll symhdr->issMax += len + 1;
1064 1.1 skrll fdr->cbSs += len + 1;
1065 1.1 skrll }
1066 1.1 skrll else
1067 1.1 skrll {
1068 1.1 skrll struct string_hash_entry *sh;
1069 1.1.1.8 christos
1070 1.1 skrll sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
1071 1.1 skrll if (sh == (struct string_hash_entry *) NULL)
1072 1.1 skrll return -1;
1073 1.1 skrll if (sh->val == -1)
1074 1.1 skrll {
1075 1.1 skrll sh->val = symhdr->issMax;
1076 1.1 skrll symhdr->issMax += len + 1;
1077 1.1 skrll if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
1078 1.1 skrll ainfo->ss_hash = sh;
1079 1.1 skrll if (ainfo->ss_hash_end
1080 1.1 skrll != (struct string_hash_entry *) NULL)
1081 1.1 skrll ainfo->ss_hash_end->next = sh;
1082 1.1 skrll ainfo->ss_hash_end = sh;
1083 1.1 skrll }
1084 1.1 skrll ret = sh->val;
1085 1.1 skrll }
1086 1.1 skrll
1087 1.1 skrll return ret;
1088 1.1 skrll }
1089 1.1 skrll
1090 1.1 skrll /* Add debugging information from a non-ECOFF file. */
1091 1.1.1.8 christos
1092 1.1.1.3 christos bool
1093 1.1.1.3 christos bfd_ecoff_debug_accumulate_other (void * handle,
1094 1.1.1.3 christos bfd *output_bfd,
1095 1.1.1.3 christos struct ecoff_debug_info *output_debug,
1096 1.1.1.3 christos const struct ecoff_debug_swap *output_swap,
1097 1.1.1.3 christos bfd *input_bfd,
1098 1.1 skrll struct bfd_link_info *info)
1099 1.1 skrll {
1100 1.1.1.3 christos struct accumulate *ainfo = (struct accumulate *) handle;
1101 1.1 skrll void (* const swap_sym_out) (bfd *, const SYMR *, void *)
1102 1.1 skrll = output_swap->swap_sym_out;
1103 1.1 skrll HDRR *output_symhdr = &output_debug->symbolic_header;
1104 1.1 skrll FDR fdr;
1105 1.1 skrll asection *sec;
1106 1.1 skrll asymbol **symbols;
1107 1.1 skrll asymbol **sym_ptr;
1108 1.1 skrll asymbol **sym_end;
1109 1.1 skrll long symsize;
1110 1.1.1.3 christos long symcount;
1111 1.1 skrll void * external_fdr;
1112 1.1.1.3 christos
1113 1.1 skrll memset (&fdr, 0, sizeof fdr);
1114 1.1 skrll
1115 1.1 skrll sec = bfd_get_section_by_name (input_bfd, ".text");
1116 1.1 skrll if (sec != NULL)
1117 1.1 skrll fdr.adr = sec->output_section->vma + sec->output_offset;
1118 1.1 skrll else
1119 1.1 skrll {
1120 1.1 skrll /* FIXME: What about .init or .fini? */
1121 1.1 skrll fdr.adr = 0;
1122 1.1 skrll }
1123 1.1 skrll
1124 1.1 skrll fdr.issBase = output_symhdr->issMax;
1125 1.1 skrll fdr.cbSs = 0;
1126 1.1.1.8 christos fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
1127 1.1 skrll bfd_get_filename (input_bfd));
1128 1.1.1.8 christos if (fdr.rss == -1)
1129 1.1 skrll return false;
1130 1.1 skrll fdr.isymBase = output_symhdr->isymMax;
1131 1.1 skrll
1132 1.1 skrll /* Get the local symbols from the input BFD. */
1133 1.1 skrll symsize = bfd_get_symtab_upper_bound (input_bfd);
1134 1.1.1.8 christos if (symsize < 0)
1135 1.1 skrll return false;
1136 1.1 skrll symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
1137 1.1.1.8 christos if (symbols == (asymbol **) NULL)
1138 1.1 skrll return false;
1139 1.1 skrll symcount = bfd_canonicalize_symtab (input_bfd, symbols);
1140 1.1.1.8 christos if (symcount < 0)
1141 1.1 skrll return false;
1142 1.1 skrll sym_end = symbols + symcount;
1143 1.1 skrll
1144 1.1 skrll /* Handle the local symbols. Any external symbols are handled
1145 1.1 skrll separately. */
1146 1.1 skrll fdr.csym = 0;
1147 1.1 skrll for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
1148 1.1 skrll {
1149 1.1.1.3 christos SYMR internal_sym;
1150 1.1 skrll void * external_sym;
1151 1.1 skrll
1152 1.1 skrll if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
1153 1.1.1.3 christos continue;
1154 1.1 skrll memset (&internal_sym, 0, sizeof internal_sym);
1155 1.1 skrll internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
1156 1.1 skrll (*sym_ptr)->name);
1157 1.1 skrll
1158 1.1.1.8 christos if (internal_sym.iss == -1)
1159 1.1 skrll return false;
1160 1.1 skrll if (bfd_is_com_section ((*sym_ptr)->section)
1161 1.1 skrll || bfd_is_und_section ((*sym_ptr)->section))
1162 1.1 skrll internal_sym.value = (*sym_ptr)->value;
1163 1.1 skrll else
1164 1.1 skrll internal_sym.value = ((*sym_ptr)->value
1165 1.1 skrll + (*sym_ptr)->section->output_offset
1166 1.1 skrll + (*sym_ptr)->section->output_section->vma);
1167 1.1 skrll internal_sym.st = stNil;
1168 1.1 skrll internal_sym.sc = scUndefined;
1169 1.1 skrll internal_sym.index = indexNil;
1170 1.1.1.3 christos
1171 1.1.1.3 christos external_sym = objalloc_alloc (ainfo->memory,
1172 1.1 skrll output_swap->external_sym_size);
1173 1.1 skrll if (!external_sym)
1174 1.1 skrll {
1175 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
1176 1.1 skrll return false;
1177 1.1 skrll }
1178 1.1 skrll (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
1179 1.1.1.2 christos add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
1180 1.1 skrll (bfd_byte *) external_sym,
1181 1.1 skrll (unsigned long) output_swap->external_sym_size);
1182 1.1 skrll ++fdr.csym;
1183 1.1 skrll ++output_symhdr->isymMax;
1184 1.1 skrll }
1185 1.1.1.3 christos
1186 1.1 skrll bfd_release (output_bfd, symbols);
1187 1.1 skrll
1188 1.1 skrll /* Leave everything else in the FDR zeroed out. This will cause
1189 1.1 skrll the lang field to be langC. The fBigendian field will
1190 1.1 skrll indicate little endian format, but it doesn't matter because
1191 1.1.1.3 christos it only applies to aux fields and there are none. */
1192 1.1.1.3 christos external_fdr = objalloc_alloc (ainfo->memory,
1193 1.1 skrll output_swap->external_fdr_size);
1194 1.1 skrll if (!external_fdr)
1195 1.1 skrll {
1196 1.1.1.8 christos bfd_set_error (bfd_error_no_memory);
1197 1.1 skrll return false;
1198 1.1 skrll }
1199 1.1 skrll (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
1200 1.1.1.2 christos add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
1201 1.1 skrll (bfd_byte *) external_fdr,
1202 1.1 skrll (unsigned long) output_swap->external_fdr_size);
1203 1.1 skrll
1204 1.1 skrll ++output_symhdr->ifdMax;
1205 1.1.1.8 christos
1206 1.1 skrll return true;
1207 1.1 skrll }
1208 1.1 skrll
1209 1.1 skrll /* Set up ECOFF debugging information for the external symbols.
1210 1.1 skrll FIXME: This is done using a memory buffer, but it should be
1211 1.1 skrll probably be changed to use a shuffle structure. The assembler uses
1212 1.1 skrll this interface, so that must be changed to do something else. */
1213 1.1.1.8 christos
1214 1.1.1.3 christos bool
1215 1.1.1.3 christos bfd_ecoff_debug_externals (bfd *abfd,
1216 1.1.1.3 christos struct ecoff_debug_info *debug,
1217 1.1.1.8 christos const struct ecoff_debug_swap *swap,
1218 1.1.1.8 christos bool relocatable,
1219 1.1.1.3 christos bool (*get_extr) (asymbol *, EXTR *),
1220 1.1 skrll void (*set_index) (asymbol *, bfd_size_type))
1221 1.1 skrll {
1222 1.1 skrll HDRR * const symhdr = &debug->symbolic_header;
1223 1.1 skrll asymbol **sym_ptr_ptr;
1224 1.1 skrll size_t c;
1225 1.1 skrll
1226 1.1 skrll sym_ptr_ptr = bfd_get_outsymbols (abfd);
1227 1.1.1.8 christos if (sym_ptr_ptr == NULL)
1228 1.1 skrll return true;
1229 1.1 skrll
1230 1.1 skrll for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
1231 1.1 skrll {
1232 1.1 skrll asymbol *sym_ptr;
1233 1.1 skrll EXTR esym;
1234 1.1 skrll
1235 1.1 skrll sym_ptr = *sym_ptr_ptr;
1236 1.1 skrll
1237 1.1 skrll /* Get the external symbol information. */
1238 1.1 skrll if (! (*get_extr) (sym_ptr, &esym))
1239 1.1 skrll continue;
1240 1.1 skrll
1241 1.1 skrll /* If we're producing an executable, move common symbols into
1242 1.1 skrll bss. */
1243 1.1 skrll if (! relocatable)
1244 1.1 skrll {
1245 1.1 skrll if (esym.asym.sc == scCommon)
1246 1.1 skrll esym.asym.sc = scBss;
1247 1.1 skrll else if (esym.asym.sc == scSCommon)
1248 1.1 skrll esym.asym.sc = scSBss;
1249 1.1 skrll }
1250 1.1 skrll
1251 1.1 skrll if (bfd_is_com_section (sym_ptr->section)
1252 1.1 skrll || bfd_is_und_section (sym_ptr->section)
1253 1.1 skrll || sym_ptr->section->output_section == (asection *) NULL)
1254 1.1 skrll {
1255 1.1 skrll /* FIXME: gas does not keep the value of a small undefined
1256 1.1 skrll symbol in the symbol itself, because of relocation
1257 1.1 skrll problems. */
1258 1.1 skrll if (esym.asym.sc != scSUndefined
1259 1.1 skrll || esym.asym.value == 0
1260 1.1 skrll || sym_ptr->value != 0)
1261 1.1 skrll esym.asym.value = sym_ptr->value;
1262 1.1 skrll }
1263 1.1 skrll else
1264 1.1 skrll esym.asym.value = (sym_ptr->value
1265 1.1 skrll + sym_ptr->section->output_offset
1266 1.1 skrll + sym_ptr->section->output_section->vma);
1267 1.1 skrll
1268 1.1 skrll if (set_index)
1269 1.1 skrll (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
1270 1.1 skrll
1271 1.1 skrll if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
1272 1.1.1.8 christos sym_ptr->name, &esym))
1273 1.1 skrll return false;
1274 1.1 skrll }
1275 1.1.1.8 christos
1276 1.1 skrll return true;
1277 1.1 skrll }
1278 1.1 skrll
1279 1.1 skrll /* Add a single external symbol to the debugging information. */
1280 1.1.1.8 christos
1281 1.1.1.3 christos bool
1282 1.1.1.3 christos bfd_ecoff_debug_one_external (bfd *abfd,
1283 1.1.1.3 christos struct ecoff_debug_info *debug,
1284 1.1.1.3 christos const struct ecoff_debug_swap *swap,
1285 1.1.1.3 christos const char *name,
1286 1.1 skrll EXTR *esym)
1287 1.1 skrll {
1288 1.1.1.3 christos const bfd_size_type external_ext_size = swap->external_ext_size;
1289 1.1 skrll void (* const swap_ext_out) (bfd *, const EXTR *, void *)
1290 1.1 skrll = swap->swap_ext_out;
1291 1.1 skrll HDRR * const symhdr = &debug->symbolic_header;
1292 1.1 skrll size_t namelen;
1293 1.1 skrll
1294 1.1 skrll namelen = strlen (name);
1295 1.1 skrll
1296 1.1 skrll if ((size_t) (debug->ssext_end - debug->ssext)
1297 1.1 skrll < symhdr->issExtMax + namelen + 1)
1298 1.1 skrll {
1299 1.1 skrll if (! ecoff_add_bytes ((char **) &debug->ssext,
1300 1.1 skrll (char **) &debug->ssext_end,
1301 1.1.1.8 christos symhdr->issExtMax + namelen + 1))
1302 1.1 skrll return false;
1303 1.1 skrll }
1304 1.1 skrll if ((size_t) ((char *) debug->external_ext_end
1305 1.1 skrll - (char *) debug->external_ext)
1306 1.1 skrll < (symhdr->iextMax + 1) * external_ext_size)
1307 1.1.1.2 christos {
1308 1.1.1.2 christos char *external_ext = (char *) debug->external_ext;
1309 1.1 skrll char *external_ext_end = (char *) debug->external_ext_end;
1310 1.1 skrll if (! ecoff_add_bytes ((char **) &external_ext,
1311 1.1 skrll (char **) &external_ext_end,
1312 1.1.1.8 christos (symhdr->iextMax + 1) * (size_t) external_ext_size))
1313 1.1 skrll return false;
1314 1.1 skrll debug->external_ext = external_ext;
1315 1.1 skrll debug->external_ext_end = external_ext_end;
1316 1.1 skrll }
1317 1.1 skrll
1318 1.1 skrll esym->asym.iss = symhdr->issExtMax;
1319 1.1 skrll
1320 1.1 skrll (*swap_ext_out) (abfd, esym,
1321 1.1 skrll ((char *) debug->external_ext
1322 1.1 skrll + symhdr->iextMax * swap->external_ext_size));
1323 1.1 skrll
1324 1.1 skrll ++symhdr->iextMax;
1325 1.1 skrll
1326 1.1 skrll strcpy (debug->ssext + symhdr->issExtMax, name);
1327 1.1 skrll symhdr->issExtMax += namelen + 1;
1328 1.1.1.8 christos
1329 1.1 skrll return true;
1330 1.1 skrll }
1331 1.1 skrll
1332 1.1 skrll /* Align the ECOFF debugging information. */
1333 1.1 skrll
1334 1.1.1.3 christos static void
1335 1.1.1.3 christos ecoff_align_debug (bfd *abfd ATTRIBUTE_UNUSED,
1336 1.1.1.3 christos struct ecoff_debug_info *debug,
1337 1.1 skrll const struct ecoff_debug_swap *swap)
1338 1.1 skrll {
1339 1.1 skrll HDRR * const symhdr = &debug->symbolic_header;
1340 1.1 skrll bfd_size_type debug_align, aux_align, rfd_align;
1341 1.1 skrll size_t add;
1342 1.1 skrll
1343 1.1 skrll /* Adjust the counts so that structures are aligned. */
1344 1.1 skrll debug_align = swap->debug_align;
1345 1.1 skrll aux_align = debug_align / sizeof (union aux_ext);
1346 1.1 skrll rfd_align = debug_align / swap->external_rfd_size;
1347 1.1 skrll
1348 1.1 skrll add = debug_align - (symhdr->cbLine & (debug_align - 1));
1349 1.1 skrll if (add != debug_align)
1350 1.1 skrll {
1351 1.1.1.3 christos if (debug->line != (unsigned char *) NULL)
1352 1.1 skrll memset ((debug->line + symhdr->cbLine), 0, add);
1353 1.1 skrll symhdr->cbLine += add;
1354 1.1 skrll }
1355 1.1 skrll
1356 1.1 skrll add = debug_align - (symhdr->issMax & (debug_align - 1));
1357 1.1 skrll if (add != debug_align)
1358 1.1 skrll {
1359 1.1.1.3 christos if (debug->ss != (char *) NULL)
1360 1.1 skrll memset ((debug->ss + symhdr->issMax), 0, add);
1361 1.1 skrll symhdr->issMax += add;
1362 1.1 skrll }
1363 1.1 skrll
1364 1.1 skrll add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1365 1.1 skrll if (add != debug_align)
1366 1.1 skrll {
1367 1.1.1.3 christos if (debug->ssext != (char *) NULL)
1368 1.1 skrll memset ((debug->ssext + symhdr->issExtMax), 0, add);
1369 1.1 skrll symhdr->issExtMax += add;
1370 1.1 skrll }
1371 1.1 skrll
1372 1.1 skrll add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1373 1.1 skrll if (add != aux_align)
1374 1.1 skrll {
1375 1.1.1.3 christos if (debug->external_aux != (union aux_ext *) NULL)
1376 1.1 skrll memset ((debug->external_aux + symhdr->iauxMax), 0,
1377 1.1 skrll add * sizeof (union aux_ext));
1378 1.1 skrll symhdr->iauxMax += add;
1379 1.1 skrll }
1380 1.1 skrll
1381 1.1 skrll add = rfd_align - (symhdr->crfd & (rfd_align - 1));
1382 1.1 skrll if (add != rfd_align)
1383 1.1.1.3 christos {
1384 1.1.1.3 christos if (debug->external_rfd != NULL)
1385 1.1.1.3 christos memset (((char *) debug->external_rfd
1386 1.1 skrll + symhdr->crfd * swap->external_rfd_size),
1387 1.1 skrll 0, (size_t) (add * swap->external_rfd_size));
1388 1.1 skrll symhdr->crfd += add;
1389 1.1 skrll }
1390 1.1 skrll }
1391 1.1 skrll
1392 1.1 skrll /* Return the size required by the ECOFF debugging information. */
1393 1.1 skrll
1394 1.1.1.3 christos bfd_size_type
1395 1.1.1.3 christos bfd_ecoff_debug_size (bfd *abfd,
1396 1.1.1.3 christos struct ecoff_debug_info *debug,
1397 1.1 skrll const struct ecoff_debug_swap *swap)
1398 1.1 skrll {
1399 1.1 skrll bfd_size_type tot;
1400 1.1 skrll
1401 1.1 skrll ecoff_align_debug (abfd, debug, swap);
1402 1.1 skrll tot = swap->external_hdr_size;
1403 1.1 skrll
1404 1.1 skrll #define ADD(count, size) \
1405 1.1 skrll tot += debug->symbolic_header.count * size
1406 1.1 skrll
1407 1.1 skrll ADD (cbLine, sizeof (unsigned char));
1408 1.1 skrll ADD (idnMax, swap->external_dnr_size);
1409 1.1 skrll ADD (ipdMax, swap->external_pdr_size);
1410 1.1 skrll ADD (isymMax, swap->external_sym_size);
1411 1.1 skrll ADD (ioptMax, swap->external_opt_size);
1412 1.1 skrll ADD (iauxMax, sizeof (union aux_ext));
1413 1.1 skrll ADD (issMax, sizeof (char));
1414 1.1 skrll ADD (issExtMax, sizeof (char));
1415 1.1 skrll ADD (ifdMax, swap->external_fdr_size);
1416 1.1 skrll ADD (crfd, swap->external_rfd_size);
1417 1.1 skrll ADD (iextMax, swap->external_ext_size);
1418 1.1 skrll
1419 1.1 skrll #undef ADD
1420 1.1 skrll
1421 1.1 skrll return tot;
1422 1.1 skrll }
1423 1.1 skrll
1424 1.1 skrll /* Write out the ECOFF symbolic header, given the file position it is
1425 1.1 skrll going to be placed at. This assumes that the counts are set
1426 1.1 skrll correctly. */
1427 1.1.1.8 christos
1428 1.1.1.3 christos static bool
1429 1.1.1.3 christos ecoff_write_symhdr (bfd *abfd,
1430 1.1.1.3 christos struct ecoff_debug_info *debug,
1431 1.1.1.3 christos const struct ecoff_debug_swap *swap,
1432 1.1 skrll file_ptr where)
1433 1.1 skrll {
1434 1.1 skrll HDRR * const symhdr = &debug->symbolic_header;
1435 1.1 skrll char *buff = NULL;
1436 1.1 skrll
1437 1.1 skrll ecoff_align_debug (abfd, debug, swap);
1438 1.1 skrll
1439 1.1 skrll /* Go to the right location in the file. */
1440 1.1.1.8 christos if (bfd_seek (abfd, where, SEEK_SET) != 0)
1441 1.1 skrll return false;
1442 1.1 skrll
1443 1.1 skrll where += swap->external_hdr_size;
1444 1.1 skrll
1445 1.1 skrll symhdr->magic = swap->sym_magic;
1446 1.1 skrll
1447 1.1 skrll /* Fill in the file offsets. */
1448 1.1 skrll #define SET(offset, count, size) \
1449 1.1 skrll if (symhdr->count == 0) \
1450 1.1 skrll symhdr->offset = 0; \
1451 1.1 skrll else \
1452 1.1 skrll { \
1453 1.1 skrll symhdr->offset = where; \
1454 1.1 skrll where += symhdr->count * size; \
1455 1.1 skrll }
1456 1.1 skrll
1457 1.1 skrll SET (cbLineOffset, cbLine, sizeof (unsigned char));
1458 1.1 skrll SET (cbDnOffset, idnMax, swap->external_dnr_size);
1459 1.1 skrll SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1460 1.1 skrll SET (cbSymOffset, isymMax, swap->external_sym_size);
1461 1.1 skrll SET (cbOptOffset, ioptMax, swap->external_opt_size);
1462 1.1 skrll SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1463 1.1 skrll SET (cbSsOffset, issMax, sizeof (char));
1464 1.1 skrll SET (cbSsExtOffset, issExtMax, sizeof (char));
1465 1.1 skrll SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1466 1.1 skrll SET (cbRfdOffset, crfd, swap->external_rfd_size);
1467 1.1 skrll SET (cbExtOffset, iextMax, swap->external_ext_size);
1468 1.1 skrll #undef SET
1469 1.1.1.2 christos
1470 1.1 skrll buff = (char *) bfd_malloc (swap->external_hdr_size);
1471 1.1 skrll if (buff == NULL && swap->external_hdr_size != 0)
1472 1.1 skrll goto error_return;
1473 1.1 skrll
1474 1.1.1.9 christos (*swap->swap_hdr_out) (abfd, symhdr, buff);
1475 1.1 skrll if (bfd_write (buff, swap->external_hdr_size, abfd)
1476 1.1 skrll != swap->external_hdr_size)
1477 1.1 skrll goto error_return;
1478 1.1.1.8 christos
1479 1.1.1.8 christos free (buff);
1480 1.1 skrll return true;
1481 1.1.1.8 christos error_return:
1482 1.1.1.8 christos free (buff);
1483 1.1 skrll return false;
1484 1.1 skrll }
1485 1.1 skrll
1486 1.1 skrll /* Write out the ECOFF debugging information. This function assumes
1487 1.1 skrll that the information (the pointers and counts) in *DEBUG have been
1488 1.1 skrll set correctly. WHERE is the position in the file to write the
1489 1.1 skrll information to. This function fills in the file offsets in the
1490 1.1 skrll symbolic header. */
1491 1.1.1.8 christos
1492 1.1.1.3 christos bool
1493 1.1.1.3 christos bfd_ecoff_write_debug (bfd *abfd,
1494 1.1.1.3 christos struct ecoff_debug_info *debug,
1495 1.1.1.3 christos const struct ecoff_debug_swap *swap,
1496 1.1 skrll file_ptr where)
1497 1.1 skrll {
1498 1.1 skrll HDRR * const symhdr = &debug->symbolic_header;
1499 1.1 skrll
1500 1.1.1.8 christos if (! ecoff_write_symhdr (abfd, debug, swap, where))
1501 1.1 skrll return false;
1502 1.1 skrll
1503 1.1.1.8 christos #define WRITE(ptr, count, size, offset) \
1504 1.1.1.8 christos BFD_ASSERT (symhdr->offset == 0 \
1505 1.1.1.8 christos || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
1506 1.1.1.9 christos if (symhdr->count != 0 \
1507 1.1.1.9 christos && bfd_write (debug->ptr, size * symhdr->count, \
1508 1.1.1.8 christos abfd) != size * symhdr->count) \
1509 1.1 skrll return false;
1510 1.1 skrll
1511 1.1 skrll WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1512 1.1 skrll WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1513 1.1 skrll WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1514 1.1 skrll WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1515 1.1.1.9 christos WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1516 1.1 skrll WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
1517 1.1 skrll WRITE (ss, issMax, sizeof (char), cbSsOffset);
1518 1.1 skrll WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1519 1.1 skrll WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1520 1.1 skrll WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1521 1.1 skrll WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1522 1.1 skrll #undef WRITE
1523 1.1.1.8 christos
1524 1.1 skrll return true;
1525 1.1 skrll }
1526 1.1 skrll
1527 1.1 skrll /* Write out a shuffle list. */
1528 1.1 skrll
1529 1.1.1.8 christos
1530 1.1.1.3 christos static bool
1531 1.1.1.3 christos ecoff_write_shuffle (bfd *abfd,
1532 1.1.1.3 christos const struct ecoff_debug_swap *swap,
1533 1.1.1.3 christos struct shuffle *shuffle,
1534 1.1 skrll void * space)
1535 1.1.1.3 christos {
1536 1.1.1.9 christos struct shuffle *l;
1537 1.1 skrll size_t total;
1538 1.1 skrll
1539 1.1.1.9 christos total = 0;
1540 1.1 skrll for (l = shuffle; l != NULL; l = l->next)
1541 1.1 skrll {
1542 1.1 skrll if (! l->filep)
1543 1.1.1.9 christos {
1544 1.1.1.8 christos if (bfd_write (l->u.memory, l->size, abfd) != l->size)
1545 1.1 skrll return false;
1546 1.1 skrll }
1547 1.1 skrll else
1548 1.1 skrll {
1549 1.1.1.9 christos if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1550 1.1.1.9 christos || bfd_read (space, l->size, l->u.file.input_bfd) != l->size
1551 1.1.1.8 christos || bfd_write (space, l->size, abfd) != l->size)
1552 1.1 skrll return false;
1553 1.1 skrll }
1554 1.1 skrll total += l->size;
1555 1.1 skrll }
1556 1.1 skrll
1557 1.1 skrll if ((total & (swap->debug_align - 1)) != 0)
1558 1.1.1.9 christos {
1559 1.1 skrll size_t i;
1560 1.1 skrll bfd_byte *s;
1561 1.1 skrll
1562 1.1.1.9 christos i = swap->debug_align - (total & (swap->debug_align - 1));
1563 1.1 skrll s = bfd_zmalloc (i);
1564 1.1.1.8 christos if (s == NULL && i != 0)
1565 1.1 skrll return false;
1566 1.1.1.9 christos
1567 1.1 skrll if (bfd_write (s, i, abfd) != i)
1568 1.1 skrll {
1569 1.1.1.8 christos free (s);
1570 1.1 skrll return false;
1571 1.1 skrll }
1572 1.1 skrll free (s);
1573 1.1 skrll }
1574 1.1.1.8 christos
1575 1.1 skrll return true;
1576 1.1 skrll }
1577 1.1 skrll
1578 1.1 skrll /* Write out debugging information using accumulated linker
1579 1.1 skrll information. */
1580 1.1.1.8 christos
1581 1.1.1.3 christos bool
1582 1.1.1.3 christos bfd_ecoff_write_accumulated_debug (void * handle,
1583 1.1.1.3 christos bfd *abfd,
1584 1.1.1.3 christos struct ecoff_debug_info *debug,
1585 1.1.1.3 christos const struct ecoff_debug_swap *swap,
1586 1.1.1.3 christos struct bfd_link_info *info,
1587 1.1 skrll file_ptr where)
1588 1.1 skrll {
1589 1.1.1.3 christos struct accumulate *ainfo = (struct accumulate *) handle;
1590 1.1 skrll void * space = NULL;
1591 1.1 skrll bfd_size_type amt;
1592 1.1 skrll
1593 1.1 skrll if (! ecoff_write_symhdr (abfd, debug, swap, where))
1594 1.1 skrll goto error_return;
1595 1.1 skrll
1596 1.1.1.3 christos amt = ainfo->largest_file_shuffle;
1597 1.1 skrll space = bfd_malloc (amt);
1598 1.1 skrll if (space == NULL && ainfo->largest_file_shuffle != 0)
1599 1.1 skrll goto error_return;
1600 1.1 skrll
1601 1.1 skrll if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1602 1.1 skrll || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1603 1.1 skrll || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1604 1.1 skrll || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1605 1.1 skrll || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1606 1.1 skrll goto error_return;
1607 1.1 skrll
1608 1.1 skrll /* The string table is written out from the hash table if this is a
1609 1.1.1.4 christos final link. */
1610 1.1 skrll if (bfd_link_relocatable (info))
1611 1.1 skrll {
1612 1.1 skrll BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1613 1.1 skrll if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1614 1.1 skrll goto error_return;
1615 1.1 skrll }
1616 1.1 skrll else
1617 1.1 skrll {
1618 1.1 skrll unsigned long total;
1619 1.1 skrll bfd_byte null;
1620 1.1 skrll struct string_hash_entry *sh;
1621 1.1.1.9 christos
1622 1.1 skrll BFD_ASSERT (ainfo->ss == NULL);
1623 1.1.1.9 christos null = 0;
1624 1.1 skrll if (bfd_write (&null, 1, abfd) != 1)
1625 1.1 skrll goto error_return;
1626 1.1 skrll total = 1;
1627 1.1.1.9 christos BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1628 1.1 skrll for (sh = ainfo->ss_hash; sh != NULL; sh = sh->next)
1629 1.1 skrll {
1630 1.1 skrll size_t len;
1631 1.1 skrll
1632 1.1 skrll len = strlen (sh->root.string);
1633 1.1.1.9 christos amt = len + 1;
1634 1.1 skrll if (bfd_write (sh->root.string, amt, abfd) != amt)
1635 1.1 skrll goto error_return;
1636 1.1 skrll total += len + 1;
1637 1.1 skrll }
1638 1.1 skrll
1639 1.1 skrll if ((total & (swap->debug_align - 1)) != 0)
1640 1.1.1.9 christos {
1641 1.1 skrll size_t i;
1642 1.1 skrll bfd_byte *s;
1643 1.1 skrll
1644 1.1.1.9 christos i = swap->debug_align - (total & (swap->debug_align - 1));
1645 1.1 skrll s = bfd_zmalloc (i);
1646 1.1 skrll if (s == NULL && i != 0)
1647 1.1 skrll goto error_return;
1648 1.1.1.9 christos
1649 1.1 skrll if (bfd_write (s, i, abfd) != i)
1650 1.1 skrll {
1651 1.1 skrll free (s);
1652 1.1 skrll goto error_return;
1653 1.1 skrll }
1654 1.1 skrll free (s);
1655 1.1 skrll }
1656 1.1 skrll }
1657 1.1 skrll
1658 1.1 skrll /* The external strings and symbol are not converted over to using
1659 1.1 skrll shuffles. FIXME: They probably should be. */
1660 1.1.1.9 christos amt = debug->symbolic_header.issExtMax;
1661 1.1 skrll if (amt != 0 && bfd_write (debug->ssext, amt, abfd) != amt)
1662 1.1 skrll goto error_return;
1663 1.1 skrll if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1664 1.1.1.9 christos {
1665 1.1 skrll size_t i;
1666 1.1 skrll bfd_byte *s;
1667 1.1 skrll
1668 1.1 skrll i = (swap->debug_align
1669 1.1.1.9 christos - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1670 1.1 skrll s = bfd_zmalloc (i);
1671 1.1 skrll if (s == NULL && i != 0)
1672 1.1 skrll goto error_return;
1673 1.1.1.9 christos
1674 1.1 skrll if (bfd_write (s, i, abfd) != i)
1675 1.1 skrll {
1676 1.1 skrll free (s);
1677 1.1 skrll goto error_return;
1678 1.1 skrll }
1679 1.1 skrll free (s);
1680 1.1 skrll }
1681 1.1 skrll
1682 1.1 skrll if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1683 1.1 skrll || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1684 1.1 skrll goto error_return;
1685 1.1 skrll
1686 1.1 skrll BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1687 1.1 skrll || (debug->symbolic_header.cbExtOffset
1688 1.1 skrll == (bfd_vma) bfd_tell (abfd)));
1689 1.1 skrll
1690 1.1.1.9 christos amt = debug->symbolic_header.iextMax * swap->external_ext_size;
1691 1.1 skrll if (amt != 0 && bfd_write (debug->external_ext, amt, abfd) != amt)
1692 1.1 skrll goto error_return;
1693 1.1.1.8 christos
1694 1.1.1.8 christos free (space);
1695 1.1 skrll return true;
1696 1.1 skrll
1697 1.1.1.8 christos error_return:
1698 1.1.1.8 christos free (space);
1699 1.1 skrll return false;
1700 1.1 skrll }
1701 1.1 skrll
1702 1.1 skrll /* Handle the find_nearest_line function for both ECOFF and MIPS ELF
1704 1.1.1.9 christos files. */
1705 1.1.1.9 christos
1706 1.1.1.9 christos /* Free ECOFF debugging info used by find_nearest_line. */
1707 1.1.1.9 christos
1708 1.1.1.9 christos void
1709 1.1.1.9 christos _bfd_ecoff_free_ecoff_debug_info (struct ecoff_debug_info *debug)
1710 1.1.1.9 christos {
1711 1.1.1.9 christos if (!debug->alloc_syments)
1712 1.1.1.9 christos {
1713 1.1.1.9 christos free (debug->line);
1714 1.1.1.9 christos free (debug->external_dnr);
1715 1.1.1.9 christos free (debug->external_pdr);
1716 1.1.1.9 christos free (debug->external_sym);
1717 1.1.1.9 christos free (debug->external_opt);
1718 1.1.1.9 christos free (debug->external_aux);
1719 1.1.1.9 christos free (debug->ss);
1720 1.1.1.9 christos free (debug->ssext);
1721 1.1.1.9 christos free (debug->external_fdr);
1722 1.1.1.9 christos free (debug->external_rfd);
1723 1.1.1.9 christos free (debug->external_ext);
1724 1.1.1.9 christos }
1725 1.1.1.9 christos debug->line= NULL;
1726 1.1.1.9 christos debug->external_dnr= NULL;
1727 1.1.1.9 christos debug->external_pdr= NULL;
1728 1.1.1.9 christos debug->external_sym= NULL;
1729 1.1.1.9 christos debug->external_opt= NULL;
1730 1.1.1.9 christos debug->external_aux= NULL;
1731 1.1.1.9 christos debug->ss= NULL;
1732 1.1.1.9 christos debug->ssext= NULL;
1733 1.1.1.9 christos debug->external_fdr= NULL;
1734 1.1.1.9 christos debug->external_rfd= NULL;
1735 1.1.1.9 christos debug->external_ext= NULL;
1736 1.1 skrll }
1737 1.1 skrll
1738 1.1 skrll /* Compare FDR entries. This is called via qsort. */
1739 1.1.1.3 christos
1740 1.1 skrll static int
1741 1.1 skrll cmp_fdrtab_entry (const void * leftp, const void * rightp)
1742 1.1 skrll {
1743 1.1 skrll const struct ecoff_fdrtab_entry *lp =
1744 1.1 skrll (const struct ecoff_fdrtab_entry *) leftp;
1745 1.1 skrll const struct ecoff_fdrtab_entry *rp =
1746 1.1 skrll (const struct ecoff_fdrtab_entry *) rightp;
1747 1.1 skrll
1748 1.1 skrll if (lp->base_addr < rp->base_addr)
1749 1.1 skrll return -1;
1750 1.1 skrll if (lp->base_addr > rp->base_addr)
1751 1.1 skrll return 1;
1752 1.1 skrll return 0;
1753 1.1 skrll }
1754 1.1 skrll
1755 1.1 skrll /* Each file descriptor (FDR) has a memory address, to simplify
1756 1.1 skrll looking up an FDR by address, we build a table covering all FDRs
1757 1.1 skrll that have a least one procedure descriptor in them. The final
1758 1.1 skrll table will be sorted by address so we can look it up via binary
1759 1.1.1.8 christos search. */
1760 1.1.1.3 christos
1761 1.1.1.3 christos static bool
1762 1.1.1.3 christos mk_fdrtab (bfd *abfd,
1763 1.1.1.3 christos struct ecoff_debug_info * const debug_info,
1764 1.1 skrll const struct ecoff_debug_swap * const debug_swap,
1765 1.1 skrll struct ecoff_find_line *line_info)
1766 1.1 skrll {
1767 1.1 skrll struct ecoff_fdrtab_entry *tab;
1768 1.1 skrll FDR *fdr_ptr;
1769 1.1.1.8 christos FDR *fdr_start;
1770 1.1.1.9 christos FDR *fdr_end;
1771 1.1.1.9 christos bool stabs;
1772 1.1 skrll size_t len;
1773 1.1 skrll size_t amt;
1774 1.1 skrll
1775 1.1 skrll fdr_start = debug_info->fdr;
1776 1.1 skrll fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
1777 1.1 skrll
1778 1.1 skrll /* First, let's see how long the table needs to be. */
1779 1.1.1.9 christos for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1780 1.1.1.9 christos {
1781 1.1.1.9 christos /* Sanity check fdr procedure descriptor pointer. */
1782 1.1.1.9 christos long ipdMax = debug_info->symbolic_header.ipdMax;
1783 1.1.1.9 christos if (fdr_ptr->ipdFirst >= ipdMax
1784 1.1.1.9 christos || fdr_ptr->cpd < 0
1785 1.1.1.9 christos || fdr_ptr->cpd > ipdMax - fdr_ptr->ipdFirst)
1786 1.1.1.9 christos fdr_ptr->cpd = 0;
1787 1.1 skrll /* Skip FDRs that have no PDRs. */
1788 1.1 skrll if (fdr_ptr->cpd == 0)
1789 1.1 skrll continue;
1790 1.1 skrll ++len;
1791 1.1 skrll }
1792 1.1.1.9 christos
1793 1.1.1.9 christos /* Now, create and fill in the table. */
1794 1.1.1.9 christos if (_bfd_mul_overflow (len, sizeof (struct ecoff_fdrtab_entry), &amt))
1795 1.1.1.9 christos {
1796 1.1.1.9 christos bfd_set_error (bfd_error_file_too_big);
1797 1.1 skrll return false;
1798 1.1 skrll }
1799 1.1.1.8 christos line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
1800 1.1 skrll if (line_info->fdrtab == NULL)
1801 1.1 skrll return false;
1802 1.1 skrll
1803 1.1 skrll tab = line_info->fdrtab;
1804 1.1 skrll for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1805 1.1 skrll {
1806 1.1 skrll if (fdr_ptr->cpd == 0)
1807 1.1 skrll continue;
1808 1.1 skrll
1809 1.1 skrll /* Check whether this file has stabs debugging information. In
1810 1.1.1.8 christos a file with stabs debugging information, the second local
1811 1.1 skrll symbol is named @stabs. */
1812 1.1 skrll stabs = false;
1813 1.1 skrll if (fdr_ptr->csym >= 2)
1814 1.1 skrll {
1815 1.1 skrll char *sym_ptr;
1816 1.1.1.9 christos SYMR sym;
1817 1.1.1.9 christos
1818 1.1.1.9 christos if ((long) ((unsigned long) fdr_ptr->isymBase + 1) <= 0
1819 1.1.1.9 christos || fdr_ptr->isymBase + 1 >= debug_info->symbolic_header.isymMax)
1820 1.1 skrll continue;
1821 1.1 skrll
1822 1.1 skrll sym_ptr = ((char *) debug_info->external_sym
1823 1.1.1.9 christos + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
1824 1.1.1.9 christos (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
1825 1.1.1.9 christos if (fdr_ptr->issBase >= 0
1826 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
1827 1.1.1.9 christos && sym.iss >= 0
1828 1.1.1.9 christos && sym.iss < (debug_info->symbolic_header.issMax
1829 1.1.1.9 christos - fdr_ptr->issBase)
1830 1.1.1.8 christos && strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
1831 1.1 skrll STABS_SYMBOL) == 0)
1832 1.1 skrll stabs = true;
1833 1.1 skrll }
1834 1.1 skrll
1835 1.1 skrll if (!stabs)
1836 1.1 skrll {
1837 1.1 skrll /* eraxxon: There are at least two problems with this computation:
1838 1.1 skrll 1) PDRs do *not* contain offsets but full vma's; and typically the
1839 1.1 skrll address of the first PDR is the address of the FDR, which will
1840 1.1 skrll make (most) of the results of the original computation 0!
1841 1.1 skrll 2) Once in a wacky while, the Compaq compiler generated PDR
1842 1.1 skrll addresses do not equal the FDR vma, but they (the PDR address)
1843 1.1 skrll are still vma's and not offsets. Cf. comments in
1844 1.1 skrll 'lookup_line'. */
1845 1.1.1.4 christos /* The address of the first PDR is the offset of that
1846 1.1 skrll procedure relative to the beginning of file FDR. */
1847 1.1 skrll tab->base_addr = fdr_ptr->adr;
1848 1.1 skrll }
1849 1.1 skrll else
1850 1.1 skrll {
1851 1.1 skrll /* XXX I don't know about stabs, so this is a guess
1852 1.1 skrll (davidm (at) cs.arizona.edu). */
1853 1.1 skrll tab->base_addr = fdr_ptr->adr;
1854 1.1 skrll }
1855 1.1 skrll tab->fdr = fdr_ptr;
1856 1.1.1.9 christos ++tab;
1857 1.1.1.9 christos }
1858 1.1 skrll len = tab - line_info->fdrtab;
1859 1.1 skrll line_info->fdrtab_len = len;
1860 1.1 skrll
1861 1.1 skrll /* Finally, the table is sorted in increasing memory-address order.
1862 1.1 skrll The table is mostly sorted already, but there are cases (e.g.,
1863 1.1.1.9 christos static functions in include files), where this does not hold.
1864 1.1 skrll Use "odump -PFv" to verify... */
1865 1.1 skrll qsort (line_info->fdrtab, len,
1866 1.1.1.8 christos sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
1867 1.1 skrll
1868 1.1 skrll return true;
1869 1.1 skrll }
1870 1.1 skrll
1871 1.1 skrll /* Return index of first FDR that covers to OFFSET. */
1872 1.1.1.3 christos
1873 1.1 skrll static long
1874 1.1 skrll fdrtab_lookup (struct ecoff_find_line *line_info, bfd_vma offset)
1875 1.1 skrll {
1876 1.1 skrll long low, high, len;
1877 1.1 skrll long mid = -1;
1878 1.1 skrll struct ecoff_fdrtab_entry *tab;
1879 1.1 skrll
1880 1.1 skrll len = line_info->fdrtab_len;
1881 1.1 skrll if (len == 0)
1882 1.1 skrll return -1;
1883 1.1 skrll
1884 1.1 skrll tab = line_info->fdrtab;
1885 1.1 skrll for (low = 0, high = len - 1 ; low != high ;)
1886 1.1 skrll {
1887 1.1 skrll mid = (high + low) / 2;
1888 1.1 skrll if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
1889 1.1 skrll goto find_min;
1890 1.1 skrll
1891 1.1 skrll if (tab[mid].base_addr > offset)
1892 1.1 skrll high = mid;
1893 1.1 skrll else
1894 1.1 skrll low = mid + 1;
1895 1.1 skrll }
1896 1.1 skrll
1897 1.1 skrll /* eraxxon: at this point 'offset' is either lower than the lowest entry or
1898 1.1 skrll higher than the highest entry. In the former case high = low = mid = 0;
1899 1.1 skrll we want to return -1. In the latter case, low = high and mid = low - 1;
1900 1.1 skrll we want to return the index of the highest entry. Only in former case
1901 1.1 skrll will the following 'catch-all' test be true. */
1902 1.1 skrll ++mid;
1903 1.1 skrll
1904 1.1 skrll /* Last entry is catch-all for all higher addresses. */
1905 1.1 skrll if (offset < tab[mid].base_addr)
1906 1.1 skrll return -1;
1907 1.1 skrll
1908 1.1 skrll find_min:
1909 1.1 skrll
1910 1.1 skrll /* eraxxon: There may be multiple FDRs in the table with the
1911 1.1 skrll same base_addr; make sure that we are at the first one. */
1912 1.1 skrll while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
1913 1.1 skrll --mid;
1914 1.1 skrll
1915 1.1 skrll return mid;
1916 1.1 skrll }
1917 1.1 skrll
1918 1.1 skrll /* Look up a line given an address, storing the information in
1919 1.1.1.8 christos LINE_INFO->cache. */
1920 1.1.1.3 christos
1921 1.1.1.3 christos static bool
1922 1.1.1.3 christos lookup_line (bfd *abfd,
1923 1.1.1.3 christos struct ecoff_debug_info * const debug_info,
1924 1.1 skrll const struct ecoff_debug_swap * const debug_swap,
1925 1.1 skrll struct ecoff_find_line *line_info)
1926 1.1 skrll {
1927 1.1.1.8 christos struct ecoff_fdrtab_entry *tab;
1928 1.1 skrll bfd_vma offset;
1929 1.1 skrll bool stabs;
1930 1.1 skrll FDR *fdr_ptr;
1931 1.1 skrll int i;
1932 1.1 skrll
1933 1.1 skrll /* eraxxon: note that 'offset' is the full vma, not a section offset. */
1934 1.1 skrll offset = line_info->cache.start;
1935 1.1 skrll
1936 1.1 skrll /* Build FDR table (sorted by object file's base-address) if we
1937 1.1 skrll don't have it already. */
1938 1.1.1.8 christos if (line_info->fdrtab == NULL
1939 1.1 skrll && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
1940 1.1 skrll return false;
1941 1.1 skrll
1942 1.1 skrll tab = line_info->fdrtab;
1943 1.1 skrll
1944 1.1 skrll /* Find first FDR for address OFFSET. */
1945 1.1.1.8 christos i = fdrtab_lookup (line_info, offset);
1946 1.1.1.4 christos if (i < 0)
1947 1.1 skrll return false; /* no FDR, no fun... */
1948 1.1 skrll
1949 1.1 skrll /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
1950 1.1 skrll C++ compiler 6.2. Consider three FDRs with starting addresses of x, y,
1951 1.1 skrll and z, respectively, such that x < y < z. Assume further that
1952 1.1 skrll y < 'offset' < z. It is possible at times that the PDR for 'offset' is
1953 1.1 skrll associated with FDR x and *not* with FDR y. Erg!!
1954 1.1 skrll
1955 1.1 skrll From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
1956 1.1 skrll (output format has been edited for our purposes):
1957 1.1.1.6 christos
1958 1.1.1.6 christos FDR [2]: (main.C): First instruction: 0x12000207c <x>
1959 1.1.1.6 christos PDR [5] for File [2]: LoopTest__Xv <0x1200020a0> (a)
1960 1.1.1.6 christos PDR [7] for File [2]: foo__Xv <0x120002168>
1961 1.1.1.6 christos FDR [1]: (-1): First instruction: 0x1200020e8 <y>
1962 1.1 skrll PDR [3] for File [1]: <0x120001ad0> (b)
1963 1.1 skrll FDR [6]: (-1): First instruction: 0x1200026f0 <z>
1964 1.1 skrll
1965 1.1 skrll (a) In the case of PDR5, the vma is such that the first few instructions
1966 1.1 skrll of the procedure can be found. But since the size of this procedure is
1967 1.1 skrll 160b, the vma will soon cross into the 'address space' of FDR1 and no
1968 1.1 skrll debugging info will be found. How repugnant!
1969 1.1 skrll
1970 1.1 skrll (b) It is also possible for a PDR to have a *lower* vma than its associated
1971 1.1 skrll FDR; see FDR1 and PDR3. Gross!
1972 1.1 skrll
1973 1.1 skrll Since the FDRs that are causing so much havok (in this case) 1) do not
1974 1.1 skrll describe actual files (fdr.rss == -1), and 2) contain only compiler
1975 1.1 skrll generated routines, I thought a simple fix would be to exclude them from
1976 1.1 skrll the FDR table in 'mk_fdrtab'. But, besides not knowing for certain
1977 1.1 skrll whether this would be correct, it creates an additional problem. If we
1978 1.1 skrll happen to ask for source file info on a compiler generated (procedure)
1979 1.1 skrll symbol -- which is still in the symbol table -- the result can be
1980 1.1 skrll information from a real procedure! This is because compiler generated
1981 1.1 skrll procedures with vma's higher than the last FDR in the fdr table will be
1982 1.1 skrll associated with a PDR from this FDR, specifically the PDR with the
1983 1.1 skrll highest vma. This wasn't a problem before, because each procedure had a
1984 1.1 skrll PDR. (Yes, this problem could be eliminated if we kept the size of the
1985 1.1 skrll last PDR around, but things are already getting ugly).
1986 1.1 skrll
1987 1.1 skrll Probably, a better solution would be to have a sorted PDR table. Each
1988 1.1 skrll PDR would have a pointer to its FDR so file information could still be
1989 1.1 skrll obtained. A FDR table could still be constructed if necessary -- since
1990 1.1 skrll it only contains pointers, not much extra memory would be used -- but
1991 1.1 skrll the PDR table would be searched to locate debugging info.
1992 1.1 skrll
1993 1.1 skrll There is still at least one remaining issue. Sometimes a FDR can have a
1994 1.1 skrll bogus name, but contain PDRs that should belong to another FDR with a
1995 1.1 skrll real name. E.g:
1996 1.1 skrll
1997 1.1 skrll FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
1998 1.1 skrll PDR [a] for File [3]: 0000000120001b50
1999 1.1 skrll PDR [b] for File [3]: 0000000120001cf0
2000 1.1 skrll PDR [c] for File [3]: 0000000120001dc8
2001 1.1 skrll PDR [d] for File [3]: 0000000120001e40
2002 1.1 skrll PDR [e] for File [3]: 0000000120001eb8
2003 1.1 skrll PDR [f] for File [3]: 0000000120001f4c
2004 1.1 skrll FDR [4]: 0000000120001b50 (/home/.../Array.H)
2005 1.1 skrll
2006 1.1 skrll Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
2007 1.1 skrll The symbol table for PDR4 does contain symbols for PDRa-f, but so does
2008 1.1 skrll the symbol table for FDR3. However the former is different; perhaps this
2009 1.1 skrll can be detected easily. (I'm not sure at this point.) This problem only
2010 1.1 skrll seems to be associated with files with templates. I am assuming the idea
2011 1.1 skrll is that there is a 'fake' FDR (with PDRs) for each differently typed set
2012 1.1 skrll of templates that must be generated. Currently, FDR4 is completely
2013 1.1 skrll excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.
2014 1.1 skrll
2015 1.1 skrll Since I don't have time to prepare a real fix for this right now, be
2016 1.1 skrll prepared for 'A Horrible Hack' to force the inspection of all non-stabs
2017 1.1 skrll FDRs. It's coming... */
2018 1.1 skrll fdr_ptr = tab[i].fdr;
2019 1.1 skrll
2020 1.1 skrll /* Check whether this file has stabs debugging information. In a
2021 1.1.1.8 christos file with stabs debugging information, the second local symbol is
2022 1.1 skrll named @stabs. */
2023 1.1 skrll stabs = false;
2024 1.1 skrll if (fdr_ptr->csym >= 2)
2025 1.1 skrll {
2026 1.1 skrll char *sym_ptr;
2027 1.1.1.9 christos SYMR sym;
2028 1.1.1.9 christos
2029 1.1.1.9 christos if ((long) ((unsigned long) fdr_ptr->isymBase + 1) > 0
2030 1.1.1.9 christos && fdr_ptr->isymBase + 1 < debug_info->symbolic_header.isymMax)
2031 1.1.1.9 christos {
2032 1.1.1.9 christos sym_ptr = ((char *) debug_info->external_sym
2033 1.1.1.9 christos + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
2034 1.1.1.9 christos (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
2035 1.1.1.9 christos if (fdr_ptr->issBase >= 0
2036 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2037 1.1.1.9 christos && sym.iss >= 0
2038 1.1.1.9 christos && sym.iss < (debug_info->symbolic_header.issMax
2039 1.1.1.9 christos - fdr_ptr->issBase)
2040 1.1.1.9 christos && strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
2041 1.1.1.9 christos STABS_SYMBOL) == 0)
2042 1.1 skrll stabs = true;
2043 1.1 skrll }
2044 1.1.1.9 christos }
2045 1.1.1.9 christos
2046 1.1.1.9 christos line_info->cache.filename = NULL;
2047 1.1.1.9 christos line_info->cache.functionname = NULL;
2048 1.1 skrll line_info->cache.line_num = 0;
2049 1.1 skrll
2050 1.1 skrll if (!stabs)
2051 1.1 skrll {
2052 1.1 skrll bfd_size_type external_pdr_size;
2053 1.1 skrll char *pdr_ptr;
2054 1.1 skrll char *best_pdr = NULL;
2055 1.1 skrll FDR *best_fdr;
2056 1.1 skrll bfd_signed_vma best_dist = -1;
2057 1.1 skrll PDR pdr;
2058 1.1 skrll unsigned char *line_ptr;
2059 1.1 skrll unsigned char *line_end;
2060 1.1.1.6 christos int lineno;
2061 1.1.1.6 christos /* This file uses ECOFF debugging information. Each FDR has a
2062 1.1.1.6 christos list of procedure descriptors (PDR). The address in the FDR
2063 1.1.1.6 christos is the absolute address of the first procedure. The address
2064 1.1.1.6 christos in the first PDR gives the offset of that procedure relative
2065 1.1.1.6 christos to the object file's base-address. The addresses in
2066 1.1.1.6 christos subsequent PDRs specify each procedure's address relative to
2067 1.1.1.6 christos the object file's base-address. To make things more juicy,
2068 1.1.1.6 christos whenever the PROF bit in the PDR is set, the real entry point
2069 1.1.1.6 christos of the procedure may be 16 bytes below what would normally be
2070 1.1.1.6 christos the procedure's entry point. Instead, DEC came up with a
2071 1.1.1.6 christos wicked scheme to create profiled libraries "on the fly":
2072 1.1.1.6 christos instead of shipping a regular and a profiled version of each
2073 1.1.1.6 christos library, they insert 16 bytes of unused space in front of
2074 1.1.1.6 christos each procedure and set the "prof" bit in the PDR to indicate
2075 1.1.1.6 christos that there is a gap there (this is done automagically by "as"
2076 1.1.1.6 christos when option "-pg" is specified). Thus, normally, you link
2077 1.1.1.6 christos against such a library and, except for lots of 16 byte gaps
2078 1.1.1.6 christos between functions, things will behave as usual. However,
2079 1.1.1.6 christos when invoking "ld" with option "-pg", it will fill those gaps
2080 1.1.1.6 christos with code that calls mcount(). It then moves the function's
2081 1.1.1.6 christos entry point down by 16 bytes, and out pops a binary that has
2082 1.1.1.6 christos all functions profiled.
2083 1.1.1.6 christos
2084 1.1.1.6 christos NOTE: Neither FDRs nor PDRs are strictly sorted in memory
2085 1.1.1.6 christos order. For example, when including header-files that
2086 1.1.1.6 christos define functions, the FDRs follow behind the including
2087 1.1.1.6 christos file, even though their code may have been generated at
2088 1.1.1.6 christos a lower address. File coff-alpha.c from libbfd
2089 1.1.1.6 christos illustrates this (use "odump -PFv" to look at a file's
2090 1.1.1.6 christos FDR/PDR). Similarly, PDRs are sometimes out of order
2091 1.1.1.6 christos as well. An example of this is OSF/1 v3.0 libc's
2092 1.1.1.6 christos malloc.c. I'm not sure why this happens, but it could
2093 1.1.1.6 christos be due to optimizations that reorder a function's
2094 1.1.1.6 christos position within an object-file.
2095 1.1.1.6 christos
2096 1.1.1.6 christos Strategy:
2097 1.1.1.6 christos
2098 1.1.1.6 christos On the first call to this function, we build a table of FDRs
2099 1.1.1.6 christos that is sorted by the base-address of the object-file the FDR
2100 1.1.1.6 christos is referring to. Notice that each object-file may contain
2101 1.1.1.6 christos code from multiple source files (e.g., due to code defined in
2102 1.1.1.6 christos include files). Thus, for any given base-address, there may
2103 1.1.1.6 christos be multiple FDRs (but this case is, fortunately, uncommon).
2104 1.1.1.6 christos lookup(addr) guarantees to return the first FDR that applies
2105 1.1.1.6 christos to address ADDR. Thus, after invoking lookup(), we have a
2106 1.1.1.6 christos list of FDRs that may contain the PDR for ADDR. Next, we
2107 1.1.1.6 christos walk through the PDRs of these FDRs and locate the one that
2108 1.1.1.6 christos is closest to ADDR (i.e., for which the difference between
2109 1.1.1.6 christos ADDR and the PDR's entry point is positive and minimal).
2110 1.1.1.6 christos Once, the right FDR and PDR are located, we simply walk
2111 1.1.1.6 christos through the line-number table to lookup the line-number that
2112 1.1.1.6 christos best matches ADDR. Obviously, things could be sped up by
2113 1.1.1.6 christos keeping a sorted list of PDRs instead of a sorted list of
2114 1.1 skrll FDRs. However, this would increase space requirements
2115 1.1 skrll considerably, which is undesirable. */
2116 1.1 skrll external_pdr_size = debug_swap->external_pdr_size;
2117 1.1 skrll
2118 1.1 skrll /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
2119 1.1 skrll to 0 so we look through all FDRs.
2120 1.1 skrll
2121 1.1 skrll Because FDR's without any symbols are assumed to be non-stabs,
2122 1.1 skrll searching through all FDRs may cause the following code to try to
2123 1.1 skrll read stabs FDRs as ECOFF ones. However, I don't think this will
2124 1.1.1.4 christos harm anything. */
2125 1.1 skrll i = 0;
2126 1.1.1.6 christos
2127 1.1 skrll /* Search FDR list starting at tab[i] for the PDR that best matches
2128 1.1 skrll OFFSET. Normally, the FDR list is only one entry long. */
2129 1.1 skrll best_fdr = NULL;
2130 1.1 skrll do
2131 1.1.1.6 christos {
2132 1.1.1.6 christos /* eraxxon: 'dist' and 'min_dist' can be negative now
2133 1.1 skrll because we iterate over every FDR rather than just ones
2134 1.1.1.9 christos with a base address less than or equal to 'offset'. */
2135 1.1 skrll bfd_signed_vma dist = -1, min_dist = -1;
2136 1.1 skrll char *pdr_hold = NULL;
2137 1.1 skrll char *pdr_end;
2138 1.1 skrll
2139 1.1 skrll fdr_ptr = tab[i].fdr;
2140 1.1 skrll
2141 1.1 skrll pdr_ptr = ((char *) debug_info->external_pdr
2142 1.1 skrll + fdr_ptr->ipdFirst * external_pdr_size);
2143 1.1 skrll pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
2144 1.1 skrll /* Find PDR that is closest to OFFSET. If pdr.prof is set,
2145 1.1 skrll the procedure entry-point *may* be 0x10 below pdr.adr. We
2146 1.1 skrll simply pretend that pdr.prof *implies* a lower entry-point.
2147 1.1.1.9 christos This is safe because it just means that may identify 4 NOPs
2148 1.1 skrll in front of the function as belonging to the function. */
2149 1.1.1.9 christos for (; pdr_ptr < pdr_end; pdr_ptr += external_pdr_size)
2150 1.1 skrll {
2151 1.1 skrll (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
2152 1.1 skrll if (offset >= (pdr.adr - 0x10 * pdr.prof))
2153 1.1 skrll {
2154 1.1 skrll dist = offset - (pdr.adr - 0x10 * pdr.prof);
2155 1.1.1.6 christos
2156 1.1 skrll /* eraxxon: 'dist' can be negative now. Note that
2157 1.1 skrll 'min_dist' can be negative if 'pdr_hold' below is NULL. */
2158 1.1 skrll if (!pdr_hold || (dist >= 0 && dist < min_dist))
2159 1.1 skrll {
2160 1.1 skrll min_dist = dist;
2161 1.1 skrll pdr_hold = pdr_ptr;
2162 1.1 skrll }
2163 1.1 skrll }
2164 1.1 skrll }
2165 1.1 skrll
2166 1.1.1.4 christos if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
2167 1.1 skrll {
2168 1.1 skrll best_dist = (bfd_vma) min_dist;
2169 1.1 skrll best_fdr = fdr_ptr;
2170 1.1 skrll best_pdr = pdr_hold;
2171 1.1 skrll }
2172 1.1 skrll /* Continue looping until base_addr of next entry is different. */
2173 1.1 skrll }
2174 1.1 skrll /* eraxxon: We want to iterate over all FDRs.
2175 1.1 skrll See previous comment about 'fdrtab_lookup'. */
2176 1.1 skrll while (++i < line_info->fdrtab_len);
2177 1.1.1.8 christos
2178 1.1 skrll if (!best_fdr || !best_pdr)
2179 1.1 skrll return false; /* Shouldn't happen... */
2180 1.1 skrll
2181 1.1 skrll /* Phew, finally we got something that we can hold onto. */
2182 1.1.1.3 christos fdr_ptr = best_fdr;
2183 1.1 skrll pdr_ptr = best_pdr;
2184 1.1.1.6 christos (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
2185 1.1.1.6 christos /* Now we can look for the actual line number. The line numbers
2186 1.1.1.6 christos are stored in a very funky format, which I won't try to
2187 1.1.1.9 christos describe. The search is bounded by the end of the FDRs line
2188 1.1.1.9 christos number entries. */
2189 1.1.1.9 christos line_ptr = line_end = debug_info->line;
2190 1.1.1.9 christos if (fdr_ptr->cbLineOffset < debug_info->symbolic_header.cbLine
2191 1.1.1.9 christos && fdr_ptr->cbLine <= (debug_info->symbolic_header.cbLine
2192 1.1.1.9 christos - fdr_ptr->cbLineOffset)
2193 1.1.1.9 christos && pdr.cbLineOffset <= (debug_info->symbolic_header.cbLine
2194 1.1.1.9 christos - fdr_ptr->cbLineOffset))
2195 1.1.1.9 christos {
2196 1.1.1.9 christos line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
2197 1.1 skrll line_ptr += fdr_ptr->cbLineOffset + pdr.cbLineOffset;
2198 1.1 skrll }
2199 1.1 skrll
2200 1.1 skrll /* Make offset relative to procedure entry. */
2201 1.1 skrll offset -= pdr.adr - 0x10 * pdr.prof;
2202 1.1 skrll lineno = pdr.lnLow;
2203 1.1 skrll while (line_ptr < line_end)
2204 1.1 skrll {
2205 1.1 skrll int delta;
2206 1.1 skrll unsigned int count;
2207 1.1 skrll
2208 1.1 skrll delta = *line_ptr >> 4;
2209 1.1 skrll if (delta >= 0x8)
2210 1.1 skrll delta -= 0x10;
2211 1.1 skrll count = (*line_ptr & 0xf) + 1;
2212 1.1 skrll ++line_ptr;
2213 1.1 skrll if (delta == -8)
2214 1.1 skrll {
2215 1.1 skrll delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
2216 1.1 skrll if (delta >= 0x8000)
2217 1.1 skrll delta -= 0x10000;
2218 1.1 skrll line_ptr += 2;
2219 1.1 skrll }
2220 1.1 skrll lineno += delta;
2221 1.1 skrll if (offset < count * 4)
2222 1.1 skrll {
2223 1.1 skrll line_info->cache.stop += count * 4 - offset;
2224 1.1 skrll break;
2225 1.1 skrll }
2226 1.1 skrll offset -= count * 4;
2227 1.1 skrll }
2228 1.1.1.6 christos
2229 1.1 skrll /* If fdr_ptr->rss is -1, then this file does not have full
2230 1.1 skrll symbols, at least according to gdb/mipsread.c. */
2231 1.1.1.9 christos if (fdr_ptr->rss == -1)
2232 1.1 skrll {
2233 1.1.1.9 christos EXTR proc_ext;
2234 1.1.1.9 christos
2235 1.1.1.9 christos if (pdr.isym >= 0
2236 1.1 skrll && pdr.isym < debug_info->symbolic_header.iextMax)
2237 1.1.1.9 christos {
2238 1.1.1.9 christos (*debug_swap->swap_ext_in)
2239 1.1 skrll (abfd, ((char *) debug_info->external_ext
2240 1.1.1.9 christos + pdr.isym * debug_swap->external_ext_size),
2241 1.1.1.9 christos &proc_ext);
2242 1.1.1.9 christos if (proc_ext.asym.iss >= 0
2243 1.1.1.9 christos && proc_ext.asym.iss < debug_info->symbolic_header.issExtMax)
2244 1.1 skrll line_info->cache.functionname = (debug_info->ssext
2245 1.1 skrll + proc_ext.asym.iss);
2246 1.1.1.9 christos }
2247 1.1.1.9 christos }
2248 1.1.1.9 christos else if (fdr_ptr->issBase >= 0
2249 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2250 1.1.1.9 christos && fdr_ptr->rss >= 0
2251 1.1 skrll && fdr_ptr->rss < (debug_info->symbolic_header.issMax
2252 1.1 skrll - fdr_ptr->issBase))
2253 1.1 skrll {
2254 1.1 skrll SYMR proc_sym;
2255 1.1 skrll
2256 1.1 skrll line_info->cache.filename = (debug_info->ss
2257 1.1.1.9 christos + fdr_ptr->issBase
2258 1.1.1.9 christos + fdr_ptr->rss);
2259 1.1.1.9 christos if (fdr_ptr->isymBase >= 0
2260 1.1.1.9 christos && fdr_ptr->isymBase < debug_info->symbolic_header.isymMax
2261 1.1.1.9 christos && pdr.isym >= 0
2262 1.1.1.9 christos && pdr.isym < (debug_info->symbolic_header.isymMax
2263 1.1.1.9 christos - fdr_ptr->isymBase))
2264 1.1.1.9 christos {
2265 1.1.1.9 christos (*debug_swap->swap_sym_in)
2266 1.1.1.9 christos (abfd, ((char *) debug_info->external_sym
2267 1.1.1.9 christos + ((fdr_ptr->isymBase + pdr.isym)
2268 1.1.1.9 christos * debug_swap->external_sym_size)),
2269 1.1.1.9 christos &proc_sym);
2270 1.1.1.9 christos if (proc_sym.iss >= 0
2271 1.1.1.9 christos && proc_sym.iss < (debug_info->symbolic_header.issMax
2272 1.1.1.9 christos - fdr_ptr->issBase))
2273 1.1.1.9 christos line_info->cache.functionname = (debug_info->ss
2274 1.1.1.9 christos + fdr_ptr->issBase
2275 1.1 skrll + proc_sym.iss);
2276 1.1 skrll }
2277 1.1 skrll }
2278 1.1 skrll if (lineno == ilineNil)
2279 1.1 skrll lineno = 0;
2280 1.1 skrll line_info->cache.line_num = lineno;
2281 1.1 skrll }
2282 1.1 skrll else
2283 1.1 skrll {
2284 1.1 skrll bfd_size_type external_sym_size;
2285 1.1 skrll const char *directory_name;
2286 1.1 skrll const char *main_file_name;
2287 1.1 skrll const char *current_file_name;
2288 1.1 skrll const char *function_name;
2289 1.1 skrll const char *line_file_name;
2290 1.1.1.8 christos bfd_vma low_func_vma;
2291 1.1.1.8 christos bfd_vma low_line_vma;
2292 1.1 skrll bool past_line;
2293 1.1 skrll bool past_fn;
2294 1.1 skrll char *sym_ptr, *sym_ptr_end;
2295 1.1 skrll size_t len, funclen;
2296 1.1 skrll char *buffer = NULL;
2297 1.1 skrll
2298 1.1 skrll /* This file uses stabs debugging information. When gcc is not
2299 1.1 skrll optimizing, it will put the line number information before
2300 1.1 skrll the function name stabs entry. When gcc is optimizing, it
2301 1.1 skrll will put the stabs entry for all the function first, followed
2302 1.1 skrll by the line number information. (This appears to happen
2303 1.1 skrll because of the two output files used by the -mgpopt switch,
2304 1.1 skrll which is implied by -O). This means that we must keep
2305 1.1 skrll looking through the symbols until we find both a line number
2306 1.1 skrll and a function name which are beyond the address we want. */
2307 1.1 skrll
2308 1.1 skrll directory_name = NULL;
2309 1.1 skrll main_file_name = NULL;
2310 1.1 skrll current_file_name = NULL;
2311 1.1 skrll function_name = NULL;
2312 1.1 skrll line_file_name = NULL;
2313 1.1.1.8 christos low_func_vma = 0;
2314 1.1.1.8 christos low_line_vma = 0;
2315 1.1 skrll past_line = false;
2316 1.1 skrll past_fn = false;
2317 1.1 skrll
2318 1.1.1.9 christos external_sym_size = debug_swap->external_sym_size;
2319 1.1.1.9 christos
2320 1.1.1.9 christos if (fdr_ptr->isymBase >= 0
2321 1.1.1.9 christos && fdr_ptr->isymBase < debug_info->symbolic_header.isymMax
2322 1.1.1.9 christos && fdr_ptr->csym >= 2
2323 1.1.1.9 christos && fdr_ptr->csym < (debug_info->symbolic_header.isymMax
2324 1.1.1.9 christos - fdr_ptr->isymBase))
2325 1.1.1.9 christos {
2326 1.1.1.9 christos sym_ptr = ((char *) debug_info->external_sym
2327 1.1.1.9 christos + (fdr_ptr->isymBase + 2) * external_sym_size);
2328 1.1.1.9 christos sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
2329 1.1.1.9 christos }
2330 1.1.1.9 christos else
2331 1.1.1.9 christos {
2332 1.1.1.9 christos sym_ptr = NULL;
2333 1.1 skrll sym_ptr_end = sym_ptr;
2334 1.1 skrll }
2335 1.1 skrll for (;
2336 1.1 skrll sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
2337 1.1 skrll sym_ptr += external_sym_size)
2338 1.1 skrll {
2339 1.1 skrll SYMR sym;
2340 1.1 skrll
2341 1.1 skrll (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
2342 1.1 skrll
2343 1.1 skrll if (ECOFF_IS_STAB (&sym))
2344 1.1 skrll {
2345 1.1 skrll switch (ECOFF_UNMARK_STAB (sym.index))
2346 1.1.1.9 christos {
2347 1.1.1.9 christos case N_SO:
2348 1.1.1.9 christos if (fdr_ptr->issBase >= 0
2349 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2350 1.1.1.9 christos && sym.iss >= 0
2351 1.1.1.9 christos && sym.iss < (debug_info->symbolic_header.issMax
2352 1.1.1.9 christos - fdr_ptr->issBase))
2353 1.1 skrll main_file_name = current_file_name
2354 1.1 skrll = debug_info->ss + fdr_ptr->issBase + sym.iss;
2355 1.1.1.6 christos
2356 1.1 skrll /* Check the next symbol to see if it is also an
2357 1.1 skrll N_SO symbol. */
2358 1.1 skrll if (sym_ptr + external_sym_size < sym_ptr_end)
2359 1.1 skrll {
2360 1.1 skrll SYMR nextsym;
2361 1.1 skrll
2362 1.1 skrll (*debug_swap->swap_sym_in) (abfd,
2363 1.1 skrll sym_ptr + external_sym_size,
2364 1.1 skrll &nextsym);
2365 1.1 skrll if (ECOFF_IS_STAB (&nextsym)
2366 1.1.1.6 christos && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
2367 1.1.1.9 christos {
2368 1.1.1.9 christos directory_name = current_file_name;
2369 1.1.1.9 christos if (fdr_ptr->issBase >= 0
2370 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2371 1.1.1.9 christos && nextsym.iss >= 0
2372 1.1.1.9 christos && nextsym.iss < (debug_info->symbolic_header.issMax
2373 1.1.1.9 christos - fdr_ptr->issBase))
2374 1.1 skrll main_file_name = current_file_name
2375 1.1 skrll = debug_info->ss + fdr_ptr->issBase + nextsym.iss;
2376 1.1 skrll sym_ptr += external_sym_size;
2377 1.1 skrll }
2378 1.1 skrll }
2379 1.1 skrll break;
2380 1.1.1.9 christos
2381 1.1.1.9 christos case N_SOL:
2382 1.1.1.9 christos if (fdr_ptr->issBase >= 0
2383 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2384 1.1.1.9 christos && sym.iss >= 0
2385 1.1.1.9 christos && sym.iss < (debug_info->symbolic_header.issMax
2386 1.1.1.9 christos - fdr_ptr->issBase))
2387 1.1 skrll current_file_name
2388 1.1 skrll = debug_info->ss + fdr_ptr->issBase + sym.iss;
2389 1.1 skrll break;
2390 1.1 skrll
2391 1.1.1.8 christos case N_FUN:
2392 1.1 skrll if (sym.value > offset)
2393 1.1 skrll past_fn = true;
2394 1.1 skrll else if (sym.value >= low_func_vma)
2395 1.1.1.9 christos {
2396 1.1.1.9 christos low_func_vma = sym.value;
2397 1.1.1.9 christos if (fdr_ptr->issBase >= 0
2398 1.1.1.9 christos && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2399 1.1.1.9 christos && sym.iss >= 0
2400 1.1.1.9 christos && sym.iss < (debug_info->symbolic_header.issMax
2401 1.1.1.9 christos - fdr_ptr->issBase))
2402 1.1 skrll function_name
2403 1.1 skrll = debug_info->ss + fdr_ptr->issBase + sym.iss;
2404 1.1 skrll }
2405 1.1 skrll break;
2406 1.1 skrll }
2407 1.1 skrll }
2408 1.1 skrll else if (sym.st == stLabel && sym.index != indexNil)
2409 1.1.1.8 christos {
2410 1.1 skrll if (sym.value > offset)
2411 1.1 skrll past_line = true;
2412 1.1 skrll else if (sym.value >= low_line_vma)
2413 1.1 skrll {
2414 1.1 skrll low_line_vma = sym.value;
2415 1.1 skrll line_file_name = current_file_name;
2416 1.1 skrll line_info->cache.line_num = sym.index;
2417 1.1 skrll }
2418 1.1 skrll }
2419 1.1 skrll }
2420 1.1 skrll
2421 1.1 skrll if (line_info->cache.line_num != 0)
2422 1.1 skrll main_file_name = line_file_name;
2423 1.1.1.6 christos
2424 1.1.1.6 christos /* We need to remove the stuff after the colon in the function
2425 1.1 skrll name. We also need to put the directory name and the file
2426 1.1 skrll name together. */
2427 1.1 skrll if (function_name == NULL)
2428 1.1 skrll len = funclen = 0;
2429 1.1 skrll else
2430 1.1 skrll len = funclen = strlen (function_name) + 1;
2431 1.1 skrll
2432 1.1 skrll if (main_file_name != NULL
2433 1.1 skrll && directory_name != NULL
2434 1.1 skrll && main_file_name[0] != '/')
2435 1.1 skrll len += strlen (directory_name) + strlen (main_file_name) + 1;
2436 1.1 skrll
2437 1.1.1.8 christos if (len != 0)
2438 1.1 skrll {
2439 1.1 skrll free (line_info->find_buffer);
2440 1.1.1.8 christos buffer = (char *) bfd_malloc ((bfd_size_type) len);
2441 1.1.1.8 christos line_info->find_buffer = buffer;
2442 1.1 skrll if (buffer == NULL)
2443 1.1 skrll return false;
2444 1.1 skrll }
2445 1.1 skrll
2446 1.1 skrll if (function_name != NULL)
2447 1.1 skrll {
2448 1.1 skrll char *colon;
2449 1.1 skrll
2450 1.1 skrll strcpy (buffer, function_name);
2451 1.1 skrll colon = strchr (buffer, ':');
2452 1.1 skrll if (colon != NULL)
2453 1.1 skrll *colon = '\0';
2454 1.1 skrll line_info->cache.functionname = buffer;
2455 1.1 skrll }
2456 1.1 skrll
2457 1.1 skrll if (main_file_name != NULL)
2458 1.1 skrll {
2459 1.1 skrll if (directory_name == NULL || main_file_name[0] == '/')
2460 1.1 skrll line_info->cache.filename = main_file_name;
2461 1.1 skrll else
2462 1.1 skrll {
2463 1.1 skrll sprintf (buffer + funclen, "%s%s", directory_name,
2464 1.1 skrll main_file_name);
2465 1.1 skrll line_info->cache.filename = buffer + funclen;
2466 1.1 skrll }
2467 1.1 skrll }
2468 1.1.1.8 christos }
2469 1.1 skrll
2470 1.1 skrll return true;
2471 1.1 skrll }
2472 1.1 skrll
2473 1.1.1.8 christos /* Do the work of find_nearest_line. */
2474 1.1.1.3 christos
2475 1.1.1.3 christos bool
2476 1.1.1.3 christos _bfd_ecoff_locate_line (bfd *abfd,
2477 1.1.1.3 christos asection *section,
2478 1.1.1.3 christos bfd_vma offset,
2479 1.1.1.3 christos struct ecoff_debug_info * const debug_info,
2480 1.1.1.3 christos const struct ecoff_debug_swap * const debug_swap,
2481 1.1.1.3 christos struct ecoff_find_line *line_info,
2482 1.1.1.3 christos const char **filename_ptr,
2483 1.1 skrll const char **functionname_ptr,
2484 1.1 skrll unsigned int *retline_ptr)
2485 1.1 skrll {
2486 1.1 skrll offset += section->vma;
2487 1.1 skrll
2488 1.1 skrll if (line_info->cache.sect == NULL
2489 1.1 skrll || line_info->cache.sect != section
2490 1.1 skrll || offset < line_info->cache.start
2491 1.1 skrll || offset >= line_info->cache.stop)
2492 1.1 skrll {
2493 1.1 skrll line_info->cache.sect = section;
2494 1.1 skrll line_info->cache.start = offset;
2495 1.1 skrll line_info->cache.stop = offset;
2496 1.1 skrll if (! lookup_line (abfd, debug_info, debug_swap, line_info))
2497 1.1.1.8 christos {
2498 1.1 skrll line_info->cache.sect = NULL;
2499 1.1 skrll return false;
2500 1.1 skrll }
2501 1.1 skrll }
2502 1.1 skrll
2503 1.1 skrll *filename_ptr = line_info->cache.filename;
2504 1.1 skrll *functionname_ptr = line_info->cache.functionname;
2505 1.1.1.8 christos *retline_ptr = line_info->cache.line_num;
2506 1.1 skrll
2507 1.1 skrll return true;
2508 1.1 skrll }
2509 1.1 skrll
2510 1.1 skrll /* These routines copy symbolic information into a memory buffer.
2512 1.1 skrll
2513 1.1 skrll FIXME: The whole point of the shuffle code is to avoid storing
2514 1.1 skrll everything in memory, since the linker is such a memory hog. This
2515 1.1 skrll code makes that effort useless. It is only called by the MIPS ELF
2516 1.1 skrll code when generating a shared library, so it is not that big a
2517 1.1 skrll deal, but it should be fixed eventually. */
2518 1.1.1.8 christos
2519 1.1.1.3 christos /* Collect a shuffle into a memory buffer. */
2520 1.1 skrll
2521 1.1 skrll static bool
2522 1.1 skrll ecoff_collect_shuffle (struct shuffle *l, bfd_byte *buff)
2523 1.1 skrll {
2524 1.1 skrll for (; l != (struct shuffle *) NULL; l = l->next)
2525 1.1 skrll {
2526 1.1 skrll if (! l->filep)
2527 1.1 skrll memcpy (buff, l->u.memory, l->size);
2528 1.1.1.9 christos else
2529 1.1.1.8 christos {
2530 1.1 skrll if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
2531 1.1 skrll || bfd_read (buff, l->size, l->u.file.input_bfd) != l->size)
2532 1.1 skrll return false;
2533 1.1 skrll }
2534 1.1.1.8 christos buff += l->size;
2535 1.1 skrll }
2536 1.1 skrll
2537 1.1 skrll return true;
2538 1.1 skrll }
2539 1.1.1.8 christos
2540 1.1.1.3 christos /* Copy PDR information into a memory buffer. */
2541 1.1.1.3 christos
2542 1.1 skrll bool
2543 1.1 skrll _bfd_ecoff_get_accumulated_pdr (void * handle,
2544 1.1 skrll bfd_byte *buff)
2545 1.1 skrll {
2546 1.1 skrll struct accumulate *ainfo = (struct accumulate *) handle;
2547 1.1 skrll
2548 1.1 skrll return ecoff_collect_shuffle (ainfo->pdr, buff);
2549 1.1 skrll }
2550 1.1.1.8 christos
2551 1.1.1.3 christos /* Copy symbol information into a memory buffer. */
2552 1.1 skrll
2553 1.1 skrll bool
2554 1.1 skrll _bfd_ecoff_get_accumulated_sym (void * handle, bfd_byte *buff)
2555 1.1 skrll {
2556 1.1 skrll struct accumulate *ainfo = (struct accumulate *) handle;
2557 1.1 skrll
2558 1.1 skrll return ecoff_collect_shuffle (ainfo->sym, buff);
2559 1.1 skrll }
2560 1.1.1.8 christos
2561 1.1.1.3 christos /* Copy the string table into a memory buffer. */
2562 1.1 skrll
2563 1.1 skrll bool
2564 1.1 skrll _bfd_ecoff_get_accumulated_ss (void * handle, bfd_byte *buff)
2565 1.1 skrll {
2566 1.1 skrll struct accumulate *ainfo = (struct accumulate *) handle;
2567 1.1 skrll struct string_hash_entry *sh;
2568 1.1 skrll
2569 1.1 skrll /* The string table is written out from the hash table if this is a
2570 1.1 skrll final link. */
2571 1.1 skrll BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
2572 1.1 skrll *buff++ = '\0';
2573 1.1 skrll BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
2574 1.1 skrll for (sh = ainfo->ss_hash;
2575 1.1 skrll sh != (struct string_hash_entry *) NULL;
2576 1.1 skrll sh = sh->next)
2577 1.1 skrll {
2578 1.1.1.3 christos size_t len;
2579 1.1 skrll
2580 1.1 skrll len = strlen (sh->root.string);
2581 1.1 skrll memcpy (buff, sh->root.string, len + 1);
2582 1.1.1.8 christos buff += len + 1;
2583 1.1 skrll }
2584
2585 return true;
2586 }
2587