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