* aoutx.h, archive.c: Add casts to avoid warnings from SVR4 cc.
[external/binutils.git] / bfd / ecofflink.c
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
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "bfdlink.h"
24 #include "libbfd.h"
25 #include "obstack.h"
26 #include "coff/internal.h"
27 #include "coff/sym.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 \f
31 static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
32                                         size_t need));
33 static struct bfd_hash_entry *string_hash_newfunc
34   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
35            const char *));
36 static void ecoff_align_debug PARAMS ((bfd *abfd,
37                                        struct ecoff_debug_info *debug,
38                                        const struct ecoff_debug_swap *swap));
39 static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *,
40                                            const struct ecoff_debug_swap *,
41                                            file_ptr where));
42
43 /* Obstack allocation and deallocation routines.  */
44 #define obstack_chunk_alloc malloc
45 #define obstack_chunk_free free
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
52 static boolean
53 ecoff_add_bytes (buf, bufend, need)
54      char **buf;
55      char **bufend;
56      size_t need;
57 {
58   size_t have;
59   size_t want;
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_set_error (bfd_error_no_memory);
78       return false;
79     }
80   *buf = newbuf;
81   *bufend = *buf + have + want;
82   return true;
83 }
84
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
89 struct 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
98 struct string_hash_table
99 {
100   struct bfd_hash_table table;
101 };
102
103 /* Routine to create an entry in a string hash table.  */
104
105 static struct bfd_hash_entry *
106 string_hash_newfunc (entry, table, string)
107      struct bfd_hash_entry *entry;
108      struct bfd_hash_table *table;
109      const char *string;
110 {
111   struct string_hash_entry *ret = (struct string_hash_entry *) entry;
112
113   /* Allocate the structure if it has not already been allocated by a
114      subclass.  */
115   if (ret == (struct string_hash_entry *) NULL)
116     ret = ((struct string_hash_entry *)
117            bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
118   if (ret == (struct string_hash_entry *) NULL)
119     {
120       bfd_set_error (bfd_error_no_memory);
121       return NULL;
122     }
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
128   if (ret)
129     {
130       /* Initialize the local fields.  */
131       ret->val = -1;
132       ret->next = NULL;
133     }
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
148 struct 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
173 struct 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
208 static boolean add_file_shuffle PARAMS ((struct accumulate *,
209                                       struct shuffle **,
210                                       struct shuffle **, bfd *, file_ptr,
211                                       unsigned long));
212
213 static boolean
214 add_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;
233       return true;
234     }
235
236   n = (struct shuffle *) obstack_alloc (&ainfo->memory,
237                                         sizeof (struct shuffle));
238   if (!n)
239     {
240       bfd_set_error (bfd_error_no_memory);
241       return false;
242     }
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;
255   return true;
256 }
257
258 /* Add a memory entry to a shuffle list.  */
259
260 static boolean add_memory_shuffle PARAMS ((struct accumulate *,
261                                            struct shuffle **head,
262                                            struct shuffle **tail,
263                                            bfd_byte *data, unsigned long size));
264
265 static boolean
266 add_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));
277   if (!n)
278     {
279       bfd_set_error (bfd_error_no_memory);
280       return false;
281     }
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;
291   return true;
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*/
298 PTR
299 bfd_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
307   ainfo = (struct accumulate *) malloc (sizeof (struct accumulate));
308   if (!ainfo)
309     {
310       bfd_set_error (bfd_error_no_memory);
311       return NULL;
312     }
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
347   if (!obstack_begin (&ainfo->memory, 4050))
348     {
349       bfd_set_error (bfd_error_no_memory);
350       return NULL;
351     }
352
353   return (PTR) ainfo;
354 }
355
356 /* Free the accumulated debugging information.  */
357
358 /*ARGSUSED*/
359 void
360 bfd_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
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
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.  */
386
387 /*ARGSUSED*/
388 boolean
389 bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
390                             input_bfd, input_debug, input_swap,
391                             info)
392      PTR handle;
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;
399      struct bfd_link_info *info;
400 {
401   struct accumulate *ainfo = (struct accumulate *) handle;
402   void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
403     = input_swap->swap_sym_in;
404   void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
405     = input_swap->swap_rfd_in;
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;
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;
419   bfd_vma section_adjust[scMax];
420   asection *sec;
421   bfd_byte *fdr_start;
422   bfd_byte *fdr_ptr;
423   bfd_byte *fdr_end;
424   bfd_size_type fdr_add;
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;
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
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)
462     {
463       fdr_start = (bfd_byte *) input_debug->fdr;
464       fdr_add = sizeof (FDR);
465     }
466   else
467     {
468       fdr_start = (bfd_byte *) input_debug->external_fdr;
469       fdr_add = input_swap->external_fdr_size;
470     }
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);
479   if (!input_debug->ifdmap || !rfd_out)
480     {
481       bfd_set_error (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;
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)
500     {
501       FDR fdr;
502
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)
510         {
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;
528
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);
534
535               /* Don't copy this FDR.  */
536               continue;
537             }
538
539           fh->val = output_symhdr->ifdMax + copied;
540         }
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;
545     }
546
547   newrfdbase = output_symhdr->crfd;
548   output_symhdr->crfd += input_symhdr->ifdMax;
549
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)
558     {
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;
566     }
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);
575   if (!fdr_out)
576     {
577       bfd_set_error (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;
582   for (fdr_ptr = fdr_start, i = 0;
583        fdr_ptr < fdr_end;
584        fdr_ptr += fdr_add, i++)
585     {
586       FDR fdr;
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         }
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
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);
613       if (!sym_out)
614         {
615           bfd_set_error (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;
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         }
701
702       fdr.isymBase = output_symhdr->isymMax;
703       output_symhdr->isymMax += fdr.csym;
704
705       /* Copy the information that does not need swapping.  */
706       if (fdr.cbLine > 0)
707         {
708           if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
709                             input_bfd,
710                             input_symhdr->cbLineOffset + fdr.cbLineOffset,
711                             fdr.cbLine))
712             return false;
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         {
720           if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
721                             input_bfd,
722                             (input_symhdr->cbAuxOffset
723                              + fdr.iauxBase * sizeof (union aux_ext)),
724                             fdr.caux * sizeof (union aux_ext)))
725             return false;
726           fdr.iauxBase = output_symhdr->iauxMax;
727           output_symhdr->iauxMax += fdr.caux;
728         }
729       if (! info->relocateable)
730         {
731
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         {
741           if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
742                             input_bfd,
743                             input_symhdr->cbSsOffset + fdr.issBase,
744                             fdr.cbSs))
745             return false;
746           fdr.issBase = output_symhdr->issMax;
747           output_symhdr->issMax += fdr.cbSs;
748         }
749
750       if (output_bfd->xvec->header_byteorder_big_p
751           == input_bfd->xvec->header_byteorder_big_p)
752         {
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)
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             }
765           BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
766           if (fdr.copt > 0)
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             }
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);
793           if (!out)
794             {
795               bfd_set_error (bfd_error_no_memory);
796               return false;
797             }
798           if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, sz))
799             return false;
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);
816           if (!out)
817             {
818               bfd_set_error (bfd_error_no_memory);
819               return false;
820             }
821           if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, sz))
822             return false;
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;
836
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;
847         }
848
849       (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
850       fdr_out += external_fdr_size;
851       ++output_symhdr->ifdMax;
852     }
853
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
860 static long ecoff_add_string PARAMS ((struct accumulate *,
861                                       struct bfd_link_info *,
862                                       struct ecoff_debug_info *,
863                                       FDR *fdr, const char *string));
864
865 static long
866 ecoff_add_string (ainfo, info, debug, fdr, string)
867      struct accumulate *ainfo;
868      struct bfd_link_info *info;
869      struct ecoff_debug_info *debug;
870      FDR *fdr;
871      const char *string;
872 {
873   HDRR *symhdr;
874   size_t len;
875   bfd_size_type ret;
876
877   symhdr = &debug->symbolic_header;
878   len = strlen (string);
879   if (info->relocateable)
880     {
881       if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
882                                len + 1))
883         return -1;
884       ret = symhdr->issMax;
885       symhdr->issMax += len + 1;
886       fdr->cbSs += len + 1;
887     }
888   else
889     {
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)
894         return -1;
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;
907     }
908
909   return ret;
910 }
911
912 /* Add debugging information from a non-ECOFF file.  */
913
914 boolean
915 bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
916                                   output_swap, input_bfd, info)
917      PTR handle;
918      bfd *output_bfd;
919      struct ecoff_debug_info *output_debug;
920      const struct ecoff_debug_swap *output_swap;
921      bfd *input_bfd;
922      struct bfd_link_info *info;
923 {
924   struct accumulate *ainfo = (struct accumulate *) handle;
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;
933   PTR external_fdr;
934
935   memset ((PTR) &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;
948   fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
949                               bfd_get_filename (input_bfd));
950   if (fdr.rss == -1)
951     return false;
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_set_error (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;
970       PTR external_sym;
971
972       if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
973         continue;
974       memset ((PTR) &internal_sym, 0, sizeof internal_sym);
975       internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
976                                            (*sym_ptr)->name);
977
978       if (internal_sym.iss == -1)
979         return false;
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
991       external_sym = (PTR) obstack_alloc (&ainfo->memory,
992                                           output_swap->external_sym_size);
993       if (!external_sym)
994         {
995           bfd_set_error (bfd_error_no_memory);
996           return false;
997         }
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);
1001       ++fdr.csym;
1002       ++output_symhdr->isymMax;
1003     }
1004
1005   bfd_release (output_bfd, (PTR) symbols);
1006
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.  */
1011   external_fdr = (PTR) obstack_alloc (&ainfo->memory,
1012                                       output_swap->external_fdr_size);
1013   if (!external_fdr)
1014     {
1015       bfd_set_error (bfd_error_no_memory);
1016       return false;
1017     }
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
1022   ++output_symhdr->ifdMax;
1023
1024   return true;
1025 }
1026
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.  */
1031
1032 boolean
1033 bfd_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 {
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
1071       if (bfd_is_com_section (sym_ptr->section)
1072           || sym_ptr->section == &bfd_und_section)
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         }
1082       else
1083         esym.asym.value = (sym_ptr->value
1084                            + sym_ptr->section->output_offset
1085                            + sym_ptr->section->output_section->vma);
1086
1087       if (set_index)
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     }
1094
1095   return true;
1096 }
1097
1098 /* Add a single external symbol to the debugging information.  */
1099
1100 boolean
1101 bfd_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;
1133     }
1134
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
1146   return true;
1147 }
1148
1149 /* Align the ECOFF debugging information.  */
1150
1151 /*ARGSUSED*/
1152 static void
1153 ecoff_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;
1159   bfd_size_type debug_align, aux_align, rfd_align;
1160   size_t add;
1161
1162   /* Adjust the counts so that structures are aligned.  */
1163   debug_align = swap->debug_align;
1164   aux_align = debug_align / sizeof (union aux_ext);
1165   rfd_align = debug_align / swap->external_rfd_size;
1166
1167   add = debug_align - (symhdr->cbLine & (debug_align - 1));
1168   if (add != debug_align)
1169     {
1170       if (debug->line != (unsigned char *) NULL)
1171         memset ((PTR) (debug->line + symhdr->cbLine), 0, add);
1172       symhdr->cbLine += add;
1173     }
1174
1175   add = debug_align - (symhdr->issMax & (debug_align - 1));
1176   if (add != debug_align)
1177     {
1178       if (debug->ss != (char *) NULL)
1179         memset ((PTR) (debug->ss + symhdr->issMax), 0, add);
1180       symhdr->issMax += add;
1181     }
1182
1183   add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1184   if (add != debug_align)
1185     {
1186       if (debug->ssext != (char *) NULL)
1187         memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);
1188       symhdr->issExtMax += add;
1189     }
1190
1191   add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1192   if (add != aux_align)
1193     {
1194       if (debug->external_aux != (union aux_ext *) NULL)
1195         memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,
1196                 add * sizeof (union aux_ext));
1197       symhdr->iauxMax += add;
1198     }
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 ((PTR) ((char *) debug->external_rfd
1205                        + symhdr->crfd * swap->external_rfd_size),
1206                 0, add * swap->external_rfd_size);
1207       symhdr->crfd += add;
1208     }
1209 }
1210
1211 /* Return the size required by the ECOFF debugging information.  */
1212
1213 bfd_size_type
1214 bfd_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
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.  */
1247
1248 static boolean
1249 ecoff_write_symhdr (abfd, debug, swap, where)
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   symhdr->magic = swap->sym_magic;
1267
1268   /* Fill in the file offsets.  */
1269 #define SET(offset, count, size) \
1270   if (symhdr->count == 0) \
1271     symhdr->offset = 0; \
1272   else \
1273     { \
1274       symhdr->offset = where; \
1275       where += symhdr->count * size; \
1276     }
1277
1278   SET (cbLineOffset, cbLine, sizeof (unsigned char));
1279   SET (cbDnOffset, idnMax, swap->external_dnr_size);
1280   SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1281   SET (cbSymOffset, isymMax, swap->external_sym_size);
1282   SET (cbOptOffset, ioptMax, swap->external_opt_size);
1283   SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1284   SET (cbSsOffset, issMax, sizeof (char));
1285   SET (cbSsExtOffset, issExtMax, sizeof (char));
1286   SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1287   SET (cbRfdOffset, crfd, swap->external_rfd_size);
1288   SET (cbExtOffset, iextMax, swap->external_ext_size);
1289 #undef SET
1290
1291   buff = (PTR) alloca (swap->external_hdr_size);
1292   (*swap->swap_hdr_out) (abfd, symhdr, buff);
1293   if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
1294       != swap->external_hdr_size)
1295     return false;
1296
1297   return true;
1298 }
1299
1300 /* Write out the ECOFF debugging information.  This function assumes
1301    that the information (the pointers and counts) in *DEBUG have been
1302    set correctly.  WHERE is the position in the file to write the
1303    information to.  This function fills in the file offsets in the
1304    symbolic header.  */
1305
1306 boolean
1307 bfd_ecoff_write_debug (abfd, debug, swap, where)
1308      bfd *abfd;
1309      struct ecoff_debug_info *debug;
1310      const struct ecoff_debug_swap *swap;
1311      file_ptr where;
1312 {
1313   HDRR * const symhdr = &debug->symbolic_header;
1314
1315   if (! ecoff_write_symhdr (abfd, debug, swap, where))
1316     return false;
1317
1318 #define WRITE(ptr, count, size, offset) \
1319   BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
1320   if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
1321       != size * symhdr->count) \
1322     return false;
1323
1324   WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1325   WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1326   WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1327   WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1328   WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1329   WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
1330   WRITE (ss, issMax, sizeof (char), cbSsOffset);
1331   WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1332   WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1333   WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1334   WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1335 #undef WRITE
1336
1337   return true;
1338 }
1339
1340 /* Write out a shuffle list.  */
1341
1342 static boolean ecoff_write_shuffle PARAMS ((bfd *,
1343                                             const struct ecoff_debug_swap *,
1344                                             struct shuffle *, PTR space));
1345
1346 static boolean
1347 ecoff_write_shuffle (abfd, swap, shuffle, space)
1348      bfd *abfd;
1349      const struct ecoff_debug_swap *swap;
1350      struct shuffle *shuffle;
1351      PTR space;
1352 {
1353   register struct shuffle *l;
1354   unsigned long total;
1355
1356   total = 0;
1357   for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
1358     {
1359       if (! l->filep)
1360         {
1361           if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
1362             return false;
1363         }
1364       else
1365         {
1366           if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1367               || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
1368               || bfd_write (space, 1, l->size, abfd) != l->size)
1369             return false;
1370         }
1371       total += l->size;
1372     }
1373
1374   if ((total & (swap->debug_align - 1)) != 0)
1375     {
1376       int i;
1377       bfd_byte *s;
1378
1379       i = swap->debug_align - (total & (swap->debug_align - 1));
1380       s = (bfd_byte *) alloca (i);
1381       memset ((PTR) s, 0, i);
1382       if (bfd_write ((PTR) s, 1, i, abfd) != i)
1383         return false;
1384     }
1385
1386   return true;
1387 }
1388
1389 /* Write out debugging information using accumulated linker
1390    information.  */
1391
1392 boolean
1393 bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
1394      PTR handle;
1395      bfd *abfd;
1396      struct ecoff_debug_info *debug;
1397      const struct ecoff_debug_swap *swap;
1398      struct bfd_link_info *info;
1399      file_ptr where;
1400 {
1401   struct accumulate *ainfo = (struct accumulate *) handle;
1402   PTR space;
1403
1404   if (! ecoff_write_symhdr (abfd, debug, swap, where))
1405     return false;
1406
1407   space = (PTR) alloca (ainfo->largest_file_shuffle);
1408
1409   if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1410       || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1411       || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1412       || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1413       || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1414     return false;
1415
1416   /* The string table is written out from the hash table if this is a
1417      final link.  */
1418   if (info->relocateable)
1419     {
1420       BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1421       if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1422         return false;
1423     }
1424   else
1425     {
1426       unsigned long total;
1427       bfd_byte null;
1428       struct string_hash_entry *sh;
1429
1430       BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
1431       null = 0;
1432       if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
1433         return false;
1434       total = 1;
1435       BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1436       for (sh = ainfo->ss_hash;
1437            sh != (struct string_hash_entry *) NULL;
1438            sh = sh->next)
1439         {
1440           size_t len;
1441
1442           len = strlen (sh->root.string);
1443           if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
1444             return false;
1445           total += len + 1;
1446         }
1447
1448       if ((total & (swap->debug_align - 1)) != 0)
1449         {
1450           int i;
1451           bfd_byte *s;
1452
1453           i = swap->debug_align - (total & (swap->debug_align - 1));
1454           s = (bfd_byte *) alloca (i);
1455           memset ((PTR) s, 0, i);
1456           if (bfd_write ((PTR) s, 1, i, abfd) != i)
1457             return false;
1458         }
1459     }
1460
1461   /* The external strings and symbol are not converted over to using
1462      shuffles.  FIXME: They probably should be.  */
1463   if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
1464       != debug->symbolic_header.issExtMax)
1465     return false;
1466   if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1467     {
1468       int i;
1469       bfd_byte *s;
1470
1471       i = (swap->debug_align
1472            - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1473       s = (bfd_byte *) alloca (i);
1474       memset ((PTR) s, 0, i);
1475       if (bfd_write ((PTR) s, 1, i, abfd) != i)
1476         return false;
1477     }
1478
1479   if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1480       || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1481     return false;
1482
1483   BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1484               || debug->symbolic_header.cbExtOffset == bfd_tell (abfd));
1485
1486   if (bfd_write (debug->external_ext, swap->external_ext_size,
1487                  debug->symbolic_header.iextMax, abfd)
1488       != debug->symbolic_header.iextMax * swap->external_ext_size)
1489     return false;
1490
1491   return true;
1492 }