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