get rid of rcs crud
[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
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include "bfd.h"
22#include "sysdep.h"
cf286547 23#include "bfdlink.h"
71efdf83 24#include "libbfd.h"
cf286547 25#include "obstack.h"
71efdf83
ILT
26#include "coff/internal.h"
27#include "coff/sym.h"
28#include "coff/symconst.h"
29#include "coff/ecoff.h"
30\f
31static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
966e0a16 32 size_t need));
cf286547
ILT
33static struct bfd_hash_entry *string_hash_newfunc
34 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
35 const char *));
71efdf83
ILT
36static void ecoff_align_debug PARAMS ((bfd *abfd,
37 struct ecoff_debug_info *debug,
38 const struct ecoff_debug_swap *swap));
cf286547
ILT
39static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *,
40 const struct ecoff_debug_swap *,
41 file_ptr where));
42
43/* Obstack allocation and deallocation routines. */
44#define obstack_chunk_alloc bfd_xmalloc_by_size_t
45#define obstack_chunk_free free
71efdf83
ILT
46\f
47/* The minimum amount of data to allocate. */
48#define ALLOC_SIZE (4064)
49
50/* Add bytes to a buffer. Return success. */
51
52static boolean
53ecoff_add_bytes (buf, bufend, need)
54 char **buf;
55 char **bufend;
966e0a16 56 size_t need;
71efdf83 57{
966e0a16
ILT
58 size_t have;
59 size_t want;
71efdf83
ILT
60 char *newbuf;
61
62 have = *bufend - *buf;
63 if (have > need)
64 want = ALLOC_SIZE;
65 else
66 {
67 want = need - have;
68 if (want < ALLOC_SIZE)
69 want = ALLOC_SIZE;
70 }
71 if (*buf == NULL)
72 newbuf = (char *) malloc (have + want);
73 else
74 newbuf = (char *) realloc (*buf, have + want);
75 if (newbuf == NULL)
76 {
77 bfd_error = no_memory;
78 return false;
79 }
80 *buf = newbuf;
81 *bufend = *buf + have + want;
82 return true;
83}
84
cf286547
ILT
85/* We keep a hash table which maps strings to numbers. We use it to
86 map FDR names to indices in the output file, and to map local
87 strings when combining stabs debugging information. */
88
89struct string_hash_entry
90{
91 struct bfd_hash_entry root;
92 /* FDR index or string table offset. */
93 long val;
94 /* Next entry in string table. */
95 struct string_hash_entry *next;
96};
97
98struct string_hash_table
99{
100 struct bfd_hash_table table;
101};
102
103/* Routine to create an entry in a string hash table. */
104
105static struct bfd_hash_entry *
106string_hash_newfunc (entry, table, string)
107 struct bfd_hash_entry *entry;
108 struct bfd_hash_table *table;
109 const char *string;
110{
111 struct string_hash_entry *ret = (struct string_hash_entry *) entry;
112
113 /* Allocate the structure if it has not already been allocated by a
114 subclass. */
115 if (ret == (struct string_hash_entry *) NULL)
116 ret = ((struct string_hash_entry *)
117 bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
118
119 /* Call the allocation method of the superclass. */
120 ret = ((struct string_hash_entry *)
121 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
122
123 /* Initialize the local fields. */
124 ret->val = -1;
125 ret->next = NULL;
126
127 return (struct bfd_hash_entry *) ret;
128}
129
130/* Look up an entry in an string hash table. */
131
132#define string_hash_lookup(t, string, create, copy) \
133 ((struct string_hash_entry *) \
134 bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
135
136/* We can't afford to read in all the debugging information when we do
137 a link. Instead, we build a list of these structures to show how
138 different parts of the input file map to the output file. */
139
140struct shuffle
141{
142 /* The next entry in this linked list. */
143 struct shuffle *next;
144 /* The length of the information. */
145 unsigned long size;
146 /* Whether this information comes from a file or not. */
147 boolean filep;
148 union
149 {
150 struct
151 {
152 /* The BFD the data comes from. */
153 bfd *input_bfd;
154 /* The offset within input_bfd. */
155 file_ptr offset;
156 } file;
157 /* The data to be written out. */
158 PTR memory;
159 } u;
160};
161
162/* This structure holds information across calls to
163 bfd_ecoff_debug_accumulate. */
164
165struct accumulate
166{
167 /* The FDR hash table. */
168 struct string_hash_table fdr_hash;
169 /* The strings hash table. */
170 struct string_hash_table str_hash;
171 /* Linked lists describing how to shuffle the input debug
172 information into the output file. We keep a pointer to both the
173 head and the tail. */
174 struct shuffle *line;
175 struct shuffle *line_end;
176 struct shuffle *pdr;
177 struct shuffle *pdr_end;
178 struct shuffle *sym;
179 struct shuffle *sym_end;
180 struct shuffle *opt;
181 struct shuffle *opt_end;
182 struct shuffle *aux;
183 struct shuffle *aux_end;
184 struct shuffle *ss;
185 struct shuffle *ss_end;
186 struct string_hash_entry *ss_hash;
187 struct string_hash_entry *ss_hash_end;
188 struct shuffle *fdr;
189 struct shuffle *fdr_end;
190 struct shuffle *rfd;
191 struct shuffle *rfd_end;
192 /* The size of the largest file shuffle. */
193 unsigned long largest_file_shuffle;
194 /* An obstack for debugging information. */
195 struct obstack memory;
196};
197
198/* Add a file entry to a shuffle list. */
199
200static void add_file_shuffle PARAMS ((struct accumulate *,
201 struct shuffle **,
202 struct shuffle **, bfd *, file_ptr,
203 unsigned long));
204
205static void
206add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
207 struct accumulate *ainfo;
208 struct shuffle **head;
209 struct shuffle **tail;
210 bfd *input_bfd;
211 file_ptr offset;
212 unsigned long size;
213{
214 struct shuffle *n;
215
216 if (*tail != (struct shuffle *) NULL
217 && (*tail)->filep
218 && (*tail)->u.file.input_bfd == input_bfd
219 && (*tail)->u.file.offset + (*tail)->size == offset)
220 {
221 /* Just merge this entry onto the existing one. */
222 (*tail)->size += size;
223 if ((*tail)->size > ainfo->largest_file_shuffle)
224 ainfo->largest_file_shuffle = (*tail)->size;
225 return;
226 }
227
228 n = (struct shuffle *) obstack_alloc (&ainfo->memory,
229 sizeof (struct shuffle));
230 n->next = NULL;
231 n->size = size;
232 n->filep = true;
233 n->u.file.input_bfd = input_bfd;
234 n->u.file.offset = offset;
235 if (*head == (struct shuffle *) NULL)
236 *head = n;
237 if (*tail != (struct shuffle *) NULL)
238 (*tail)->next = n;
239 *tail = n;
240 if (size > ainfo->largest_file_shuffle)
241 ainfo->largest_file_shuffle = size;
242}
243
244/* Add a memory entry to a shuffle list. */
245
246static void add_memory_shuffle PARAMS ((struct accumulate *,
247 struct shuffle **head,
248 struct shuffle **tail,
249 bfd_byte *data, unsigned long size));
250
251static void
252add_memory_shuffle (ainfo, head, tail, data, size)
253 struct accumulate *ainfo;
254 struct shuffle **head;
255 struct shuffle **tail;
256 bfd_byte *data;
257 unsigned long size;
258{
259 struct shuffle *n;
260
261 n = (struct shuffle *) obstack_alloc (&ainfo->memory,
262 sizeof (struct shuffle));
263 n->next = NULL;
264 n->size = size;
265 n->filep = false;
266 n->u.memory = (PTR) data;
267 if (*head == (struct shuffle *) NULL)
268 *head = n;
269 if (*tail != (struct shuffle *) NULL)
270 (*tail)->next = n;
271 *tail = n;
272}
273
274/* Initialize the FDR hash table. This returns a handle which is then
275 passed in to bfd_ecoff_debug_accumulate, et. al. */
276
277/*ARGSUSED*/
278PTR
279bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info)
280 bfd *output_bfd;
281 struct ecoff_debug_info *output_debug;
282 const struct ecoff_debug_swap *output_swap;
283 struct bfd_link_info *info;
284{
285 struct accumulate *ainfo;
286
287 ainfo = (struct accumulate *) bfd_xmalloc (sizeof (struct accumulate));
288 if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
289 1021))
290 return NULL;
291
292 ainfo->line = NULL;
293 ainfo->line_end = NULL;
294 ainfo->pdr = NULL;
295 ainfo->pdr_end = NULL;
296 ainfo->sym = NULL;
297 ainfo->sym_end = NULL;
298 ainfo->opt = NULL;
299 ainfo->opt_end = NULL;
300 ainfo->aux = NULL;
301 ainfo->aux_end = NULL;
302 ainfo->ss = NULL;
303 ainfo->ss_end = NULL;
304 ainfo->ss_hash = NULL;
305 ainfo->ss_hash_end = NULL;
306 ainfo->fdr = NULL;
307 ainfo->fdr_end = NULL;
308 ainfo->rfd = NULL;
309 ainfo->rfd_end = NULL;
310
311 ainfo->largest_file_shuffle = 0;
312
313 if (! info->relocateable)
314 {
315 if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc))
316 return NULL;
317
318 /* The first entry in the string table is the empty string. */
319 output_debug->symbolic_header.issMax = 1;
320 }
321
322 obstack_begin (&ainfo->memory, 4050);
323
324 return (PTR) ainfo;
325}
326
327/* Free the accumulated debugging information. */
328
329/*ARGSUSED*/
330void
331bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info)
332 PTR handle;
333 bfd *output_bfd;
334 struct ecoff_debug_info *output_debug;
335 const struct ecoff_debug_swap *output_swap;
336 struct bfd_link_info *info;
337{
338 struct accumulate *ainfo = (struct accumulate *) handle;
339
340 bfd_hash_table_free (&ainfo->fdr_hash.table);
341
342 if (! info->relocateable)
343 bfd_hash_table_free (&ainfo->str_hash.table);
344
345 obstack_free (&ainfo->memory, (PTR) NULL);
346
347 free (ainfo);
348}
349
71efdf83
ILT
350/* Accumulate the debugging information from INPUT_BFD into
351 OUTPUT_BFD. The INPUT_DEBUG argument points to some ECOFF
352 debugging information which we want to link into the information
353 pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
cf286547
ILT
354 INPUT_SWAP point to the swapping information needed. INFO is the
355 linker information structure. HANDLE is returned by
356 bfd_ecoff_debug_init. */
71efdf83 357
966e0a16 358/*ARGSUSED*/
71efdf83 359boolean
cf286547 360bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
71efdf83 361 input_bfd, input_debug, input_swap,
cf286547
ILT
362 info)
363 PTR handle;
71efdf83
ILT
364 bfd *output_bfd;
365 struct ecoff_debug_info *output_debug;
366 const struct ecoff_debug_swap *output_swap;
367 bfd *input_bfd;
368 struct ecoff_debug_info *input_debug;
369 const struct ecoff_debug_swap *input_swap;
cf286547 370 struct bfd_link_info *info;
71efdf83 371{
cf286547 372 struct accumulate *ainfo = (struct accumulate *) handle;
71efdf83
ILT
373 void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
374 = input_swap->swap_sym_in;
cf286547
ILT
375 void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
376 = input_swap->swap_rfd_in;
71efdf83
ILT
377 void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
378 = output_swap->swap_sym_out;
379 void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
380 = output_swap->swap_fdr_out;
381 void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
382 = output_swap->swap_rfd_out;
cf286547
ILT
383 bfd_size_type external_pdr_size = output_swap->external_pdr_size;
384 bfd_size_type external_sym_size = output_swap->external_sym_size;
385 bfd_size_type external_opt_size = output_swap->external_opt_size;
386 bfd_size_type external_fdr_size = output_swap->external_fdr_size;
387 bfd_size_type external_rfd_size = output_swap->external_rfd_size;
388 HDRR * const output_symhdr = &output_debug->symbolic_header;
389 HDRR * const input_symhdr = &input_debug->symbolic_header;
71efdf83
ILT
390 bfd_vma section_adjust[scMax];
391 asection *sec;
cf286547
ILT
392 bfd_byte *fdr_start;
393 bfd_byte *fdr_ptr;
394 bfd_byte *fdr_end;
71efdf83 395 bfd_size_type fdr_add;
cf286547
ILT
396 unsigned int copied;
397 RFDT i;
398 unsigned long sz;
399 bfd_byte *rfd_out;
400 bfd_byte *rfd_in;
401 bfd_byte *rfd_end;
402 long newrfdbase = 0;
403 long oldrfdbase = 0;
404 bfd_byte *fdr_out;
71efdf83
ILT
405
406 /* Use section_adjust to hold the value to add to a symbol in a
407 particular section. */
408 memset ((PTR) section_adjust, 0, sizeof section_adjust);
409
410#define SET(name, indx) \
411 sec = bfd_get_section_by_name (input_bfd, name); \
412 if (sec != NULL) \
413 section_adjust[indx] = (sec->output_section->vma \
414 + sec->output_offset \
415 - sec->vma);
416
417 SET (".text", scText);
418 SET (".data", scData);
419 SET (".bss", scBss);
420 SET (".sdata", scSData);
421 SET (".sbss", scSBss);
422 /* scRdata section may be either .rdata or .rodata. */
423 SET (".rdata", scRData);
424 SET (".rodata", scRData);
425 SET (".init", scInit);
426 SET (".fini", scFini);
427
428#undef SET
429
cf286547
ILT
430 /* Find all the debugging information based on the FDR's. We need
431 to handle them whether they are swapped or not. */
432 if (input_debug->fdr != (FDR *) NULL)
71efdf83 433 {
cf286547
ILT
434 fdr_start = (bfd_byte *) input_debug->fdr;
435 fdr_add = sizeof (FDR);
71efdf83 436 }
cf286547 437 else
71efdf83 438 {
cf286547
ILT
439 fdr_start = (bfd_byte *) input_debug->external_fdr;
440 fdr_add = input_swap->external_fdr_size;
71efdf83 441 }
cf286547
ILT
442 fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
443
444 input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd,
445 (input_symhdr->ifdMax
446 * sizeof (RFDT)));
447
448 sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
449 rfd_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
450 add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz);
451
452 copied = 0;
453
454 /* Look through the FDR's to see which ones we are going to include
455 in the final output. We do not want duplicate FDR information
456 for header files, because ECOFF debugging is often very large.
457 When we find an FDR with no line information which can be merged,
458 we look it up in a hash table to ensure that we only include it
459 once. We keep a table mapping FDR numbers to the final number
460 they get with the BFD, so that we can refer to it when we write
461 out the external symbols. */
462 for (fdr_ptr = fdr_start, i = 0;
463 fdr_ptr < fdr_end;
464 fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
71efdf83 465 {
cf286547 466 FDR fdr;
71efdf83 467
cf286547
ILT
468 if (input_debug->fdr != (FDR *) NULL)
469 fdr = *(FDR *) fdr_ptr;
470 else
471 (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
472
473 /* See if this FDR can be merged with an existing one. */
474 if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
71efdf83 475 {
cf286547
ILT
476 const char *name;
477 char *lookup;
478 struct string_hash_entry *fh;
479
480 /* We look up a string formed from the file name and the
481 number of symbols. Sometimes an include file will
482 conditionally define a typedef or something based on the
483 order of include files. Using the number of symbols as a
484 hash reduces the chance that we will merge symbol
485 information that should not be merged. */
486 name = input_debug->ss + fdr.issBase + fdr.rss;
487 lookup = (char *) alloca (strlen (name) + 20);
488 sprintf (lookup, "%s %lx", name, fdr.csym);
489
490 fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
491 if (fh == (struct string_hash_entry *) NULL)
492 return false;
71efdf83 493
cf286547
ILT
494 if (fh->val != -1)
495 {
496 input_debug->ifdmap[i] = fh->val;
497 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i,
498 (PTR) rfd_out);
71efdf83 499
cf286547
ILT
500 /* Don't copy this FDR. */
501 continue;
502 }
71efdf83 503
cf286547 504 fh->val = output_symhdr->ifdMax + copied;
71efdf83 505 }
cf286547
ILT
506
507 input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
508 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out);
509 ++copied;
71efdf83
ILT
510 }
511
cf286547
ILT
512 newrfdbase = output_symhdr->crfd;
513 output_symhdr->crfd += input_symhdr->ifdMax;
71efdf83 514
cf286547
ILT
515 /* Copy over any existing RFD's. RFD's are only created by the
516 linker, so this will only happen for input files which are the
517 result of a partial link. */
518 rfd_in = (bfd_byte *) input_debug->external_rfd;
519 rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
520 for (;
521 rfd_in < rfd_end;
522 rfd_in += input_swap->external_rfd_size)
71efdf83 523 {
cf286547
ILT
524 RFDT rfd;
525
526 (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd);
527 BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
528 rfd = input_debug->ifdmap[rfd];
529 (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out);
530 rfd_out += external_rfd_size;
71efdf83 531 }
cf286547
ILT
532
533 oldrfdbase = output_symhdr->crfd;
534 output_symhdr->crfd += input_symhdr->crfd;
535
536 /* Look through the FDR's and copy over all associated debugging
537 information. */
538 sz = copied * external_fdr_size;
539 fdr_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
540 add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz);
541 for (fdr_ptr = fdr_start, i = 0;
71efdf83 542 fdr_ptr < fdr_end;
cf286547 543 fdr_ptr += fdr_add, i++)
71efdf83
ILT
544 {
545 FDR fdr;
cf286547
ILT
546 bfd_byte *sym_out;
547 bfd_byte *lraw_src;
548 bfd_byte *lraw_end;
549 boolean fgotfilename;
550
551 if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
552 {
553 /* We are not copying this FDR. */
554 continue;
555 }
71efdf83
ILT
556
557 if (input_debug->fdr != (FDR *) NULL)
558 fdr = *(FDR *) fdr_ptr;
559 else
560 (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
561
562 /* FIXME: It is conceivable that this FDR points to the .init or
563 .fini section, in which case this will not do the right
564 thing. */
565 fdr.adr += section_adjust[scText];
566
cf286547
ILT
567 /* Swap in the local symbols, adjust their values, and swap them
568 out again. */
569 fgotfilename = false;
570 sz = fdr.csym * external_sym_size;
571 sym_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
572 add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out, sz);
573 lraw_src = ((bfd_byte *) input_debug->external_sym
574 + fdr.isymBase * input_swap->external_sym_size);
575 lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
576 for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size)
577 {
578 SYMR internal_sym;
579
580 (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
581
582 BFD_ASSERT (internal_sym.sc != scCommon
583 && internal_sym.sc != scSCommon);
584
585 /* Adjust the symbol value if appropriate. */
586 switch (internal_sym.st)
587 {
588 case stNil:
589 if (ECOFF_IS_STAB (&internal_sym))
590 break;
591 /* Fall through. */
592 case stGlobal:
593 case stStatic:
594 case stLabel:
595 case stProc:
596 case stStaticProc:
597 internal_sym.value += section_adjust[internal_sym.sc];
598 break;
599
600 default:
601 break;
602 }
603
604 /* If we are doing a final link, we hash all the strings in
605 the local symbol table together. This reduces the amount
606 of space required by debugging information. We don't do
607 this when performing a relocateable link because it would
608 prevent us from easily merging different FDR's. */
609 if (! info->relocateable)
610 {
611 boolean ffilename;
612 const char *name;
613
614 if (! fgotfilename && internal_sym.iss == fdr.rss)
615 ffilename = true;
616 else
617 ffilename = false;
618
619 /* Hash the name into the string table. */
620 name = input_debug->ss + fdr.issBase + internal_sym.iss;
621 if (*name == '\0')
622 internal_sym.iss = 0;
623 else
624 {
625 struct string_hash_entry *sh;
626
627 sh = string_hash_lookup (&ainfo->str_hash, name, true, true);
628 if (sh == (struct string_hash_entry *) NULL)
629 return false;
630 if (sh->val == -1)
631 {
632 sh->val = output_symhdr->issMax;
633 output_symhdr->issMax += strlen (name) + 1;
634 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
635 ainfo->ss_hash = sh;
636 if (ainfo->ss_hash_end
637 != (struct string_hash_entry *) NULL)
638 ainfo->ss_hash_end->next = sh;
639 ainfo->ss_hash_end = sh;
640 }
641 internal_sym.iss = sh->val;
642 }
643
644 if (ffilename)
645 {
646 fdr.rss = internal_sym.iss;
647 fgotfilename = true;
648 }
649 }
650
651 (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
652 sym_out += external_sym_size;
653 }
71efdf83 654
cf286547
ILT
655 fdr.isymBase = output_symhdr->isymMax;
656 output_symhdr->isymMax += fdr.csym;
71efdf83 657
cf286547
ILT
658 /* Copy the information that does not need swapping. */
659 if (fdr.cbLine > 0)
660 {
661 add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
662 input_bfd,
663 input_symhdr->cbLineOffset + fdr.cbLineOffset,
664 fdr.cbLine);
665 fdr.ilineBase = output_symhdr->ilineMax;
666 fdr.cbLineOffset = output_symhdr->cbLine;
667 output_symhdr->ilineMax += fdr.cline;
668 output_symhdr->cbLine += fdr.cbLine;
669 }
670 if (fdr.caux > 0)
671 {
672 add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
673 input_bfd,
674 (input_symhdr->cbAuxOffset
675 + fdr.iauxBase * sizeof (union aux_ext)),
676 fdr.caux * sizeof (union aux_ext));
677 fdr.iauxBase = output_symhdr->iauxMax;
678 output_symhdr->iauxMax += fdr.caux;
679 }
680 if (! info->relocateable)
681 {
71efdf83 682
cf286547
ILT
683 /* When are are hashing strings, we lie about the number of
684 strings attached to each FDR. We need to set cbSs
685 because some versions of dbx apparently use it to decide
686 how much of the string table to read in. */
687 fdr.issBase = 0;
688 fdr.cbSs = output_symhdr->issMax;
689 }
690 else if (fdr.cbSs > 0)
691 {
692 add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
693 input_bfd,
694 input_symhdr->cbSsOffset + fdr.issBase,
695 fdr.cbSs);
696 fdr.issBase = output_symhdr->issMax;
697 output_symhdr->issMax += fdr.cbSs;
698 }
71efdf83 699
cf286547
ILT
700 if (output_bfd->xvec->header_byteorder_big_p
701 == input_bfd->xvec->header_byteorder_big_p)
71efdf83 702 {
cf286547
ILT
703 /* The two BFD's have the same endianness, so simply copying
704 the information will suffice. */
705 BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
706 if (fdr.cpd > 0)
707 add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
708 input_bfd,
709 (input_symhdr->cbPdOffset
710 + fdr.ipdFirst * external_pdr_size),
711 fdr.cpd * external_pdr_size);
712 BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
713 if (fdr.copt > 0)
714 add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
715 input_bfd,
716 (input_symhdr->cbOptOffset
717 + fdr.ioptBase * external_opt_size),
718 fdr.copt * external_opt_size);
719 }
720 else
721 {
722 bfd_size_type outsz, insz;
723 bfd_byte *in;
724 bfd_byte *end;
725 bfd_byte *out;
726
727 /* The two BFD's have different endianness, so we must swap
728 everything in and out. This code would always work, but
729 it would be unnecessarily slow in the normal case. */
730 outsz = external_pdr_size;
731 insz = input_swap->external_pdr_size;
732 in = ((bfd_byte *) input_debug->external_pdr
733 + fdr.ipdFirst * insz);
734 end = in + fdr.cpd * insz;
735 sz = fdr.cpd * outsz;
736 out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
737 add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, sz);
738 for (; in < end; in += insz, out += outsz)
739 {
740 PDR pdr;
741
742 (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
743 (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
744 }
745
746 /* Swap over the optimization information. */
747 outsz = external_opt_size;
748 insz = input_swap->external_opt_size;
749 in = ((bfd_byte *) input_debug->external_opt
750 + fdr.ioptBase * insz);
751 end = in + fdr.copt * insz;
752 sz = fdr.copt * outsz;
753 out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
754 add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, sz);
755 for (; in < end; in += insz, out += outsz)
756 {
757 OPTR opt;
758
759 (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);
760 (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);
761 }
762 }
763
764 fdr.ipdFirst = output_symhdr->ipdMax;
765 output_symhdr->ipdMax += fdr.cpd;
766 fdr.ioptBase = output_symhdr->ioptMax;
767 output_symhdr->ioptMax += fdr.copt;
71efdf83 768
cf286547
ILT
769 if (fdr.crfd <= 0)
770 {
771 /* Point this FDR at the table of RFD's we created. */
772 fdr.rfdBase = newrfdbase;
773 fdr.crfd = input_symhdr->ifdMax;
774 }
775 else
776 {
777 /* Point this FDR at the remapped RFD's. */
778 fdr.rfdBase += oldrfdbase;
71efdf83 779 }
71efdf83 780
cf286547
ILT
781 (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
782 fdr_out += external_fdr_size;
783 ++output_symhdr->ifdMax;
71efdf83
ILT
784 }
785
71efdf83
ILT
786 return true;
787}
788
789/* Add a string to the debugging information we are accumulating.
790 Return the offset from the fdr string base. */
791
cf286547
ILT
792static long ecoff_add_string PARAMS ((struct accumulate *,
793 struct bfd_link_info *,
794 struct ecoff_debug_info *,
795 FDR *fdr, const char *string));
796
797static long
798ecoff_add_string (ainfo, info, debug, fdr, string)
799 struct accumulate *ainfo;
800 struct bfd_link_info *info;
801 struct ecoff_debug_info *debug;
71efdf83
ILT
802 FDR *fdr;
803 const char *string;
804{
805 HDRR *symhdr;
806 size_t len;
807 bfd_size_type ret;
808
cf286547 809 symhdr = &debug->symbolic_header;
71efdf83 810 len = strlen (string);
cf286547
ILT
811 if (info->relocateable)
812 {
813 add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
814 len + 1);
815 ret = symhdr->issMax;
816 symhdr->issMax += len + 1;
817 fdr->cbSs += len + 1;
818 }
819 else
71efdf83 820 {
cf286547
ILT
821 struct string_hash_entry *sh;
822
823 sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
824 if (sh == (struct string_hash_entry *) NULL)
966e0a16 825 return (bfd_size_type) -1;
cf286547
ILT
826 if (sh->val == -1)
827 {
828 sh->val = symhdr->issMax;
829 symhdr->issMax += len + 1;
830 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
831 ainfo->ss_hash = sh;
832 if (ainfo->ss_hash_end
833 != (struct string_hash_entry *) NULL)
834 ainfo->ss_hash_end->next = sh;
835 ainfo->ss_hash_end = sh;
836 }
837 ret = sh->val;
71efdf83 838 }
cf286547 839
71efdf83
ILT
840 return ret;
841}
842
843/* Add debugging information from a non-ECOFF file. */
844
845boolean
cf286547
ILT
846bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
847 output_swap, input_bfd, info)
848 PTR handle;
71efdf83
ILT
849 bfd *output_bfd;
850 struct ecoff_debug_info *output_debug;
851 const struct ecoff_debug_swap *output_swap;
852 bfd *input_bfd;
cf286547 853 struct bfd_link_info *info;
71efdf83 854{
cf286547 855 struct accumulate *ainfo = (struct accumulate *) handle;
71efdf83
ILT
856 void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
857 = output_swap->swap_sym_out;
858 HDRR *output_symhdr = &output_debug->symbolic_header;
859 FDR fdr;
860 asection *sec;
861 asymbol **symbols;
862 asymbol **sym_ptr;
863 asymbol **sym_end;
cf286547 864 PTR external_fdr;
71efdf83
ILT
865
866 memset (&fdr, 0, sizeof fdr);
867
868 sec = bfd_get_section_by_name (input_bfd, ".text");
869 if (sec != NULL)
870 fdr.adr = sec->output_section->vma + sec->output_offset;
871 else
872 {
873 /* FIXME: What about .init or .fini? */
874 fdr.adr = 0;
875 }
876
877 fdr.issBase = output_symhdr->issMax;
878 fdr.cbSs = 0;
cf286547 879 fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
71efdf83 880 bfd_get_filename (input_bfd));
966e0a16
ILT
881 if (fdr.rss == -1)
882 return false;
71efdf83
ILT
883 fdr.isymBase = output_symhdr->isymMax;
884
885 /* Get the local symbols from the input BFD. */
886 symbols = (asymbol **) bfd_alloc (output_bfd,
887 get_symtab_upper_bound (input_bfd));
888 if (symbols == (asymbol **) NULL)
889 {
890 bfd_error = no_memory;
891 return false;
892 }
893 sym_end = symbols + bfd_canonicalize_symtab (input_bfd, symbols);
894
895 /* Handle the local symbols. Any external symbols are handled
896 separately. */
897 fdr.csym = 0;
898 for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
899 {
900 SYMR internal_sym;
cf286547 901 PTR external_sym;
71efdf83
ILT
902
903 if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
904 continue;
905 memset (&internal_sym, 0, sizeof internal_sym);
cf286547 906 internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
71efdf83
ILT
907 (*sym_ptr)->name);
908
966e0a16
ILT
909 if (internal_sym.iss == -1)
910 return false;
71efdf83
ILT
911 if (bfd_is_com_section ((*sym_ptr)->section)
912 || (*sym_ptr)->section == &bfd_und_section)
913 internal_sym.value = (*sym_ptr)->value;
914 else
915 internal_sym.value = ((*sym_ptr)->value
916 + (*sym_ptr)->section->output_offset
917 + (*sym_ptr)->section->output_section->vma);
918 internal_sym.st = stNil;
919 internal_sym.sc = scUndefined;
920 internal_sym.index = indexNil;
921
cf286547
ILT
922 external_sym = (PTR) obstack_alloc (&ainfo->memory,
923 output_swap->external_sym_size);
924 (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
925 add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
926 external_sym, output_swap->external_sym_size);
71efdf83
ILT
927 ++fdr.csym;
928 ++output_symhdr->isymMax;
929 }
930
931 bfd_release (output_bfd, (PTR) symbols);
932
71efdf83
ILT
933 /* Leave everything else in the FDR zeroed out. This will cause
934 the lang field to be langC. The fBigendian field will
935 indicate little endian format, but it doesn't matter because
936 it only applies to aux fields and there are none. */
cf286547
ILT
937 external_fdr = (PTR) obstack_alloc (&ainfo->memory,
938 output_swap->external_fdr_size);
939 (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
940 add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
941 external_fdr, output_swap->external_fdr_size);
942
71efdf83 943 ++output_symhdr->ifdMax;
cf286547 944
71efdf83
ILT
945 return true;
946}
947
cf286547
ILT
948/* Set up ECOFF debugging information for the external symbols.
949 FIXME: This is done using a memory buffer, but it should be
950 probably be changed to use a shuffle structure. The assembler uses
951 this interface, so that must be changed to do something else. */
71efdf83
ILT
952
953boolean
954bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
955 set_index)
956 bfd *abfd;
957 struct ecoff_debug_info *debug;
958 const struct ecoff_debug_swap *swap;
959 boolean relocateable;
960 boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
961 void (*set_index) PARAMS ((asymbol *, bfd_size_type));
962{
71efdf83
ILT
963 HDRR * const symhdr = &debug->symbolic_header;
964 asymbol **sym_ptr_ptr;
965 size_t c;
966
967 sym_ptr_ptr = bfd_get_outsymbols (abfd);
968 if (sym_ptr_ptr == NULL)
969 return true;
970
971 for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
972 {
973 asymbol *sym_ptr;
974 EXTR esym;
975
976 sym_ptr = *sym_ptr_ptr;
977
978 /* Get the external symbol information. */
979 if ((*get_extr) (sym_ptr, &esym) == false)
980 continue;
981
982 /* If we're producing an executable, move common symbols into
983 bss. */
984 if (relocateable == false)
985 {
986 if (esym.asym.sc == scCommon)
987 esym.asym.sc = scBss;
988 else if (esym.asym.sc == scSCommon)
989 esym.asym.sc = scSBss;
990 }
991
71efdf83
ILT
992 if (bfd_is_com_section (sym_ptr->section)
993 || sym_ptr->section == &bfd_und_section)
994 esym.asym.value = sym_ptr->value;
995 else
996 esym.asym.value = (sym_ptr->value
997 + sym_ptr->section->output_offset
998 + sym_ptr->section->output_section->vma);
999
71efdf83 1000 if (set_index)
966e0a16
ILT
1001 (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
1002
1003 if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
1004 sym_ptr->name, &esym))
1005 return false;
1006 }
71efdf83 1007
966e0a16
ILT
1008 return true;
1009}
71efdf83 1010
966e0a16
ILT
1011/* Add a single external symbol to the debugging information. */
1012
1013boolean
1014bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
1015 bfd *abfd;
1016 struct ecoff_debug_info *debug;
1017 const struct ecoff_debug_swap *swap;
1018 const char *name;
1019 EXTR *esym;
1020{
1021 const bfd_size_type external_ext_size = swap->external_ext_size;
1022 void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
1023 = swap->swap_ext_out;
1024 HDRR * const symhdr = &debug->symbolic_header;
1025 size_t namelen;
1026
1027 namelen = strlen (name);
1028
1029 if (debug->ssext_end - debug->ssext
1030 < symhdr->issExtMax + namelen + 1)
1031 {
1032 if (ecoff_add_bytes ((char **) &debug->ssext,
1033 (char **) &debug->ssext_end,
1034 symhdr->issExtMax + namelen + 1)
1035 == false)
1036 return false;
1037 }
1038 if ((char *) debug->external_ext_end - (char *) debug->external_ext
1039 < (symhdr->iextMax + 1) * external_ext_size)
1040 {
1041 if (ecoff_add_bytes ((char **) &debug->external_ext,
1042 (char **) &debug->external_ext_end,
1043 (symhdr->iextMax + 1) * external_ext_size)
1044 == false)
1045 return false;
71efdf83
ILT
1046 }
1047
966e0a16
ILT
1048 esym->asym.iss = symhdr->issExtMax;
1049
1050 (*swap_ext_out) (abfd, esym,
1051 ((char *) debug->external_ext
1052 + symhdr->iextMax * swap->external_ext_size));
1053
1054 ++symhdr->iextMax;
1055
1056 strcpy (debug->ssext + symhdr->issExtMax, name);
1057 symhdr->issExtMax += namelen + 1;
1058
71efdf83
ILT
1059 return true;
1060}
1061
1062/* Align the ECOFF debugging information. */
1063
966e0a16 1064/*ARGSUSED*/
71efdf83
ILT
1065static void
1066ecoff_align_debug (abfd, debug, swap)
1067 bfd *abfd;
1068 struct ecoff_debug_info *debug;
1069 const struct ecoff_debug_swap *swap;
1070{
1071 HDRR * const symhdr = &debug->symbolic_header;
1fe2801a 1072 bfd_size_type debug_align, aux_align, rfd_align;
966e0a16 1073 size_t add;
71efdf83 1074
cf286547 1075 /* Adjust the counts so that structures are aligned. */
71efdf83
ILT
1076 debug_align = swap->debug_align;
1077 aux_align = debug_align / sizeof (union aux_ext);
1fe2801a 1078 rfd_align = debug_align / swap->external_rfd_size;
71efdf83
ILT
1079
1080 add = debug_align - (symhdr->cbLine & (debug_align - 1));
1081 if (add != debug_align)
1082 {
cf286547
ILT
1083 if (debug->line != (unsigned char *) NULL)
1084 memset (debug->line + symhdr->cbLine, 0, add);
71efdf83
ILT
1085 symhdr->cbLine += add;
1086 }
1087
1088 add = debug_align - (symhdr->issMax & (debug_align - 1));
1089 if (add != debug_align)
1090 {
cf286547
ILT
1091 if (debug->ss != (char *) NULL)
1092 memset (debug->ss + symhdr->issMax, 0, add);
71efdf83
ILT
1093 symhdr->issMax += add;
1094 }
1095
1096 add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1097 if (add != debug_align)
1098 {
cf286547
ILT
1099 if (debug->ssext != (char *) NULL)
1100 memset (debug->ssext + symhdr->issExtMax, 0, add);
71efdf83
ILT
1101 symhdr->issExtMax += add;
1102 }
1103
1104 add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1105 if (add != aux_align)
1106 {
cf286547
ILT
1107 if (debug->external_aux != (union aux_ext *) NULL)
1108 memset (debug->external_aux + symhdr->iauxMax, 0,
1109 add * sizeof (union aux_ext));
71efdf83
ILT
1110 symhdr->iauxMax += add;
1111 }
1fe2801a
ILT
1112
1113 add = rfd_align - (symhdr->crfd & (rfd_align - 1));
1114 if (add != rfd_align)
1115 {
1116 if (debug->external_rfd != (PTR) NULL)
1117 memset (((char *) debug->external_rfd
1118 + symhdr->crfd * swap->external_rfd_size),
1119 0, add * swap->external_rfd_size);
1120 symhdr->crfd += add;
1121 }
71efdf83
ILT
1122}
1123
1124/* Return the size required by the ECOFF debugging information. */
1125
1126bfd_size_type
1127bfd_ecoff_debug_size (abfd, debug, swap)
1128 bfd *abfd;
1129 struct ecoff_debug_info *debug;
1130 const struct ecoff_debug_swap *swap;
1131{
1132 bfd_size_type tot;
1133
1134 ecoff_align_debug (abfd, debug, swap);
1135 tot = swap->external_hdr_size;
1136
1137#define ADD(count, size) \
1138 tot += debug->symbolic_header.count * size
1139
1140 ADD (cbLine, sizeof (unsigned char));
1141 ADD (idnMax, swap->external_dnr_size);
1142 ADD (ipdMax, swap->external_pdr_size);
1143 ADD (isymMax, swap->external_sym_size);
1144 ADD (ioptMax, swap->external_opt_size);
1145 ADD (iauxMax, sizeof (union aux_ext));
1146 ADD (issMax, sizeof (char));
1147 ADD (issExtMax, sizeof (char));
1148 ADD (ifdMax, swap->external_fdr_size);
1149 ADD (crfd, swap->external_rfd_size);
1150 ADD (iextMax, swap->external_ext_size);
1151
1152#undef ADD
1153
1154 return tot;
1155}
1156
cf286547
ILT
1157/* Write out the ECOFF symbolic header, given the file position it is
1158 going to be placed at. This assumes that the counts are set
1159 correctly. */
71efdf83 1160
cf286547
ILT
1161static boolean
1162ecoff_write_symhdr (abfd, debug, swap, where)
71efdf83
ILT
1163 bfd *abfd;
1164 struct ecoff_debug_info *debug;
1165 const struct ecoff_debug_swap *swap;
1166 file_ptr where;
1167{
1168 HDRR * const symhdr = &debug->symbolic_header;
1169 char *buff;
1170
1171 ecoff_align_debug (abfd, debug, swap);
1172
1173 /* Go to the right location in the file. */
1174 if (bfd_seek (abfd, where, SEEK_SET) != 0)
1175 return false;
1176
1177 where += swap->external_hdr_size;
1178
1179 /* Fill in the file offsets. */
1180#define SET(offset, count, size) \
1181 if (symhdr->count == 0) \
1182 symhdr->offset = 0; \
1183 else \
1184 { \
1185 symhdr->offset = where; \
1186 where += symhdr->count * size; \
1187 }
1188
1189 SET (cbLineOffset, cbLine, sizeof (unsigned char));
1190 SET (cbDnOffset, idnMax, swap->external_dnr_size);
1191 SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1192 SET (cbSymOffset, isymMax, swap->external_sym_size);
1193 SET (cbOptOffset, ioptMax, swap->external_opt_size);
1194 SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1195 SET (cbSsOffset, issMax, sizeof (char));
1196 SET (cbSsExtOffset, issExtMax, sizeof (char));
1197 SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1198 SET (cbRfdOffset, crfd, swap->external_rfd_size);
1199 SET (cbExtOffset, iextMax, swap->external_ext_size);
1200#undef SET
1201
1202 buff = (PTR) alloca (swap->external_hdr_size);
1203 (*swap->swap_hdr_out) (abfd, symhdr, buff);
1204 if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
1205 != swap->external_hdr_size)
1206 return false;
1207
cf286547
ILT
1208 return true;
1209}
1210
1211/* Write out the ECOFF debugging information. This function assumes
1212 that the information (the pointers and counts) in *DEBUG have been
1213 set correctly. WHERE is the position in the file to write the
1214 information to. This function fills in the file offsets in the
1215 symbolic header. */
1216
1217boolean
1218bfd_ecoff_write_debug (abfd, debug, swap, where)
1219 bfd *abfd;
1220 struct ecoff_debug_info *debug;
1221 const struct ecoff_debug_swap *swap;
1222 file_ptr where;
1223{
1224 HDRR * const symhdr = &debug->symbolic_header;
1225
1226 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1227 return false;
1228
71efdf83
ILT
1229#define WRITE(ptr, count, size, offset) \
1230 BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
966e0a16 1231 if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
71efdf83
ILT
1232 != size * symhdr->count) \
1233 return false;
1234
1235 WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1236 WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1237 WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1238 WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1239 WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1240 WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
1241 WRITE (ss, issMax, sizeof (char), cbSsOffset);
1242 WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1243 WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1244 WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1245 WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1246#undef WRITE
1247
1248 return true;
1249}
cf286547
ILT
1250
1251/* Write out a shuffle list. */
1252
1253static boolean ecoff_write_shuffle PARAMS ((bfd *,
1254 const struct ecoff_debug_swap *,
1255 struct shuffle *, PTR space));
1256
1257static boolean
1258ecoff_write_shuffle (abfd, swap, shuffle, space)
1259 bfd *abfd;
1260 const struct ecoff_debug_swap *swap;
1261 struct shuffle *shuffle;
1262 PTR space;
1263{
1264 register struct shuffle *l;
1265 unsigned long total;
1266
1267 total = 0;
1268 for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
1269 {
1270 if (! l->filep)
1271 {
1272 if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
1273 return false;
1274 }
1275 else
1276 {
1277 if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1278 || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
1279 || bfd_write (space, 1, l->size, abfd) != l->size)
1280 return false;
1281 }
1282 total += l->size;
1283 }
1284
1285 if ((total & (swap->debug_align - 1)) != 0)
1286 {
1287 int i;
1288 bfd_byte *s;
1289
1290 i = swap->debug_align - (total & (swap->debug_align - 1));
1291 s = (bfd_byte *) alloca (i);
1292 memset (s, 0, i);
1293 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1294 return false;
1295 }
1296
1297 return true;
1298}
1299
1300/* Write out debugging information using accumulated linker
1301 information. */
1302
1303boolean
1304bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
1305 PTR handle;
1306 bfd *abfd;
1307 struct ecoff_debug_info *debug;
1308 const struct ecoff_debug_swap *swap;
1309 struct bfd_link_info *info;
1310 file_ptr where;
1311{
1312 struct accumulate *ainfo = (struct accumulate *) handle;
1313 PTR space;
cf286547
ILT
1314
1315 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1316 return false;
1317
1318 space = (PTR) alloca (ainfo->largest_file_shuffle);
1319
1320 if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1321 || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1322 || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1323 || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1324 || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1325 return false;
1326
1327 /* The string table is written out from the hash table if this is a
1328 final link. */
1329 if (info->relocateable)
1330 {
1331 BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1332 if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1333 return false;
1334 }
1335 else
1336 {
1337 unsigned long total;
1338 bfd_byte null;
1339 struct string_hash_entry *sh;
1340
1341 BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
1342 null = 0;
1343 if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
1344 return false;
1345 total = 1;
1346 BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1347 for (sh = ainfo->ss_hash;
1348 sh != (struct string_hash_entry *) NULL;
1349 sh = sh->next)
1350 {
1351 size_t len;
1352
1353 len = strlen (sh->root.string);
1354 if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
1355 return false;
1356 total += len + 1;
1357 }
1358
1359 if ((total & (swap->debug_align - 1)) != 0)
1360 {
1361 int i;
1362 bfd_byte *s;
1363
1364 i = swap->debug_align - (total & (swap->debug_align - 1));
1365 s = (bfd_byte *) alloca (i);
1366 memset (s, 0, i);
1367 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1368 return false;
1369 }
1370 }
1371
1372 /* The external strings and symbol are not converted over to using
1373 shuffles. FIXME: They probably should be. */
1374 if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
1375 != debug->symbolic_header.issExtMax)
1376 return false;
1377 if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1378 {
1379 int i;
1380 bfd_byte *s;
1381
1382 i = (swap->debug_align
1383 - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1384 s = (bfd_byte *) alloca (i);
1385 memset (s, 0, i);
1386 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1387 return false;
1388 }
1389
1390 if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1391 || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1392 return false;
1393
1394 BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1395 || debug->symbolic_header.cbExtOffset == bfd_tell (abfd));
1396
1397 if (bfd_write (debug->external_ext, swap->external_ext_size,
1398 debug->symbolic_header.iextMax, abfd)
1399 != debug->symbolic_header.iextMax * swap->external_ext_size)
1400 return false;
1401
1402 return true;
1403}
This page took 0.084366 seconds and 4 git commands to generate.