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