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