Eliminate arg from bfd_xmalloc_by_size_t macro, allowing
[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. */
6a5439a9 44#define obstack_chunk_alloc bfd_xmalloc_by_size_t
cf286547 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)
cbc174e7
ILT
994 {
995 /* FIXME: gas does not keep the value of a small undefined
996 symbol in the symbol itself, because of relocation
997 problems. */
998 if (esym.asym.sc != scSUndefined
999 || esym.asym.value == 0
1000 || sym_ptr->value != 0)
1001 esym.asym.value = sym_ptr->value;
1002 }
71efdf83
ILT
1003 else
1004 esym.asym.value = (sym_ptr->value
1005 + sym_ptr->section->output_offset
1006 + sym_ptr->section->output_section->vma);
1007
71efdf83 1008 if (set_index)
966e0a16
ILT
1009 (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
1010
1011 if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
1012 sym_ptr->name, &esym))
1013 return false;
1014 }
71efdf83 1015
966e0a16
ILT
1016 return true;
1017}
71efdf83 1018
966e0a16
ILT
1019/* Add a single external symbol to the debugging information. */
1020
1021boolean
1022bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
1023 bfd *abfd;
1024 struct ecoff_debug_info *debug;
1025 const struct ecoff_debug_swap *swap;
1026 const char *name;
1027 EXTR *esym;
1028{
1029 const bfd_size_type external_ext_size = swap->external_ext_size;
1030 void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
1031 = swap->swap_ext_out;
1032 HDRR * const symhdr = &debug->symbolic_header;
1033 size_t namelen;
1034
1035 namelen = strlen (name);
1036
1037 if (debug->ssext_end - debug->ssext
1038 < symhdr->issExtMax + namelen + 1)
1039 {
1040 if (ecoff_add_bytes ((char **) &debug->ssext,
1041 (char **) &debug->ssext_end,
1042 symhdr->issExtMax + namelen + 1)
1043 == false)
1044 return false;
1045 }
1046 if ((char *) debug->external_ext_end - (char *) debug->external_ext
1047 < (symhdr->iextMax + 1) * external_ext_size)
1048 {
1049 if (ecoff_add_bytes ((char **) &debug->external_ext,
1050 (char **) &debug->external_ext_end,
1051 (symhdr->iextMax + 1) * external_ext_size)
1052 == false)
1053 return false;
71efdf83
ILT
1054 }
1055
966e0a16
ILT
1056 esym->asym.iss = symhdr->issExtMax;
1057
1058 (*swap_ext_out) (abfd, esym,
1059 ((char *) debug->external_ext
1060 + symhdr->iextMax * swap->external_ext_size));
1061
1062 ++symhdr->iextMax;
1063
1064 strcpy (debug->ssext + symhdr->issExtMax, name);
1065 symhdr->issExtMax += namelen + 1;
1066
71efdf83
ILT
1067 return true;
1068}
1069
1070/* Align the ECOFF debugging information. */
1071
966e0a16 1072/*ARGSUSED*/
71efdf83
ILT
1073static void
1074ecoff_align_debug (abfd, debug, swap)
1075 bfd *abfd;
1076 struct ecoff_debug_info *debug;
1077 const struct ecoff_debug_swap *swap;
1078{
1079 HDRR * const symhdr = &debug->symbolic_header;
1fe2801a 1080 bfd_size_type debug_align, aux_align, rfd_align;
966e0a16 1081 size_t add;
71efdf83 1082
cf286547 1083 /* Adjust the counts so that structures are aligned. */
71efdf83
ILT
1084 debug_align = swap->debug_align;
1085 aux_align = debug_align / sizeof (union aux_ext);
1fe2801a 1086 rfd_align = debug_align / swap->external_rfd_size;
71efdf83
ILT
1087
1088 add = debug_align - (symhdr->cbLine & (debug_align - 1));
1089 if (add != debug_align)
1090 {
cf286547
ILT
1091 if (debug->line != (unsigned char *) NULL)
1092 memset (debug->line + symhdr->cbLine, 0, add);
71efdf83
ILT
1093 symhdr->cbLine += add;
1094 }
1095
1096 add = debug_align - (symhdr->issMax & (debug_align - 1));
1097 if (add != debug_align)
1098 {
cf286547
ILT
1099 if (debug->ss != (char *) NULL)
1100 memset (debug->ss + symhdr->issMax, 0, add);
71efdf83
ILT
1101 symhdr->issMax += add;
1102 }
1103
1104 add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1105 if (add != debug_align)
1106 {
cf286547
ILT
1107 if (debug->ssext != (char *) NULL)
1108 memset (debug->ssext + symhdr->issExtMax, 0, add);
71efdf83
ILT
1109 symhdr->issExtMax += add;
1110 }
1111
1112 add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1113 if (add != aux_align)
1114 {
cf286547
ILT
1115 if (debug->external_aux != (union aux_ext *) NULL)
1116 memset (debug->external_aux + symhdr->iauxMax, 0,
1117 add * sizeof (union aux_ext));
71efdf83
ILT
1118 symhdr->iauxMax += add;
1119 }
1fe2801a
ILT
1120
1121 add = rfd_align - (symhdr->crfd & (rfd_align - 1));
1122 if (add != rfd_align)
1123 {
1124 if (debug->external_rfd != (PTR) NULL)
1125 memset (((char *) debug->external_rfd
1126 + symhdr->crfd * swap->external_rfd_size),
1127 0, add * swap->external_rfd_size);
1128 symhdr->crfd += add;
1129 }
71efdf83
ILT
1130}
1131
1132/* Return the size required by the ECOFF debugging information. */
1133
1134bfd_size_type
1135bfd_ecoff_debug_size (abfd, debug, swap)
1136 bfd *abfd;
1137 struct ecoff_debug_info *debug;
1138 const struct ecoff_debug_swap *swap;
1139{
1140 bfd_size_type tot;
1141
1142 ecoff_align_debug (abfd, debug, swap);
1143 tot = swap->external_hdr_size;
1144
1145#define ADD(count, size) \
1146 tot += debug->symbolic_header.count * size
1147
1148 ADD (cbLine, sizeof (unsigned char));
1149 ADD (idnMax, swap->external_dnr_size);
1150 ADD (ipdMax, swap->external_pdr_size);
1151 ADD (isymMax, swap->external_sym_size);
1152 ADD (ioptMax, swap->external_opt_size);
1153 ADD (iauxMax, sizeof (union aux_ext));
1154 ADD (issMax, sizeof (char));
1155 ADD (issExtMax, sizeof (char));
1156 ADD (ifdMax, swap->external_fdr_size);
1157 ADD (crfd, swap->external_rfd_size);
1158 ADD (iextMax, swap->external_ext_size);
1159
1160#undef ADD
1161
1162 return tot;
1163}
1164
cf286547
ILT
1165/* Write out the ECOFF symbolic header, given the file position it is
1166 going to be placed at. This assumes that the counts are set
1167 correctly. */
71efdf83 1168
cf286547
ILT
1169static boolean
1170ecoff_write_symhdr (abfd, debug, swap, where)
71efdf83
ILT
1171 bfd *abfd;
1172 struct ecoff_debug_info *debug;
1173 const struct ecoff_debug_swap *swap;
1174 file_ptr where;
1175{
1176 HDRR * const symhdr = &debug->symbolic_header;
1177 char *buff;
1178
1179 ecoff_align_debug (abfd, debug, swap);
1180
1181 /* Go to the right location in the file. */
1182 if (bfd_seek (abfd, where, SEEK_SET) != 0)
1183 return false;
1184
1185 where += swap->external_hdr_size;
1186
1187 /* Fill in the file offsets. */
1188#define SET(offset, count, size) \
1189 if (symhdr->count == 0) \
1190 symhdr->offset = 0; \
1191 else \
1192 { \
1193 symhdr->offset = where; \
1194 where += symhdr->count * size; \
1195 }
1196
1197 SET (cbLineOffset, cbLine, sizeof (unsigned char));
1198 SET (cbDnOffset, idnMax, swap->external_dnr_size);
1199 SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1200 SET (cbSymOffset, isymMax, swap->external_sym_size);
1201 SET (cbOptOffset, ioptMax, swap->external_opt_size);
1202 SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1203 SET (cbSsOffset, issMax, sizeof (char));
1204 SET (cbSsExtOffset, issExtMax, sizeof (char));
1205 SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1206 SET (cbRfdOffset, crfd, swap->external_rfd_size);
1207 SET (cbExtOffset, iextMax, swap->external_ext_size);
1208#undef SET
1209
1210 buff = (PTR) alloca (swap->external_hdr_size);
1211 (*swap->swap_hdr_out) (abfd, symhdr, buff);
1212 if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
1213 != swap->external_hdr_size)
1214 return false;
1215
cf286547
ILT
1216 return true;
1217}
1218
1219/* Write out the ECOFF debugging information. This function assumes
1220 that the information (the pointers and counts) in *DEBUG have been
1221 set correctly. WHERE is the position in the file to write the
1222 information to. This function fills in the file offsets in the
1223 symbolic header. */
1224
1225boolean
1226bfd_ecoff_write_debug (abfd, debug, swap, where)
1227 bfd *abfd;
1228 struct ecoff_debug_info *debug;
1229 const struct ecoff_debug_swap *swap;
1230 file_ptr where;
1231{
1232 HDRR * const symhdr = &debug->symbolic_header;
1233
1234 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1235 return false;
1236
71efdf83
ILT
1237#define WRITE(ptr, count, size, offset) \
1238 BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
966e0a16 1239 if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
71efdf83
ILT
1240 != size * symhdr->count) \
1241 return false;
1242
1243 WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1244 WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1245 WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1246 WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1247 WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1248 WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
1249 WRITE (ss, issMax, sizeof (char), cbSsOffset);
1250 WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1251 WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1252 WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1253 WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1254#undef WRITE
1255
1256 return true;
1257}
cf286547
ILT
1258
1259/* Write out a shuffle list. */
1260
1261static boolean ecoff_write_shuffle PARAMS ((bfd *,
1262 const struct ecoff_debug_swap *,
1263 struct shuffle *, PTR space));
1264
1265static boolean
1266ecoff_write_shuffle (abfd, swap, shuffle, space)
1267 bfd *abfd;
1268 const struct ecoff_debug_swap *swap;
1269 struct shuffle *shuffle;
1270 PTR space;
1271{
1272 register struct shuffle *l;
1273 unsigned long total;
1274
1275 total = 0;
1276 for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
1277 {
1278 if (! l->filep)
1279 {
1280 if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
1281 return false;
1282 }
1283 else
1284 {
1285 if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1286 || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
1287 || bfd_write (space, 1, l->size, abfd) != l->size)
1288 return false;
1289 }
1290 total += l->size;
1291 }
1292
1293 if ((total & (swap->debug_align - 1)) != 0)
1294 {
1295 int i;
1296 bfd_byte *s;
1297
1298 i = swap->debug_align - (total & (swap->debug_align - 1));
1299 s = (bfd_byte *) alloca (i);
1300 memset (s, 0, i);
1301 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1302 return false;
1303 }
1304
1305 return true;
1306}
1307
1308/* Write out debugging information using accumulated linker
1309 information. */
1310
1311boolean
1312bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
1313 PTR handle;
1314 bfd *abfd;
1315 struct ecoff_debug_info *debug;
1316 const struct ecoff_debug_swap *swap;
1317 struct bfd_link_info *info;
1318 file_ptr where;
1319{
1320 struct accumulate *ainfo = (struct accumulate *) handle;
1321 PTR space;
cf286547
ILT
1322
1323 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1324 return false;
1325
1326 space = (PTR) alloca (ainfo->largest_file_shuffle);
1327
1328 if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1329 || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1330 || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1331 || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1332 || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1333 return false;
1334
1335 /* The string table is written out from the hash table if this is a
1336 final link. */
1337 if (info->relocateable)
1338 {
1339 BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1340 if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1341 return false;
1342 }
1343 else
1344 {
1345 unsigned long total;
1346 bfd_byte null;
1347 struct string_hash_entry *sh;
1348
1349 BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
1350 null = 0;
1351 if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
1352 return false;
1353 total = 1;
1354 BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1355 for (sh = ainfo->ss_hash;
1356 sh != (struct string_hash_entry *) NULL;
1357 sh = sh->next)
1358 {
1359 size_t len;
1360
1361 len = strlen (sh->root.string);
1362 if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
1363 return false;
1364 total += len + 1;
1365 }
1366
1367 if ((total & (swap->debug_align - 1)) != 0)
1368 {
1369 int i;
1370 bfd_byte *s;
1371
1372 i = swap->debug_align - (total & (swap->debug_align - 1));
1373 s = (bfd_byte *) alloca (i);
1374 memset (s, 0, i);
1375 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1376 return false;
1377 }
1378 }
1379
1380 /* The external strings and symbol are not converted over to using
1381 shuffles. FIXME: They probably should be. */
1382 if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
1383 != debug->symbolic_header.issExtMax)
1384 return false;
1385 if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1386 {
1387 int i;
1388 bfd_byte *s;
1389
1390 i = (swap->debug_align
1391 - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1392 s = (bfd_byte *) alloca (i);
1393 memset (s, 0, i);
1394 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1395 return false;
1396 }
1397
1398 if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1399 || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1400 return false;
1401
1402 BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1403 || debug->symbolic_header.cbExtOffset == bfd_tell (abfd));
1404
1405 if (bfd_write (debug->external_ext, swap->external_ext_size,
1406 debug->symbolic_header.iextMax, abfd)
1407 != debug->symbolic_header.iextMax * swap->external_ext_size)
1408 return false;
1409
1410 return true;
1411}
This page took 0.087065 seconds and 4 git commands to generate.