* rltty.c: #if out some code if __GO32__.
[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 {
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)));
9783e04a
DM
118 if (ret == (struct string_hash_entry *) NULL)
119 {
120 bfd_error = no_memory;
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 {
240 bfd_error = no_memory;
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 {
279 bfd_error = no_memory;
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 {
310 bfd_error = no_memory;
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 {
349 bfd_error = no_memory;
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 {
481 bfd_error = no_memory;
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;
522 lookup = (char *) alloca (strlen (name) + 20);
523 sprintf (lookup, "%s %lx", name, fdr.csym);
524
525 fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
526 if (fh == (struct string_hash_entry *) NULL)
527 return false;
71efdf83 528
cf286547
ILT
529 if (fh->val != -1)
530 {
531 input_debug->ifdmap[i] = fh->val;
532 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i,
533 (PTR) rfd_out);
71efdf83 534
cf286547
ILT
535 /* Don't copy this FDR. */
536 continue;
537 }
71efdf83 538
cf286547 539 fh->val = output_symhdr->ifdMax + copied;
71efdf83 540 }
cf286547
ILT
541
542 input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
543 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out);
544 ++copied;
71efdf83
ILT
545 }
546
cf286547
ILT
547 newrfdbase = output_symhdr->crfd;
548 output_symhdr->crfd += input_symhdr->ifdMax;
71efdf83 549
cf286547
ILT
550 /* Copy over any existing RFD's. RFD's are only created by the
551 linker, so this will only happen for input files which are the
552 result of a partial link. */
553 rfd_in = (bfd_byte *) input_debug->external_rfd;
554 rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
555 for (;
556 rfd_in < rfd_end;
557 rfd_in += input_swap->external_rfd_size)
71efdf83 558 {
cf286547
ILT
559 RFDT rfd;
560
561 (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd);
562 BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
563 rfd = input_debug->ifdmap[rfd];
564 (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out);
565 rfd_out += external_rfd_size;
71efdf83 566 }
cf286547
ILT
567
568 oldrfdbase = output_symhdr->crfd;
569 output_symhdr->crfd += input_symhdr->crfd;
570
571 /* Look through the FDR's and copy over all associated debugging
572 information. */
573 sz = copied * external_fdr_size;
574 fdr_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
9783e04a
DM
575 if (!fdr_out)
576 {
577 bfd_error = no_memory;
578 return false;
579 }
580 if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
581 return false;
cf286547 582 for (fdr_ptr = fdr_start, i = 0;
71efdf83 583 fdr_ptr < fdr_end;
cf286547 584 fdr_ptr += fdr_add, i++)
71efdf83
ILT
585 {
586 FDR fdr;
cf286547
ILT
587 bfd_byte *sym_out;
588 bfd_byte *lraw_src;
589 bfd_byte *lraw_end;
590 boolean fgotfilename;
591
592 if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
593 {
594 /* We are not copying this FDR. */
595 continue;
596 }
71efdf83
ILT
597
598 if (input_debug->fdr != (FDR *) NULL)
599 fdr = *(FDR *) fdr_ptr;
600 else
601 (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
602
603 /* FIXME: It is conceivable that this FDR points to the .init or
604 .fini section, in which case this will not do the right
605 thing. */
606 fdr.adr += section_adjust[scText];
607
cf286547
ILT
608 /* Swap in the local symbols, adjust their values, and swap them
609 out again. */
610 fgotfilename = false;
611 sz = fdr.csym * external_sym_size;
612 sym_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
9783e04a
DM
613 if (!sym_out)
614 {
615 bfd_error = no_memory;
616 return false;
617 }
618 if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out, sz))
619 return false;
cf286547
ILT
620 lraw_src = ((bfd_byte *) input_debug->external_sym
621 + fdr.isymBase * input_swap->external_sym_size);
622 lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
623 for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size)
624 {
625 SYMR internal_sym;
626
627 (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
628
629 BFD_ASSERT (internal_sym.sc != scCommon
630 && internal_sym.sc != scSCommon);
631
632 /* Adjust the symbol value if appropriate. */
633 switch (internal_sym.st)
634 {
635 case stNil:
636 if (ECOFF_IS_STAB (&internal_sym))
637 break;
638 /* Fall through. */
639 case stGlobal:
640 case stStatic:
641 case stLabel:
642 case stProc:
643 case stStaticProc:
644 internal_sym.value += section_adjust[internal_sym.sc];
645 break;
646
647 default:
648 break;
649 }
650
651 /* If we are doing a final link, we hash all the strings in
652 the local symbol table together. This reduces the amount
653 of space required by debugging information. We don't do
654 this when performing a relocateable link because it would
655 prevent us from easily merging different FDR's. */
656 if (! info->relocateable)
657 {
658 boolean ffilename;
659 const char *name;
660
661 if (! fgotfilename && internal_sym.iss == fdr.rss)
662 ffilename = true;
663 else
664 ffilename = false;
665
666 /* Hash the name into the string table. */
667 name = input_debug->ss + fdr.issBase + internal_sym.iss;
668 if (*name == '\0')
669 internal_sym.iss = 0;
670 else
671 {
672 struct string_hash_entry *sh;
673
674 sh = string_hash_lookup (&ainfo->str_hash, name, true, true);
675 if (sh == (struct string_hash_entry *) NULL)
676 return false;
677 if (sh->val == -1)
678 {
679 sh->val = output_symhdr->issMax;
680 output_symhdr->issMax += strlen (name) + 1;
681 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
682 ainfo->ss_hash = sh;
683 if (ainfo->ss_hash_end
684 != (struct string_hash_entry *) NULL)
685 ainfo->ss_hash_end->next = sh;
686 ainfo->ss_hash_end = sh;
687 }
688 internal_sym.iss = sh->val;
689 }
690
691 if (ffilename)
692 {
693 fdr.rss = internal_sym.iss;
694 fgotfilename = true;
695 }
696 }
697
698 (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
699 sym_out += external_sym_size;
700 }
71efdf83 701
cf286547
ILT
702 fdr.isymBase = output_symhdr->isymMax;
703 output_symhdr->isymMax += fdr.csym;
71efdf83 704
cf286547
ILT
705 /* Copy the information that does not need swapping. */
706 if (fdr.cbLine > 0)
707 {
9783e04a 708 if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
cf286547
ILT
709 input_bfd,
710 input_symhdr->cbLineOffset + fdr.cbLineOffset,
9783e04a
DM
711 fdr.cbLine))
712 return false;
cf286547
ILT
713 fdr.ilineBase = output_symhdr->ilineMax;
714 fdr.cbLineOffset = output_symhdr->cbLine;
715 output_symhdr->ilineMax += fdr.cline;
716 output_symhdr->cbLine += fdr.cbLine;
717 }
718 if (fdr.caux > 0)
719 {
9783e04a 720 if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
cf286547
ILT
721 input_bfd,
722 (input_symhdr->cbAuxOffset
723 + fdr.iauxBase * sizeof (union aux_ext)),
9783e04a
DM
724 fdr.caux * sizeof (union aux_ext)))
725 return false;
cf286547
ILT
726 fdr.iauxBase = output_symhdr->iauxMax;
727 output_symhdr->iauxMax += fdr.caux;
728 }
729 if (! info->relocateable)
730 {
71efdf83 731
cf286547
ILT
732 /* When are are hashing strings, we lie about the number of
733 strings attached to each FDR. We need to set cbSs
734 because some versions of dbx apparently use it to decide
735 how much of the string table to read in. */
736 fdr.issBase = 0;
737 fdr.cbSs = output_symhdr->issMax;
738 }
739 else if (fdr.cbSs > 0)
740 {
9783e04a 741 if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
cf286547
ILT
742 input_bfd,
743 input_symhdr->cbSsOffset + fdr.issBase,
9783e04a
DM
744 fdr.cbSs))
745 return false;
cf286547
ILT
746 fdr.issBase = output_symhdr->issMax;
747 output_symhdr->issMax += fdr.cbSs;
748 }
71efdf83 749
cf286547
ILT
750 if (output_bfd->xvec->header_byteorder_big_p
751 == input_bfd->xvec->header_byteorder_big_p)
71efdf83 752 {
cf286547
ILT
753 /* The two BFD's have the same endianness, so simply copying
754 the information will suffice. */
755 BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
756 if (fdr.cpd > 0)
9783e04a
DM
757 {
758 if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
759 input_bfd,
760 (input_symhdr->cbPdOffset
761 + fdr.ipdFirst * external_pdr_size),
762 fdr.cpd * external_pdr_size))
763 return false;
764 }
cf286547
ILT
765 BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
766 if (fdr.copt > 0)
9783e04a
DM
767 {
768 if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
769 input_bfd,
770 (input_symhdr->cbOptOffset
771 + fdr.ioptBase * external_opt_size),
772 fdr.copt * external_opt_size))
773 return false;
774 }
cf286547
ILT
775 }
776 else
777 {
778 bfd_size_type outsz, insz;
779 bfd_byte *in;
780 bfd_byte *end;
781 bfd_byte *out;
782
783 /* The two BFD's have different endianness, so we must swap
784 everything in and out. This code would always work, but
785 it would be unnecessarily slow in the normal case. */
786 outsz = external_pdr_size;
787 insz = input_swap->external_pdr_size;
788 in = ((bfd_byte *) input_debug->external_pdr
789 + fdr.ipdFirst * insz);
790 end = in + fdr.cpd * insz;
791 sz = fdr.cpd * outsz;
792 out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
9783e04a
DM
793 if (!out)
794 {
795 bfd_error = no_memory;
796 return false;
797 }
798 if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, sz))
799 return false;
cf286547
ILT
800 for (; in < end; in += insz, out += outsz)
801 {
802 PDR pdr;
803
804 (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
805 (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
806 }
807
808 /* Swap over the optimization information. */
809 outsz = external_opt_size;
810 insz = input_swap->external_opt_size;
811 in = ((bfd_byte *) input_debug->external_opt
812 + fdr.ioptBase * insz);
813 end = in + fdr.copt * insz;
814 sz = fdr.copt * outsz;
815 out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz);
9783e04a
DM
816 if (!out)
817 {
818 bfd_error = no_memory;
819 return false;
820 }
821 if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, sz))
822 return false;
cf286547
ILT
823 for (; in < end; in += insz, out += outsz)
824 {
825 OPTR opt;
826
827 (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);
828 (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);
829 }
830 }
831
832 fdr.ipdFirst = output_symhdr->ipdMax;
833 output_symhdr->ipdMax += fdr.cpd;
834 fdr.ioptBase = output_symhdr->ioptMax;
835 output_symhdr->ioptMax += fdr.copt;
71efdf83 836
cf286547
ILT
837 if (fdr.crfd <= 0)
838 {
839 /* Point this FDR at the table of RFD's we created. */
840 fdr.rfdBase = newrfdbase;
841 fdr.crfd = input_symhdr->ifdMax;
842 }
843 else
844 {
845 /* Point this FDR at the remapped RFD's. */
846 fdr.rfdBase += oldrfdbase;
71efdf83 847 }
71efdf83 848
cf286547
ILT
849 (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
850 fdr_out += external_fdr_size;
851 ++output_symhdr->ifdMax;
71efdf83
ILT
852 }
853
71efdf83
ILT
854 return true;
855}
856
857/* Add a string to the debugging information we are accumulating.
858 Return the offset from the fdr string base. */
859
cf286547
ILT
860static long ecoff_add_string PARAMS ((struct accumulate *,
861 struct bfd_link_info *,
862 struct ecoff_debug_info *,
863 FDR *fdr, const char *string));
864
865static long
866ecoff_add_string (ainfo, info, debug, fdr, string)
867 struct accumulate *ainfo;
868 struct bfd_link_info *info;
869 struct ecoff_debug_info *debug;
71efdf83
ILT
870 FDR *fdr;
871 const char *string;
872{
873 HDRR *symhdr;
874 size_t len;
875 bfd_size_type ret;
876
cf286547 877 symhdr = &debug->symbolic_header;
71efdf83 878 len = strlen (string);
cf286547
ILT
879 if (info->relocateable)
880 {
9783e04a
DM
881 if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
882 len + 1))
883 return -1;
cf286547
ILT
884 ret = symhdr->issMax;
885 symhdr->issMax += len + 1;
886 fdr->cbSs += len + 1;
887 }
888 else
71efdf83 889 {
cf286547
ILT
890 struct string_hash_entry *sh;
891
892 sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
893 if (sh == (struct string_hash_entry *) NULL)
966e0a16 894 return (bfd_size_type) -1;
cf286547
ILT
895 if (sh->val == -1)
896 {
897 sh->val = symhdr->issMax;
898 symhdr->issMax += len + 1;
899 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
900 ainfo->ss_hash = sh;
901 if (ainfo->ss_hash_end
902 != (struct string_hash_entry *) NULL)
903 ainfo->ss_hash_end->next = sh;
904 ainfo->ss_hash_end = sh;
905 }
906 ret = sh->val;
71efdf83 907 }
cf286547 908
71efdf83
ILT
909 return ret;
910}
911
912/* Add debugging information from a non-ECOFF file. */
913
914boolean
cf286547
ILT
915bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
916 output_swap, input_bfd, info)
917 PTR handle;
71efdf83
ILT
918 bfd *output_bfd;
919 struct ecoff_debug_info *output_debug;
920 const struct ecoff_debug_swap *output_swap;
921 bfd *input_bfd;
cf286547 922 struct bfd_link_info *info;
71efdf83 923{
cf286547 924 struct accumulate *ainfo = (struct accumulate *) handle;
71efdf83
ILT
925 void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
926 = output_swap->swap_sym_out;
927 HDRR *output_symhdr = &output_debug->symbolic_header;
928 FDR fdr;
929 asection *sec;
930 asymbol **symbols;
931 asymbol **sym_ptr;
932 asymbol **sym_end;
cf286547 933 PTR external_fdr;
71efdf83
ILT
934
935 memset (&fdr, 0, sizeof fdr);
936
937 sec = bfd_get_section_by_name (input_bfd, ".text");
938 if (sec != NULL)
939 fdr.adr = sec->output_section->vma + sec->output_offset;
940 else
941 {
942 /* FIXME: What about .init or .fini? */
943 fdr.adr = 0;
944 }
945
946 fdr.issBase = output_symhdr->issMax;
947 fdr.cbSs = 0;
cf286547 948 fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
71efdf83 949 bfd_get_filename (input_bfd));
966e0a16
ILT
950 if (fdr.rss == -1)
951 return false;
71efdf83
ILT
952 fdr.isymBase = output_symhdr->isymMax;
953
954 /* Get the local symbols from the input BFD. */
955 symbols = (asymbol **) bfd_alloc (output_bfd,
956 get_symtab_upper_bound (input_bfd));
957 if (symbols == (asymbol **) NULL)
958 {
959 bfd_error = no_memory;
960 return false;
961 }
962 sym_end = symbols + bfd_canonicalize_symtab (input_bfd, symbols);
963
964 /* Handle the local symbols. Any external symbols are handled
965 separately. */
966 fdr.csym = 0;
967 for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
968 {
969 SYMR internal_sym;
cf286547 970 PTR external_sym;
71efdf83
ILT
971
972 if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
973 continue;
974 memset (&internal_sym, 0, sizeof internal_sym);
cf286547 975 internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
71efdf83
ILT
976 (*sym_ptr)->name);
977
966e0a16
ILT
978 if (internal_sym.iss == -1)
979 return false;
71efdf83
ILT
980 if (bfd_is_com_section ((*sym_ptr)->section)
981 || (*sym_ptr)->section == &bfd_und_section)
982 internal_sym.value = (*sym_ptr)->value;
983 else
984 internal_sym.value = ((*sym_ptr)->value
985 + (*sym_ptr)->section->output_offset
986 + (*sym_ptr)->section->output_section->vma);
987 internal_sym.st = stNil;
988 internal_sym.sc = scUndefined;
989 internal_sym.index = indexNil;
990
cf286547
ILT
991 external_sym = (PTR) obstack_alloc (&ainfo->memory,
992 output_swap->external_sym_size);
9783e04a
DM
993 if (!external_sym)
994 {
995 bfd_error = no_memory;
996 return false;
997 }
cf286547
ILT
998 (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
999 add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
1000 external_sym, output_swap->external_sym_size);
71efdf83
ILT
1001 ++fdr.csym;
1002 ++output_symhdr->isymMax;
1003 }
1004
1005 bfd_release (output_bfd, (PTR) symbols);
1006
71efdf83
ILT
1007 /* Leave everything else in the FDR zeroed out. This will cause
1008 the lang field to be langC. The fBigendian field will
1009 indicate little endian format, but it doesn't matter because
1010 it only applies to aux fields and there are none. */
cf286547
ILT
1011 external_fdr = (PTR) obstack_alloc (&ainfo->memory,
1012 output_swap->external_fdr_size);
9783e04a
DM
1013 if (!external_fdr)
1014 {
1015 bfd_error = no_memory;
1016 return false;
1017 }
cf286547
ILT
1018 (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
1019 add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
1020 external_fdr, output_swap->external_fdr_size);
1021
71efdf83 1022 ++output_symhdr->ifdMax;
cf286547 1023
71efdf83
ILT
1024 return true;
1025}
1026
cf286547
ILT
1027/* Set up ECOFF debugging information for the external symbols.
1028 FIXME: This is done using a memory buffer, but it should be
1029 probably be changed to use a shuffle structure. The assembler uses
1030 this interface, so that must be changed to do something else. */
71efdf83
ILT
1031
1032boolean
1033bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
1034 set_index)
1035 bfd *abfd;
1036 struct ecoff_debug_info *debug;
1037 const struct ecoff_debug_swap *swap;
1038 boolean relocateable;
1039 boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
1040 void (*set_index) PARAMS ((asymbol *, bfd_size_type));
1041{
71efdf83
ILT
1042 HDRR * const symhdr = &debug->symbolic_header;
1043 asymbol **sym_ptr_ptr;
1044 size_t c;
1045
1046 sym_ptr_ptr = bfd_get_outsymbols (abfd);
1047 if (sym_ptr_ptr == NULL)
1048 return true;
1049
1050 for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
1051 {
1052 asymbol *sym_ptr;
1053 EXTR esym;
1054
1055 sym_ptr = *sym_ptr_ptr;
1056
1057 /* Get the external symbol information. */
1058 if ((*get_extr) (sym_ptr, &esym) == false)
1059 continue;
1060
1061 /* If we're producing an executable, move common symbols into
1062 bss. */
1063 if (relocateable == false)
1064 {
1065 if (esym.asym.sc == scCommon)
1066 esym.asym.sc = scBss;
1067 else if (esym.asym.sc == scSCommon)
1068 esym.asym.sc = scSBss;
1069 }
1070
71efdf83
ILT
1071 if (bfd_is_com_section (sym_ptr->section)
1072 || sym_ptr->section == &bfd_und_section)
cbc174e7
ILT
1073 {
1074 /* FIXME: gas does not keep the value of a small undefined
1075 symbol in the symbol itself, because of relocation
1076 problems. */
1077 if (esym.asym.sc != scSUndefined
1078 || esym.asym.value == 0
1079 || sym_ptr->value != 0)
1080 esym.asym.value = sym_ptr->value;
1081 }
71efdf83
ILT
1082 else
1083 esym.asym.value = (sym_ptr->value
1084 + sym_ptr->section->output_offset
1085 + sym_ptr->section->output_section->vma);
1086
71efdf83 1087 if (set_index)
966e0a16
ILT
1088 (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
1089
1090 if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
1091 sym_ptr->name, &esym))
1092 return false;
1093 }
71efdf83 1094
966e0a16
ILT
1095 return true;
1096}
71efdf83 1097
966e0a16
ILT
1098/* Add a single external symbol to the debugging information. */
1099
1100boolean
1101bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
1102 bfd *abfd;
1103 struct ecoff_debug_info *debug;
1104 const struct ecoff_debug_swap *swap;
1105 const char *name;
1106 EXTR *esym;
1107{
1108 const bfd_size_type external_ext_size = swap->external_ext_size;
1109 void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
1110 = swap->swap_ext_out;
1111 HDRR * const symhdr = &debug->symbolic_header;
1112 size_t namelen;
1113
1114 namelen = strlen (name);
1115
1116 if (debug->ssext_end - debug->ssext
1117 < symhdr->issExtMax + namelen + 1)
1118 {
1119 if (ecoff_add_bytes ((char **) &debug->ssext,
1120 (char **) &debug->ssext_end,
1121 symhdr->issExtMax + namelen + 1)
1122 == false)
1123 return false;
1124 }
1125 if ((char *) debug->external_ext_end - (char *) debug->external_ext
1126 < (symhdr->iextMax + 1) * external_ext_size)
1127 {
1128 if (ecoff_add_bytes ((char **) &debug->external_ext,
1129 (char **) &debug->external_ext_end,
1130 (symhdr->iextMax + 1) * external_ext_size)
1131 == false)
1132 return false;
71efdf83
ILT
1133 }
1134
966e0a16
ILT
1135 esym->asym.iss = symhdr->issExtMax;
1136
1137 (*swap_ext_out) (abfd, esym,
1138 ((char *) debug->external_ext
1139 + symhdr->iextMax * swap->external_ext_size));
1140
1141 ++symhdr->iextMax;
1142
1143 strcpy (debug->ssext + symhdr->issExtMax, name);
1144 symhdr->issExtMax += namelen + 1;
1145
71efdf83
ILT
1146 return true;
1147}
1148
1149/* Align the ECOFF debugging information. */
1150
966e0a16 1151/*ARGSUSED*/
71efdf83
ILT
1152static void
1153ecoff_align_debug (abfd, debug, swap)
1154 bfd *abfd;
1155 struct ecoff_debug_info *debug;
1156 const struct ecoff_debug_swap *swap;
1157{
1158 HDRR * const symhdr = &debug->symbolic_header;
1fe2801a 1159 bfd_size_type debug_align, aux_align, rfd_align;
966e0a16 1160 size_t add;
71efdf83 1161
cf286547 1162 /* Adjust the counts so that structures are aligned. */
71efdf83
ILT
1163 debug_align = swap->debug_align;
1164 aux_align = debug_align / sizeof (union aux_ext);
1fe2801a 1165 rfd_align = debug_align / swap->external_rfd_size;
71efdf83
ILT
1166
1167 add = debug_align - (symhdr->cbLine & (debug_align - 1));
1168 if (add != debug_align)
1169 {
cf286547
ILT
1170 if (debug->line != (unsigned char *) NULL)
1171 memset (debug->line + symhdr->cbLine, 0, add);
71efdf83
ILT
1172 symhdr->cbLine += add;
1173 }
1174
1175 add = debug_align - (symhdr->issMax & (debug_align - 1));
1176 if (add != debug_align)
1177 {
cf286547
ILT
1178 if (debug->ss != (char *) NULL)
1179 memset (debug->ss + symhdr->issMax, 0, add);
71efdf83
ILT
1180 symhdr->issMax += add;
1181 }
1182
1183 add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1184 if (add != debug_align)
1185 {
cf286547
ILT
1186 if (debug->ssext != (char *) NULL)
1187 memset (debug->ssext + symhdr->issExtMax, 0, add);
71efdf83
ILT
1188 symhdr->issExtMax += add;
1189 }
1190
1191 add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1192 if (add != aux_align)
1193 {
cf286547
ILT
1194 if (debug->external_aux != (union aux_ext *) NULL)
1195 memset (debug->external_aux + symhdr->iauxMax, 0,
1196 add * sizeof (union aux_ext));
71efdf83
ILT
1197 symhdr->iauxMax += add;
1198 }
1fe2801a
ILT
1199
1200 add = rfd_align - (symhdr->crfd & (rfd_align - 1));
1201 if (add != rfd_align)
1202 {
1203 if (debug->external_rfd != (PTR) NULL)
1204 memset (((char *) debug->external_rfd
1205 + symhdr->crfd * swap->external_rfd_size),
1206 0, add * swap->external_rfd_size);
1207 symhdr->crfd += add;
1208 }
71efdf83
ILT
1209}
1210
1211/* Return the size required by the ECOFF debugging information. */
1212
1213bfd_size_type
1214bfd_ecoff_debug_size (abfd, debug, swap)
1215 bfd *abfd;
1216 struct ecoff_debug_info *debug;
1217 const struct ecoff_debug_swap *swap;
1218{
1219 bfd_size_type tot;
1220
1221 ecoff_align_debug (abfd, debug, swap);
1222 tot = swap->external_hdr_size;
1223
1224#define ADD(count, size) \
1225 tot += debug->symbolic_header.count * size
1226
1227 ADD (cbLine, sizeof (unsigned char));
1228 ADD (idnMax, swap->external_dnr_size);
1229 ADD (ipdMax, swap->external_pdr_size);
1230 ADD (isymMax, swap->external_sym_size);
1231 ADD (ioptMax, swap->external_opt_size);
1232 ADD (iauxMax, sizeof (union aux_ext));
1233 ADD (issMax, sizeof (char));
1234 ADD (issExtMax, sizeof (char));
1235 ADD (ifdMax, swap->external_fdr_size);
1236 ADD (crfd, swap->external_rfd_size);
1237 ADD (iextMax, swap->external_ext_size);
1238
1239#undef ADD
1240
1241 return tot;
1242}
1243
cf286547
ILT
1244/* Write out the ECOFF symbolic header, given the file position it is
1245 going to be placed at. This assumes that the counts are set
1246 correctly. */
71efdf83 1247
cf286547
ILT
1248static boolean
1249ecoff_write_symhdr (abfd, debug, swap, where)
71efdf83
ILT
1250 bfd *abfd;
1251 struct ecoff_debug_info *debug;
1252 const struct ecoff_debug_swap *swap;
1253 file_ptr where;
1254{
1255 HDRR * const symhdr = &debug->symbolic_header;
1256 char *buff;
1257
1258 ecoff_align_debug (abfd, debug, swap);
1259
1260 /* Go to the right location in the file. */
1261 if (bfd_seek (abfd, where, SEEK_SET) != 0)
1262 return false;
1263
1264 where += swap->external_hdr_size;
1265
1266 /* Fill in the file offsets. */
1267#define SET(offset, count, size) \
1268 if (symhdr->count == 0) \
1269 symhdr->offset = 0; \
1270 else \
1271 { \
1272 symhdr->offset = where; \
1273 where += symhdr->count * size; \
1274 }
1275
1276 SET (cbLineOffset, cbLine, sizeof (unsigned char));
1277 SET (cbDnOffset, idnMax, swap->external_dnr_size);
1278 SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1279 SET (cbSymOffset, isymMax, swap->external_sym_size);
1280 SET (cbOptOffset, ioptMax, swap->external_opt_size);
1281 SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1282 SET (cbSsOffset, issMax, sizeof (char));
1283 SET (cbSsExtOffset, issExtMax, sizeof (char));
1284 SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1285 SET (cbRfdOffset, crfd, swap->external_rfd_size);
1286 SET (cbExtOffset, iextMax, swap->external_ext_size);
1287#undef SET
1288
1289 buff = (PTR) alloca (swap->external_hdr_size);
1290 (*swap->swap_hdr_out) (abfd, symhdr, buff);
1291 if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
1292 != swap->external_hdr_size)
1293 return false;
1294
cf286547
ILT
1295 return true;
1296}
1297
1298/* Write out the ECOFF debugging information. This function assumes
1299 that the information (the pointers and counts) in *DEBUG have been
1300 set correctly. WHERE is the position in the file to write the
1301 information to. This function fills in the file offsets in the
1302 symbolic header. */
1303
1304boolean
1305bfd_ecoff_write_debug (abfd, debug, swap, where)
1306 bfd *abfd;
1307 struct ecoff_debug_info *debug;
1308 const struct ecoff_debug_swap *swap;
1309 file_ptr where;
1310{
1311 HDRR * const symhdr = &debug->symbolic_header;
1312
1313 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1314 return false;
1315
71efdf83
ILT
1316#define WRITE(ptr, count, size, offset) \
1317 BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
966e0a16 1318 if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
71efdf83
ILT
1319 != size * symhdr->count) \
1320 return false;
1321
1322 WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1323 WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1324 WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1325 WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1326 WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1327 WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
1328 WRITE (ss, issMax, sizeof (char), cbSsOffset);
1329 WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1330 WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1331 WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1332 WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1333#undef WRITE
1334
1335 return true;
1336}
cf286547
ILT
1337
1338/* Write out a shuffle list. */
1339
1340static boolean ecoff_write_shuffle PARAMS ((bfd *,
1341 const struct ecoff_debug_swap *,
1342 struct shuffle *, PTR space));
1343
1344static boolean
1345ecoff_write_shuffle (abfd, swap, shuffle, space)
1346 bfd *abfd;
1347 const struct ecoff_debug_swap *swap;
1348 struct shuffle *shuffle;
1349 PTR space;
1350{
1351 register struct shuffle *l;
1352 unsigned long total;
1353
1354 total = 0;
1355 for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
1356 {
1357 if (! l->filep)
1358 {
1359 if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
1360 return false;
1361 }
1362 else
1363 {
1364 if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1365 || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
1366 || bfd_write (space, 1, l->size, abfd) != l->size)
1367 return false;
1368 }
1369 total += l->size;
1370 }
1371
1372 if ((total & (swap->debug_align - 1)) != 0)
1373 {
1374 int i;
1375 bfd_byte *s;
1376
1377 i = swap->debug_align - (total & (swap->debug_align - 1));
1378 s = (bfd_byte *) alloca (i);
1379 memset (s, 0, i);
1380 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1381 return false;
1382 }
1383
1384 return true;
1385}
1386
1387/* Write out debugging information using accumulated linker
1388 information. */
1389
1390boolean
1391bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
1392 PTR handle;
1393 bfd *abfd;
1394 struct ecoff_debug_info *debug;
1395 const struct ecoff_debug_swap *swap;
1396 struct bfd_link_info *info;
1397 file_ptr where;
1398{
1399 struct accumulate *ainfo = (struct accumulate *) handle;
1400 PTR space;
cf286547
ILT
1401
1402 if (! ecoff_write_symhdr (abfd, debug, swap, where))
1403 return false;
1404
1405 space = (PTR) alloca (ainfo->largest_file_shuffle);
1406
1407 if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1408 || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1409 || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1410 || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1411 || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1412 return false;
1413
1414 /* The string table is written out from the hash table if this is a
1415 final link. */
1416 if (info->relocateable)
1417 {
1418 BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1419 if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1420 return false;
1421 }
1422 else
1423 {
1424 unsigned long total;
1425 bfd_byte null;
1426 struct string_hash_entry *sh;
1427
1428 BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
1429 null = 0;
1430 if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
1431 return false;
1432 total = 1;
1433 BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1434 for (sh = ainfo->ss_hash;
1435 sh != (struct string_hash_entry *) NULL;
1436 sh = sh->next)
1437 {
1438 size_t len;
1439
1440 len = strlen (sh->root.string);
1441 if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
1442 return false;
1443 total += len + 1;
1444 }
1445
1446 if ((total & (swap->debug_align - 1)) != 0)
1447 {
1448 int i;
1449 bfd_byte *s;
1450
1451 i = swap->debug_align - (total & (swap->debug_align - 1));
1452 s = (bfd_byte *) alloca (i);
1453 memset (s, 0, i);
1454 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1455 return false;
1456 }
1457 }
1458
1459 /* The external strings and symbol are not converted over to using
1460 shuffles. FIXME: They probably should be. */
1461 if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
1462 != debug->symbolic_header.issExtMax)
1463 return false;
1464 if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1465 {
1466 int i;
1467 bfd_byte *s;
1468
1469 i = (swap->debug_align
1470 - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1471 s = (bfd_byte *) alloca (i);
1472 memset (s, 0, i);
1473 if (bfd_write ((PTR) s, 1, i, abfd) != i)
1474 return false;
1475 }
1476
1477 if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1478 || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1479 return false;
1480
1481 BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1482 || debug->symbolic_header.cbExtOffset == bfd_tell (abfd));
1483
1484 if (bfd_write (debug->external_ext, swap->external_ext_size,
1485 debug->symbolic_header.iextMax, abfd)
1486 != debug->symbolic_header.iextMax * swap->external_ext_size)
1487 return false;
1488
1489 return true;
1490}
This page took 0.091649 seconds and 4 git commands to generate.