8882bac555fa357be876f611b38418f13ce87754
[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 "libbfd.h"
24 #include "coff/internal.h"
25 #include "coff/sym.h"
26 #include "coff/symconst.h"
27 #include "coff/ecoff.h"
28 \f
29 static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
30                                         bfd_size_type need));
31 static bfd_size_type ecoff_add_string PARAMS ((struct ecoff_debug_info *,
32                                                FDR *fdr, const char *string));
33 static void ecoff_align_debug PARAMS ((bfd *abfd,
34                                        struct ecoff_debug_info *debug,
35                                        const struct ecoff_debug_swap *swap));
36 \f
37 /* The minimum amount of data to allocate.  */
38 #define ALLOC_SIZE (4064)
39
40 /* Add bytes to a buffer.  Return success.  */
41
42 static boolean
43 ecoff_add_bytes (buf, bufend, need)
44      char **buf;
45      char **bufend;
46      bfd_size_type need;
47 {
48   bfd_size_type have;
49   bfd_size_type want;
50   char *newbuf;
51
52   have = *bufend - *buf;
53   if (have > need)
54     want = ALLOC_SIZE;
55   else
56     {
57       want = need - have;
58       if (want < ALLOC_SIZE)
59         want = ALLOC_SIZE;
60     }
61   if (*buf == NULL)
62     newbuf = (char *) malloc (have + want);
63   else
64     newbuf = (char *) realloc (*buf, have + want);
65   if (newbuf == NULL)
66     {
67       bfd_error = no_memory;
68       return false;
69     }
70   *buf = newbuf;
71   *bufend = *buf + have + want;
72   return true;
73 }
74
75 /* Accumulate the debugging information from INPUT_BFD into
76    OUTPUT_BFD.  The INPUT_DEBUG argument points to some ECOFF
77    debugging information which we want to link into the information
78    pointed to by the OUTPUT_DEBUG argument.  OUTPUT_SWAP and
79    INPUT_SWAP point to the swapping information needed.  */
80
81 boolean
82 bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
83                             input_bfd, input_debug, input_swap,
84                             relocateable)
85      bfd *output_bfd;
86      struct ecoff_debug_info *output_debug;
87      const struct ecoff_debug_swap *output_swap;
88      bfd *input_bfd;
89      struct ecoff_debug_info *input_debug;
90      const struct ecoff_debug_swap *input_swap;
91      boolean relocateable;
92 {
93   void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
94     = input_swap->swap_sym_in;
95   void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
96     = output_swap->swap_sym_out;
97   void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
98     = output_swap->swap_fdr_out;
99   void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
100     = output_swap->swap_rfd_out;
101   HDRR *output_symhdr;
102   HDRR *input_symhdr;
103   bfd_vma section_adjust[scMax];
104   asection *sec;
105   char *sym_out;
106   char *lraw_src;
107   char *lraw_end;
108   char *fdr_ptr;
109   char *fdr_end;
110   bfd_size_type fdr_add;
111   char *fdr_out;
112
113   output_symhdr = &output_debug->symbolic_header;
114   input_symhdr = &input_debug->symbolic_header;
115
116   /* Make sure the buffers are large enough.  */
117 #define CHECK(start, end, count, size)                          \
118   if ((char *) output_debug->end - (char *) output_debug->start \
119       < (output_symhdr->count + input_symhdr->count) * size)    \
120     {                                                           \
121       if (! ecoff_add_bytes ((char **) &output_debug->start,    \
122                              (char **) &output_debug->end,      \
123                              ((output_symhdr->count             \
124                                + input_symhdr->count)           \
125                               * size)))                         \
126         return false;                                           \
127     }
128
129   CHECK (line, line_end, cbLine, sizeof (unsigned char));
130 #if 0
131   /* I don't think dense number information is needed.  */
132   CHECK (external_dnr, external_dnr_end, idnMax,
133          output_swap->external_dnr_size);
134 #endif
135   CHECK (external_pdr, external_pdr_end, ipdMax,
136          output_swap->external_pdr_size);
137   CHECK (external_sym, external_sym_end, isymMax,
138          output_swap->external_sym_size);
139   CHECK (external_opt, external_opt_end, ioptMax,
140          output_swap->external_opt_size);
141   CHECK (external_aux, external_aux_end, iauxMax,
142          sizeof (union aux_ext));
143   CHECK (ss, ss_end, issMax, sizeof (char));
144   CHECK (external_fdr, external_fdr_end, ifdMax,
145          output_swap->external_fdr_size);
146
147   /* The RFD's are special, since we create them if needed.  */
148   {
149     bfd_size_type crfd;
150
151     crfd = input_symhdr->crfd;
152     if (input_symhdr->crfd == 0)
153       input_symhdr->crfd = input_symhdr->ifdMax;
154     CHECK (external_rfd, external_rfd_end, crfd,
155            output_swap->external_rfd_size);
156     input_symhdr->crfd = crfd;
157   }
158
159 #undef CHECK
160
161   /* Use section_adjust to hold the value to add to a symbol in a
162      particular section.  */
163   memset ((PTR) section_adjust, 0, sizeof section_adjust);
164
165 #define SET(name, indx) \
166   sec = bfd_get_section_by_name (input_bfd, name); \
167   if (sec != NULL) \
168     section_adjust[indx] = (sec->output_section->vma \
169                             + sec->output_offset \
170                             - sec->vma);
171
172   SET (".text", scText);
173   SET (".data", scData);
174   SET (".bss", scBss);
175   SET (".sdata", scSData);
176   SET (".sbss", scSBss);
177   /* scRdata section may be either .rdata or .rodata.  */
178   SET (".rdata", scRData);
179   SET (".rodata", scRData);
180   SET (".init", scInit);
181   SET (".fini", scFini);
182
183 #undef SET
184
185   /* Swap in the local symbols, adjust their values, and swap them out
186      again.  The external symbols are handled separately.  */
187   sym_out = ((char *) output_debug->external_sym
188              + output_symhdr->isymMax * output_swap->external_sym_size);
189   lraw_src = (char *) input_debug->external_sym;
190   lraw_end = lraw_src + input_symhdr->isymMax * input_swap->external_sym_size;
191   for (;  lraw_src < lraw_end;  lraw_src += input_swap->external_sym_size)
192     {
193       SYMR internal_sym;
194
195       (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
196
197       BFD_ASSERT (internal_sym.sc != scCommon
198                   && internal_sym.sc != scSCommon);
199
200       /* Adjust the symbol value if appropriate.  */
201       switch (internal_sym.st)
202         {
203         case stNil:
204           if (ECOFF_IS_STAB (&internal_sym))
205             break;
206           /* Fall through.  */
207         case stGlobal:
208         case stStatic:
209         case stLabel:
210         case stProc:
211         case stStaticProc:
212           internal_sym.value += section_adjust[internal_sym.sc];
213           break;
214
215         default:
216           break;
217         }
218
219       (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
220       sym_out += output_swap->external_sym_size;
221     }
222
223   /* Copy the information that does not need swapping.  */
224   memcpy (output_debug->line + output_symhdr->cbLine,
225           input_debug->line,
226           input_symhdr->cbLine * sizeof (unsigned char));
227   memcpy (output_debug->external_aux + output_symhdr->iauxMax,
228           input_debug->external_aux,
229           input_symhdr->iauxMax * sizeof (union aux_ext));
230   memcpy (output_debug->ss + output_symhdr->issMax,
231           input_debug->ss,
232           input_symhdr->issMax * sizeof (char));
233
234   /* Some of the information may need to be swapped.  */
235   if (output_bfd->xvec->header_byteorder_big_p
236       == input_bfd->xvec->header_byteorder_big_p)
237     {
238       /* The two BFD's have the same endianness, so memcpy will
239          suffice.  */
240 #if 0
241       /* I don't think dense number information is needed.  */
242       BFD_ASSERT (output_swap->external_dnr_size
243                   == input_swap->external_dnr_size);
244       if (input_symhdr->idnMax > 0)
245         memcpy (((char *) output_debug->external_dnr
246                  + output_symhdr->idnMax * output_swap->external_dnr_size),
247                 input_debug->external_dnr,
248                 input_symhdr->idnMax * output_swap->external_dnr_size);
249 #endif
250       BFD_ASSERT (output_swap->external_pdr_size
251                   == input_swap->external_pdr_size);
252       if (input_symhdr->ipdMax > 0)
253         memcpy (((char *) output_debug->external_pdr
254                  + output_symhdr->ipdMax * output_swap->external_pdr_size),
255                 input_debug->external_pdr,
256                 input_symhdr->ipdMax * output_swap->external_pdr_size);
257       BFD_ASSERT (output_swap->external_opt_size
258                   == input_swap->external_opt_size);
259       if (input_symhdr->ioptMax > 0)
260         memcpy (((char *) output_debug->external_opt
261                  + output_symhdr->ioptMax * output_swap->external_opt_size),
262                 input_debug->external_opt,
263                 input_symhdr->ioptMax * output_swap->external_opt_size);
264     }
265   else
266     {
267       bfd_size_type outsz, insz;
268       char *in;
269       char *end;
270       char *out;
271
272       /* The two BFD's have different endianness, so we must swap
273          everything in and out.  This code would always work, but it
274          would be slow in the normal case.  */
275 #if 0
276       /* I don't think dense number information is needed.  */
277       outsz = output_swap->external_dnr_size;
278       insz = input_swap->external_dnr_size;
279       in = (char *) input_debug->external_dnr;
280       end = in + input_symhdr->idnMax * insz;
281       out = ((char *) output_debug->external_dnr
282              + output_symhdr->idnMax * outsz);
283       for (; in < end; in += insz, out += outsz)
284         {
285           DNR dnr;
286
287           (*input_swap->swap_dnr_in) (input_bfd, in, &dnr);
288           (*output_swap->swap_dnr_out) (output_bfd, &dnr, out);
289         }
290 #endif
291
292       outsz = output_swap->external_pdr_size;
293       insz = input_swap->external_pdr_size;
294       in = (char *) input_debug->external_pdr;
295       end = in + input_symhdr->ipdMax * insz;
296       out = ((char *) output_debug->external_pdr
297              + output_symhdr->ipdMax * outsz);
298       for (; in < end; in += insz, out += outsz)
299         {
300           PDR pdr;
301
302           (*input_swap->swap_pdr_in) (input_bfd, in, &pdr);
303           (*output_swap->swap_pdr_out) (output_bfd, &pdr, out);
304         }
305
306       outsz = output_swap->external_opt_size;
307       insz = input_swap->external_opt_size;
308       in = (char *) input_debug->external_opt;
309       end = in + input_symhdr->ioptMax * insz;
310       out = ((char *) output_debug->external_opt
311              + output_symhdr->ioptMax * outsz);
312       for (; in < end; in += insz, out += outsz)
313         {
314           OPTR opt;
315
316           (*input_swap->swap_opt_in) (input_bfd, in, &opt);
317           (*output_swap->swap_opt_out) (output_bfd, &opt, out);
318         }
319     }
320
321   /* Set ifdbase so that the external symbols know how to adjust their
322      ifd values.  */
323   input_debug->ifdbase = output_symhdr->ifdMax;
324
325   /* We need to handle the FDR's whether they are swapped or not.  */
326   if (input_debug->fdr != (FDR *) NULL)
327     {
328       fdr_ptr = (char *) input_debug->fdr;
329       fdr_add = sizeof (FDR);
330     }
331   else
332     {
333       fdr_ptr = (char *) input_debug->external_fdr;
334       fdr_add = input_swap->external_fdr_size;
335     }
336   fdr_end = fdr_ptr + input_symhdr->ifdMax * fdr_add;
337   fdr_out = ((char *) output_debug->external_fdr
338              + output_symhdr->ifdMax * output_swap->external_fdr_size);
339   for (;
340        fdr_ptr < fdr_end;
341        fdr_ptr += fdr_add, fdr_out += output_swap->external_fdr_size)
342     {
343       FDR fdr;
344
345       if (input_debug->fdr != (FDR *) NULL)
346         fdr = *(FDR *) fdr_ptr;
347       else
348         (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
349
350       /* FIXME: It is conceivable that this FDR points to the .init or
351          .fini section, in which case this will not do the right
352          thing.  */
353       fdr.adr += section_adjust[scText];
354
355       fdr.issBase += output_symhdr->issMax;
356       fdr.isymBase += output_symhdr->isymMax;
357       fdr.ilineBase += output_symhdr->ilineMax;
358       fdr.ioptBase += output_symhdr->ioptMax;
359       fdr.ipdFirst += output_symhdr->ipdMax;
360       fdr.iauxBase += output_symhdr->iauxMax;
361       fdr.rfdBase += output_symhdr->crfd;
362
363       /* If there are no RFD's, we are going to add some.  We don't
364          want to adjust crfd for this, so that all the FDR's can share
365          the RFD's.  */
366       if (input_symhdr->crfd == 0)
367         fdr.crfd = input_symhdr->ifdMax;
368
369       if (fdr.cbLine != 0)
370         fdr.cbLineOffset += output_symhdr->cbLine;
371
372       (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
373     }
374
375   if (input_symhdr->crfd > 0)
376     {
377       void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
378         = input_swap->swap_rfd_in;
379       bfd_size_type outsz, insz;
380       char *rfd_in;
381       char *rfd_end;
382       char *rfd_out;
383
384       /* Swap and adjust the RFD's.  RFD's are only created by the
385          linker, so this will only be necessary if one of the input
386          files is the result of a partial link.  Presumably all
387          necessary RFD's are present.  */
388       outsz = output_swap->external_rfd_size;
389       insz = input_swap->external_rfd_size;
390       rfd_in = (char *) input_debug->external_rfd;
391       rfd_end = rfd_in + input_symhdr->crfd * insz;
392       rfd_out = ((char *) output_debug->external_rfd
393                  + output_symhdr->crfd * outsz);
394       for (;
395            rfd_in < rfd_end;
396            rfd_in += insz, rfd_out += outsz)
397         {
398           RFDT rfd;
399
400           (*swap_rfd_in) (input_bfd, rfd_in, &rfd);
401           rfd += output_symhdr->ifdMax;
402           (*swap_rfd_out) (output_bfd, &rfd, rfd_out);
403         }
404       output_symhdr->crfd += input_symhdr->crfd;
405     }
406   else
407     {
408       bfd_size_type outsz;
409       char *rfd_out;
410       char *rfd_end;
411       RFDT rfd;
412
413       /* Create RFD's.  Some of the debugging information includes
414          relative file indices.  These indices are taken as indices to
415          the RFD table if there is one, or to the global table if
416          there is not.  If we did not create RFD's, we would have to
417          parse and adjust all the debugging information which contains
418          file indices.  */
419       outsz = output_swap->external_rfd_size;
420       rfd = output_symhdr->ifdMax;
421       rfd_out = ((char *) output_debug->external_rfd
422                  + output_symhdr->crfd * outsz);
423       rfd_end = (rfd_out + input_symhdr->ifdMax * outsz);
424       for (; rfd_out < rfd_end; rfd_out += outsz, rfd++)
425         (*swap_rfd_out) (output_bfd, &rfd, rfd_out);
426       output_symhdr->crfd += input_symhdr->ifdMax;
427     }
428
429   /* Update the counts.  */
430   output_symhdr->ilineMax += input_symhdr->ilineMax;
431   output_symhdr->cbLine += input_symhdr->cbLine;
432 #if 0
433   /* I don't think dense number information is needed.  */
434   output_symhdr->idnMax += input_symhdr->idnMax;
435 #endif
436   output_symhdr->ipdMax += input_symhdr->ipdMax;
437   output_symhdr->isymMax += input_symhdr->isymMax;
438   output_symhdr->ioptMax += input_symhdr->ioptMax;
439   output_symhdr->iauxMax += input_symhdr->iauxMax;
440   output_symhdr->issMax += input_symhdr->issMax;
441   output_symhdr->ifdMax += input_symhdr->ifdMax;
442
443   return true;
444 }
445
446 /* Add a string to the debugging information we are accumulating.
447    Return the offset from the fdr string base.  */
448
449 static bfd_size_type
450 ecoff_add_string (output, fdr, string)
451      struct ecoff_debug_info *output;
452      FDR *fdr;
453      const char *string;
454 {
455   HDRR *symhdr;
456   size_t len;
457   bfd_size_type ret;
458
459   symhdr = &output->symbolic_header;
460   len = strlen (string);
461   if (output->ss_end - output->ss < symhdr->issMax + len + 1)
462     {
463       if (ecoff_add_bytes (&output->ss, &output->ss_end,
464                            symhdr->issMax + len + 1) == false)
465         return -1;
466     }
467   memcpy (output->ss + symhdr->issMax, string, len + 1);
468   ret = fdr->cbSs;
469   symhdr->issMax += len + 1;
470   fdr->cbSs += len + 1;
471   return ret;
472 }
473
474 /* Add debugging information from a non-ECOFF file.  */
475
476 boolean
477 bfd_ecoff_debug_link_other (output_bfd, output_debug, output_swap, input_bfd)
478      bfd *output_bfd;
479      struct ecoff_debug_info *output_debug;
480      const struct ecoff_debug_swap *output_swap;
481      bfd *input_bfd;
482 {
483   void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
484     = output_swap->swap_sym_out;
485   HDRR *output_symhdr = &output_debug->symbolic_header;
486   FDR fdr;
487   asection *sec;
488   asymbol **symbols;
489   asymbol **sym_ptr;
490   asymbol **sym_end;
491
492   memset (&fdr, 0, sizeof fdr);
493
494   sec = bfd_get_section_by_name (input_bfd, ".text");
495   if (sec != NULL)
496     fdr.adr = sec->output_section->vma + sec->output_offset;
497   else
498     {
499       /* FIXME: What about .init or .fini?  */
500       fdr.adr = 0;
501     }
502
503   fdr.issBase = output_symhdr->issMax;
504   fdr.cbSs = 0;
505   fdr.rss = ecoff_add_string (output_debug, &fdr,
506                               bfd_get_filename (input_bfd));
507   fdr.isymBase = output_symhdr->isymMax;
508
509   /* Get the local symbols from the input BFD.  */
510   symbols = (asymbol **) bfd_alloc (output_bfd,
511                                     get_symtab_upper_bound (input_bfd));
512   if (symbols == (asymbol **) NULL)
513     {
514       bfd_error = no_memory;
515       return false;
516     }
517   sym_end = symbols + bfd_canonicalize_symtab (input_bfd, symbols);
518
519   /* Handle the local symbols.  Any external symbols are handled
520      separately.  */
521   fdr.csym = 0;
522   for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
523     {
524       SYMR internal_sym;
525
526       if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
527         continue;
528       memset (&internal_sym, 0, sizeof internal_sym);
529       internal_sym.iss = ecoff_add_string (output_debug, &fdr,
530                                            (*sym_ptr)->name);
531
532       if (bfd_is_com_section ((*sym_ptr)->section)
533           || (*sym_ptr)->section == &bfd_und_section)
534         internal_sym.value = (*sym_ptr)->value;
535       else
536         internal_sym.value = ((*sym_ptr)->value
537                               + (*sym_ptr)->section->output_offset
538                               + (*sym_ptr)->section->output_section->vma);
539       internal_sym.st = stNil;
540       internal_sym.sc = scUndefined;
541       internal_sym.index = indexNil;
542
543       if (((char *) output_debug->external_sym_end
544            - (char *) output_debug->external_sym)
545           < (output_symhdr->isymMax + 1) * output_swap->external_sym_size)
546         {
547           if (! ecoff_add_bytes ((char **) &output_debug->external_sym,
548                                  (char **) &output_debug->external_sym_end,
549                                  ((output_symhdr->isymMax + 1)
550                                   * output_swap->external_sym_size)))
551             return false;
552         }
553
554       (*swap_sym_out) (output_bfd, &internal_sym,
555                        ((char *) output_debug->external_sym
556                         + (output_symhdr->isymMax
557                            * output_swap->external_sym_size)));
558       ++fdr.csym;
559       ++output_symhdr->isymMax;
560     }
561
562   bfd_release (output_bfd, (PTR) symbols);
563
564   if (((char *) output_debug->external_fdr_end
565        - (char *) output_debug->external_fdr)
566       < (output_symhdr->ifdMax + 1) * output_swap->external_fdr_size)
567     {
568       if (! ecoff_add_bytes ((char **) &output_debug->external_fdr,
569                              (char **) &output_debug->external_fdr_end,
570                              ((output_symhdr->ifdMax + 1)
571                               * output_swap->external_fdr_size)))
572         return false;
573     }
574
575   /* Leave everything else in the FDR zeroed out.  This will cause
576      the lang field to be langC.  The fBigendian field will
577      indicate little endian format, but it doesn't matter because
578      it only applies to aux fields and there are none.  */
579   (*output_swap->swap_fdr_out)
580     (output_bfd, &fdr,
581      ((char *) output_debug->external_fdr
582       + output_symhdr->ifdMax * output_swap->external_fdr_size));
583   ++output_symhdr->ifdMax;
584   return true;
585 }
586
587 /* Set up ECOFF debugging information for the external symbols.  */
588
589 boolean
590 bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
591                            set_index)
592      bfd *abfd;
593      struct ecoff_debug_info *debug;
594      const struct ecoff_debug_swap *swap;
595      boolean relocateable;
596      boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
597      void (*set_index) PARAMS ((asymbol *, bfd_size_type));
598 {
599   const bfd_size_type external_ext_size = swap->external_ext_size;
600   void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
601     = swap->swap_ext_out;
602   HDRR * const symhdr = &debug->symbolic_header;
603   asymbol **sym_ptr_ptr;
604   size_t c;
605
606   sym_ptr_ptr = bfd_get_outsymbols (abfd);
607   if (sym_ptr_ptr == NULL)
608     return true;
609
610   for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
611     {
612       asymbol *sym_ptr;
613       EXTR esym;
614
615       sym_ptr = *sym_ptr_ptr;
616
617       /* Get the external symbol information.  */
618       if ((*get_extr) (sym_ptr, &esym) == false)
619         continue;
620
621       /* If we're producing an executable, move common symbols into
622          bss.  */
623       if (relocateable == false)
624         {
625           if (esym.asym.sc == scCommon)
626             esym.asym.sc = scBss;
627           else if (esym.asym.sc == scSCommon)
628             esym.asym.sc = scSBss;
629         }
630
631       if (debug->ssext_end - debug->ssext
632           < symhdr->issExtMax + strlen (sym_ptr->name) + 1)
633         {
634           if (ecoff_add_bytes ((char **) &debug->ssext,
635                                (char **) &debug->ssext_end,
636                                symhdr->issExtMax + strlen (sym_ptr->name) + 1)
637               == false)
638             return false;
639         }
640       if ((char *) debug->external_ext_end - (char *) debug->external_ext
641           < (symhdr->iextMax + 1) * external_ext_size)
642         {
643           if (ecoff_add_bytes ((char **) &debug->external_ext,
644                                (char **) &debug->external_ext_end,
645                                (symhdr->iextMax + 1) * external_ext_size)
646               == false)
647             return false;
648         }
649
650       esym.asym.iss = symhdr->issExtMax;
651
652       if (bfd_is_com_section (sym_ptr->section)
653           || sym_ptr->section == &bfd_und_section)
654         esym.asym.value = sym_ptr->value;
655       else
656         esym.asym.value = (sym_ptr->value
657                            + sym_ptr->section->output_offset
658                            + sym_ptr->section->output_section->vma);
659
660       (*swap_ext_out) (abfd, &esym,
661                        ((char *) debug->external_ext
662                         + symhdr->iextMax * swap->external_ext_size));
663
664       if (set_index)
665         (*set_index) (sym_ptr, symhdr->iextMax);
666
667       ++symhdr->iextMax;
668
669       strcpy (debug->ssext + symhdr->issExtMax, sym_ptr->name);
670       symhdr->issExtMax += strlen (sym_ptr->name) + 1;
671     }
672
673   return true;
674 }
675
676 /* Align the ECOFF debugging information.  */
677
678 static void
679 ecoff_align_debug (abfd, debug, swap)
680      bfd *abfd;
681      struct ecoff_debug_info *debug;
682      const struct ecoff_debug_swap *swap;
683 {
684   HDRR * const symhdr = &debug->symbolic_header;
685   bfd_size_type debug_align, aux_align, add;
686
687   /* Adjust the counts so that structures are aligned.  The alignment
688      of ALLOC_SIZE ensures that we do not have to worry about running
689      off the end of the memory block when doing the memset.  */
690   debug_align = swap->debug_align;
691   aux_align = debug_align / sizeof (union aux_ext);
692
693   add = debug_align - (symhdr->cbLine & (debug_align - 1));
694   if (add != debug_align)
695     {
696       memset (debug->line + symhdr->cbLine, 0, add);
697       symhdr->cbLine += add;
698     }
699
700   add = debug_align - (symhdr->issMax & (debug_align - 1));
701   if (add != debug_align)
702     {
703       memset (debug->ss + symhdr->issMax, 0, add);
704       symhdr->issMax += add;
705     }
706
707   add = debug_align - (symhdr->issExtMax & (debug_align - 1));
708   if (add != debug_align)
709     {
710       memset (debug->ssext + symhdr->issExtMax, 0, add);
711       symhdr->issExtMax += add;
712     }
713
714   add = aux_align - (symhdr->iauxMax & (aux_align - 1));
715   if (add != aux_align)
716     {
717       memset (debug->external_aux + symhdr->iauxMax, 0,
718               add * sizeof (union aux_ext));
719       symhdr->iauxMax += add;
720     }
721 }
722
723 /* Return the size required by the ECOFF debugging information.  */
724
725 bfd_size_type
726 bfd_ecoff_debug_size (abfd, debug, swap)
727      bfd *abfd;
728      struct ecoff_debug_info *debug;
729      const struct ecoff_debug_swap *swap;
730 {
731   bfd_size_type tot;
732
733   ecoff_align_debug (abfd, debug, swap);
734   tot = swap->external_hdr_size;
735
736 #define ADD(count, size) \
737   tot += debug->symbolic_header.count * size
738
739   ADD (cbLine, sizeof (unsigned char));
740   ADD (idnMax, swap->external_dnr_size);
741   ADD (ipdMax, swap->external_pdr_size);
742   ADD (isymMax, swap->external_sym_size);
743   ADD (ioptMax, swap->external_opt_size);
744   ADD (iauxMax, sizeof (union aux_ext));
745   ADD (issMax, sizeof (char));
746   ADD (issExtMax, sizeof (char));
747   ADD (ifdMax, swap->external_fdr_size);
748   ADD (crfd, swap->external_rfd_size);
749   ADD (iextMax, swap->external_ext_size);
750
751 #undef ADD
752
753   return tot;
754 }
755
756 /* Write out the ECOFF debugging information.  This function assumes
757    that the information (the pointers and counts) in *DEBUG have been
758    set correctly.  WHERE is the position in the file to write the
759    information to.  This function fills in the file offsets in the
760    symbolic header.  */
761
762 boolean
763 bfd_ecoff_write_debug (abfd, debug, swap, where)
764      bfd *abfd;
765      struct ecoff_debug_info *debug;
766      const struct ecoff_debug_swap *swap;
767      file_ptr where;
768 {
769   HDRR * const symhdr = &debug->symbolic_header;
770   char *buff;
771
772   ecoff_align_debug (abfd, debug, swap);
773
774   /* Go to the right location in the file.  */
775   if (bfd_seek (abfd, where, SEEK_SET) != 0)
776     return false;
777
778   where += swap->external_hdr_size;
779
780   /* Fill in the file offsets.  */
781 #define SET(offset, count, size) \
782   if (symhdr->count == 0) \
783     symhdr->offset = 0; \
784   else \
785     { \
786       symhdr->offset = where; \
787       where += symhdr->count * size; \
788     }
789
790   SET (cbLineOffset, cbLine, sizeof (unsigned char));
791   SET (cbDnOffset, idnMax, swap->external_dnr_size);
792   SET (cbPdOffset, ipdMax, swap->external_pdr_size);
793   SET (cbSymOffset, isymMax, swap->external_sym_size);
794   SET (cbOptOffset, ioptMax, swap->external_opt_size);
795   SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
796   SET (cbSsOffset, issMax, sizeof (char));
797   SET (cbSsExtOffset, issExtMax, sizeof (char));
798   SET (cbFdOffset, ifdMax, swap->external_fdr_size);
799   SET (cbRfdOffset, crfd, swap->external_rfd_size);
800   SET (cbExtOffset, iextMax, swap->external_ext_size);
801 #undef SET
802
803   buff = (PTR) alloca (swap->external_hdr_size);
804   (*swap->swap_hdr_out) (abfd, symhdr, buff);
805   if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
806       != swap->external_hdr_size)
807     return false;
808
809 #define WRITE(ptr, count, size, offset) \
810   BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
811   if (bfd_write (debug->ptr, size, symhdr->count, abfd) \
812       != size * symhdr->count) \
813     return false;
814
815   WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
816   WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
817   WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
818   WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
819   WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
820   WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
821   WRITE (ss, issMax, sizeof (char), cbSsOffset);
822   WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
823   WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
824   WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
825   WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
826 #undef WRITE
827
828   return true;
829 }