source: trunk/src/binutils/bfd/ecofflink.c@ 610

Last change on this file since 610 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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