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