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>.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
24 #include "coff/internal.h"
26 #include "coff/symconst.h"
27 #include "coff/ecoff.h"
29 static boolean ecoff_add_bytes
PARAMS ((char **buf
, char **bufend
,
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
));
37 /* The minimum amount of data to allocate. */
38 #define ALLOC_SIZE (4064)
40 /* Add bytes to a buffer. Return success. */
43 ecoff_add_bytes (buf
, bufend
, need
)
52 have
= *bufend
- *buf
;
58 if (want
< ALLOC_SIZE
)
62 newbuf
= (char *) malloc (have
+ want
);
64 newbuf
= (char *) realloc (*buf
, have
+ want
);
67 bfd_error
= no_memory
;
71 *bufend
= *buf
+ have
+ want
;
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. */
83 bfd_ecoff_debug_accumulate (output_bfd
, output_debug
, output_swap
,
84 input_bfd
, input_debug
, input_swap
,
87 struct ecoff_debug_info
*output_debug
;
88 const struct ecoff_debug_swap
*output_swap
;
90 struct ecoff_debug_info
*input_debug
;
91 const struct ecoff_debug_swap
*input_swap
;
94 void (* const swap_sym_in
) PARAMS ((bfd
*, PTR
, SYMR
*))
95 = input_swap
->swap_sym_in
;
96 void (* const swap_sym_out
) PARAMS ((bfd
*, const SYMR
*, PTR
))
97 = output_swap
->swap_sym_out
;
98 void (* const swap_fdr_out
) PARAMS ((bfd
*, const FDR
*, PTR
))
99 = output_swap
->swap_fdr_out
;
100 void (* const swap_rfd_out
) PARAMS ((bfd
*, const RFDT
*, PTR
))
101 = output_swap
->swap_rfd_out
;
104 bfd_vma section_adjust
[scMax
];
111 bfd_size_type fdr_add
;
114 output_symhdr
= &output_debug
->symbolic_header
;
115 input_symhdr
= &input_debug
->symbolic_header
;
117 /* Make sure the buffers are large enough. */
118 #define CHECK(start, end, count, size) \
119 if ((char *) output_debug->end - (char *) output_debug->start \
120 < (output_symhdr->count + input_symhdr->count) * size) \
122 if (! ecoff_add_bytes ((char **) &output_debug->start, \
123 (char **) &output_debug->end, \
124 ((output_symhdr->count \
125 + input_symhdr->count) \
130 CHECK (line
, line_end
, cbLine
, sizeof (unsigned char));
132 /* I don't think dense number information is needed. */
133 CHECK (external_dnr
, external_dnr_end
, idnMax
,
134 output_swap
->external_dnr_size
);
136 CHECK (external_pdr
, external_pdr_end
, ipdMax
,
137 output_swap
->external_pdr_size
);
138 CHECK (external_sym
, external_sym_end
, isymMax
,
139 output_swap
->external_sym_size
);
140 CHECK (external_opt
, external_opt_end
, ioptMax
,
141 output_swap
->external_opt_size
);
142 CHECK (external_aux
, external_aux_end
, iauxMax
,
143 sizeof (union aux_ext
));
144 CHECK (ss
, ss_end
, issMax
, sizeof (char));
145 CHECK (external_fdr
, external_fdr_end
, ifdMax
,
146 output_swap
->external_fdr_size
);
148 /* The RFD's are special, since we create them if needed. */
152 crfd
= input_symhdr
->crfd
;
153 if (input_symhdr
->crfd
== 0)
154 input_symhdr
->crfd
= input_symhdr
->ifdMax
;
155 CHECK (external_rfd
, external_rfd_end
, crfd
,
156 output_swap
->external_rfd_size
);
157 input_symhdr
->crfd
= crfd
;
162 /* Use section_adjust to hold the value to add to a symbol in a
163 particular section. */
164 memset ((PTR
) section_adjust
, 0, sizeof section_adjust
);
166 #define SET(name, indx) \
167 sec = bfd_get_section_by_name (input_bfd, name); \
169 section_adjust[indx] = (sec->output_section->vma \
170 + sec->output_offset \
173 SET (".text", scText
);
174 SET (".data", scData
);
176 SET (".sdata", scSData
);
177 SET (".sbss", scSBss
);
178 /* scRdata section may be either .rdata or .rodata. */
179 SET (".rdata", scRData
);
180 SET (".rodata", scRData
);
181 SET (".init", scInit
);
182 SET (".fini", scFini
);
186 /* Swap in the local symbols, adjust their values, and swap them out
187 again. The external symbols are handled separately. */
188 sym_out
= ((char *) output_debug
->external_sym
189 + output_symhdr
->isymMax
* output_swap
->external_sym_size
);
190 lraw_src
= (char *) input_debug
->external_sym
;
191 lraw_end
= lraw_src
+ input_symhdr
->isymMax
* input_swap
->external_sym_size
;
192 for (; lraw_src
< lraw_end
; lraw_src
+= input_swap
->external_sym_size
)
196 (*swap_sym_in
) (input_bfd
, (PTR
) lraw_src
, &internal_sym
);
198 BFD_ASSERT (internal_sym
.sc
!= scCommon
199 && internal_sym
.sc
!= scSCommon
);
201 /* Adjust the symbol value if appropriate. */
202 switch (internal_sym
.st
)
205 if (ECOFF_IS_STAB (&internal_sym
))
213 internal_sym
.value
+= section_adjust
[internal_sym
.sc
];
220 (*swap_sym_out
) (output_bfd
, &internal_sym
, sym_out
);
221 sym_out
+= output_swap
->external_sym_size
;
224 /* Copy the information that does not need swapping. */
225 memcpy (output_debug
->line
+ output_symhdr
->cbLine
,
227 (size_t) (input_symhdr
->cbLine
* sizeof (unsigned char)));
228 memcpy (output_debug
->external_aux
+ output_symhdr
->iauxMax
,
229 input_debug
->external_aux
,
230 (size_t) (input_symhdr
->iauxMax
* sizeof (union aux_ext
)));
231 memcpy (output_debug
->ss
+ output_symhdr
->issMax
,
233 (size_t) (input_symhdr
->issMax
* sizeof (char)));
235 /* Some of the information may need to be swapped. */
236 if (output_bfd
->xvec
->header_byteorder_big_p
237 == input_bfd
->xvec
->header_byteorder_big_p
)
239 /* The two BFD's have the same endianness, so memcpy will
242 /* I don't think dense number information is needed. */
243 BFD_ASSERT (output_swap
->external_dnr_size
244 == input_swap
->external_dnr_size
);
245 if (input_symhdr
->idnMax
> 0)
246 memcpy (((char *) output_debug
->external_dnr
247 + output_symhdr
->idnMax
* output_swap
->external_dnr_size
),
248 input_debug
->external_dnr
,
250 (input_symhdr
->idnMax
* output_swap
->external_dnr_size
)));
252 BFD_ASSERT (output_swap
->external_pdr_size
253 == input_swap
->external_pdr_size
);
254 if (input_symhdr
->ipdMax
> 0)
255 memcpy (((char *) output_debug
->external_pdr
256 + output_symhdr
->ipdMax
* output_swap
->external_pdr_size
),
257 input_debug
->external_pdr
,
259 (input_symhdr
->ipdMax
* output_swap
->external_pdr_size
)));
260 BFD_ASSERT (output_swap
->external_opt_size
261 == input_swap
->external_opt_size
);
262 if (input_symhdr
->ioptMax
> 0)
263 memcpy (((char *) output_debug
->external_opt
264 + output_symhdr
->ioptMax
* output_swap
->external_opt_size
),
265 input_debug
->external_opt
,
267 (input_symhdr
->ioptMax
* output_swap
->external_opt_size
)));
271 bfd_size_type outsz
, insz
;
276 /* The two BFD's have different endianness, so we must swap
277 everything in and out. This code would always work, but it
278 would be slow in the normal case. */
280 /* I don't think dense number information is needed. */
281 outsz
= output_swap
->external_dnr_size
;
282 insz
= input_swap
->external_dnr_size
;
283 in
= (char *) input_debug
->external_dnr
;
284 end
= in
+ input_symhdr
->idnMax
* insz
;
285 out
= ((char *) output_debug
->external_dnr
286 + output_symhdr
->idnMax
* outsz
);
287 for (; in
< end
; in
+= insz
, out
+= outsz
)
291 (*input_swap
->swap_dnr_in
) (input_bfd
, in
, &dnr
);
292 (*output_swap
->swap_dnr_out
) (output_bfd
, &dnr
, out
);
296 outsz
= output_swap
->external_pdr_size
;
297 insz
= input_swap
->external_pdr_size
;
298 in
= (char *) input_debug
->external_pdr
;
299 end
= in
+ input_symhdr
->ipdMax
* insz
;
300 out
= ((char *) output_debug
->external_pdr
301 + output_symhdr
->ipdMax
* outsz
);
302 for (; in
< end
; in
+= insz
, out
+= outsz
)
306 (*input_swap
->swap_pdr_in
) (input_bfd
, in
, &pdr
);
307 (*output_swap
->swap_pdr_out
) (output_bfd
, &pdr
, out
);
310 outsz
= output_swap
->external_opt_size
;
311 insz
= input_swap
->external_opt_size
;
312 in
= (char *) input_debug
->external_opt
;
313 end
= in
+ input_symhdr
->ioptMax
* insz
;
314 out
= ((char *) output_debug
->external_opt
315 + output_symhdr
->ioptMax
* outsz
);
316 for (; in
< end
; in
+= insz
, out
+= outsz
)
320 (*input_swap
->swap_opt_in
) (input_bfd
, in
, &opt
);
321 (*output_swap
->swap_opt_out
) (output_bfd
, &opt
, out
);
325 /* Set ifdbase so that the external symbols know how to adjust their
327 input_debug
->ifdbase
= output_symhdr
->ifdMax
;
329 /* We need to handle the FDR's whether they are swapped or not. */
330 if (input_debug
->fdr
!= (FDR
*) NULL
)
332 fdr_ptr
= (char *) input_debug
->fdr
;
333 fdr_add
= sizeof (FDR
);
337 fdr_ptr
= (char *) input_debug
->external_fdr
;
338 fdr_add
= input_swap
->external_fdr_size
;
340 fdr_end
= fdr_ptr
+ input_symhdr
->ifdMax
* fdr_add
;
341 fdr_out
= ((char *) output_debug
->external_fdr
342 + output_symhdr
->ifdMax
* output_swap
->external_fdr_size
);
345 fdr_ptr
+= fdr_add
, fdr_out
+= output_swap
->external_fdr_size
)
349 if (input_debug
->fdr
!= (FDR
*) NULL
)
350 fdr
= *(FDR
*) fdr_ptr
;
352 (*input_swap
->swap_fdr_in
) (input_bfd
, (PTR
) fdr_ptr
, &fdr
);
354 /* FIXME: It is conceivable that this FDR points to the .init or
355 .fini section, in which case this will not do the right
357 fdr
.adr
+= section_adjust
[scText
];
359 fdr
.issBase
+= output_symhdr
->issMax
;
360 fdr
.isymBase
+= output_symhdr
->isymMax
;
361 fdr
.ilineBase
+= output_symhdr
->ilineMax
;
362 fdr
.ioptBase
+= output_symhdr
->ioptMax
;
363 fdr
.ipdFirst
+= output_symhdr
->ipdMax
;
364 fdr
.iauxBase
+= output_symhdr
->iauxMax
;
365 fdr
.rfdBase
+= output_symhdr
->crfd
;
367 /* If there are no RFD's, we are going to add some. We don't
368 want to adjust crfd for this, so that all the FDR's can share
370 if (input_symhdr
->crfd
== 0)
371 fdr
.crfd
= input_symhdr
->ifdMax
;
374 fdr
.cbLineOffset
+= output_symhdr
->cbLine
;
376 (*swap_fdr_out
) (output_bfd
, &fdr
, fdr_out
);
379 if (input_symhdr
->crfd
> 0)
381 void (* const swap_rfd_in
) PARAMS ((bfd
*, PTR
, RFDT
*))
382 = input_swap
->swap_rfd_in
;
383 bfd_size_type outsz
, insz
;
388 /* Swap and adjust the RFD's. RFD's are only created by the
389 linker, so this will only be necessary if one of the input
390 files is the result of a partial link. Presumably all
391 necessary RFD's are present. */
392 outsz
= output_swap
->external_rfd_size
;
393 insz
= input_swap
->external_rfd_size
;
394 rfd_in
= (char *) input_debug
->external_rfd
;
395 rfd_end
= rfd_in
+ input_symhdr
->crfd
* insz
;
396 rfd_out
= ((char *) output_debug
->external_rfd
397 + output_symhdr
->crfd
* outsz
);
400 rfd_in
+= insz
, rfd_out
+= outsz
)
404 (*swap_rfd_in
) (input_bfd
, rfd_in
, &rfd
);
405 rfd
+= output_symhdr
->ifdMax
;
406 (*swap_rfd_out
) (output_bfd
, &rfd
, rfd_out
);
408 output_symhdr
->crfd
+= input_symhdr
->crfd
;
417 /* Create RFD's. Some of the debugging information includes
418 relative file indices. These indices are taken as indices to
419 the RFD table if there is one, or to the global table if
420 there is not. If we did not create RFD's, we would have to
421 parse and adjust all the debugging information which contains
423 outsz
= output_swap
->external_rfd_size
;
424 rfd
= output_symhdr
->ifdMax
;
425 rfd_out
= ((char *) output_debug
->external_rfd
426 + output_symhdr
->crfd
* outsz
);
427 rfd_end
= (rfd_out
+ input_symhdr
->ifdMax
* outsz
);
428 for (; rfd_out
< rfd_end
; rfd_out
+= outsz
, rfd
++)
429 (*swap_rfd_out
) (output_bfd
, &rfd
, rfd_out
);
430 output_symhdr
->crfd
+= input_symhdr
->ifdMax
;
433 /* Update the counts. */
434 output_symhdr
->ilineMax
+= input_symhdr
->ilineMax
;
435 output_symhdr
->cbLine
+= input_symhdr
->cbLine
;
437 /* I don't think dense number information is needed. */
438 output_symhdr
->idnMax
+= input_symhdr
->idnMax
;
440 output_symhdr
->ipdMax
+= input_symhdr
->ipdMax
;
441 output_symhdr
->isymMax
+= input_symhdr
->isymMax
;
442 output_symhdr
->ioptMax
+= input_symhdr
->ioptMax
;
443 output_symhdr
->iauxMax
+= input_symhdr
->iauxMax
;
444 output_symhdr
->issMax
+= input_symhdr
->issMax
;
445 output_symhdr
->ifdMax
+= input_symhdr
->ifdMax
;
450 /* Add a string to the debugging information we are accumulating.
451 Return the offset from the fdr string base. */
454 ecoff_add_string (output
, fdr
, string
)
455 struct ecoff_debug_info
*output
;
463 symhdr
= &output
->symbolic_header
;
464 len
= strlen (string
);
465 if (output
->ss_end
- output
->ss
< symhdr
->issMax
+ len
+ 1)
467 if (ecoff_add_bytes (&output
->ss
, &output
->ss_end
,
468 symhdr
->issMax
+ len
+ 1) == false)
469 return (bfd_size_type
) -1;
471 memcpy (output
->ss
+ symhdr
->issMax
, string
, len
+ 1);
473 symhdr
->issMax
+= len
+ 1;
474 fdr
->cbSs
+= len
+ 1;
478 /* Add debugging information from a non-ECOFF file. */
481 bfd_ecoff_debug_link_other (output_bfd
, output_debug
, output_swap
, input_bfd
)
483 struct ecoff_debug_info
*output_debug
;
484 const struct ecoff_debug_swap
*output_swap
;
487 void (* const swap_sym_out
) PARAMS ((bfd
*, const SYMR
*, PTR
))
488 = output_swap
->swap_sym_out
;
489 HDRR
*output_symhdr
= &output_debug
->symbolic_header
;
496 memset (&fdr
, 0, sizeof fdr
);
498 sec
= bfd_get_section_by_name (input_bfd
, ".text");
500 fdr
.adr
= sec
->output_section
->vma
+ sec
->output_offset
;
503 /* FIXME: What about .init or .fini? */
507 fdr
.issBase
= output_symhdr
->issMax
;
509 fdr
.rss
= ecoff_add_string (output_debug
, &fdr
,
510 bfd_get_filename (input_bfd
));
513 fdr
.isymBase
= output_symhdr
->isymMax
;
515 /* Get the local symbols from the input BFD. */
516 symbols
= (asymbol
**) bfd_alloc (output_bfd
,
517 get_symtab_upper_bound (input_bfd
));
518 if (symbols
== (asymbol
**) NULL
)
520 bfd_error
= no_memory
;
523 sym_end
= symbols
+ bfd_canonicalize_symtab (input_bfd
, symbols
);
525 /* Handle the local symbols. Any external symbols are handled
528 for (sym_ptr
= symbols
; sym_ptr
!= sym_end
; sym_ptr
++)
532 if (((*sym_ptr
)->flags
& BSF_EXPORT
) != 0)
534 memset (&internal_sym
, 0, sizeof internal_sym
);
535 internal_sym
.iss
= ecoff_add_string (output_debug
, &fdr
,
538 if (internal_sym
.iss
== -1)
540 if (bfd_is_com_section ((*sym_ptr
)->section
)
541 || (*sym_ptr
)->section
== &bfd_und_section
)
542 internal_sym
.value
= (*sym_ptr
)->value
;
544 internal_sym
.value
= ((*sym_ptr
)->value
545 + (*sym_ptr
)->section
->output_offset
546 + (*sym_ptr
)->section
->output_section
->vma
);
547 internal_sym
.st
= stNil
;
548 internal_sym
.sc
= scUndefined
;
549 internal_sym
.index
= indexNil
;
551 if (((char *) output_debug
->external_sym_end
552 - (char *) output_debug
->external_sym
)
553 < (output_symhdr
->isymMax
+ 1) * output_swap
->external_sym_size
)
555 if (! ecoff_add_bytes ((char **) &output_debug
->external_sym
,
556 (char **) &output_debug
->external_sym_end
,
557 ((output_symhdr
->isymMax
+ 1)
558 * output_swap
->external_sym_size
)))
562 (*swap_sym_out
) (output_bfd
, &internal_sym
,
563 ((char *) output_debug
->external_sym
564 + (output_symhdr
->isymMax
565 * output_swap
->external_sym_size
)));
567 ++output_symhdr
->isymMax
;
570 bfd_release (output_bfd
, (PTR
) symbols
);
572 if (((char *) output_debug
->external_fdr_end
573 - (char *) output_debug
->external_fdr
)
574 < (output_symhdr
->ifdMax
+ 1) * output_swap
->external_fdr_size
)
576 if (! ecoff_add_bytes ((char **) &output_debug
->external_fdr
,
577 (char **) &output_debug
->external_fdr_end
,
578 ((output_symhdr
->ifdMax
+ 1)
579 * output_swap
->external_fdr_size
)))
583 /* Leave everything else in the FDR zeroed out. This will cause
584 the lang field to be langC. The fBigendian field will
585 indicate little endian format, but it doesn't matter because
586 it only applies to aux fields and there are none. */
587 (*output_swap
->swap_fdr_out
)
589 ((char *) output_debug
->external_fdr
590 + output_symhdr
->ifdMax
* output_swap
->external_fdr_size
));
591 ++output_symhdr
->ifdMax
;
595 /* Set up ECOFF debugging information for the external symbols. */
598 bfd_ecoff_debug_externals (abfd
, debug
, swap
, relocateable
, get_extr
,
601 struct ecoff_debug_info
*debug
;
602 const struct ecoff_debug_swap
*swap
;
603 boolean relocateable
;
604 boolean (*get_extr
) PARAMS ((asymbol
*, EXTR
*));
605 void (*set_index
) PARAMS ((asymbol
*, bfd_size_type
));
607 HDRR
* const symhdr
= &debug
->symbolic_header
;
608 asymbol
**sym_ptr_ptr
;
611 sym_ptr_ptr
= bfd_get_outsymbols (abfd
);
612 if (sym_ptr_ptr
== NULL
)
615 for (c
= bfd_get_symcount (abfd
); c
> 0; c
--, sym_ptr_ptr
++)
620 sym_ptr
= *sym_ptr_ptr
;
622 /* Get the external symbol information. */
623 if ((*get_extr
) (sym_ptr
, &esym
) == false)
626 /* If we're producing an executable, move common symbols into
628 if (relocateable
== false)
630 if (esym
.asym
.sc
== scCommon
)
631 esym
.asym
.sc
= scBss
;
632 else if (esym
.asym
.sc
== scSCommon
)
633 esym
.asym
.sc
= scSBss
;
637 if (bfd_is_com_section (sym_ptr
->section
)
638 || sym_ptr
->section
== &bfd_und_section
)
639 esym
.asym
.value
= sym_ptr
->value
;
641 esym
.asym
.value
= (sym_ptr
->value
642 + sym_ptr
->section
->output_offset
643 + sym_ptr
->section
->output_section
->vma
);
646 (*set_index
) (sym_ptr
, (bfd_size_type
) symhdr
->iextMax
);
648 if (! bfd_ecoff_debug_one_external (abfd
, debug
, swap
,
649 sym_ptr
->name
, &esym
))
656 /* Add a single external symbol to the debugging information. */
659 bfd_ecoff_debug_one_external (abfd
, debug
, swap
, name
, esym
)
661 struct ecoff_debug_info
*debug
;
662 const struct ecoff_debug_swap
*swap
;
666 const bfd_size_type external_ext_size
= swap
->external_ext_size
;
667 void (* const swap_ext_out
) PARAMS ((bfd
*, const EXTR
*, PTR
))
668 = swap
->swap_ext_out
;
669 HDRR
* const symhdr
= &debug
->symbolic_header
;
672 namelen
= strlen (name
);
674 if (debug
->ssext_end
- debug
->ssext
675 < symhdr
->issExtMax
+ namelen
+ 1)
677 if (ecoff_add_bytes ((char **) &debug
->ssext
,
678 (char **) &debug
->ssext_end
,
679 symhdr
->issExtMax
+ namelen
+ 1)
683 if ((char *) debug
->external_ext_end
- (char *) debug
->external_ext
684 < (symhdr
->iextMax
+ 1) * external_ext_size
)
686 if (ecoff_add_bytes ((char **) &debug
->external_ext
,
687 (char **) &debug
->external_ext_end
,
688 (symhdr
->iextMax
+ 1) * external_ext_size
)
693 esym
->asym
.iss
= symhdr
->issExtMax
;
695 (*swap_ext_out
) (abfd
, esym
,
696 ((char *) debug
->external_ext
697 + symhdr
->iextMax
* swap
->external_ext_size
));
701 strcpy (debug
->ssext
+ symhdr
->issExtMax
, name
);
702 symhdr
->issExtMax
+= namelen
+ 1;
707 /* Align the ECOFF debugging information. */
711 ecoff_align_debug (abfd
, debug
, swap
)
713 struct ecoff_debug_info
*debug
;
714 const struct ecoff_debug_swap
*swap
;
716 HDRR
* const symhdr
= &debug
->symbolic_header
;
717 bfd_size_type debug_align
, aux_align
;
720 /* Adjust the counts so that structures are aligned. The alignment
721 of ALLOC_SIZE ensures that we do not have to worry about running
722 off the end of the memory block when doing the memset. */
723 debug_align
= swap
->debug_align
;
724 aux_align
= debug_align
/ sizeof (union aux_ext
);
726 add
= debug_align
- (symhdr
->cbLine
& (debug_align
- 1));
727 if (add
!= debug_align
)
729 memset (debug
->line
+ symhdr
->cbLine
, 0, add
);
730 symhdr
->cbLine
+= add
;
733 add
= debug_align
- (symhdr
->issMax
& (debug_align
- 1));
734 if (add
!= debug_align
)
736 memset (debug
->ss
+ symhdr
->issMax
, 0, add
);
737 symhdr
->issMax
+= add
;
740 add
= debug_align
- (symhdr
->issExtMax
& (debug_align
- 1));
741 if (add
!= debug_align
)
743 memset (debug
->ssext
+ symhdr
->issExtMax
, 0, add
);
744 symhdr
->issExtMax
+= add
;
747 add
= aux_align
- (symhdr
->iauxMax
& (aux_align
- 1));
748 if (add
!= aux_align
)
750 memset (debug
->external_aux
+ symhdr
->iauxMax
, 0,
751 add
* sizeof (union aux_ext
));
752 symhdr
->iauxMax
+= add
;
756 /* Return the size required by the ECOFF debugging information. */
759 bfd_ecoff_debug_size (abfd
, debug
, swap
)
761 struct ecoff_debug_info
*debug
;
762 const struct ecoff_debug_swap
*swap
;
766 ecoff_align_debug (abfd
, debug
, swap
);
767 tot
= swap
->external_hdr_size
;
769 #define ADD(count, size) \
770 tot += debug->symbolic_header.count * size
772 ADD (cbLine
, sizeof (unsigned char));
773 ADD (idnMax
, swap
->external_dnr_size
);
774 ADD (ipdMax
, swap
->external_pdr_size
);
775 ADD (isymMax
, swap
->external_sym_size
);
776 ADD (ioptMax
, swap
->external_opt_size
);
777 ADD (iauxMax
, sizeof (union aux_ext
));
778 ADD (issMax
, sizeof (char));
779 ADD (issExtMax
, sizeof (char));
780 ADD (ifdMax
, swap
->external_fdr_size
);
781 ADD (crfd
, swap
->external_rfd_size
);
782 ADD (iextMax
, swap
->external_ext_size
);
789 /* Write out the ECOFF debugging information. This function assumes
790 that the information (the pointers and counts) in *DEBUG have been
791 set correctly. WHERE is the position in the file to write the
792 information to. This function fills in the file offsets in the
796 bfd_ecoff_write_debug (abfd
, debug
, swap
, where
)
798 struct ecoff_debug_info
*debug
;
799 const struct ecoff_debug_swap
*swap
;
802 HDRR
* const symhdr
= &debug
->symbolic_header
;
805 ecoff_align_debug (abfd
, debug
, swap
);
807 /* Go to the right location in the file. */
808 if (bfd_seek (abfd
, where
, SEEK_SET
) != 0)
811 where
+= swap
->external_hdr_size
;
813 /* Fill in the file offsets. */
814 #define SET(offset, count, size) \
815 if (symhdr->count == 0) \
816 symhdr->offset = 0; \
819 symhdr->offset = where; \
820 where += symhdr->count * size; \
823 SET (cbLineOffset
, cbLine
, sizeof (unsigned char));
824 SET (cbDnOffset
, idnMax
, swap
->external_dnr_size
);
825 SET (cbPdOffset
, ipdMax
, swap
->external_pdr_size
);
826 SET (cbSymOffset
, isymMax
, swap
->external_sym_size
);
827 SET (cbOptOffset
, ioptMax
, swap
->external_opt_size
);
828 SET (cbAuxOffset
, iauxMax
, sizeof (union aux_ext
));
829 SET (cbSsOffset
, issMax
, sizeof (char));
830 SET (cbSsExtOffset
, issExtMax
, sizeof (char));
831 SET (cbFdOffset
, ifdMax
, swap
->external_fdr_size
);
832 SET (cbRfdOffset
, crfd
, swap
->external_rfd_size
);
833 SET (cbExtOffset
, iextMax
, swap
->external_ext_size
);
836 buff
= (PTR
) alloca (swap
->external_hdr_size
);
837 (*swap
->swap_hdr_out
) (abfd
, symhdr
, buff
);
838 if (bfd_write (buff
, 1, swap
->external_hdr_size
, abfd
)
839 != swap
->external_hdr_size
)
842 #define WRITE(ptr, count, size, offset) \
843 BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
844 if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
845 != size * symhdr->count) \
848 WRITE (line
, cbLine
, sizeof (unsigned char), cbLineOffset
);
849 WRITE (external_dnr
, idnMax
, swap
->external_dnr_size
, cbDnOffset
);
850 WRITE (external_pdr
, ipdMax
, swap
->external_pdr_size
, cbPdOffset
);
851 WRITE (external_sym
, isymMax
, swap
->external_sym_size
, cbSymOffset
);
852 WRITE (external_opt
, ioptMax
, swap
->external_opt_size
, cbOptOffset
);
853 WRITE (external_aux
, iauxMax
, sizeof (union aux_ext
), cbAuxOffset
);
854 WRITE (ss
, issMax
, sizeof (char), cbSsOffset
);
855 WRITE (ssext
, issExtMax
, sizeof (char), cbSsExtOffset
);
856 WRITE (external_fdr
, ifdMax
, swap
->external_fdr_size
, cbFdOffset
);
857 WRITE (external_rfd
, crfd
, swap
->external_rfd_size
, cbRfdOffset
);
858 WRITE (external_ext
, iextMax
, swap
->external_ext_size
, cbExtOffset
);