1 diff -uNdr binutils-2.17.50.0.18-old/bfd/Makefile.am binutils-2.17.50.0.18/bfd/Makefile.am
2 --- binutils-2.17.50.0.18-old/bfd/Makefile.am 2007-08-01 15:11:47.000000000 +0200
3 +++ binutils-2.17.50.0.18/bfd/Makefile.am 2007-10-20 16:45:33.000000000 +0200
22 @@ -1186,6 +1190,12 @@
23 coff-m68k.c $(INCDIR)/hashtab.h $(INCDIR)/coff/m68k.h \
24 $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
26 +coff-avr.lo: coff-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \
27 + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
28 + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
29 +coff-ext-avr.lo: coff-ext-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \
30 + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
31 + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
32 coff-h8300.lo: coff-h8300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
33 $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/coff/h8300.h \
34 $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
35 diff -uNdr binutils-2.17.50.0.18-old/bfd/Makefile.in binutils-2.17.50.0.18/bfd/Makefile.in
36 --- binutils-2.17.50.0.18-old/bfd/Makefile.in 2007-10-20 15:38:12.000000000 +0200
37 +++ binutils-2.17.50.0.18/bfd/Makefile.in 2007-10-20 16:45:33.000000000 +0200
56 @@ -1767,6 +1771,12 @@
57 coff-m68k.c $(INCDIR)/hashtab.h $(INCDIR)/coff/m68k.h \
58 $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
60 +coff-avr.lo: coff-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \
61 + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
62 + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
63 +coff-ext-avr.lo: coff-ext-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \
64 + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
65 + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
66 coff-h8300.lo: coff-h8300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
67 $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/coff/h8300.h \
68 $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
69 diff -uNdr binutils-2.17.50.0.18-old/bfd/coff-avr.c binutils-2.17.50.0.18/bfd/coff-avr.c
70 --- binutils-2.17.50.0.18-old/bfd/coff-avr.c 1970-01-01 01:00:00.000000000 +0100
71 +++ binutils-2.17.50.0.18/bfd/coff-avr.c 2007-10-20 16:45:33.000000000 +0200
73 +/* BFD back-end for Atmel AVR COFF files.
74 + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
75 + Free Software Foundation, Inc.
76 + Created mostly by substituting "avr" for "i860" in coff-i860.c
78 +This file is part of BFD, the Binary File Descriptor library.
80 +This program is free software; you can redistribute it and/or modify
81 +it under the terms of the GNU General Public License as published by
82 +the Free Software Foundation; either version 2 of the License, or
83 +(at your option) any later version.
85 +This program is distributed in the hope that it will be useful,
86 +but WITHOUT ANY WARRANTY; without even the implied warranty of
87 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88 +GNU General Public License for more details.
90 +You should have received a copy of the GNU General Public License
91 +along with this program; if not, write to the Free Software
92 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
98 +#include "coff/avr.h"
100 +#include "coff/internal.h"
102 +#include "libcoff.h"
104 +static bfd_reloc_status_type coff_avr_reloc
105 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
106 +static reloc_howto_type *coff_avr_rtype_to_howto
107 + PARAMS ((bfd *, asection *, struct internal_reloc *,
108 + struct coff_link_hash_entry *, struct internal_syment *,
110 +static const bfd_target * coff_avr_object_p PARAMS ((bfd *));
112 +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
113 +/* The page size is a guess based on ELF. */
115 +#define COFF_PAGE_SIZE 0x1000
117 +/* For some reason when using avr COFF the value stored in the .text
118 + section for a reference to a common symbol is the value itself plus
119 + any desired offset. Ian Taylor, Cygnus Support. */
121 +/* If we are producing relocateable output, we need to do some
122 + adjustments to the object file that are not done by the
123 + bfd_perform_relocation function. This function is called by every
124 + reloc type to make any required adjustments. */
126 +static bfd_reloc_status_type
127 +coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
130 + arelent *reloc_entry;
133 + asection *input_section ATTRIBUTE_UNUSED;
135 + char **error_message ATTRIBUTE_UNUSED;
139 + if (output_bfd == (bfd *) NULL)
140 + return bfd_reloc_continue;
142 + if (bfd_is_com_section (symbol->section))
144 + /* We are relocating a common symbol. The current value in the
145 + object file is ORIG + OFFSET, where ORIG is the value of the
146 + common symbol as seen by the object file when it was compiled
147 + (this may be zero if the symbol was undefined) and OFFSET is
148 + the offset into the common symbol (normally zero, but may be
149 + non-zero when referring to a field in a common structure).
150 + ORIG is the negative of reloc_entry->addend, which is set by
151 + the CALC_ADDEND macro below. We want to replace the value in
152 + the object file with NEW + OFFSET, where NEW is the value of
153 + the common symbol which we are going to put in the final
154 + object file. NEW is symbol->value. */
155 + diff = symbol->value + reloc_entry->addend;
159 + /* For some reason bfd_perform_relocation always effectively
160 + ignores the addend for a COFF target when producing
161 + relocateable output. This seems to be always wrong for 860
162 + COFF, so we handle the addend here instead. */
163 + diff = reloc_entry->addend;
167 + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
171 + reloc_howto_type *howto = reloc_entry->howto;
172 + unsigned char *addr = (unsigned char *) data + reloc_entry->address;
174 + switch (howto->size)
178 + char x = bfd_get_8 (abfd, addr);
180 + bfd_put_8 (abfd, x, addr);
186 + short x = bfd_get_16 (abfd, addr);
188 + bfd_put_16 (abfd, (bfd_vma) x, addr);
194 + long x = bfd_get_32 (abfd, addr);
196 + bfd_put_32 (abfd, (bfd_vma) x, addr);
205 + /* Now let bfd_perform_relocation finish everything up. */
206 + return bfd_reloc_continue;
210 +#define PCRELOFFSET FALSE
213 +static reloc_howto_type howto_table[] =
221 + HOWTO (R_DIR32, /* type */
222 + 0, /* rightshift */
223 + 2, /* size (0 = byte, 1 = short, 2 = long) */
225 + FALSE, /* pc_relative */
227 + complain_overflow_bitfield, /* complain_on_overflow */
228 + coff_avr_reloc, /* special_function */
229 + "dir32", /* name */
230 + TRUE, /* partial_inplace */
231 + 0xffffffff, /* src_mask */
232 + 0xffffffff, /* dst_mask */
233 + TRUE), /* pcrel_offset */
235 + HOWTO (R_IMAGEBASE, /* type */
236 + 0, /* rightshift */
237 + 2, /* size (0 = byte, 1 = short, 2 = long) */
239 + FALSE, /* pc_relative */
241 + complain_overflow_bitfield, /* complain_on_overflow */
242 + coff_avr_reloc, /* special_function */
243 + "rva32", /* name */
244 + TRUE, /* partial_inplace */
245 + 0xffffffff, /* src_mask */
246 + 0xffffffff, /* dst_mask */
247 + FALSE), /* pcrel_offset */
255 + HOWTO (R_RELBYTE, /* type */
256 + 0, /* rightshift */
257 + 0, /* size (0 = byte, 1 = short, 2 = long) */
259 + FALSE, /* pc_relative */
261 + complain_overflow_bitfield, /* complain_on_overflow */
262 + coff_avr_reloc, /* special_function */
264 + TRUE, /* partial_inplace */
265 + 0x000000ff, /* src_mask */
266 + 0x000000ff, /* dst_mask */
267 + PCRELOFFSET), /* pcrel_offset */
268 + HOWTO (R_RELWORD, /* type */
269 + 0, /* rightshift */
270 + 1, /* size (0 = byte, 1 = short, 2 = long) */
272 + FALSE, /* pc_relative */
274 + complain_overflow_bitfield, /* complain_on_overflow */
275 + coff_avr_reloc, /* special_function */
277 + TRUE, /* partial_inplace */
278 + 0x0000ffff, /* src_mask */
279 + 0x0000ffff, /* dst_mask */
280 + PCRELOFFSET), /* pcrel_offset */
281 + HOWTO (R_RELLONG, /* type */
282 + 0, /* rightshift */
283 + 2, /* size (0 = byte, 1 = short, 2 = long) */
285 + FALSE, /* pc_relative */
287 + complain_overflow_bitfield, /* complain_on_overflow */
288 + coff_avr_reloc, /* special_function */
290 + TRUE, /* partial_inplace */
291 + 0xffffffff, /* src_mask */
292 + 0xffffffff, /* dst_mask */
293 + PCRELOFFSET), /* pcrel_offset */
294 + HOWTO (R_PCRBYTE, /* type */
295 + 0, /* rightshift */
296 + 0, /* size (0 = byte, 1 = short, 2 = long) */
298 + TRUE, /* pc_relative */
300 + complain_overflow_signed, /* complain_on_overflow */
301 + coff_avr_reloc, /* special_function */
302 + "DISP8", /* name */
303 + TRUE, /* partial_inplace */
304 + 0x000000ff, /* src_mask */
305 + 0x000000ff, /* dst_mask */
306 + PCRELOFFSET), /* pcrel_offset */
307 + HOWTO (R_PCRWORD, /* type */
308 + 0, /* rightshift */
309 + 1, /* size (0 = byte, 1 = short, 2 = long) */
311 + TRUE, /* pc_relative */
313 + complain_overflow_signed, /* complain_on_overflow */
314 + coff_avr_reloc, /* special_function */
315 + "DISP16", /* name */
316 + TRUE, /* partial_inplace */
317 + 0x0000ffff, /* src_mask */
318 + 0x0000ffff, /* dst_mask */
319 + PCRELOFFSET), /* pcrel_offset */
320 + HOWTO (R_PCRLONG, /* type */
321 + 0, /* rightshift */
322 + 2, /* size (0 = byte, 1 = short, 2 = long) */
324 + TRUE, /* pc_relative */
326 + complain_overflow_signed, /* complain_on_overflow */
327 + coff_avr_reloc, /* special_function */
328 + "DISP32", /* name */
329 + TRUE, /* partial_inplace */
330 + 0xffffffff, /* src_mask */
331 + 0xffffffff, /* dst_mask */
332 + PCRELOFFSET) /* pcrel_offset */
335 +/* Turn a howto into a reloc nunmber */
337 +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
338 +#define BADMAG(x) AVRBADMAG(x)
339 +#define AVR 1 /* Customize coffcode.h */
341 +#define RTYPE2HOWTO(cache_ptr, dst) \
342 + (cache_ptr)->howto = howto_table + (dst)->r_type;
344 +/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
345 + library. On some other COFF targets STYP_BSS is normally
347 +#define BSS_NOLOAD_IS_SHARED_LIBRARY
349 +/* Compute the addend of a reloc. If the reloc is to a common symbol,
350 + the object file contains the value of the common symbol. By the
351 + time this is called, the linker may be using a different symbol
352 + from a different object file with a different value. Therefore, we
353 + hack wildly to locate the original symbol from this file so that we
354 + can make the correct adjustment. This macro sets coffsym to the
355 + symbol from the original file, and uses it to set the addend value
356 + correctly. If this is not a common symbol, the usual addend
357 + calculation is done, except that an additional tweak is needed for
358 + PC relative relocs.
359 + FIXME: This macro refers to symbols and asect; these are from the
360 + calling function, not the macro arguments. */
362 +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
364 + coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
365 + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
366 + coffsym = (obj_symbols (abfd) \
367 + + (cache_ptr->sym_ptr_ptr - symbols)); \
369 + coffsym = coff_symbol_from (abfd, ptr); \
370 + if (coffsym != (coff_symbol_type *) NULL \
371 + && coffsym->native->u.syment.n_scnum == 0) \
372 + cache_ptr->addend = - coffsym->native->u.syment.n_value; \
373 + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
374 + && ptr->section != (asection *) NULL) \
375 + cache_ptr->addend = - (ptr->section->vma + ptr->value); \
377 + cache_ptr->addend = 0; \
378 + if (ptr && howto_table[reloc.r_type].pc_relative) \
379 + cache_ptr->addend += asect->vma; \
382 +/* We use the special COFF backend linker. */
383 +#define coff_relocate_section _bfd_coff_generic_relocate_section
385 +static reloc_howto_type *
386 +coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
387 + bfd *abfd ATTRIBUTE_UNUSED;
389 + struct internal_reloc *rel;
390 + struct coff_link_hash_entry *h;
391 + struct internal_syment *sym;
395 + reloc_howto_type *howto;
397 + howto = howto_table + rel->r_type;
399 + if (howto->pc_relative)
400 + *addendp += sec->vma;
402 + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
404 + /* This is a common symbol. The section contents include the
405 + size (sym->n_value) as an addend. The relocate_section
406 + function will be adding in the final value of the symbol. We
407 + need to subtract out the current size in order to get the
410 + BFD_ASSERT (h != NULL);
412 + /* I think we *do* want to bypass this. If we don't, I have seen some data
413 + parameters get the wrong relcation address. If I link two versions
414 + with and without this section bypassed and then do a binary comparison,
415 + the addresses which are different can be looked up in the map. The
416 + case in which this section has been bypassed has addresses which correspond
417 + to values I can find in the map. */
418 + *addendp -= sym->n_value;
421 + /* If the output symbol is common (in which case this must be a
422 + relocateable link), we need to add in the final size of the
424 + if (h != NULL && h->root.type == bfd_link_hash_common)
425 + *addendp += h->root.u.c.size;
430 +#define coff_rtype_to_howto coff_avr_rtype_to_howto
432 +#include "coffcode.h"
434 +static const bfd_target *
435 +coff_avr_object_p(a)
438 + return coff_object_p (a);
441 +/* Handle all the abominations of AVR COFF:
443 + Generic COFF always uses the D1 slot to indicate the "most
444 + important" derived type, and the D2...Dn slots for decreasing
445 + importance. E. g., a function symbol will always have its DT_FCN
446 + element in D1, an array its DT_ARY (its first DT_ARY in a
447 + multi-dimensional array). In contrast, AVR COFF expects this most
448 + important derived type specifier in the upmost Dn slot that is
449 + allocated at all (i. e. that is != 0).
451 + Generic COFF says that "Any symbol that satisfies more than one
452 + condition [... for AUX entries] should have a union format in its
453 + auxiliary entry." AVR COFF uses sepearate AUX entries for multiple
454 + derived types, and in some cases (like the ISFCN one), even puts
455 + the most important one into the last allocated AUX entry. We
456 + join/split them here at the border as well. Note that when
457 + generating AUX entries (where we need to split them), the n_numaux
458 + field must already have been set up properly (e. g. in
459 + binutils/wrcoff.c) since the entry renumbering and pointerization
460 + would not work otherwise. Thus, we only split the information into
461 + multiple records if n_numaux > 1. For similar reasons, we keep
462 + n_numaux > 1 on input to keep the appropriate AUX entries
463 + allocated, so a symbol can be reconstructed if it is being passed
464 + through one of the GNU tools.
466 + Note that this adjustment is called after the symbol itself has
467 + been swapped in, but before the AUX entries are swapped in. This
468 + is the only hook available that could swap (or merge) AUX entries
469 + at all, so we have to operate on the external AUX entries still. */
472 +avr_coff_adjust_sym_in_post (abfd, ext, in)
477 + struct internal_syment *dst = (struct internal_syment *)in;
478 + unsigned short dt, bt, ndt;
479 + dt = dst->n_type & ~N_BTMASK;
480 + bt = BTYPE (dst->n_type);
482 + /* Some AVR COFF producers seem to violate the COFF specs, and
483 + produce symbols for tag names that have the C_FOO filled in
484 + properly, but T_NULL as the base type value. Patch up here,
485 + since some of our generic COFF tools (in particular
486 + binutils/rdcoff.c) rely on the correct data. */
488 + switch (dst->n_sclass)
503 + /* Swap the derived type slots. */
509 + ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
512 + dst->n_type = (ndt << N_BTSHFT) | bt;
517 + /* If the derived type is function, and there is more than one AUX
518 + entry, swap the first and the last AUX entry, so the most
519 + interesting one will become the first.
521 + If the fundamental type is a tagged type (struct/union/enum), try
522 + to find the AUX entry describing the tagged type (the one that
523 + has x_sym.x_tagndx filled in), and merge the tag index into the
524 + first AUX entry. Depending on the actual input file, there might
525 + be further DT_PTR entries which we just ignore, since we could
526 + not handle that information anyway. */
527 + if (dst->n_numaux > 1 && dst->n_sclass != C_FILE)
529 + AUXENT caux, *auxp1, *auxp2;
533 + symesz = bfd_coff_symesz (abfd);
536 + auxp1 = (AUXENT *)((char *)ext + symesz);
537 + auxp2 = (AUXENT *)((char *)ext + i * symesz);
539 + if (ISFCN (dst->n_type)
540 + || (ISPTR(dst->n_type)
541 + && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)))
550 + if ((ISFCN (dst->n_type) || ISARY (dst->n_type))
551 + && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))
555 + auxp2 = (AUXENT *)((char *)ext + i * symesz);
557 + if (auxp2->x_sym.x_tagndx[0] != 0 || auxp2->x_sym.x_tagndx[1] != 0
558 + || auxp2->x_sym.x_tagndx[2] != 0 || auxp2->x_sym.x_tagndx[3] != 0)
560 + memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx,
561 + 4 * sizeof (char));
572 +/* When exporting an AVR COFF file, just undo all that has been done
573 + above. Again, we are called after the symbol itself has been
574 + swapped out, but before the AUX entries are being written.
575 + Unfortunately, we are only given a pointer to the symbol itself, so
576 + we have to derive the pointer to the respective aux entries from
577 + that address, which is a bit clumsy. */
579 +avr_coff_adjust_sym_out_post (abfd, in, ext)
584 + struct internal_syment *src = (struct internal_syment *)(in);
585 + struct external_syment *dst = (struct external_syment *)(ext);
586 + unsigned short dt, bt, ndt;
588 + dt = src->n_type & ~N_BTMASK;
589 + bt = BTYPE (src->n_type);
596 + ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
599 + H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type);
602 + if (src->n_numaux > 1 && src->n_sclass != C_FILE)
604 + combined_entry_type *srce, *dste;
608 + /* Recover the original combinend_entry_type *. */
609 + hackp = (char *)in;
610 + hackp -= offsetof(combined_entry_type, u.syment);
611 + srce = (combined_entry_type *)hackp;
614 + /* We simply duplicate the first AUX entry as many times as
615 + needed. Since COFF itself normally uses just a single AUX
616 + entry for all the information, this will work -- each COFF
617 + consumer will then just pick the fields it is particularly
618 + interested in. This would not work for the AVR COFF specific
619 + DT_PTR AUX entries, but we don't support them anyway. */
620 + for (i = 1; i < src->n_numaux; i++)
638 + "coff-avr", /* name */
640 + bfd_target_coff_flavour,
641 + BFD_ENDIAN_LITTLE, /* data byte order is little */
642 + BFD_ENDIAN_LITTLE, /* header byte order is little */
644 + (HAS_RELOC | EXEC_P | /* object flags */
645 + HAS_LINENO | HAS_DEBUG |
646 + HAS_SYMS | HAS_LOCALS | WP_TEXT),
648 + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
649 + 0, /* leading char */
650 + '/', /* ar_pad_char */
651 + 15, /* ar_max_namelen */
653 + bfd_getl64, bfd_getl_signed_64, bfd_putl64,
654 + bfd_getl32, bfd_getl_signed_32, bfd_putl32,
655 + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
656 + bfd_getl64, bfd_getl_signed_64, bfd_putl64,
657 + bfd_getl32, bfd_getl_signed_32, bfd_putl32,
658 + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
660 +/* Note that we allow an object file to be treated as a core file as well. */
661 + {_bfd_dummy_target, coff_avr_object_p, /* bfd_check_format */
662 + bfd_generic_archive_p, coff_avr_object_p},
663 + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
665 + {bfd_false, coff_write_object_contents, /* bfd_write_contents */
666 + _bfd_write_archive_contents, bfd_false},
668 + BFD_JUMP_TABLE_GENERIC (coff),
669 + BFD_JUMP_TABLE_COPY (coff),
670 + BFD_JUMP_TABLE_CORE (_bfd_nocore),
671 + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
672 + BFD_JUMP_TABLE_SYMBOLS (coff),
673 + BFD_JUMP_TABLE_RELOCS (coff),
674 + BFD_JUMP_TABLE_WRITE (coff),
675 + BFD_JUMP_TABLE_LINK (coff),
676 + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
682 diff -uNdr binutils-2.17.50.0.18-old/bfd/coff-ext-avr.c binutils-2.17.50.0.18/bfd/coff-ext-avr.c
683 --- binutils-2.17.50.0.18-old/bfd/coff-ext-avr.c 1970-01-01 01:00:00.000000000 +0100
684 +++ binutils-2.17.50.0.18/bfd/coff-ext-avr.c 2007-10-20 16:45:33.000000000 +0200
686 +/* BFD back-end for Atmel AVR "extended" COFF files.
687 + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
688 + Free Software Foundation, Inc.
689 + This is mostly the same as avr-coff, except of the presence of the
690 + COFF optional header.
692 +This file is part of BFD, the Binary File Descriptor library.
694 +This program is free software; you can redistribute it and/or modify
695 +it under the terms of the GNU General Public License as published by
696 +the Free Software Foundation; either version 2 of the License, or
697 +(at your option) any later version.
699 +This program is distributed in the hope that it will be useful,
700 +but WITHOUT ANY WARRANTY; without even the implied warranty of
701 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
702 +GNU General Public License for more details.
704 +You should have received a copy of the GNU General Public License
705 +along with this program; if not, write to the Free Software
706 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
712 +#define AVR_EXT_COFF 1
713 +#include "coff/avr.h"
715 +#include "coff/internal.h"
717 +#include "libcoff.h"
719 +static bfd_reloc_status_type coff_ext_avr_reloc
720 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
721 +static reloc_howto_type *coff_ext_avr_rtype_to_howto
722 + PARAMS ((bfd *, asection *, struct internal_reloc *,
723 + struct coff_link_hash_entry *, struct internal_syment *,
725 +static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *));
727 +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
728 +/* The page size is a guess based on ELF. */
730 +#define COFF_PAGE_SIZE 0x1000
732 +/* For some reason when using avr COFF the value stored in the .text
733 + section for a reference to a common symbol is the value itself plus
734 + any desired offset. Ian Taylor, Cygnus Support. */
736 +/* If we are producing relocateable output, we need to do some
737 + adjustments to the object file that are not done by the
738 + bfd_perform_relocation function. This function is called by every
739 + reloc type to make any required adjustments. */
741 +static bfd_reloc_status_type
742 +coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
745 + arelent *reloc_entry;
748 + asection *input_section ATTRIBUTE_UNUSED;
750 + char **error_message ATTRIBUTE_UNUSED;
754 + if (output_bfd == (bfd *) NULL)
755 + return bfd_reloc_continue;
757 + if (bfd_is_com_section (symbol->section))
759 + /* We are relocating a common symbol. The current value in the
760 + object file is ORIG + OFFSET, where ORIG is the value of the
761 + common symbol as seen by the object file when it was compiled
762 + (this may be zero if the symbol was undefined) and OFFSET is
763 + the offset into the common symbol (normally zero, but may be
764 + non-zero when referring to a field in a common structure).
765 + ORIG is the negative of reloc_entry->addend, which is set by
766 + the CALC_ADDEND macro below. We want to replace the value in
767 + the object file with NEW + OFFSET, where NEW is the value of
768 + the common symbol which we are going to put in the final
769 + object file. NEW is symbol->value. */
770 + diff = symbol->value + reloc_entry->addend;
774 + /* For some reason bfd_perform_relocation always effectively
775 + ignores the addend for a COFF target when producing
776 + relocateable output. This seems to be always wrong for 860
777 + COFF, so we handle the addend here instead. */
778 + diff = reloc_entry->addend;
782 + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
786 + reloc_howto_type *howto = reloc_entry->howto;
787 + unsigned char *addr = (unsigned char *) data + reloc_entry->address;
789 + switch (howto->size)
793 + char x = bfd_get_8 (abfd, addr);
795 + bfd_put_8 (abfd, x, addr);
801 + short x = bfd_get_16 (abfd, addr);
803 + bfd_put_16 (abfd, (bfd_vma) x, addr);
809 + long x = bfd_get_32 (abfd, addr);
811 + bfd_put_32 (abfd, (bfd_vma) x, addr);
820 + /* Now let bfd_perform_relocation finish everything up. */
821 + return bfd_reloc_continue;
825 +#define PCRELOFFSET FALSE
828 +static reloc_howto_type howto_table[] =
836 + HOWTO (R_DIR32, /* type */
837 + 0, /* rightshift */
838 + 2, /* size (0 = byte, 1 = short, 2 = long) */
840 + FALSE, /* pc_relative */
842 + complain_overflow_bitfield, /* complain_on_overflow */
843 + coff_ext_avr_reloc, /* special_function */
844 + "dir32", /* name */
845 + TRUE, /* partial_inplace */
846 + 0xffffffff, /* src_mask */
847 + 0xffffffff, /* dst_mask */
848 + TRUE), /* pcrel_offset */
850 + HOWTO (R_IMAGEBASE, /* type */
851 + 0, /* rightshift */
852 + 2, /* size (0 = byte, 1 = short, 2 = long) */
854 + FALSE, /* pc_relative */
856 + complain_overflow_bitfield, /* complain_on_overflow */
857 + coff_ext_avr_reloc, /* special_function */
858 + "rva32", /* name */
859 + TRUE, /* partial_inplace */
860 + 0xffffffff, /* src_mask */
861 + 0xffffffff, /* dst_mask */
862 + FALSE), /* pcrel_offset */
870 + HOWTO (R_RELBYTE, /* type */
871 + 0, /* rightshift */
872 + 0, /* size (0 = byte, 1 = short, 2 = long) */
874 + FALSE, /* pc_relative */
876 + complain_overflow_bitfield, /* complain_on_overflow */
877 + coff_ext_avr_reloc, /* special_function */
879 + TRUE, /* partial_inplace */
880 + 0x000000ff, /* src_mask */
881 + 0x000000ff, /* dst_mask */
882 + PCRELOFFSET), /* pcrel_offset */
883 + HOWTO (R_RELWORD, /* type */
884 + 0, /* rightshift */
885 + 1, /* size (0 = byte, 1 = short, 2 = long) */
887 + FALSE, /* pc_relative */
889 + complain_overflow_bitfield, /* complain_on_overflow */
890 + coff_ext_avr_reloc, /* special_function */
892 + TRUE, /* partial_inplace */
893 + 0x0000ffff, /* src_mask */
894 + 0x0000ffff, /* dst_mask */
895 + PCRELOFFSET), /* pcrel_offset */
896 + HOWTO (R_RELLONG, /* type */
897 + 0, /* rightshift */
898 + 2, /* size (0 = byte, 1 = short, 2 = long) */
900 + FALSE, /* pc_relative */
902 + complain_overflow_bitfield, /* complain_on_overflow */
903 + coff_ext_avr_reloc, /* special_function */
905 + TRUE, /* partial_inplace */
906 + 0xffffffff, /* src_mask */
907 + 0xffffffff, /* dst_mask */
908 + PCRELOFFSET), /* pcrel_offset */
909 + HOWTO (R_PCRBYTE, /* type */
910 + 0, /* rightshift */
911 + 0, /* size (0 = byte, 1 = short, 2 = long) */
913 + TRUE, /* pc_relative */
915 + complain_overflow_signed, /* complain_on_overflow */
916 + coff_ext_avr_reloc, /* special_function */
917 + "DISP8", /* name */
918 + TRUE, /* partial_inplace */
919 + 0x000000ff, /* src_mask */
920 + 0x000000ff, /* dst_mask */
921 + PCRELOFFSET), /* pcrel_offset */
922 + HOWTO (R_PCRWORD, /* type */
923 + 0, /* rightshift */
924 + 1, /* size (0 = byte, 1 = short, 2 = long) */
926 + TRUE, /* pc_relative */
928 + complain_overflow_signed, /* complain_on_overflow */
929 + coff_ext_avr_reloc, /* special_function */
930 + "DISP16", /* name */
931 + TRUE, /* partial_inplace */
932 + 0x0000ffff, /* src_mask */
933 + 0x0000ffff, /* dst_mask */
934 + PCRELOFFSET), /* pcrel_offset */
935 + HOWTO (R_PCRLONG, /* type */
936 + 0, /* rightshift */
937 + 2, /* size (0 = byte, 1 = short, 2 = long) */
939 + TRUE, /* pc_relative */
941 + complain_overflow_signed, /* complain_on_overflow */
942 + coff_ext_avr_reloc, /* special_function */
943 + "DISP32", /* name */
944 + TRUE, /* partial_inplace */
945 + 0xffffffff, /* src_mask */
946 + 0xffffffff, /* dst_mask */
947 + PCRELOFFSET) /* pcrel_offset */
950 +/* Turn a howto into a reloc nunmber */
952 +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
953 +#define BADMAG(x) AVRBADMAG(x)
954 +#define AVR 1 /* Customize coffcode.h */
956 +#define RTYPE2HOWTO(cache_ptr, dst) \
957 + (cache_ptr)->howto = howto_table + (dst)->r_type;
959 +/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
960 + library. On some other COFF targets STYP_BSS is normally
962 +#define BSS_NOLOAD_IS_SHARED_LIBRARY
964 +/* Compute the addend of a reloc. If the reloc is to a common symbol,
965 + the object file contains the value of the common symbol. By the
966 + time this is called, the linker may be using a different symbol
967 + from a different object file with a different value. Therefore, we
968 + hack wildly to locate the original symbol from this file so that we
969 + can make the correct adjustment. This macro sets coffsym to the
970 + symbol from the original file, and uses it to set the addend value
971 + correctly. If this is not a common symbol, the usual addend
972 + calculation is done, except that an additional tweak is needed for
973 + PC relative relocs.
974 + FIXME: This macro refers to symbols and asect; these are from the
975 + calling function, not the macro arguments. */
977 +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
979 + coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
980 + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
981 + coffsym = (obj_symbols (abfd) \
982 + + (cache_ptr->sym_ptr_ptr - symbols)); \
984 + coffsym = coff_symbol_from (abfd, ptr); \
985 + if (coffsym != (coff_symbol_type *) NULL \
986 + && coffsym->native->u.syment.n_scnum == 0) \
987 + cache_ptr->addend = - coffsym->native->u.syment.n_value; \
988 + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
989 + && ptr->section != (asection *) NULL) \
990 + cache_ptr->addend = - (ptr->section->vma + ptr->value); \
992 + cache_ptr->addend = 0; \
993 + if (ptr && howto_table[reloc.r_type].pc_relative) \
994 + cache_ptr->addend += asect->vma; \
997 +/* We use the special COFF backend linker. */
998 +#define coff_relocate_section _bfd_coff_generic_relocate_section
1000 +static reloc_howto_type *
1001 +coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
1002 + bfd *abfd ATTRIBUTE_UNUSED;
1004 + struct internal_reloc *rel;
1005 + struct coff_link_hash_entry *h;
1006 + struct internal_syment *sym;
1010 + reloc_howto_type *howto;
1012 + howto = howto_table + rel->r_type;
1014 + if (howto->pc_relative)
1015 + *addendp += sec->vma;
1017 + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
1019 + /* This is a common symbol. The section contents include the
1020 + size (sym->n_value) as an addend. The relocate_section
1021 + function will be adding in the final value of the symbol. We
1022 + need to subtract out the current size in order to get the
1023 + correct result. */
1025 + BFD_ASSERT (h != NULL);
1027 + /* I think we *do* want to bypass this. If we don't, I have seen some data
1028 + parameters get the wrong relcation address. If I link two versions
1029 + with and without this section bypassed and then do a binary comparison,
1030 + the addresses which are different can be looked up in the map. The
1031 + case in which this section has been bypassed has addresses which correspond
1032 + to values I can find in the map. */
1033 + *addendp -= sym->n_value;
1036 + /* If the output symbol is common (in which case this must be a
1037 + relocateable link), we need to add in the final size of the
1039 + if (h != NULL && h->root.type == bfd_link_hash_common)
1040 + *addendp += h->root.u.c.size;
1045 +#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto
1047 +#include "coffcode.h"
1049 +static const bfd_target *
1050 +coff_ext_avr_object_p(a)
1053 + return coff_object_p (a);
1066 + "coff-ext-avr", /* name */
1068 + bfd_target_coff_flavour,
1069 + BFD_ENDIAN_LITTLE, /* data byte order is little */
1070 + BFD_ENDIAN_LITTLE, /* header byte order is little */
1072 + (HAS_RELOC | EXEC_P | /* object flags */
1073 + HAS_LINENO | HAS_DEBUG |
1074 + HAS_SYMS | HAS_LOCALS | WP_TEXT),
1076 + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1077 + 0, /* leading char */
1078 + '/', /* ar_pad_char */
1079 + 15, /* ar_max_namelen */
1081 + bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1082 + bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1083 + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1084 + bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1085 + bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1086 + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1088 +/* Note that we allow an object file to be treated as a core file as well. */
1089 + {_bfd_dummy_target, coff_ext_avr_object_p, /* bfd_check_format */
1090 + bfd_generic_archive_p, coff_ext_avr_object_p},
1091 + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
1093 + {bfd_false, coff_write_object_contents, /* bfd_write_contents */
1094 + _bfd_write_archive_contents, bfd_false},
1096 + BFD_JUMP_TABLE_GENERIC (coff),
1097 + BFD_JUMP_TABLE_COPY (coff),
1098 + BFD_JUMP_TABLE_CORE (_bfd_nocore),
1099 + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1100 + BFD_JUMP_TABLE_SYMBOLS (coff),
1101 + BFD_JUMP_TABLE_RELOCS (coff),
1102 + BFD_JUMP_TABLE_WRITE (coff),
1103 + BFD_JUMP_TABLE_LINK (coff),
1104 + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1110 diff -uNdr binutils-2.17.50.0.18-old/bfd/coffcode.h binutils-2.17.50.0.18/bfd/coffcode.h
1111 --- binutils-2.17.50.0.18-old/bfd/coffcode.h 2007-08-01 17:12:02.000000000 +0200
1112 +++ binutils-2.17.50.0.18/bfd/coffcode.h 2007-10-20 16:45:33.000000000 +0200
1115 /* Support for the generic parts of most COFF variants, for BFD.
1116 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
1117 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
1118 @@ -1767,6 +1768,17 @@
1119 coff->relocbase = 0;
1120 coff->local_toc_sym_map = 0;
1122 + /* These members communicate important constants about the symbol
1123 + table to GDB's symbol-reading code. These `constants'
1124 + unfortunately vary among coff implementations... */
1125 + coff->local_n_btmask = N_BTMASK;
1126 + coff->local_n_btshft = N_BTSHFT;
1127 + coff->local_n_tmask = N_TMASK;
1128 + coff->local_n_tshift = N_TSHIFT;
1129 + coff->local_symesz = bfd_coff_symesz (abfd);
1130 + coff->local_auxesz = bfd_coff_auxesz (abfd);
1131 + coff->local_linesz = bfd_coff_linesz (abfd);
1133 /* make_abs_section(abfd);*/
1136 @@ -1791,17 +1803,6 @@
1138 coff->sym_filepos = internal_f->f_symptr;
1140 - /* These members communicate important constants about the symbol
1141 - table to GDB's symbol-reading code. These `constants'
1142 - unfortunately vary among coff implementations... */
1143 - coff->local_n_btmask = N_BTMASK;
1144 - coff->local_n_btshft = N_BTSHFT;
1145 - coff->local_n_tmask = N_TMASK;
1146 - coff->local_n_tshift = N_TSHIFT;
1147 - coff->local_symesz = bfd_coff_symesz (abfd);
1148 - coff->local_auxesz = bfd_coff_auxesz (abfd);
1149 - coff->local_linesz = bfd_coff_linesz (abfd);
1151 coff->timestamp = internal_f->f_timdat;
1153 obj_raw_syment_count (abfd) =
1154 @@ -1928,6 +1929,11 @@
1160 + arch = bfd_arch_avr;
1166 @@ -2724,6 +2730,13 @@
1171 + case bfd_arch_avr:
1172 + *magicp = AVRMAGIC;
1178 case bfd_arch_powerpc:
1180 @@ -3520,6 +3533,11 @@
1181 section.s_page = coff_get_section_load_page (current);
1185 + /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively
1186 + ignores s_vaddr. */
1187 + section.s_paddr = current->vma;
1190 section.s_paddr = 0;
1192 @@ -3864,6 +3882,17 @@
1193 internal_a.magic = ZMAGIC;
1197 + /* a.out is a dummy for non-extended COFF */
1198 + internal_a.magic = AVRAOUTMAGIC;
1199 + /* Upper nibble of f_flags must be set for historical reasons.
1200 + The upper byte remains blank on coff-avr, so undo the F_AR32WR
1201 + setting performed above. */
1202 + internal_f.f_flags |= F_JUNK;
1203 + internal_f.f_flags &= ~F_UNUSED;
1204 +#define __A_MAGIC_SET__
1208 #define __A_MAGIC_SET__
1209 internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
1210 @@ -3931,8 +3960,16 @@
1214 +#ifdef AVR_EXT_COFF
1215 + /* Note that we do not set F_PTRINFO because the GNU toolchain
1216 + doesn't provide any information about the target of a pointer,
1217 + so we cannot derive which section our pointer target would be
1219 + internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO;
1221 /* FIXME: Does anybody ever set this to another value? */
1222 internal_a.vstamp = 0;
1225 /* Now should write relocs, strings, syms. */
1226 obj_sym_filepos (abfd) = sym_base;
1227 @@ -4118,22 +4155,29 @@
1229 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1231 - buff = bfd_malloc (amount);
1234 + /* Do not attempt to malloc() zero bytes. According to the
1235 + C standard, the behaviour is implementation-defined, and
1236 + malloc() might return NULL in that case, which would confuse
1237 + us to assume an error where it actually isn't. */
1240 + buff = bfd_malloc (amount);
1244 - coff_swap_aouthdr_out (abfd, & internal_a, buff);
1245 - amount = bfd_bwrite (buff, amount, abfd);
1246 + coff_swap_aouthdr_out (abfd, & internal_a, buff);
1247 + amount = bfd_bwrite (buff, amount, abfd);
1252 - if (amount != bfd_coff_aoutsz (abfd))
1254 + if (amount != bfd_coff_aoutsz (abfd))
1257 #ifdef COFF_IMAGE_WITH_PE
1258 - if (! coff_apply_checksum (abfd))
1260 + if (! coff_apply_checksum (abfd))
1267 @@ -4414,6 +4458,10 @@
1268 /* In PE, 0x69 (105) denotes a weak external symbol. */
1272 + /* Some AVR COFF compilers handle EXTDEF like EXT. */
1273 + case C_EXTDEF: /* external definition */
1275 switch (coff_classify_symbol (abfd, &src->u.syment))
1277 case COFF_SYMBOL_GLOBAL:
1278 @@ -4637,7 +4685,9 @@
1279 && src->u.syment.n_scnum == 0)
1283 case C_EXTDEF: /* External definition. */
1285 case C_ULABEL: /* Undefined label. */
1286 case C_USTATIC: /* Undefined static. */
1287 #ifndef COFF_WITH_PE
1288 diff -uNdr binutils-2.17.50.0.18-old/bfd/coffgen.c binutils-2.17.50.0.18/bfd/coffgen.c
1289 --- binutils-2.17.50.0.18-old/bfd/coffgen.c 2007-08-01 15:11:47.000000000 +0200
1290 +++ binutils-2.17.50.0.18/bfd/coffgen.c 2007-10-20 16:45:33.000000000 +0200
1291 @@ -687,6 +687,20 @@
1292 if (last_file != NULL)
1293 last_file->n_value = native_index;
1294 last_file = &(s->u.syment);
1295 + if (bfd_get_arch (bfd_ptr) == bfd_arch_avr
1296 + && bfd_coff_long_filenames (bfd_ptr)
1297 + && s->u.syment.n_numaux > 0)
1299 + /* AVR COFF records long filenames in successive aux
1300 + records. Adjust the number of aux records
1301 + required here, so the renumbering will account
1303 + unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr);
1304 + unsigned int namelen = strlen (coff_symbol_ptr->symbol.name);
1305 + unsigned int n = (namelen + filnmlen - 1) / filnmlen;
1307 + s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n;
1311 /* Modify the symbol values according to their section and
1312 @@ -815,6 +829,20 @@
1314 if (name_length <= filnmlen)
1315 strncpy (auxent->x_file.x_fname, name, filnmlen);
1316 + else if (bfd_get_arch (abfd) == bfd_arch_avr)
1318 + /* AVR COFF records long filenames in successive aux records. */
1320 + while (name_length > filnmlen && i < NAUXENTS)
1322 + strncpy (auxent->x_file.x_fname, name, filnmlen);
1324 + name_length -= filnmlen;
1326 + auxent = &(native + i)->u.auxent;
1328 + strncpy (auxent->x_file.x_fname, name, filnmlen);
1332 auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
1333 @@ -1218,7 +1246,11 @@
1334 if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
1337 - maxlen = bfd_coff_filnmlen (abfd);
1338 + if (bfd_get_arch (abfd) == bfd_arch_avr)
1339 + /* AVR COFF handles long file names in aux records. */
1340 + maxlen = name_length;
1342 + maxlen = bfd_coff_filnmlen (abfd);
1345 maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
1346 @@ -1655,14 +1687,27 @@
1348 /* Ordinary short filename, put into memory anyway. The
1349 Microsoft PE tools sometimes store a filename in
1350 - multiple AUX entries. */
1351 - if (internal_ptr->u.syment.n_numaux > 1
1352 - && coff_data (abfd)->pe)
1353 - internal_ptr->u.syment._n._n_n._n_offset =
1356 - (internal_ptr + 1)->u.auxent.x_file.x_fname,
1357 - internal_ptr->u.syment.n_numaux * symesz));
1358 + multiple AUX entries.
1359 + AVR COFF does it that way, too. */
1360 + if (internal_ptr->u.syment.n_numaux > 1
1361 + && (coff_data (abfd)->pe
1362 + || (bfd_get_arch (abfd) == bfd_arch_avr)))
1367 + /* We allocate enough storage to fit the contents of
1368 + this many aux records, and simply append a \0.
1369 + This ensures the string will always be
1370 + terminated, even in the case where it just fit
1371 + into the aux records. */
1372 + b = (char *) bfd_alloc (abfd,
1373 + internal_ptr->u.syment.n_numaux * FILNMLEN + 1);
1374 + internal_ptr->u.syment._n._n_n._n_offset = (long) b;
1375 + b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0';
1376 + for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN)
1377 + memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN);
1380 internal_ptr->u.syment._n._n_n._n_offset =
1382 @@ -1768,9 +1813,9 @@
1386 - /* @@ The 10 is a guess at a plausible maximum number of aux entries
1387 - (but shouldn't be a constant). */
1388 - amt = sizeof (combined_entry_type) * 10;
1389 + /* @@ The NAUXENTS is a guess at a plausible maximum number of aux
1390 + entries (but shouldn't be a constant). */
1391 + amt = sizeof (combined_entry_type) * (NAUXENTS + 1);
1392 new->native = bfd_zalloc (abfd, amt);
1395 diff -uNdr binutils-2.17.50.0.18-old/bfd/coffswap.h binutils-2.17.50.0.18/bfd/coffswap.h
1396 --- binutils-2.17.50.0.18-old/bfd/coffswap.h 2007-08-01 15:11:47.000000000 +0200
1397 +++ binutils-2.17.50.0.18/bfd/coffswap.h 2007-10-20 16:45:33.000000000 +0200
1398 @@ -383,7 +383,11 @@
1404 +#if defined(AVR) && __GNUC__
1405 + __attribute__((unused))
1411 @@ -409,9 +413,13 @@
1416 + memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT));
1419 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
1420 numaux * sizeof (AUXENT));
1424 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
1425 diff -uNdr binutils-2.17.50.0.18-old/bfd/config.bfd binutils-2.17.50.0.18/bfd/config.bfd
1426 --- binutils-2.17.50.0.18-old/bfd/config.bfd 2007-08-01 15:11:47.000000000 +0200
1427 +++ binutils-2.17.50.0.18/bfd/config.bfd 2007-10-20 16:45:33.000000000 +0200
1431 targ_defvec=bfd_elf32_avr_vec
1432 + targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec"
1436 diff -uNdr binutils-2.17.50.0.18-old/bfd/configure binutils-2.17.50.0.18/bfd/configure
1437 --- binutils-2.17.50.0.18-old/bfd/configure 2007-08-01 15:11:47.000000000 +0200
1438 +++ binutils-2.17.50.0.18/bfd/configure 2007-10-20 16:45:33.000000000 +0200
1439 @@ -19034,6 +19034,8 @@
1440 armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
1441 armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1442 armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1443 + avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;;
1444 + avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;;
1445 b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
1446 b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
1447 bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;;
1448 diff -uNdr binutils-2.17.50.0.18-old/bfd/configure.in binutils-2.17.50.0.18/bfd/configure.in
1449 --- binutils-2.17.50.0.18-old/bfd/configure.in 2007-08-01 15:11:47.000000000 +0200
1450 +++ binutils-2.17.50.0.18/bfd/configure.in 2007-10-20 16:45:33.000000000 +0200
1452 armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
1453 armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1454 armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1455 + avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;;
1456 + avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;;
1457 b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
1458 b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
1459 bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;;
1460 diff -uNdr binutils-2.17.50.0.18-old/bfd/targets.c binutils-2.17.50.0.18/bfd/targets.c
1461 --- binutils-2.17.50.0.18-old/bfd/targets.c 2007-08-01 15:11:48.000000000 +0200
1462 +++ binutils-2.17.50.0.18/bfd/targets.c 2007-10-20 16:45:33.000000000 +0200
1464 extern const bfd_target armpe_little_vec;
1465 extern const bfd_target armpei_big_vec;
1466 extern const bfd_target armpei_little_vec;
1467 +extern const bfd_target avrcoff_vec;
1468 +extern const bfd_target avrextcoff_vec;
1469 extern const bfd_target b_out_vec_big_host;
1470 extern const bfd_target b_out_vec_little_host;
1471 extern const bfd_target bfd_efi_app_ia32_vec;
1478 &b_out_vec_big_host,
1479 &b_out_vec_little_host,
1480 &bfd_efi_app_ia32_vec,
1481 diff -uNdr binutils-2.17.50.0.18-old/binutils/Makefile.am binutils-2.17.50.0.18/binutils/Makefile.am
1482 --- binutils-2.17.50.0.18-old/binutils/Makefile.am 2007-08-01 15:11:48.000000000 +0200
1483 +++ binutils-2.17.50.0.18/binutils/Makefile.am 2007-10-20 16:45:33.000000000 +0200
1485 resbin.c rescoff.c resrc.c resres.c \
1486 size.c srconv.c stabs.c strings.c sysdump.c \
1487 unwind-ia64.c version.c \
1488 - windres.c winduni.c wrstabs.c \
1489 + windres.c winduni.c wrcoff.c wrstabs.c \
1492 GENERATED_CFILES = \
1494 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1496 DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
1497 -WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
1498 +WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c
1500 # Code shared by all the binutils.
1501 BULIBS = bucomm.c version.c filemode.c
1502 diff -uNdr binutils-2.17.50.0.18-old/binutils/Makefile.in binutils-2.17.50.0.18/binutils/Makefile.in
1503 --- binutils-2.17.50.0.18-old/binutils/Makefile.in 2007-08-01 15:11:48.000000000 +0200
1504 +++ binutils-2.17.50.0.18/binutils/Makefile.in 2007-10-20 16:45:33.000000000 +0200
1506 nm_new_OBJECTS = $(am_nm_new_OBJECTS)
1507 nm_new_LDADD = $(LDADD)
1508 am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
1509 - ieee.$(OBJEXT) rdcoff.$(OBJEXT)
1510 + ieee.$(OBJEXT) rdcoff.$(OBJEXT) wrcoff.$(OBJEXT)
1511 am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT)
1512 am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \
1513 rename.$(OBJEXT) $(am__objects_3) $(am__objects_1)
1515 resbin.c rescoff.c resrc.c resres.c \
1516 size.c srconv.c stabs.c strings.c sysdump.c \
1517 unwind-ia64.c version.c \
1518 - windres.c winduni.c wrstabs.c \
1519 + windres.c winduni.c wrcoff.c wrstabs.c \
1522 GENERATED_CFILES = \
1524 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1526 DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
1527 -WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
1528 +WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c
1530 # Code shared by all the binutils.
1531 BULIBS = bucomm.c version.c filemode.c
1532 diff -uNdr binutils-2.17.50.0.18-old/binutils/bucomm.c binutils-2.17.50.0.18/binutils/bucomm.c
1533 --- binutils-2.17.50.0.18-old/binutils/bucomm.c 2007-08-01 15:11:49.000000000 +0200
1534 +++ binutils-2.17.50.0.18/binutils/bucomm.c 2007-10-20 16:45:33.000000000 +0200
1535 @@ -501,6 +501,32 @@
1539 +/* Return the basename of "file", i. e. everything minus whatever
1540 + directory part has been provided. Stolen from bfd/archive.c.
1541 + Should we also handle the VMS case (as in bfd/archive.c)? */
1546 + const char *filename = strrchr (file, '/');
1548 +#ifdef HAVE_DOS_BASED_FILE_SYSTEM
1550 + /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
1551 + char *bslash = strrchr (file, '\\');
1552 + if (filename == NULL || (bslash != NULL && bslash > filename))
1553 + filename = bslash;
1554 + if (filename == NULL && file[0] != '\0' && file[1] == ':')
1555 + filename = file + 1;
1558 + if (filename != (char *) NULL)
1565 /* Returns the size of the named file. If the file does not
1566 exist, or if it is not a real file, then a suitable non-fatal
1567 error message is printed and zero is returned. */
1568 diff -uNdr binutils-2.17.50.0.18-old/binutils/bucomm.h binutils-2.17.50.0.18/binutils/bucomm.h
1569 --- binutils-2.17.50.0.18-old/binutils/bucomm.h 2007-08-01 15:11:49.000000000 +0200
1570 +++ binutils-2.17.50.0.18/binutils/bucomm.h 2007-10-20 16:45:33.000000000 +0200
1573 off_t get_file_size (const char *);
1575 +const char *bu_basename PARAMS ((const char *));
1577 extern char *program_name;
1580 diff -uNdr binutils-2.17.50.0.18-old/binutils/budbg.h binutils-2.17.50.0.18/binutils/budbg.h
1581 --- binutils-2.17.50.0.18-old/binutils/budbg.h 2007-08-01 15:11:49.000000000 +0200
1582 +++ binutils-2.17.50.0.18/binutils/budbg.h 2007-10-20 16:45:33.000000000 +0200
1585 extern bfd_boolean write_ieee_debugging_info (bfd *, void *);
1587 -/* Routine used to read COFF debugging information. */
1588 +/* Routine used to read and write COFF debugging information. */
1590 extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *);
1592 +extern bfd_boolean write_coff_debugging_info
1593 + (bfd *abfd, void *, long *symcountp, asymbol ***);
1596 diff -uNdr binutils-2.17.50.0.18-old/binutils/debug.c binutils-2.17.50.0.18/binutils/debug.c
1597 --- binutils-2.17.50.0.18-old/binutils/debug.c 2007-08-01 15:11:49.000000000 +0200
1598 +++ binutils-2.17.50.0.18/binutils/debug.c 2007-10-20 16:45:33.000000000 +0200
1602 #include "libiberty.h"
1603 +#include "bucomm.h"
1606 /* Global information we keep for debugging. A pointer to this
1607 @@ -552,6 +553,19 @@
1608 struct debug_type *t;
1611 +/* Simple list, used for pathname translations. */
1614 + /* Next string on list. */
1615 + struct xlat_list *next;
1616 + /* Old part to match against. */
1619 + /* New part to replace. */
1620 + const char *newstr;
1624 /* Local functions. */
1626 static void debug_error (const char *);
1627 @@ -588,6 +602,11 @@
1628 (struct debug_handle *, struct debug_type *, struct debug_type *);
1629 static bfd_boolean debug_class_type_samep
1630 (struct debug_handle *, struct debug_type *, struct debug_type *);
1631 +static const char *debug_xlat_pathname (const char *);
1633 +/* List of pathname translations. */
1634 +static struct xlat_list *xlat, *xltail;
1635 +static bfd_boolean xlat_basename;
1637 /* Issue an error message. */
1644 + name = debug_xlat_pathname (name);
1646 nfile = (struct debug_file *) xmalloc (sizeof *nfile);
1647 memset (nfile, 0, sizeof *nfile);
1653 + name = debug_xlat_pathname (name);
1655 if (info->current_unit == NULL)
1657 @@ -3370,3 +3393,69 @@
1662 +/* Register a pathname translation. */
1664 +debug_register_pathname_xlat (oname, nname)
1665 + const char *oname;
1666 + const char *nname;
1668 + struct xlat_list *xlp;
1670 + /* Special case: if oname is given as NULL, this means the
1671 + --basename option has been given to objcopy. */
1672 + if (oname == NULL)
1674 + xlat_basename = TRUE;
1678 + xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list));
1681 + xlat = xltail = xlp;
1684 + xltail->next = xlp;
1688 + xlp->newstr = nname;
1689 + xlp->olen = strlen (oname);
1690 + xlp->nlen = strlen (nname);
1693 +/* Try to translate a pathname. */
1694 +static const char *
1695 +debug_xlat_pathname (oname)
1696 + const char *oname;
1698 + struct xlat_list *xlp;
1702 + if (xlat_basename)
1703 + return bu_basename (oname);
1705 + olen = strlen (oname);
1706 + for (xlp = xlat; xlp; xlp = xlp->next)
1708 + if (xlp->olen > olen)
1709 + /* This cannot be our turn. */
1711 + /* Since we have pre-computed all our length values to avoid
1712 + repetitively computing them, just use memcmp() since it's
1713 + faster than strcmp(). */
1714 + if (memcmp (xlp->old, oname, xlp->olen) == 0)
1716 + cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1);
1717 + memcpy (cp, xlp->newstr, xlp->nlen);
1718 + memcpy (cp + xlp->nlen, oname + xlp->olen,
1719 + olen - xlp->olen + 1);
1724 + /* Not found, pass the original name on. */
1727 diff -uNdr binutils-2.17.50.0.18-old/binutils/debug.h binutils-2.17.50.0.18/binutils/debug.h
1728 --- binutils-2.17.50.0.18-old/binutils/debug.h 2007-08-01 15:11:49.000000000 +0200
1729 +++ binutils-2.17.50.0.18/binutils/debug.h 2007-10-20 16:45:33.000000000 +0200
1730 @@ -440,6 +440,12 @@
1732 extern bfd_boolean debug_start_source (void *, const char *);
1734 +/* Register a pathname translation for source (and include) filenames.
1735 + This is used by the --change-pathname option of objcopy. */
1737 +extern void debug_register_pathname_xlat
1738 + PARAMS ((const char *, const char *));
1740 /* Record a function definition. This implicitly starts a function
1741 block. The debug_type argument is the type of the return value.
1742 The bfd_boolean indicates whether the function is globally visible.
1743 diff -uNdr binutils-2.17.50.0.18-old/binutils/objcopy.c binutils-2.17.50.0.18/binutils/objcopy.c
1744 --- binutils-2.17.50.0.18-old/binutils/objcopy.c 2007-08-01 15:11:49.000000000 +0200
1745 +++ binutils-2.17.50.0.18/binutils/objcopy.c 2007-10-20 16:45:33.000000000 +0200
1747 #include "elf-bfd.h"
1748 #include <sys/stat.h>
1752 /* A list of symbols to explicitly strip out, or to keep. A linked
1753 list is good enough for a small number from the command line, but
1757 OPTION_EXTRACT_SYMBOL,
1758 - OPTION_REVERSE_BYTES
1759 + OPTION_REVERSE_BYTES,
1760 + OPTION_CHANGE_PATHNAME,
1764 /* Options to handle if running as "strip". */
1765 @@ -316,10 +319,12 @@
1766 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
1767 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
1768 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
1769 + {"basename", no_argument, 0, OPTION_BASENAME},
1770 {"binary-architecture", required_argument, 0, 'B'},
1771 {"byte", required_argument, 0, 'b'},
1772 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
1773 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
1774 + {"change-pathname", required_argument, 0, OPTION_CHANGE_PATHNAME},
1775 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
1776 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
1777 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
1779 --prefix-alloc-sections <prefix>\n\
1780 Add <prefix> to start of every allocatable\n\
1782 + --change-pathname <old>=<new> Change debug pathnames from <old> to <new>\n\
1783 + --basename Strip directory part from debug pathnames\n\
1784 -v --verbose List all object files modified\n\
1785 @<file> Read options from <file>\n\
1786 -V --version Display this program's version number\n\
1788 asymbol **from = isyms, **to = osyms;
1789 long src_count = 0, dst_count = 0;
1790 int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
1791 + bfd_boolean need_for_debugging = convert_debugging
1792 + && bfd_get_arch (abfd) == bfd_arch_avr;
1794 for (; src_count < symcount; src_count++)
1796 @@ -1010,9 +1019,10 @@
1797 || bfd_is_com_section (bfd_get_section (sym)))
1798 keep = strip_symbols != STRIP_UNNEEDED;
1799 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
1800 - keep = (strip_symbols != STRIP_DEBUG
1801 - && strip_symbols != STRIP_UNNEEDED
1802 - && ! convert_debugging);
1803 + keep = need_for_debugging
1804 + || (strip_symbols != STRIP_DEBUG
1805 + && strip_symbols != STRIP_UNNEEDED
1806 + && ! convert_debugging);
1807 else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
1808 /* COMDAT sections store special information in local
1809 symbols, so we cannot risk stripping any of them. */
1810 @@ -2579,6 +2589,10 @@
1811 return write_ieee_debugging_info (obfd, dhandle);
1813 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1814 + && bfd_get_arch (obfd) == bfd_arch_avr)
1815 + return write_coff_debugging_info (obfd, dhandle, symcountp, symppp);
1817 + if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1818 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1820 bfd_byte *syms, *strings;
1821 @@ -3280,6 +3294,30 @@
1822 prefix_alloc_sections_string = optarg;
1825 + case OPTION_CHANGE_PATHNAME:
1831 + s = strchr (optarg, '=');
1833 + fatal (_("bad format for %s"), "--change-pathname");
1836 + name = (char *) xmalloc (len + 1);
1837 + strncpy (name, optarg, len);
1840 + debug_register_pathname_xlat (name, s + 1);
1844 + case OPTION_BASENAME:
1845 + /* very special case of pathname translation */
1846 + debug_register_pathname_xlat (NULL, NULL);
1849 case OPTION_READONLY_TEXT:
1850 bfd_flags_to_set |= WP_TEXT;
1851 bfd_flags_to_clear &= ~WP_TEXT;
1852 diff -uNdr binutils-2.17.50.0.18-old/binutils/rdcoff.c binutils-2.17.50.0.18/binutils/rdcoff.c
1853 --- binutils-2.17.50.0.18-old/binutils/rdcoff.c 2007-08-01 15:11:49.000000000 +0200
1854 +++ binutils-2.17.50.0.18/binutils/rdcoff.c 2007-10-20 16:45:33.000000000 +0200
1856 struct coff_slots *slots;
1858 debug_type basic[T_MAX + 1];
1859 + /* Some general information, kept here for convenience. */
1860 + size_t intsize; /* sizeof (int) */
1861 + size_t doublesize; /* sizeof (double) */
1864 static debug_type *coff_get_slot (struct coff_types *, int);
1866 (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
1867 void *, debug_type, bfd_boolean);
1868 static bfd_boolean external_coff_symbol_p (int sym_class);
1869 +static bfd_vma coff_convert_register (bfd *, bfd_vma);
1871 /* Return the slot for a type. */
1877 - /* FIXME: Perhaps the size should depend upon the architecture. */
1878 - ret = debug_make_int_type (dhandle, 4, FALSE);
1879 + ret = debug_make_int_type (dhandle, types->intsize, FALSE);
1887 - ret = debug_make_float_type (dhandle, 8);
1888 + ret = debug_make_float_type (dhandle, types->doublesize);
1896 - ret = debug_make_int_type (dhandle, 4, TRUE);
1897 + ret = debug_make_int_type (dhandle, types->intsize, TRUE);
1898 name = "unsigned int";
1905 + /* AVR COFF abuses C_EXTDEF */
1907 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
1908 DEBUG_GLOBAL, bfd_asymbol_value (sym)))
1914 - /* FIXME: We may need to convert the register number. */
1915 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
1916 - DEBUG_REGISTER, bfd_asymbol_value (sym)))
1918 + coff_convert_register (abfd, bfd_asymbol_value (sym))))
1926 - /* FIXME: We may need to convert the register number. */
1927 if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
1928 - DEBUG_PARM_REG, bfd_asymbol_value (sym)))
1930 + coff_convert_register (abfd, bfd_asymbol_value (sym))))
1934 @@ -648,6 +653,28 @@
1939 +coff_convert_register (abfd, val)
1944 + switch (bfd_get_arch (abfd))
1946 + case bfd_arch_avr:
1947 + /* AVR COFF wants to describe up to four registers by the four
1948 + bytes of the 32-bit value. Unused bytes are filled with
1949 + 0xff. In theory, this would allow for non-contiguous
1950 + register usage to hold a single value, but hopefully, no
1951 + compiler is going to use that feature. We could not handle
1953 + return val & 0xff;
1960 /* This is the main routine. It looks through all the symbols and
1963 @@ -674,6 +701,17 @@
1965 for (i = 0; i <= T_MAX; i++)
1966 types.basic[i] = DEBUG_TYPE_NULL;
1967 + switch (bfd_get_arch (abfd))
1969 + case bfd_arch_avr:
1970 + types.intsize = 2;
1971 + types.doublesize = 4;
1975 + types.intsize = 4;
1976 + types.doublesize = 8;
1982 switch (syment.n_sclass)
1993 + /* AVR COFF abuses C_EXTDEF for C_EXT */
1995 if (ISFCN (syment.n_type))
1998 diff -uNdr binutils-2.17.50.0.18-old/binutils/wrcoff.c binutils-2.17.50.0.18/binutils/wrcoff.c
1999 --- binutils-2.17.50.0.18-old/binutils/wrcoff.c 1970-01-01 01:00:00.000000000 +0100
2000 +++ binutils-2.17.50.0.18/binutils/wrcoff.c 2007-10-20 16:45:53.000000000 +0200
2002 +/* wrcoff.c -- Generate (AVR) COFF debugging information
2003 + Copyright 2003 Free Software Foundation, Inc.
2005 + Written by Joerg Wunsch.
2007 + This file is part of GNU Binutils.
2009 + This program is free software; you can redistribute it and/or modify
2010 + it under the terms of the GNU General Public License as published by
2011 + the Free Software Foundation; either version 2 of the License, or
2012 + (at your option) any later version.
2014 + This program is distributed in the hope that it will be useful,
2015 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2016 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2017 + GNU General Public License for more details.
2019 + You should have received a copy of the GNU General Public License
2020 + along with this program; if not, write to the Free Software
2021 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
2022 + 02111-1307, USA. */
2024 +/* This file contains code which writes out COFF debugging
2025 + information. By now, this has only been tested on the AVR
2026 + platform, though any attempt has been made to keep the conversion
2027 + applicable to possible other COFF debugging consumers as well. */
2029 +#include <assert.h>
2030 +#include "sysdep.h"
2032 +#include "coff/internal.h"
2033 +#include "bucomm.h"
2034 +#include "libiberty.h"
2035 +#include "safe-ctype.h"
2039 +/* Enabling COFF_DEBUG will trace the internal callback functions and
2040 + their parameters as debug_write() calls them. */
2041 +//#define COFF_DEBUG 1
2043 +#include "libcoff.h"
2045 +#define N_TMASK (coff_data (info->abfd)->local_n_tmask)
2046 +#define N_BTSHFT (coff_data (info->abfd)->local_n_btshft)
2047 +#define N_BTMASK (coff_data (info->abfd)->local_n_btmask)
2048 +#define N_TSHIFT (coff_data (info->abfd)->local_n_tshift)
2050 +/* Structure of local symbols per compilation unit. */
2051 +struct coff_compilation_unit
2053 + const char *fname;
2055 + long nsyms, totsyms;
2073 +/* Structure defining the pre-defined types. */
2074 +struct coff_predef_type
2076 + enum ts_kind kind;
2077 + unsigned int size; /* in bytes */
2078 + bfd_boolean isunsigned;
2082 +struct coff_type_stack;
2083 +struct coff_hash_entry;
2085 +struct coff_struct_fields
2090 + enum debug_visibility visibility;
2091 + struct coff_type_stack *types;
2094 +/* Our type stack. */
2095 +struct coff_type_stack
2097 + struct coff_type_stack *next;
2104 + unsigned int size;
2105 + bfd_boolean isunsigned;
2112 + unsigned int size;
2121 + const char *fixtag;
2125 + bfd_boolean tagismalloced;
2126 + const char **names;
2127 + bfd_signed_vma *vals;
2128 + struct coff_enum_hash_entry *ehash;
2135 + struct coff_type_stack *savedts;
2142 + bfd_signed_vma low;
2143 + bfd_signed_vma high;
2152 + const char *fixtag;
2156 + bfd_boolean tagismalloced;
2158 + bfd_boolean isstruct;
2159 + unsigned int size;
2161 + struct coff_struct_fields *fields;
2162 + struct coff_type_stack *savedts;
2163 + struct coff_struct_hash_entry *shash;
2170 +struct coff_name_type_hash_table
2172 + struct bfd_hash_table root;
2175 +struct coff_name_type_hash_entry
2177 + struct bfd_hash_entry root;
2178 + /* Information for this name. */
2179 + struct coff_type_stack *types;
2180 + bfd_boolean emitted;
2183 +struct coff_struct_hash_table
2185 + struct bfd_hash_table root;
2188 +struct coff_struct_hash_entry
2190 + struct bfd_hash_entry root;
2191 + /* Information for this name. */
2192 + struct coff_type_stack *types;
2193 + bfd_boolean emitted;
2194 + combined_entry_type *native;
2195 + /* list of symbol indices that need fixing */
2197 + unsigned nfixidxs;
2200 +struct coff_enum_hash_table
2202 + struct bfd_hash_table root;
2205 +struct coff_enum_hash_entry
2207 + struct bfd_hash_entry root;
2208 + /* Information for this name. */
2209 + struct coff_type_stack *types;
2210 + bfd_boolean emitted;
2211 + combined_entry_type *native;
2212 + /* list of symbol indices that need fixing */
2214 + unsigned nfixidxs;
2217 +/* COFF private symbol data. Used as a cookie to pass data around
2218 + between various processing stages. The generic COFF handling code
2219 + doesn't use any private data. */
2220 +struct coff_private_symdata
2222 + unsigned int size; /* size of symbol, used in AVR register
2224 + struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */
2225 + struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */
2228 +/* Stack of tags that need endndx fixing. */
2229 +struct coff_fix_stack
2231 + struct coff_fix_stack *next;
2232 + combined_entry_type *native;
2235 +/* This is the handle passed through debug_write. */
2237 +struct coff_write_handle
2241 + /* Pointers to .text and .data sections, can be used as defaults if
2242 + no other information is available. */
2243 + asection *textsect;
2244 + asection *datasect;
2245 + /* Some special flags. */
2246 + unsigned long flags;
2247 + /* Flags describing architecture options. */
2248 +#define COFF_FL_AVR 0x0001 /* COFF is for AVR platform. */
2249 +#define COFF_FL_EXT_AVR 0x0002 /* AVR "extended" COFF */
2250 + /* Flags describing internal status information. */
2251 +#define COFF_FL_FIX_ENDNDX 0x10000 /* apply endndx fix at next symbol */
2252 +#define COFF_FL_START_FCN 0x20000 /* begin of function pending */
2253 +#define COFF_FL_FIX_BB 0x40000 /* fix last ".bb" symbol */
2254 + /* List of our compilation units, from input symbol table. */
2255 + struct coff_compilation_unit *units;
2257 + struct coff_compilation_unit *currentfile;
2258 + /* Global symbols from input symbol table. */
2259 + asymbol **globals;
2261 + /* Section syms for named sections. */
2262 + coff_symbol_type **secsyms;
2264 + /* Our COFF symbols. */
2267 + /* Total line number count. */
2268 + unsigned long totlnos;
2269 + /* Size of standard objects on this arch. */
2270 + unsigned int pointersize;
2271 + unsigned int enumsize;
2272 + /* Pending information when starting a function. We have to defer
2273 + almost everything, some actions can be taken when seeing the
2274 + starting block of that function, some will even have to wait
2275 + until we see the end of the function. */
2276 + const char *funname; /* name of function */
2277 + bfd_boolean funglobal; /* global/local function? */
2278 + unsigned int lastlno; /* last line number seen so far */
2279 + long funcindex; /* index of ".func" symbol in syms */
2280 + unsigned int nlnos; /* line numbers recorded for this function*/
2281 + bfd_vma endaddr; /* last .eb address we have seen so far */
2282 + unsigned int funlno; /* first line number in function */
2283 + coff_symbol_type **fargs; /* function arguments */
2284 + unsigned int nfargs;
2285 + asection *funcsection; /* section the current function is using */
2286 + /* Type information */
2287 + struct coff_type_stack *tstack;
2288 + struct coff_name_type_hash_table types;
2289 + struct coff_struct_hash_table structs;
2290 + struct coff_enum_hash_table enums;
2291 + unsigned nenums; /* counter for anonymous enum tags */
2292 + /* Stack of pending endndx fixes, see coff_record_symbol(). */
2293 + struct coff_fix_stack *fixes;
2296 +/* Predefined types, default to usual 32-bit architectures.
2297 + Arch-dependant different byte sizes will be tuned upon entering
2298 + write_coff_debugging_info(). The table is looked up from front to
2299 + end, so we put `more popular' types that might have the same size
2300 + as other types first (e. g. "int" precedes "long" and "short"). */
2301 +static struct coff_predef_type coff_predef_types[] =
2303 + { TS_INT, 4, FALSE, 4 }, /* signed int */
2304 + { TS_INT, 1, FALSE, 2 }, /* signed char */
2305 + { TS_INT, 2, FALSE, 3 }, /* signed short */
2306 + { TS_INT, 4, FALSE, 5 }, /* long int */
2307 + { TS_FLOAT, 8, FALSE, 7 }, /* double */
2308 + { TS_FLOAT, 4, FALSE, 6 }, /* float */
2309 + { TS_INT, 4, TRUE, 14 }, /* unsigned int */
2310 + { TS_INT, 1, TRUE, 12 }, /* unsigned char */
2311 + { TS_INT, 2, TRUE, 13 }, /* unsigned short */
2312 + { TS_INT, 4, TRUE, 15 }, /* unsigned long */
2315 +static bfd_boolean coff_copy_symbols
2316 + PARAMS ((struct coff_write_handle *, long, asymbol **));
2317 +static asymbol *coff_find_symbol
2318 + PARAMS ((struct coff_write_handle *, const char *, bfd_boolean, bfd_boolean));
2319 +static void coff_record_symbol
2320 + PARAMS ((struct coff_write_handle *, coff_symbol_type *));
2321 +static symvalue coff_fixup_avr_register PARAMS ((symvalue, int));
2322 +static struct bfd_hash_entry *coff_name_type_newfunc
2323 + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2324 +static bfd_boolean coff_free_type_info
2325 + PARAMS ((struct coff_name_type_hash_entry *, PTR));
2326 +static struct bfd_hash_entry *coff_struct_newfunc
2327 + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2328 +static bfd_boolean coff_free_struct_info
2329 + PARAMS ((struct coff_struct_hash_entry *, PTR));
2330 +static struct bfd_hash_entry *coff_enum_newfunc
2331 + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2332 +static bfd_boolean coff_free_enum_info
2333 + PARAMS ((struct coff_enum_hash_entry *, PTR));
2334 +static unsigned int coff_get_fundamental_type
2335 + PARAMS ((struct coff_write_handle *, struct coff_type_stack *));
2336 +static bfd_boolean coff_make_typed_symbol
2337 + PARAMS ((struct coff_write_handle *, coff_symbol_type **, enum ts_kind));
2338 +static bfd_boolean coff_emit_struct
2339 + PARAMS ((struct coff_write_handle *, struct coff_type_stack *,
2340 + struct coff_struct_hash_entry *));
2341 +static bfd_boolean coff_emit_enum
2342 + PARAMS ((struct coff_write_handle *, struct coff_type_stack *,
2343 + struct coff_enum_hash_entry *));
2344 +static bfd_boolean coff_emit_ndebug_sym
2345 + PARAMS ((struct coff_write_handle *, asymbol *, bfd_boolean));
2347 +static bfd_boolean coff_start_compilation_unit PARAMS ((PTR, const char *));
2348 +static bfd_boolean coff_start_source PARAMS ((PTR, const char *));
2349 +static bfd_boolean coff_empty_type PARAMS ((PTR));
2350 +static bfd_boolean coff_void_type PARAMS ((PTR));
2351 +static bfd_boolean coff_int_type PARAMS ((PTR, unsigned int, bfd_boolean));
2352 +static bfd_boolean coff_float_type PARAMS ((PTR, unsigned int));
2353 +static bfd_boolean coff_complex_type PARAMS ((PTR, unsigned int));
2354 +static bfd_boolean coff_bool_type PARAMS ((PTR, unsigned int));
2355 +static bfd_boolean coff_enum_type
2356 + PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
2357 +static bfd_boolean coff_pointer_type PARAMS ((PTR));
2358 +static bfd_boolean coff_function_type PARAMS ((PTR, int, bfd_boolean));
2359 +static bfd_boolean coff_reference_type PARAMS ((PTR));
2360 +static bfd_boolean coff_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
2361 +static bfd_boolean coff_array_type
2362 + PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean));
2363 +static bfd_boolean coff_set_type PARAMS ((PTR, bfd_boolean));
2364 +static bfd_boolean coff_offset_type PARAMS ((PTR));
2365 +static bfd_boolean coff_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean));
2366 +static bfd_boolean coff_const_type PARAMS ((PTR));
2367 +static bfd_boolean coff_volatile_type PARAMS ((PTR));
2368 +static bfd_boolean coff_start_struct_type
2369 + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int));
2370 +static bfd_boolean coff_struct_field
2371 + PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
2372 +static bfd_boolean coff_end_struct_type PARAMS ((PTR));
2373 +static bfd_boolean coff_start_class_type
2374 + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean,
2376 +static bfd_boolean coff_class_static_member
2377 + PARAMS ((PTR, const char *, const char *, enum debug_visibility));
2378 +static bfd_boolean coff_class_baseclass
2379 + PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility));
2380 +static bfd_boolean coff_class_start_method PARAMS ((PTR, const char *));
2381 +static bfd_boolean coff_class_method_variant
2382 + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
2383 + bfd_vma, bfd_boolean));
2384 +static bfd_boolean coff_class_static_method_variant
2385 + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean));
2386 +static bfd_boolean coff_class_end_method PARAMS ((PTR));
2387 +static bfd_boolean coff_end_class_type PARAMS ((PTR));
2388 +static bfd_boolean coff_typedef_type PARAMS ((PTR, const char *));
2389 +static bfd_boolean coff_tag_type
2390 + PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
2391 +static bfd_boolean coff_typdef PARAMS ((PTR, const char *));
2392 +static bfd_boolean coff_tag PARAMS ((PTR, const char *));
2393 +static bfd_boolean coff_int_constant PARAMS ((PTR, const char *, bfd_vma));
2394 +static bfd_boolean coff_float_constant PARAMS ((PTR, const char *, double));
2395 +static bfd_boolean coff_typed_constant PARAMS ((PTR, const char *, bfd_vma));
2396 +static bfd_boolean coff_variable
2397 + PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
2398 +static bfd_boolean coff_start_function PARAMS ((PTR, const char *, bfd_boolean));
2399 +static bfd_boolean coff_function_parameter
2400 + PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
2401 +static bfd_boolean coff_start_block PARAMS ((PTR, bfd_vma));
2402 +static bfd_boolean coff_end_block PARAMS ((PTR, bfd_vma));
2403 +static bfd_boolean coff_end_function PARAMS ((PTR));
2404 +static bfd_boolean coff_lineno
2405 + PARAMS ((PTR, const char *, unsigned long, bfd_vma));
2407 +static const struct debug_write_fns coff_fns =
2409 + coff_start_compilation_unit,
2410 + coff_start_source,
2415 + coff_complex_type,
2418 + coff_pointer_type,
2419 + coff_function_type,
2420 + coff_reference_type,
2427 + coff_volatile_type,
2428 + coff_start_struct_type,
2429 + coff_struct_field,
2430 + coff_end_struct_type,
2431 + coff_start_class_type,
2432 + coff_class_static_member,
2433 + coff_class_baseclass,
2434 + coff_class_start_method,
2435 + coff_class_method_variant,
2436 + coff_class_static_method_variant,
2437 + coff_class_end_method,
2438 + coff_end_class_type,
2439 + coff_typedef_type,
2443 + coff_int_constant,
2444 + coff_float_constant,
2445 + coff_typed_constant,
2447 + coff_start_function,
2448 + coff_function_parameter,
2451 + coff_end_function,
2456 + * Copy our input (non-debugging) symbols. Local symbols will be
2457 + * maintained in one bucket per each compilation unit, global (and
2458 + * weak) symbols will be kept in a simple array.
2461 +coff_copy_symbols (info, count, sympp)
2462 + struct coff_write_handle *info;
2468 + struct coff_compilation_unit *up;
2472 + for (i = 0; i < count; i++)
2476 + /* Try to figure out the .text and .data sections from our input
2477 + symbols as we walk them. Unfortunately, this ought to be the
2478 + /input/ section pointers, so their ->output_section is
2479 + non-NULL. That's why we can't simply walk through all the
2480 + sections of our abfd since this is describing the output
2482 + if (info->textsect == NULL && osym->section->flags & SEC_CODE)
2483 + /* Assume this to be our .text section. */
2484 + info->textsect = osym->section;
2485 + else if (info->datasect == NULL && osym->section->flags & SEC_DATA)
2486 + /* Assume this to be our .data section. */
2487 + info->datasect = osym->section;
2489 + if (osym->flags & BSF_FILE)
2491 + /* New file name. */
2496 + /* Well, maybe an old one actually? If so, append it there.
2497 + This can happen for files that contribute to multiple
2498 + (input) sections that were concatenated by the linker
2500 + for (l = 0; l < info->nunits; l++)
2502 + if (strcmp (info->units[l].fname, osym->name) == 0)
2504 + up = info->units + l;
2511 + info->units = (struct coff_compilation_unit *)
2512 + xrealloc (info->units,
2513 + ++info->nunits * sizeof(struct coff_compilation_unit));
2514 + up = info->units + (info->nunits - 1);
2515 + up->fname = osym->name;
2517 + up->nsyms = up->totsyms = 0;
2520 + else if (osym->flags & (BSF_GLOBAL | BSF_WEAK))
2522 + /* Global (or weak) symbols are recorded outside compilation
2524 + info->globals = (asymbol **)
2525 + xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *));
2526 + info->globals[info->nglobals - 1] = osym;
2529 + else if (!bfd_is_const_section(osym->section))
2531 + if (osym->flags & BSF_SECTION_SYM)
2533 + coff_symbol_type *csymp;
2534 + /* Just record them by now, they'll be fixed up later. */
2536 + if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0)
2538 + /* Very first symbol, fake a compilation unit name
2539 + for it. Historical precedence seems to dictate
2540 + this, but AVR COFF does not use that. */
2541 + csymp = (coff_symbol_type *)
2542 + coff_bfd_make_debug_symbol (info->abfd, 0, 0);
2543 + if (csymp == NULL)
2546 + csymp->symbol.name = xstrdup ("<fake>");
2547 + csymp->symbol.value = 0;
2548 + csymp->symbol.udata.p = NULL;
2549 + csymp->native->u.syment.n_sclass = C_FILE;
2550 + /* force filename into aux entry */
2551 + csymp->native->u.syment.n_numaux = 1;
2552 + coff_record_symbol (info, csymp);
2555 + /* convert to COFF native section symbol */
2556 + csymp = (coff_symbol_type *)
2557 + coff_bfd_make_debug_symbol (info->abfd, 0, 0);
2558 + if (csymp == NULL)
2561 + csymp->symbol.name = xstrdup (osym->section->name);
2562 + csymp->symbol.value = osym->section->output_section->vma;
2563 + csymp->symbol.flags = BSF_DEBUGGING | BSF_SECTION_SYM;
2564 + csymp->symbol.section = osym->section;
2565 + csymp->symbol.udata.p = NULL;
2566 + csymp->native->fix_scnlen = 1;
2567 + csymp->native->u.syment.n_sclass = C_STAT;
2568 + csymp->native->u.syment.n_type = T_NULL;
2569 + csymp->native->u.syment.n_numaux = 1;
2571 + coff_record_symbol (info, csymp);
2573 + info->secsyms = (coff_symbol_type **)
2574 + xrealloc (info->secsyms,
2575 + ++info->nsecsyms * sizeof(coff_symbol_type *));
2576 + info->secsyms[info->nsecsyms - 1] = csymp;
2580 + /* Local symbol in a named section, will be recorded
2581 + within the respective compilation unit. */
2585 + _("Discarding local symbol outside any compilation unit"));
2587 + fprintf (stderr, ": %s", osym->name);
2588 + putc ('\n', stderr);
2592 + up->syms = (asymbol **)
2593 + xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *));
2594 + up->syms[up->nsyms - 1] = osym;
2595 + up->totsyms = up->nsyms;
2605 +/* Find a name in the symbol table. If found, the respective entry in
2606 + the symbol vector is zeroed, so after processing all debugging
2607 + symbols, only non-debugging symbols will remain. */
2609 +coff_find_symbol (info, name, isfunction, global)
2610 + struct coff_write_handle *info;
2612 + bfd_boolean isfunction;
2613 + bfd_boolean global;
2621 + for (i = 0; i < info->nglobals; i++)
2623 + symp = info->globals[i];
2626 + if (strcmp (name, symp->name) == 0
2627 + && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
2629 + info->globals[i] = NULL;
2636 + if (info->currentfile == NULL)
2639 + /* For local symbols, the match optionally stops at a dot in the
2640 + symtab symbol's name; this is used by gcc to indicate
2641 + function-scope static symbols (e. g. symbol "foo" will become
2642 + "foo.1" in function scope). */
2643 + namelen = strlen (name);
2644 + for (i = 0; i < info->currentfile->nsyms; i++)
2646 + symp = info->currentfile->syms[i];
2649 + if (strncmp (name, symp->name, namelen) == 0
2650 + && (symp->name[namelen] == '\0' || symp->name[namelen] == '.')
2651 + && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
2653 + info->currentfile->syms[i] = NULL;
2654 + info->currentfile->totsyms--;
2662 +coff_record_symbol (info, csymp)
2663 + struct coff_write_handle *info;
2664 + coff_symbol_type *csymp;
2666 + struct coff_private_symdata *priv;
2668 + info->syms = (asymbol **) xrealloc (info->syms,
2669 + ++info->nsyms * sizeof (asymbol *));
2670 + info->syms[info->nsyms - 1] = (asymbol *)csymp;
2672 + if ((priv = csymp->symbol.udata.p) != NULL)
2674 + if (priv->shash != NULL)
2676 + struct coff_struct_hash_entry *shash = priv->shash;
2677 + shash->fixidxs = (long *)
2678 + xrealloc (shash->fixidxs, ++shash->nfixidxs * sizeof (long));
2679 + shash->fixidxs[shash->nfixidxs - 1] = info->nsyms - 1;
2681 + if (priv->ehash != NULL)
2683 + struct coff_enum_hash_entry *ehash = priv->ehash;
2684 + ehash->fixidxs = (long *)
2685 + xrealloc (ehash->fixidxs, ++ehash->nfixidxs * sizeof (long));
2686 + ehash->fixidxs[ehash->nfixidxs - 1] = info->nsyms - 1;
2689 + csymp->symbol.udata.p = NULL;
2692 + /* If there are any pending endndx fixes, pop the last element from
2693 + that stack, and record the current symbol for fixing. We need to
2694 + do this here since we need to record our current csymp->native
2695 + (where that csymp is completely unrelated to whatever symbol was
2696 + previously generated that requested the fixup). The stack of
2697 + pending fixes is required since several endndx fixes could be
2698 + nested, e. g. the start of a function has a pending fix that
2699 + needs to point to the first symbol after the function, but there
2700 + could be an anonymous struct definition inside that function's
2701 + local variables where the endndx needs to point after the last
2702 + symbol of this struct. Also, structs and unions could be nested.
2704 + Each call to coff_record_symbol() can fix at most one endndx
2705 + (even if more are pending in the stack), but that's OK.
2707 + Note that bfd/coffgen.c converts that csymp->native into a
2708 + symtable slot number after coff_renumber_symbols() has been
2710 + if (info->flags & COFF_FL_FIX_ENDNDX)
2712 + struct coff_fix_stack *fsp, *ofsp;
2713 + union internal_auxent *aux;
2715 + assert (info->fixes != NULL);
2717 + fsp = info->fixes;
2719 + while (fsp->next != NULL)
2725 + info->fixes = NULL;
2727 + ofsp->next = NULL;
2729 + aux = &(fsp->native->u.auxent);
2730 + fsp->native->fix_end = 1;
2731 + aux->x_sym.x_fcnary.x_fcn.x_endndx.p = csymp->native;
2734 + info->flags &= ~COFF_FL_FIX_ENDNDX;
2738 +/* Fixup AVR COFF register handling: they don't only mention the
2739 + starting register number, but all registers, each within one byte
2740 + of the value. Unused register positions are filled up with
2743 +coff_fixup_avr_register (val, size)
2749 + unsigned char c[4];
2753 + u.c[1] = u.c[2] = u.c[3] = 0xff;
2766 +/* Initialize an entry in the hash tables. */
2768 +static struct bfd_hash_entry *
2769 +coff_name_type_newfunc (entry, table, string)
2770 + struct bfd_hash_entry *entry;
2771 + struct bfd_hash_table *table;
2772 + const char *string;
2774 + struct coff_name_type_hash_entry *ret =
2775 + (struct coff_name_type_hash_entry *) entry;
2777 + /* Allocate the structure if it has not already been allocated by a
2780 + ret = ((struct coff_name_type_hash_entry *)
2781 + bfd_hash_allocate (table, sizeof *ret));
2785 + /* Call the allocation method of the superclass. */
2786 + ret = ((struct coff_name_type_hash_entry *)
2787 + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2790 + /* Set local fields. */
2791 + ret->types = NULL;
2792 + ret->emitted = FALSE;
2795 + return (struct bfd_hash_entry *) ret;
2798 +static struct bfd_hash_entry *
2799 +coff_struct_newfunc (entry, table, string)
2800 + struct bfd_hash_entry *entry;
2801 + struct bfd_hash_table *table;
2802 + const char *string;
2804 + struct coff_struct_hash_entry *ret =
2805 + (struct coff_struct_hash_entry *) entry;
2807 + /* Allocate the structure if it has not already been allocated by a
2810 + ret = ((struct coff_struct_hash_entry *)
2811 + bfd_hash_allocate (table, sizeof *ret));
2815 + /* Call the allocation method of the superclass. */
2816 + ret = ((struct coff_struct_hash_entry *)
2817 + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2820 + /* Set local fields. */
2821 + ret->types = NULL;
2822 + ret->emitted = FALSE;
2823 + ret->fixidxs = NULL;
2824 + ret->nfixidxs = 0;
2825 + ret->native = NULL;
2828 + return (struct bfd_hash_entry *) ret;
2831 +static struct bfd_hash_entry *
2832 +coff_enum_newfunc (entry, table, string)
2833 + struct bfd_hash_entry *entry;
2834 + struct bfd_hash_table *table;
2835 + const char *string;
2837 + struct coff_enum_hash_entry *ret =
2838 + (struct coff_enum_hash_entry *) entry;
2840 + /* Allocate the structure if it has not already been allocated by a
2843 + ret = ((struct coff_enum_hash_entry *)
2844 + bfd_hash_allocate (table, sizeof *ret));
2848 + /* Call the allocation method of the superclass. */
2849 + ret = ((struct coff_enum_hash_entry *)
2850 + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2853 + /* Set local fields. */
2854 + ret->types = NULL;
2855 + ret->emitted = FALSE;
2856 + ret->fixidxs = NULL;
2857 + ret->nfixidxs = 0;
2858 + ret->native = NULL;
2861 + return (struct bfd_hash_entry *) ret;
2864 +/* Look up an entry in the hash tables. */
2866 +#define coff_name_type_hash_lookup(table, string, create, copy) \
2867 + ((struct coff_name_type_hash_entry *) \
2868 + bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
2870 +/* Traverse the hash table. */
2872 +#define coff_name_type_hash_traverse(table, func, info) \
2873 + (bfd_hash_traverse \
2874 + (&(table)->root, \
2875 + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2878 +#define coff_struct_hash_lookup(table, string, create, copy) \
2879 + ((struct coff_struct_hash_entry *) \
2880 + bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
2882 +/* Traverse the hash table. */
2884 +#define coff_struct_hash_traverse(table, func, info) \
2885 + (bfd_hash_traverse \
2886 + (&(table)->root, \
2887 + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2890 +#define coff_enum_hash_lookup(table, string, create, copy) \
2891 + ((struct coff_enum_hash_entry *) \
2892 + bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
2894 +/* Traverse the hash table. */
2896 +#define coff_enum_hash_traverse(table, func, info) \
2897 + (bfd_hash_traverse \
2898 + (&(table)->root, \
2899 + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2902 +#define coff_push_type(kind) \
2903 + tst = (struct coff_type_stack *) xmalloc (sizeof (struct coff_type_stack)); \
2904 + memset (tst, 0, sizeof (*tst)); \
2905 + tst->next = info->tstack; \
2906 + tst->tsk = kind; \
2907 + info->tstack = tst
2909 +#define coff_pop_type() \
2910 + tst = info->tstack; \
2911 + if (tst == NULL) { \
2912 + fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \
2915 + info->tstack = tst->next; \
2918 +#define coff_complain_unsupp(s) \
2919 + fprintf (stderr, _("%s type not supported in %s\n"), \
2920 + s, info->abfd->xvec->name); \
2923 +/* These function is called via the hash traverse routine when freeing
2924 + a hash table (at the end of a translation unit). */
2926 +coff_free_type_info (h, p)
2927 + struct coff_name_type_hash_entry *h;
2928 + PTR p ATTRIBUTE_UNUSED;
2930 + struct coff_type_stack *tst, *otst;
2932 + for (tst = h->types; tst != NULL;)
2942 +coff_free_struct_info (h, p)
2943 + struct coff_struct_hash_entry *h;
2944 + PTR p ATTRIBUTE_UNUSED;
2946 + struct coff_type_stack *tst, *otst, *xtst, *xotst;
2947 + struct coff_struct_fields *fp;
2950 + for (tst = h->types; tst != NULL;)
2953 + if (tst->u.ts_struct.tagismalloced)
2954 + free (tst->u.ts_struct.tag.malloctag);
2955 + for (i = 0, fp = tst->u.ts_struct.fields;
2956 + i < tst->u.ts_struct.nfields;
2960 + while (xtst != NULL)
2962 + xotst = xtst->next;
2967 + free (tst->u.ts_struct.fields);
2975 +coff_free_enum_info (h, p)
2976 + struct coff_enum_hash_entry *h;
2977 + PTR p ATTRIBUTE_UNUSED;
2979 + struct coff_type_stack *tst, *otst;
2981 + for (tst = h->types; tst != NULL;)
2984 + if (tst->u.ts_enum.tagismalloced)
2985 + free (tst->u.ts_enum.tag.malloctag);
2992 +static unsigned int
2993 +coff_get_fundamental_type (info, tst)
2994 + struct coff_write_handle *info ATTRIBUTE_UNUSED;
2995 + struct coff_type_stack *tst;
2999 + /* See if one of our predefined types will fit. */
3000 + if (tst->tsk == TS_INT)
3003 + i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
3006 + if (coff_predef_types[i].kind == TS_INT
3007 + && coff_predef_types[i].size == tst->u.ts_int.size
3008 + && coff_predef_types[i].isunsigned == tst->u.ts_int.isunsigned)
3009 + return coff_predef_types[i].slot;
3012 + _("%ssigned %d-bit integer type not available in COFF\n"),
3013 + tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8);
3018 + i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
3021 + if (coff_predef_types[i].kind == TS_FLOAT
3022 + && coff_predef_types[i].size == tst->u.ts_float.size)
3023 + return coff_predef_types[i].slot;
3025 + fprintf (stderr, _("%d-bit float type not available in COFF\n"),
3026 + tst->u.ts_float.size * 8);
3033 +coff_make_typed_symbol (info, csympp, stopat)
3034 + struct coff_write_handle *info;
3035 + coff_symbol_type **csympp;
3036 + enum ts_kind stopat;
3038 + struct coff_type_stack *tst;
3039 + union internal_auxent *aux;
3040 + struct coff_struct_hash_entry *shash;
3041 + struct coff_enum_hash_entry *ehash;
3042 + struct coff_private_symdata *priv;
3043 + unsigned int type, numaux, arydim, size, i, nele, nderived;
3045 + bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR))
3048 + /* Synthesize a new internal COFF symbol. */
3049 + *csympp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3050 + if (*csympp == NULL)
3053 + priv = (struct coff_private_symdata *) xmalloc (sizeof *priv);
3054 + memset (priv, 0, sizeof *priv);
3056 + type = arydim = size = nderived = 0;
3058 + aux = &(((*csympp)->native + 1)->u.auxent);
3060 + /* Now, walk the type stack, and see how we could convert the info
3061 + we've got to what COFF understands. */
3064 + if (info->tstack == NULL)
3067 + /* If we have been advised to not pop the entire stack, stop
3069 + if (info->tstack->tsk == stopat && info->tstack->next == NULL)
3077 + /* cannot happen */
3081 + if (info->tstack != NULL && info->tstack->tsk != stopat)
3082 + fprintf (stderr, _("empty type not last on type stack\n"));
3083 + /* type |= T_NULL; */
3087 + if (info->tstack != NULL && info->tstack->tsk != stopat)
3088 + fprintf (stderr, _("void type not last on type stack\n"));
3093 + if (info->tstack != NULL && info->tstack->tsk != stopat)
3094 + fprintf (stderr, _("int type not last on type stack\n"));
3095 + type |= coff_get_fundamental_type (info, tst);
3097 + size = tst->u.ts_int.size;
3101 + if (info->tstack != NULL && info->tstack->tsk != stopat)
3102 + fprintf (stderr, _("float type not last on type stack\n"));
3103 + type |= coff_get_fundamental_type (info, tst);
3105 + size = tst->u.ts_float.size;
3110 + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT);
3111 + size = info->pointersize;
3116 + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT);
3117 + /* AUX entry for DT_FCN will be filled in elsewhere. */
3121 + /* We need to limit arydim so the assignment below won't
3122 + overwrite random locations. */
3123 + if (arydim >= DIMNUM)
3126 + _("More than %d array dimensions, result is invalid.\n"),
3128 + arydim = DIMNUM - 1;
3131 + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_ARY << N_BTSHFT);
3132 + aux->x_sym.x_fcnary.x_ary.x_dimen[arydim++] =
3133 + tst->u.ts_array.high - tst->u.ts_array.low + 1;
3138 + coff_complain_unsupp (_("complex"));
3143 + size = info->enumsize;
3145 + if (tst->u.ts_enum.ehash != NULL)
3147 + /* enum tag will be fixed later. */
3148 + priv->ehash = tst->u.ts_enum.ehash;
3151 + if (tst->u.ts_enum.tagismalloced)
3152 + name = tst->u.ts_enum.tag.malloctag;
3154 + name = tst->u.ts_enum.tag.fixtag;
3155 + ehash = coff_enum_hash_lookup (&info->enums, name,
3156 + TRUE, tst->u.ts_enum.tagismalloced);
3157 + if (ehash == NULL)
3159 + if (!ehash->emitted)
3161 + if (ehash->types == NULL)
3163 + ehash->types = (struct coff_type_stack *)
3164 + xmalloc (sizeof (struct coff_type_stack));
3165 + memcpy (ehash->types, tst, sizeof (struct coff_type_stack));
3167 + ehash->emitted = TRUE;
3168 + coff_emit_enum (info, tst, ehash);
3169 + if (ehash->nfixidxs != 0)
3171 + coff_symbol_type *symp;
3174 + for (i = 0; i < ehash->nfixidxs; i++)
3176 + combined_entry_type *np;
3178 + symp = (coff_symbol_type *) info->syms[ehash->fixidxs[i]];
3179 + symp->native->u.syment.n_type &= ~N_BTMASK;
3180 + symp->native->u.syment.n_type |= T_ENUM;
3185 + np = symp->native + 1;
3187 + np->u.auxent.x_sym.x_tagndx.p = ehash->native;
3188 + if (np->u.auxent.x_sym.x_misc.x_fsize == 0)
3189 + np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size;
3192 + free (ehash->fixidxs);
3193 + ehash->nfixidxs = 0;
3198 + ((*csympp)->native + 1)->fix_tag = 1;
3199 + aux->x_sym.x_tagndx.p = ehash->native;
3200 + if (aux->x_sym.x_misc.x_fsize == 0)
3201 + aux->x_sym.x_misc.x_lnsz.x_size = size;
3206 + if (tst->u.ts_struct.isstruct)
3211 + size = tst->u.ts_struct.size;
3213 + if (tst->u.ts_struct.shash != NULL)
3215 + /* struct tag will be fixed later. */
3216 + priv->shash = tst->u.ts_struct.shash;
3219 + if (tst->u.ts_struct.tagismalloced)
3220 + name = tst->u.ts_struct.tag.malloctag;
3222 + name = tst->u.ts_struct.tag.fixtag;
3223 + shash = coff_struct_hash_lookup (&info->structs, name,
3224 + TRUE, tst->u.ts_struct.tagismalloced);
3225 + if (shash == NULL)
3227 + if (!shash->emitted)
3229 + if (shash->types == NULL)
3231 + shash->types = (struct coff_type_stack *)
3232 + xmalloc (sizeof (struct coff_type_stack));
3233 + memcpy (shash->types, tst, sizeof (struct coff_type_stack));
3235 + shash->emitted = TRUE;
3236 + coff_emit_struct (info, tst, shash);
3237 + if (shash->nfixidxs != 0)
3239 + coff_symbol_type *symp;
3242 + for (i = 0; i < shash->nfixidxs; i++)
3244 + combined_entry_type *np;
3246 + symp = (coff_symbol_type *) info->syms[shash->fixidxs[i]];
3247 + symp->native->u.syment.n_type &= ~N_BTMASK;
3248 + if (tst->u.ts_struct.isstruct)
3249 + symp->native->u.syment.n_type |= T_STRUCT;
3251 + symp->native->u.syment.n_type |= T_UNION;
3256 + np = symp->native + 1;
3258 + np->u.auxent.x_sym.x_tagndx.p = shash->native;
3259 + if (np->u.auxent.x_sym.x_misc.x_fsize == 0)
3260 + np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size;
3263 + free (shash->fixidxs);
3264 + shash->nfixidxs = 0;
3269 + ((*csympp)->native + 1)->fix_tag = 1;
3270 + aux->x_sym.x_tagndx.p = shash->native;
3271 + if (aux->x_sym.x_misc.x_fsize == 0)
3272 + aux->x_sym.x_misc.x_lnsz.x_size = size;
3281 + _("More than 6 derived type specifiers, result is invalid.\n"));
3283 + /* Our type computation so far used the reverse order for derived
3284 + type specifiers. Fix this here if there was more than one
3285 + derived type specifier. */
3288 + unsigned int nty, bty;
3289 + bty = type & N_BTMASK;
3290 + type = type >> N_BTSHFT;
3292 + while (nderived-- > 0)
3294 + nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT));
3295 + type >>= N_TSHIFT;
3297 + type = (nty << N_BTSHFT) | bty;
3302 + /* Compute size of entire array. */
3303 + for (i = 0, nele = 1; i < arydim; i++)
3304 + nele *= aux->x_sym.x_fcnary.x_ary.x_dimen[i];
3305 + aux->x_sym.x_misc.x_lnsz.x_size = size * nele;
3309 + if (ISARY (type) || ISFCN (type))
3311 + if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION
3312 + || BTYPE (type) == T_ENUM)
3315 + /* Only AVR COFF uses multiple AUX entries. */
3316 + if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0)
3319 + priv->size = size;
3320 + (*csympp)->symbol.udata.p = priv;
3321 + (*csympp)->native->u.syment.n_type = type;
3322 + (*csympp)->native->u.syment.n_numaux = numaux;
3324 + /* If the fundamental type comes out as T_NULL, this means we don't
3325 + have any type information. Just don't emit any aux entries in
3326 + that case, and drop any derived type information as well. */
3327 + if (BTYPE (type) == T_NULL)
3329 + printf ("coff_make_typed_symbol() -> T_NULL\n");
3330 + //(*csympp)->native->u.syment.n_type = T_NULL;
3331 + (*csympp)->native->u.syment.n_numaux = 0;
3337 +static bfd_boolean coff_emit_struct (info, tst, shash)
3338 + struct coff_write_handle *info;
3339 + struct coff_type_stack *tst;
3340 + struct coff_struct_hash_entry *shash;
3342 + coff_symbol_type *csymp, *scsymp, *ecsymp;
3343 + union internal_auxent *aux;
3344 + struct coff_fix_stack *fixp, *ofp;
3345 + bfd_boolean isstruct = tst->u.ts_struct.isstruct;
3346 + bfd_boolean isbitfield = FALSE;
3347 + struct coff_type_stack *savedtst;
3348 + struct coff_struct_fields *fp;
3349 + unsigned short sclass;
3352 + if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3354 + /* old AVR COFF doesn't support struct debugging */
3357 + /* Synthesize a new internal COFF symbol for the struct/union. */
3358 + scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3359 + if (scsymp == NULL)
3362 + if (tst->u.ts_struct.tagismalloced)
3363 + scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag);
3365 + scsymp->symbol.name = tst->u.ts_struct.tag.fixtag;
3366 + scsymp->symbol.flags = BSF_NOT_AT_END;
3367 + scsymp->symbol.section = bfd_und_section_ptr;
3368 + scsymp->native->u.syment.n_sclass = isstruct? C_STRTAG: C_UNTAG;
3369 + scsymp->native->u.syment.n_type = isstruct? T_STRUCT: T_UNION;
3370 + scsymp->native->u.syment.n_numaux = 1;
3371 + scsymp->symbol.udata.p = NULL;
3372 + scsymp->symbol.value = 0;
3374 + shash->native = scsymp->native;
3376 + /* Synthesize a new internal COFF symbol for the end of struct/union. */
3377 + ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3378 + if (ecsymp == NULL)
3381 + ecsymp->symbol.name = ".eos";
3382 + ecsymp->symbol.flags = BSF_NOT_AT_END;
3383 + /* We need to use the com section here since bfd/coffgen.c
3384 + translates this into an N_UNDEF one without clobbering the
3386 + ecsymp->symbol.section = bfd_com_section_ptr;
3387 + ecsymp->native->u.syment.n_sclass = C_EOS;
3388 + ecsymp->symbol.udata.p = NULL;
3389 + ecsymp->symbol.value = tst->u.ts_struct.size;
3390 + ecsymp->native->u.syment.n_numaux = 1;
3391 + (ecsymp->native + 1)->fix_tag = 1;
3392 + aux = &((ecsymp->native + 1)->u.auxent);
3393 + aux->x_sym.x_tagndx.p = scsymp->native;
3394 + aux->x_sym.x_misc.x_lnsz.x_size = tst->u.ts_struct.size;
3396 + coff_record_symbol (info, scsymp);
3398 + savedtst = info->tstack;
3402 + /* First, make a quick walk along all the fields, and figure out
3403 + * whether we've got a genuine struct or a bitfield struct. */
3404 + for (i = 0, fp = tst->u.ts_struct.fields;
3405 + i < tst->u.ts_struct.nfields;
3407 + if (fp->bitsize % 8 != 0)
3409 + isbitfield = TRUE;
3414 + sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU;
3416 + for (i = 0, fp = tst->u.ts_struct.fields;
3417 + i < tst->u.ts_struct.nfields;
3420 + if (strlen (fp->name) == 0)
3422 + /* empty name could happen inside bitfield */
3427 + info->tstack = fp->types;
3428 + if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
3431 + csymp->symbol.name = xstrdup (fp->name);
3432 + csymp->symbol.flags = BSF_NOT_AT_END;
3433 + csymp->symbol.section = bfd_com_section_ptr;
3434 + csymp->native->u.syment.n_sclass = sclass;
3435 + csymp->symbol.value = isbitfield? fp->bitpos: fp->bitpos / 8;
3438 + csymp->native->u.syment.n_numaux = 1;
3439 + aux = &((csymp->native + 1)->u.auxent);
3440 + aux->x_sym.x_misc.x_lnsz.x_size = fp->bitsize;
3443 + coff_record_symbol (info, csymp);
3448 + info->tstack = savedtst;
3450 + /* Record our endndx field for later fixing. */
3451 + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
3452 + fixp->native = scsymp->native + 1; /* points to first AUX */
3453 + fixp->next = NULL;
3454 + if (info->fixes == NULL)
3455 + info->fixes = fixp;
3458 + for (ofp = info->fixes; ofp->next != NULL;)
3463 + coff_record_symbol (info, ecsymp);
3464 + info->flags |= COFF_FL_FIX_ENDNDX;
3469 +static bfd_boolean coff_emit_enum (info, tst, ehash)
3470 + struct coff_write_handle *info;
3471 + struct coff_type_stack *tst;
3472 + struct coff_enum_hash_entry *ehash;
3474 + coff_symbol_type *csymp, *scsymp, *ecsymp;
3475 + union internal_auxent *aux;
3476 + struct coff_fix_stack *fixp, *ofp;
3479 + if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3481 + /* old AVR COFF doesn't support enum debugging */
3484 + /* Synthesize a new internal COFF symbol for the enum. */
3485 + scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3486 + if (scsymp == NULL)
3489 + if (tst->u.ts_enum.tagismalloced)
3490 + scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag);
3492 + scsymp->symbol.name = tst->u.ts_enum.tag.fixtag;
3493 + scsymp->symbol.flags = BSF_NOT_AT_END;
3494 + scsymp->symbol.section = bfd_und_section_ptr;
3495 + scsymp->native->u.syment.n_sclass = C_ENTAG;
3496 + scsymp->native->u.syment.n_type = T_ENUM;
3497 + scsymp->native->u.syment.n_numaux = 1;
3498 + scsymp->symbol.udata.p = NULL;
3499 + scsymp->symbol.value = 0;
3501 + ehash->native = scsymp->native;
3503 + /* Synthesize a new internal COFF symbol for the end of struct/union. */
3504 + ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3505 + if (ecsymp == NULL)
3508 + ecsymp->symbol.name = ".eos";
3509 + ecsymp->symbol.flags = BSF_NOT_AT_END;
3510 + /* We need to use the com section here since bfd/coffgen.c
3511 + translates this into an N_UNDEF one without clobbering the
3513 + ecsymp->symbol.section = bfd_com_section_ptr;
3514 + ecsymp->native->u.syment.n_sclass = C_EOS;
3515 + ecsymp->symbol.udata.p = NULL;
3516 + ecsymp->symbol.value = info->enumsize;
3517 + ecsymp->native->u.syment.n_numaux = 1;
3518 + (ecsymp->native + 1)->fix_tag = 1;
3519 + aux = &((ecsymp->native + 1)->u.auxent);
3520 + aux->x_sym.x_tagndx.p = scsymp->native;
3521 + aux->x_sym.x_misc.x_lnsz.x_size = info->enumsize;
3523 + coff_record_symbol (info, scsymp);
3527 + const char *name = tst->u.ts_enum.names[i];
3531 + /* Synthesize a new internal COFF symbol for the enum. */
3532 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3533 + if (csymp == NULL)
3536 + csymp->symbol.name = xstrdup (name);
3537 + csymp->symbol.flags = BSF_NOT_AT_END;
3538 + csymp->symbol.section = bfd_com_section_ptr;
3539 + csymp->native->u.syment.n_sclass = C_MOE;
3540 + csymp->symbol.udata.p = NULL;
3541 + csymp->symbol.value = tst->u.ts_enum.vals[i];
3543 + coff_record_symbol (info, csymp);
3546 + /* Record our endndx field for later fixing. */
3547 + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
3548 + fixp->native = scsymp->native + 1; /* points to first AUX */
3549 + fixp->next = NULL;
3550 + if (info->fixes == NULL)
3551 + info->fixes = fixp;
3554 + for (ofp = info->fixes; ofp->next != NULL;)
3559 + coff_record_symbol (info, ecsymp);
3560 + info->flags |= COFF_FL_FIX_ENDNDX;
3565 +/* Emit a non-debugging symbol that came from the input symbol table,
3566 + and has not been claimed by one of the debugging symbols. */
3568 +coff_emit_ndebug_sym (info, osymp, localp)
3569 + struct coff_write_handle *info;
3571 + bfd_boolean localp;
3573 + coff_symbol_type *csymp;
3575 + /* Create new COFF symbol. */
3576 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3577 + if (csymp == NULL)
3580 + csymp->symbol.name = xstrdup (osymp->name);
3581 + csymp->symbol.value = osymp->value;
3582 + csymp->symbol.flags = localp? BSF_LOCAL: BSF_GLOBAL;
3583 + csymp->symbol.section = osymp->section;
3584 + csymp->symbol.udata.p = NULL;
3585 + csymp->native->u.syment.n_sclass = localp? C_STAT: C_EXT;
3586 + csymp->native->u.syment.n_type = T_NULL;
3588 + coff_record_symbol (info, csymp);
3593 +/* The general routine to write out COFF debugging information. This
3594 + synthesizes and accumulates the COFF symbols. Actual symbol table
3595 + output is performed later on by the BFD functions. ABFD is the BFD
3596 + and DHANDLE is the handle for the debugging information. symcountp
3597 + and symppp point to the incoming (parsed) symbol list on entry, and
3598 + will be updated to point to the new symbol table's values upon
3602 +write_coff_debugging_info (abfd, dhandle, symcountp, symppp)
3606 + asymbol ***symppp;
3608 + struct coff_write_handle info;
3611 + struct coff_compilation_unit *up;
3612 + coff_symbol_type *csymp;
3614 + memset ((void *)&info, 0, sizeof info);
3618 + info.pointersize = info.enumsize = 4;
3620 + switch (bfd_get_arch (abfd))
3622 + case bfd_arch_avr:
3623 + info.flags |= COFF_FL_AVR;
3624 + if (strcmp (abfd->xvec->name, "coff-ext-avr") == 0)
3625 + info.flags |= COFF_FL_EXT_AVR;
3626 + /* Fix the builtin type sizes. */
3627 + coff_predef_types[0].size = 2; /* sizeof(int) == 2 */
3628 + coff_predef_types[4].size = 4; /* sizeof(double) == 4 */
3629 + coff_predef_types[6].size = 2; /* sizeof(unsigned int) == 2 */
3630 + info.pointersize = info.enumsize = 2;
3637 + coff_copy_symbols(&info, *symcountp, *symppp);
3639 + if (info.textsect == NULL)
3641 + fprintf (stderr, _("Warning: no \"text\" section found in output file\n"));
3642 + info.textsect = bfd_abs_section_ptr;
3644 + if (info.datasect == NULL)
3646 + fprintf (stderr, _("Warning: no \"data\" section found in output file\n"));
3647 + info.datasect = bfd_abs_section_ptr;
3650 + if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc,
3651 + sizeof(struct coff_name_type_hash_entry)))
3654 + if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc,
3655 + sizeof(struct coff_struct_hash_entry)))
3658 + if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc,
3659 + sizeof(struct coff_enum_hash_entry)))
3662 + if (! debug_write (dhandle, &coff_fns, (PTR) &info))
3665 + /* If there is an old compilation unit that has got any local
3666 + non-debugging symbols left over, send them out now. */
3667 + if (info.currentfile != NULL && info.currentfile->totsyms != 0)
3668 + for (i = 0; i < info.currentfile->nsyms; i++)
3670 + up = info.currentfile;
3672 + if (up->syms[i] != NULL)
3674 + coff_emit_ndebug_sym (&info, up->syms[i], TRUE);
3675 + up->syms[i] = NULL;
3680 + /* See whether there are any non-debugging symbols left from the
3681 + input symbol table. First look at all local symbols which must
3682 + be from entire compilation units we didn't see yet in the
3683 + debugging information, because anything else has already been
3684 + handled at the end of each compilation unit (like in the loop
3685 + immediately above). Any compilation unit that has already been
3686 + processed that way is supposed to have its "totsyms" counted down
3687 + to 0 now, so we can skip them.
3689 + Finally, put out all remaining global non-debugging symbols. */
3690 + for (l = 0; l < info.nunits; l++)
3694 + up = info.units + l;
3695 + if (up->totsyms == 0)
3698 + /* Create COFF symbol for this compilation unit. */
3699 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info.abfd, 0, 0);
3700 + if (csymp == NULL)
3703 + bn = bu_basename (up->fname);
3705 + if (bfd_coff_long_filenames (info.abfd))
3706 + csymp->symbol.name = up->fname;
3708 + csymp->symbol.name = bn;
3710 + csymp->symbol.value = 0;
3711 + csymp->symbol.udata.p = NULL;
3712 + csymp->native->u.syment.n_sclass = C_FILE;
3713 + csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */
3714 + coff_record_symbol (&info, csymp);
3716 + for (i = 0; i < up->nsyms; i++)
3718 + symp = up->syms[i];
3722 + coff_emit_ndebug_sym (&info, symp, TRUE);
3726 + for (i = 0; i < info.nglobals; i++)
3728 + symp = info.globals[i];
3732 + coff_emit_ndebug_sym (&info, symp, FALSE);
3735 + /* Fixup the AUX entries for the section symbols we have emitted
3736 + earlier (so they are guaranteed to be at the beginning of the
3737 + symbol table). In particular, the line number count (which we
3738 + only have for the text section) is known right now. */
3739 + for (i = 0; i < info.nsecsyms; i++)
3741 + union internal_auxent *aux;
3743 + csymp = info.secsyms[i];
3745 + aux = &((csymp->native + 1)->u.auxent);
3746 + aux->x_scn.x_scnlen = csymp->symbol.section->output_section->rawsize;
3747 + aux->x_scn.x_nreloc = csymp->symbol.section->reloc_count;
3748 + if (csymp->symbol.section == info.textsect)
3749 + aux->x_scn.x_nlinno = info.totlnos;
3751 + free (info.secsyms);
3753 + coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL);
3754 + bfd_hash_table_free (&info.types.root);
3756 + coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL);
3757 + bfd_hash_table_free (&info.structs.root);
3759 + coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL);
3760 + bfd_hash_table_free (&info.enums.root);
3762 + /* FIXME: free all the other stuff remembered in "info". */
3766 + *symcountp = info.nsyms;
3767 + *symppp = (asymbol **)info.syms;
3772 +/* Start writing out information for a compilation unit. */
3775 +coff_start_compilation_unit (p, filename)
3777 + const char *filename;
3779 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3782 + bfd_boolean found;
3783 + coff_symbol_type *csymp;
3786 + printf ("coff_start_compilation_unit(%s)\n", filename);
3789 + /* If there is an old compilation unit that has got any local
3790 + non-debugging symbols left over, send them out now. */
3791 + if (info->currentfile != NULL && info->currentfile->totsyms != 0)
3792 + for (i = 0; i < info->currentfile->nsyms; i++)
3794 + struct coff_compilation_unit *up = info->currentfile;
3796 + if (up->syms[i] != NULL)
3798 + coff_emit_ndebug_sym (info, up->syms[i], TRUE);
3799 + up->syms[i] = NULL;
3804 + /* symtab (and thus COFF debugging) symbols can only transfer the
3805 + basename of the file, so strip the dirname */
3806 + bn = bu_basename (filename);
3808 + for (i = 0, found = FALSE; i < info->nunits; i++)
3810 + if (strcmp (info->units[i].fname, bn) == 0)
3812 + info->currentfile = info->units + i;
3820 + _("Warning: file %s not found in symbol table, ignoring\n"),
3822 + info->currentfile = NULL;
3826 + /* Synthesize a new internal COFF symbol. */
3827 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3828 + if (csymp == NULL)
3831 + /* Note that coff_fix_symbol_name() [coffgen.c] will fix this for
3832 + us: the symbol name will be replaced by ".file", and the filename
3833 + will be moved to the aux entries. We use the long name obtained
3834 + from the debugging information (that includes the full path) if
3835 + our COFF format supports long filenames, otherwise we only use
3836 + the basename of the file. */
3837 + if (bfd_coff_long_filenames (info->abfd))
3838 + csymp->symbol.name = filename;
3840 + csymp->symbol.name = bn;
3841 + csymp->symbol.value = 0;
3842 + csymp->symbol.udata.p = NULL;
3843 + csymp->native->u.syment.n_sclass = C_FILE;
3844 + csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */
3845 + coff_record_symbol (info, csymp);
3850 +/* Start writing out information for a particular source file. */
3853 +coff_start_source (p, filename)
3854 + PTR p ATTRIBUTE_UNUSED;
3855 + const char *filename ATTRIBUTE_UNUSED;
3859 + printf ("coff_start_source(%s)\n", filename);
3862 + /* COFF cannot handle include filenames. */
3867 +/* Push an empty type. This shouldn't normally happen. */
3870 +coff_empty_type (p)
3873 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3874 + struct coff_type_stack *tst;
3877 + printf ("coff_empty_type()\n");
3880 + coff_push_type (TS_EMPTY);
3885 +/* Push a void type. */
3891 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3892 + struct coff_type_stack *tst;
3895 + printf ("coff_void_type()\n");
3898 + coff_push_type (TS_VOID);
3903 +/* Push an integer type. */
3906 +coff_int_type (p, size, unsignedp)
3908 + unsigned int size;
3909 + bfd_boolean unsignedp;
3911 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3912 + struct coff_type_stack *tst;
3915 + printf ("coff_int_type(%d, %d)\n", size, unsignedp);
3918 + coff_push_type (TS_INT);
3919 + tst->u.ts_int.size = size;
3920 + tst->u.ts_int.isunsigned = unsignedp;
3925 +/* Push a floating point type. */
3928 +coff_float_type (p, size)
3930 + unsigned int size;
3932 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3933 + struct coff_type_stack *tst;
3936 + printf ("coff_float_type(%d)\n", size);
3939 + coff_push_type (TS_FLOAT);
3940 + tst->u.ts_float.size = size;
3945 +/* Push a complex type. */
3948 +coff_complex_type (p, size)
3950 + unsigned int size ATTRIBUTE_UNUSED;
3952 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3953 + struct coff_type_stack *tst;
3956 + printf ("coff_complex_type(%d)\n", size);
3959 + coff_push_type (TS_COMPLEX);
3964 +/* Push a bfd_boolean type. */
3967 +coff_bool_type (p, size)
3969 + unsigned int size;
3971 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3972 + struct coff_type_stack *tst;
3975 + printf ("coff_bool_type(%d)\n", size);
3978 + coff_push_type (TS_INT);
3979 + tst->u.ts_int.size = size;
3980 + tst->u.ts_int.isunsigned = TRUE;
3985 +/* Push an enum type. */
3988 +coff_enum_type (p, tag, names, vals)
3991 + const char **names;
3992 + bfd_signed_vma *vals;
3994 + struct coff_write_handle *info = (struct coff_write_handle *) p;
3995 + struct coff_type_stack *tst;
4000 + printf ("coff_enum_type(%s [", tag);
4001 + for (idx = 0; names[idx] != NULL; idx++)
4002 + printf ("%s -> %d, ", names[idx], (int)vals[idx]);
4006 + coff_push_type (TS_ENUM);
4010 + sprintf(buf, ".%dfake", info->nenums++);
4011 + tst->u.ts_enum.tag.malloctag = xstrdup (buf);
4012 + tst->u.ts_enum.tagismalloced = TRUE;
4015 + tst->u.ts_enum.tag.fixtag = tag;
4016 + tst->u.ts_enum.names = names;
4017 + tst->u.ts_enum.vals = vals;
4022 +/* Push a pointer type. */
4025 +coff_pointer_type (p)
4028 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4029 + struct coff_type_stack *tst;
4032 + printf ("coff_pointer_type()\n");
4035 + coff_push_type (TS_POINTER);
4040 +/* Push a function type. */
4043 +coff_function_type (p, argcount, varargs)
4046 + bfd_boolean varargs ATTRIBUTE_UNUSED;
4048 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4049 + struct coff_type_stack *tst;
4052 + printf ("coff_function_type(%d, %d)\n", argcount, varargs);
4055 + coff_push_type (TS_FUNC);
4057 + /* FIXME should properly discard function arguments */
4058 + if (argcount > -1)
4061 + _("coff_function_type() called with positive argcount\n"));
4068 +/* Push a reference type. */
4071 +coff_reference_type (p)
4074 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4077 + printf ("coff_reference_type()\n");
4080 + coff_complain_unsupp (_("reference"));
4085 +/* Push a range type. */
4088 +coff_range_type (p, low, high)
4090 + bfd_signed_vma low ATTRIBUTE_UNUSED;
4091 + bfd_signed_vma high ATTRIBUTE_UNUSED;
4093 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4096 + printf ("coff_range_type([%d..%d)\n", (int)low, (int)high);
4099 + coff_complain_unsupp (_("range"));
4104 +/* Push an array type. */
4107 +coff_array_type (p, low, high, stringp)
4109 + bfd_signed_vma low;
4110 + bfd_signed_vma high;
4111 + bfd_boolean stringp;
4113 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4114 + struct coff_type_stack *tst;
4117 + printf ("coff_array_type([%d..%d], %d)\n",
4118 + (int)low, (int)high, stringp);
4121 + /* Pop the range type, but ignore it. COFF doesn't use it. */
4124 + /* FIXME What to do here? */
4127 + fprintf(stderr, _("coff_array_type(): stringp == TRUE\n"));
4131 + coff_push_type (TS_ARRAY);
4132 + tst->u.ts_array.low = low;
4133 + tst->u.ts_array.high = high;
4138 +/* Push a set type. */
4141 +coff_set_type (p, bitstringp)
4143 + bfd_boolean bitstringp ATTRIBUTE_UNUSED;
4145 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4148 + printf ("coff_set_type(%d)\n", bitstringp);
4151 + coff_complain_unsupp (_("set"));
4156 +/* Push an offset type. */
4159 +coff_offset_type (p)
4162 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4165 + printf ("coff_offset_type()\n");
4168 + coff_complain_unsupp (_("offset"));
4173 +/* Push a method type. */
4176 +coff_method_type (p, domainp, argcount, varargs)
4178 + bfd_boolean domainp ATTRIBUTE_UNUSED;
4179 + int argcount ATTRIBUTE_UNUSED;
4180 + bfd_boolean varargs ATTRIBUTE_UNUSED;
4182 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4185 + printf ("coff_method_type(%d, %d, %d)\n",
4186 + domainp, argcount, varargs);
4189 + coff_complain_unsupp (_("method"));
4194 +/* Push a const version of a type. */
4197 +coff_const_type (p)
4198 + PTR p ATTRIBUTE_UNUSED;
4202 + printf ("coff_const_type()\n");
4205 + /* const modifier is ignored by COFF */
4210 +/* Push a volatile version of a type. */
4213 +coff_volatile_type (p)
4214 + PTR p ATTRIBUTE_UNUSED;
4218 + printf ("coff_volatile_type()\n");
4221 + /* volatile modifier is ignored by COFF */
4226 +/* Start outputting a struct. */
4229 +coff_start_struct_type (p, tag, id, structp, size)
4233 + bfd_boolean structp;
4234 + unsigned int size;
4236 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4237 + struct coff_type_stack *tst, *savedts;
4238 + struct coff_struct_hash_entry *shash;
4243 + printf ("coff_start_struct_type(%s, %d, %d, %d)\n",
4244 + tag, id, structp, size);
4247 + savedts = info->tstack;
4248 + info->tstack = NULL;
4250 + coff_push_type (TS_STRUCT);
4254 + sprintf(buf, ".%dfake", id);
4255 + name = tst->u.ts_struct.tag.malloctag = xstrdup (buf);
4256 + tst->u.ts_struct.tagismalloced = TRUE;
4259 + name = tst->u.ts_struct.tag.fixtag = tag;
4260 + tst->u.ts_struct.id = id;
4261 + tst->u.ts_struct.isstruct = structp;
4262 + tst->u.ts_struct.size = size;
4263 + tst->u.ts_struct.savedts = savedts;
4265 + shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE);
4266 + if (shash != NULL && shash->types != NULL)
4269 + printf ("new %s definition for %s\n",
4270 + tst->u.ts_struct.isstruct? "struct": "union", name);
4272 + coff_free_struct_info (shash, NULL);
4273 + shash->types = NULL;
4274 + shash->emitted = FALSE;
4277 + (void)coff_struct_hash_lookup (&info->structs, name,
4278 + TRUE, tst->u.ts_struct.tagismalloced);
4283 +/* Add a field to a struct. */
4286 +coff_struct_field (p, name, bitpos, bitsize, visibility)
4291 + enum debug_visibility visibility;
4293 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4294 + struct coff_type_stack *tst, *otst;
4295 + struct coff_struct_fields *fp;
4296 + struct coff_struct_hash_entry *shash;
4297 + struct coff_enum_hash_entry *ehash;
4301 + printf ("coff_struct_field(%s, %d, %d, %d)\n",
4302 + name, (int)bitpos, (int)bitsize, (int)visibility);
4305 + /* Find the last element on the type stack. */
4306 + assert (info->tstack != NULL);
4307 + for (tst = info->tstack, otst = NULL; tst->next != NULL;)
4313 + otst->next = NULL;
4315 + if (tst->tsk != TS_STRUCT)
4317 + fprintf (stderr, "coff_struct_field() not within structure definition\n");
4320 + tst->u.ts_struct.fields = (struct coff_struct_fields *)
4321 + xrealloc (tst->u.ts_struct.fields,
4322 + ++tst->u.ts_struct.nfields * sizeof (struct coff_struct_fields));
4323 + fp = tst->u.ts_struct.fields + (tst->u.ts_struct.nfields - 1);
4325 + fp->bitpos = bitpos;
4326 + fp->bitsize = bitsize;
4327 + fp->visibility = visibility;
4328 + otst = fp->types = info->tstack;
4329 + while (otst->next != NULL)
4330 + otst = otst->next;
4331 + if (otst->tsk == TS_STRUCT && otst->u.ts_struct.shash == NULL)
4333 + if (otst->u.ts_struct.tagismalloced)
4334 + tag = otst->u.ts_struct.tag.malloctag;
4336 + tag = otst->u.ts_struct.tag.fixtag;
4337 + shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE);
4338 + assert (shash != NULL);
4339 + if (!shash->emitted)
4341 + if (shash->types == NULL)
4343 + shash->types = (struct coff_type_stack *)
4344 + xmalloc (sizeof (struct coff_type_stack));
4345 + memcpy (shash->types, otst, sizeof (struct coff_type_stack));
4347 + shash->emitted = TRUE;
4348 + coff_emit_struct (info, otst, shash);
4351 + else if (otst->tsk == TS_ENUM)
4353 + if (otst->u.ts_enum.tagismalloced)
4354 + tag = otst->u.ts_enum.tag.malloctag;
4356 + tag = otst->u.ts_enum.tag.fixtag;
4357 + ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE);
4358 + assert (ehash != NULL);
4359 + if (!ehash->emitted)
4361 + if (ehash->types == NULL)
4363 + ehash->types = (struct coff_type_stack *)
4364 + xmalloc (sizeof (struct coff_type_stack));
4365 + memcpy (ehash->types, otst, sizeof (struct coff_type_stack));
4367 + ehash->emitted = TRUE;
4368 + coff_emit_enum (info, otst, ehash);
4372 + info->tstack = tst;
4377 +/* Finish up a struct. */
4380 +coff_end_struct_type (p)
4383 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4384 + struct coff_type_stack *tst, *savedts;
4387 + printf ("coff_end_struct_type()\n");
4390 + /* Our struct definition should be the only type stack element by
4392 + assert (info->tstack != NULL);
4393 + tst = info->tstack;
4394 + if (tst->tsk != TS_STRUCT || tst->next != NULL)
4396 + fprintf (stderr, "coff_struct_field() not within structure definition\n");
4400 + /* Restore saved type stack, and push our now complete struct
4401 + definition on top. */
4402 + savedts = tst->u.ts_struct.savedts;
4403 + tst->u.ts_struct.savedts = info->tstack;
4404 + info->tstack = savedts;
4405 + tst->next = info->tstack;
4406 + info->tstack = tst;
4411 +/* Start outputting a class. */
4414 +coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
4416 + const char *tag ATTRIBUTE_UNUSED;
4417 + unsigned int id ATTRIBUTE_UNUSED;
4418 + bfd_boolean structp ATTRIBUTE_UNUSED;
4419 + unsigned int size ATTRIBUTE_UNUSED;
4420 + bfd_boolean vptr ATTRIBUTE_UNUSED;
4421 + bfd_boolean ownvptr ATTRIBUTE_UNUSED;
4423 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4426 + printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n",
4427 + tag, id, structp, size, vptr, ownvptr);
4430 + coff_complain_unsupp (_("class"));
4435 +/* Add a static member to the class on the type stack. */
4438 +coff_class_static_member (p, name, physname, visibility)
4439 + PTR p ATTRIBUTE_UNUSED;
4440 + const char *name ATTRIBUTE_UNUSED;
4441 + const char *physname ATTRIBUTE_UNUSED;
4442 + enum debug_visibility visibility ATTRIBUTE_UNUSED;
4446 + printf ("coff_class_static_member(%s, %s, %d)\n",
4447 + name, physname, (int)visibility);
4453 +/* Add a base class to the class on the type stack. */
4456 +coff_class_baseclass (p, bitpos, virtual, visibility)
4457 + PTR p ATTRIBUTE_UNUSED;
4458 + bfd_vma bitpos ATTRIBUTE_UNUSED;
4459 + bfd_boolean virtual ATTRIBUTE_UNUSED;
4460 + enum debug_visibility visibility ATTRIBUTE_UNUSED;
4464 + printf ("coff_class_baseclass(%d, %d, %d)\n",
4465 + (int)bitpos, virtual, (int)visibility);
4471 +/* Start adding a method to the class on the type stack. */
4474 +coff_class_start_method (p, name)
4475 + PTR p ATTRIBUTE_UNUSED;
4476 + const char *name ATTRIBUTE_UNUSED;
4480 + printf ("coff_class_start_method(%s)\n", name);
4486 +/* Add a variant to the current method. */
4489 +coff_class_method_variant (p, physname, visibility, constp, volatilep,
4490 + voffset, contextp)
4491 + PTR p ATTRIBUTE_UNUSED;
4492 + const char *physname ATTRIBUTE_UNUSED;
4493 + enum debug_visibility visibility ATTRIBUTE_UNUSED;
4494 + bfd_boolean constp ATTRIBUTE_UNUSED;
4495 + bfd_boolean volatilep ATTRIBUTE_UNUSED;
4496 + bfd_vma voffset ATTRIBUTE_UNUSED;
4497 + bfd_boolean contextp ATTRIBUTE_UNUSED;
4501 + printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n",
4502 + physname, (int)visibility, constp, volatilep,
4503 + (int)voffset, contextp);
4509 +/* Add a static variant to the current method. */
4512 +coff_class_static_method_variant (p, physname, visibility, constp, volatilep)
4513 + PTR p ATTRIBUTE_UNUSED;
4514 + const char *physname ATTRIBUTE_UNUSED;
4515 + enum debug_visibility visibility ATTRIBUTE_UNUSED;
4516 + bfd_boolean constp ATTRIBUTE_UNUSED;
4517 + bfd_boolean volatilep ATTRIBUTE_UNUSED;
4521 + printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n",
4522 + physname, (int)visibility, constp, volatilep);
4528 +/* Finish up a method. */
4531 +coff_class_end_method (p)
4532 + PTR p ATTRIBUTE_UNUSED;
4536 + printf ("coff_class_end_method()\n");
4542 +/* Finish up a class. */
4545 +coff_end_class_type (p)
4546 + PTR p ATTRIBUTE_UNUSED;
4550 + printf ("coff_end_class_type()\n");
4556 +/* Push a typedef which was previously defined. */
4559 +coff_typedef_type (p, name)
4563 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4564 + struct coff_name_type_hash_entry *nthash;
4565 + struct coff_type_stack *tst, *newchain, *newst, *temp;
4568 + printf ("coff_typedef_type(%s)\n", name);
4571 + nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4573 + /* nthash should never be NULL, since that would imply that the
4574 + generic debugging code has asked for a typedef which it has not
4576 + assert (nthash != NULL);
4578 + /* Just push the entire type stack snapshot we've got on top of the
4579 + existing typestack. See coff_typdef() below for how this
4580 + works. We need to copy over each element however, since anybody
4581 + popping elements off the typestack is supposed to free() each of
4584 + for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;)
4587 + newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4588 + if (newchain == NULL)
4590 + memcpy (newst, tst, sizeof (*newst));
4592 + temp->next = newst;
4596 + newst->next = info->tstack;
4597 + info->tstack = newchain;
4602 +/* Push a struct, union or class tag. */
4605 +coff_tag_type (p, name, id, kind)
4608 + unsigned int id ATTRIBUTE_UNUSED;
4609 + enum debug_type_kind kind;
4611 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4612 + struct coff_type_stack *tst, *newchain, *newst, *temp;
4613 + struct coff_struct_hash_entry *shash;
4614 + struct coff_enum_hash_entry *ehash;
4616 + bfd_boolean needcopy = FALSE;
4617 + bfd_boolean isstruct = TRUE;
4620 + printf ("coff_tag_type(%s, %d, %d)\n",
4626 + sprintf(buf, ".%dfake", id);
4632 + case DEBUG_KIND_UNION:
4633 + case DEBUG_KIND_UNION_CLASS:
4636 + case DEBUG_KIND_STRUCT:
4637 + case DEBUG_KIND_CLASS:
4638 + shash = coff_struct_hash_lookup (&info->structs,
4639 + name == NULL? buf: name, TRUE, needcopy);
4640 + assert (shash != NULL);
4641 + tst = shash->types;
4644 + /* This is a reference to a tag that has not yet been
4645 + defined (i. e., a forward reference). Synthesize a
4646 + ts_struct entry by now, and mark it for later fixup. */
4647 + tst = (struct coff_type_stack *) xmalloc (sizeof *tst);
4648 + memset (tst, 0, sizeof *tst);
4649 + tst->tsk = TS_STRUCT;
4650 + tst->u.ts_struct.isstruct = isstruct;
4651 + tst->u.ts_struct.shash = shash;
4654 + /* Just push the entire type stack snapshot we've got on top of the
4655 + existing typestack. See coff_typdef() below for how this
4656 + works. We need to copy over each element however, since anybody
4657 + popping elements off the typestack is supposed to free() each of
4659 + for (temp = newst = newchain = NULL; tst != NULL;)
4662 + newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4663 + if (newchain == NULL)
4665 + memcpy (newst, tst, sizeof (*newst));
4667 + temp->next = newst;
4673 + newst->next = info->tstack;
4674 + info->tstack = newchain;
4678 + case DEBUG_KIND_ENUM:
4679 + ehash = coff_enum_hash_lookup (&info->enums,
4680 + name == NULL? buf: name, TRUE, needcopy);
4681 + assert (ehash != NULL);
4682 + tst = ehash->types;
4685 + /* This is a reference to a tag that has not yet been
4686 + defined (i. e., a forward reference). Synthesize a
4687 + ts_enum entry by now, and mark it for later fixup. */
4688 + tst = (struct coff_type_stack *) xmalloc (sizeof *tst);
4689 + memset (tst, 0, sizeof *tst);
4690 + tst->tsk = TS_ENUM;
4691 + tst->u.ts_enum.ehash = ehash;
4696 + fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"),
4703 +/* Define a typedef. */
4706 +coff_typdef (p, name)
4710 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4711 + struct coff_name_type_hash_entry *nthash;
4714 + printf ("coff_typdef(%s)\n", name);
4717 + /* COFF cannot really handle typedefs. While there is the option to
4718 + mark a symbol using the storage class C_TPDEF (so the COFF reader
4719 + will know that name), there is no way to place a reference to
4720 + that typedef into the just 16 bits COFF reserves for all of its
4721 + type information. Thus, any use of the typedef must always fully
4722 + dereference the typedef again. We do this by "snapshotting" the
4723 + current type stack under the name of our typedef, and later on,
4724 + when BFD debugging tells us to make use of the typedef (in
4725 + coff_typedef_type()), we just look it up, and push all we've got
4726 + completely onto the type stack again. */
4728 + if (info->tstack == NULL)
4730 + fprintf (stderr, _("coff_typdef() on an empty type stack\n"));
4734 + nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4735 + if (nthash != NULL)
4738 + printf ("new typedef for %s\n", name);
4740 + coff_free_type_info (nthash, NULL);
4743 + nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE);
4744 + if (nthash == NULL)
4746 + nthash->types = info->tstack;
4748 + /* If the typestack is "sufficiently complex", emit a C_TPDEF symbol
4749 + for it. We assume it to be sufficiently complex if there are
4750 + either at least two derived types, or one derived type where the
4751 + base type is not a simple scalar one. */
4752 + if (!nthash->emitted
4753 + && info->tstack->next != NULL
4754 + && (info->tstack->next->next != NULL || info->tstack->next->tsk >= TS_ENUM))
4756 + struct coff_type_stack *newchain, *otst, *tst, *ntst;
4757 + coff_symbol_type *csymp;
4759 + nthash->emitted = TRUE;
4761 + for (tst = info->tstack, newchain = otst = NULL;
4765 + ntst = (struct coff_type_stack *)
4766 + xmalloc (sizeof (struct coff_type_stack));
4767 + memcpy (ntst, tst, sizeof (struct coff_type_stack));
4771 + otst->next = ntst;
4774 + info->tstack = newchain;
4775 + if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4778 + csymp->symbol.name = xstrdup (name);
4779 + csymp->symbol.flags = BSF_NOT_AT_END;
4780 + csymp->symbol.section = bfd_com_section_ptr;
4781 + csymp->native->u.syment.n_sclass = C_TPDEF;
4782 + csymp->symbol.value = 0;
4784 + coff_record_symbol (info, csymp);
4786 + info->tstack = NULL;
4791 +/* Define a tag. */
4798 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4799 + struct coff_type_stack *tst = NULL;
4800 + struct coff_struct_hash_entry *shash;
4801 + struct coff_enum_hash_entry *ehash;
4805 + printf ("coff_tag(%s)\n", tag);
4808 + if (info->tstack == NULL)
4810 + fprintf (stderr, _("coff_tag() called on an empty typestack\n"));
4814 + switch (info->tstack->tsk)
4817 + shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE);
4818 + assert (shash != NULL);
4819 + shash->types = info->tstack;
4820 + info->tstack = NULL;
4824 + ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE);
4825 + if (ehash != NULL && ehash->types != NULL)
4828 + printf ("new enum definition for %s\n", tag);
4830 + coff_free_enum_info (ehash, NULL);
4833 + ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE);
4834 + if (ehash == NULL)
4836 + ehash->types = info->tstack;
4837 + info->tstack = NULL;
4841 + fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk);
4848 +/* Define an integer constant. */
4851 +coff_int_constant (p, name, val)
4853 + const char *name ATTRIBUTE_UNUSED;
4854 + bfd_vma val ATTRIBUTE_UNUSED;
4856 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4859 + printf ("coff_int_constant(%s, %d)\n", name, (int)val);
4862 + coff_complain_unsupp (_("int constant"));
4867 +/* Define a floating point constant. */
4870 +coff_float_constant (p, name, val)
4872 + const char *name ATTRIBUTE_UNUSED;
4873 + double val ATTRIBUTE_UNUSED;
4875 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4878 + printf ("coff_float_constant(%s, %g)\n", name, val);
4881 + coff_complain_unsupp (_("float constant"));
4886 +/* Define a typed constant. */
4889 +coff_typed_constant (p, name, val)
4891 + const char *name ATTRIBUTE_UNUSED;
4892 + bfd_vma val ATTRIBUTE_UNUSED;
4894 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4897 + printf ("coff_typed_constant(%s, %d)\n", name, (int)val);
4900 + coff_complain_unsupp (_("typed constant"));
4905 +/* Record a variable. */
4908 +coff_variable (p, name, kind, val)
4911 + enum debug_var_kind kind;
4914 + struct coff_write_handle *info = (struct coff_write_handle *) p;
4915 + unsigned char class;
4916 + asymbol *symp = NULL;
4917 + coff_symbol_type *csymp;
4918 + bfd_boolean global = FALSE;
4919 + flagword flags = BSF_LOCAL;
4920 + bfd_vma vmadiff = 0;
4923 + printf ("coff_variable(%s, %d, %d)\n",
4924 + name, (int)kind, (int)val);
4932 + case DEBUG_GLOBAL:
4933 + flags = BSF_GLOBAL;
4935 + /* AVR COFF historically used C_EXTDEF for global variables, and
4936 + C_EXT for global functions. Since some AVR COFF consumers
4937 + apparently depend on this, we mimic this behaviour as
4939 + class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT;
4942 + case DEBUG_STATIC:
4943 + case DEBUG_LOCAL_STATIC:
4951 + case DEBUG_REGISTER:
4956 + if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4959 + if (class == C_REG && (info->flags & COFF_FL_AVR) != 0)
4961 + struct coff_private_symdata *priv = (struct coff_private_symdata *)
4962 + csymp->symbol.udata.p;
4963 + val = coff_fixup_avr_register (val, priv->size * 8);
4966 + csymp->symbol.name = name;
4967 + csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */
4969 + /* Match the debugging symbol against the input symtab symbols. If
4970 + we found one, use the section information from it. Otherwise, we
4971 + are lost here and just use the absolute section that was
4972 + predeclared by coff_bfd_make_debug_symbol(). C_REG and C_AUTO
4973 + symbols (which we do not attempt to lookup in the symtab symbols
4974 + at all) go into the ABS section anyway. */
4975 + if (class != C_REG && class != C_AUTO)
4977 + symp = coff_find_symbol (info, name, FALSE, global);
4980 + csymp->symbol.section = symp->section;
4981 + vmadiff = symp->section->vma;
4985 + /* Symbols are relative to section vma. */
4986 + csymp->symbol.value = val - vmadiff;
4987 + csymp->native->u.syment.n_sclass = class;
4988 + coff_record_symbol (info, csymp);
4993 +/* Start outputting a function. */
4996 +coff_start_function (p, name, globalp)
4999 + bfd_boolean globalp;
5001 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5002 + struct coff_type_stack *tst, *savedts;
5005 + printf ("coff_start_function(%s, %d)\n",
5009 + savedts = info->tstack;
5010 + info->tstack = NULL;
5012 + coff_push_type (TS_FUNC);
5014 + if (info->funname != NULL)
5017 + _("coff_start_function() called twice, pending %s, new %s\n"),
5018 + info->funname, name);
5021 + info->funname = name;
5022 + info->funglobal = globalp;
5023 + info->flags |= COFF_FL_START_FCN;
5024 + tst->u.ts_func.savedts = savedts;
5029 +/* Output a function parameter. */
5032 +coff_function_parameter (p, name, kind, val)
5035 + enum debug_parm_kind kind;
5038 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5039 + coff_symbol_type *csymp;
5040 + unsigned char class;
5043 + printf ("coff_function_parameter(%s, %d, %d)\n",
5044 + name, (int)kind, (int)val);
5052 + case DEBUG_PARM_STACK:
5056 + case DEBUG_PARM_REG:
5057 + class = C_REGPARM;
5060 + case DEBUG_PARM_REFERENCE:
5061 + case DEBUG_PARM_REF_REG:
5062 + fprintf (stderr, _("Reference parameters not available in COFF\n"));
5066 + if (!coff_make_typed_symbol (info, &csymp, TS_FUNC))
5069 + if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0)
5071 + struct coff_private_symdata *priv = (struct coff_private_symdata *)
5072 + csymp->symbol.udata.p;
5073 + val = coff_fixup_avr_register (val, priv->size * 8);
5076 + csymp->symbol.name = name;
5077 + csymp->symbol.value = val;
5078 + csymp->symbol.flags |= BSF_LOCAL;
5079 + csymp->native->u.syment.n_sclass = class;
5081 + /* Since function parameters precede the actual function definition,
5082 + defer their output until the function has been created. */
5083 + info->fargs = (coff_symbol_type **)
5084 + xrealloc (info->fargs, ++info->nfargs * sizeof (coff_symbol_type *));
5085 + info->fargs[info->nfargs - 1] = csymp;
5090 +/* Start a block. */
5093 +coff_start_block (p, addr)
5097 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5098 + struct coff_type_stack *tst, *otst;
5099 + struct coff_fix_stack *fixp, *ofp;
5101 + coff_symbol_type *csymp;
5103 + bfd_boolean is_start_fcn;
5106 + printf ("coff_start_block(%#x)\n", (int)addr);
5109 + is_start_fcn = info->flags & COFF_FL_START_FCN;
5113 + /* This is the starting block of a function. We are going to
5114 + write three symbols here, one for the function itself, one
5115 + ".bf" symbol to indicate the begin of the function, and
5116 + finally one ".bb" for the first block inside the function. */
5117 + info->flags &= ~COFF_FL_START_FCN;
5119 + /* Our function definition should be the only type stack element
5121 + assert (info->tstack != NULL);
5122 + tst = info->tstack;
5123 + if (tst->tsk != TS_FUNC || tst->next != NULL)
5126 + _("coff_start_block() not within function definition\n"));
5130 + /* Restore saved type stack, and push our now complete function
5131 + definition on top. */
5132 + info->tstack = tst->u.ts_func.savedts;
5133 + tst->next = info->tstack;
5134 + info->tstack = tst;
5136 + if (info->currentfile == NULL)
5139 + _("Warning: ignoring function %s() outside any compilation unit\n"),
5141 + for (tst = info->tstack, otst = NULL; tst != NULL;)
5145 + if (otst->tsk == TS_ENUM &&
5146 + otst->u.ts_enum.tagismalloced)
5147 + free (otst->u.ts_enum.tag.malloctag);
5148 + else if (otst->tsk == TS_STRUCT &&
5149 + otst->u.ts_struct.tagismalloced)
5150 + free (otst->u.ts_struct.tag.malloctag);
5153 + info->tstack = NULL;
5154 + info->funname = NULL;
5159 + if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
5162 + csymp->symbol.name = info->funname;
5163 + csymp->symbol.flags = BSF_FUNCTION |
5164 + (info->funglobal? BSF_GLOBAL: BSF_LOCAL);
5165 + symp = coff_find_symbol (info, info->funname, TRUE, info->funglobal);
5169 + _("function %s not found in symbol table, defaulting to \"text\" section\n"),
5171 + csymp->symbol.section = info->funcsection = info->textsect;
5174 + csymp->symbol.section = info->funcsection = symp->section;
5176 + /* Symbol addresses are relative to section vma. */
5177 + csymp->symbol.value = addr - info->funcsection->vma;
5178 + csymp->native->u.syment.n_sclass = info->funglobal? C_EXT: C_STAT;
5179 + /* Create two initial line number entries. The first one holds
5180 + the function symbol, the second one is the trailing record
5181 + that is required by coffgen.c::coff_write_native_symbol() to
5182 + have a line number of zero. */
5183 + csymp->lineno = (alent *) xmalloc (2 * sizeof (alent));
5184 + memset (csymp->lineno, 0, 2 * sizeof (alent));
5187 + csymp->lineno[0].u.sym = (asymbol *)csymp;
5188 + coff_record_symbol (info, csymp);
5189 + info->funcindex = info->nsyms - 1; /* remember for later */
5190 + /* Record our endndx field for later fixing. */
5191 + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
5192 + fixp->native = csymp->native + 1; /* points to first AUX */
5193 + fixp->next = NULL;
5194 + if (info->fixes == NULL)
5195 + info->fixes = fixp;
5198 + for (ofp = info->fixes; ofp->next != NULL;)
5203 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5204 + if (csymp == NULL)
5207 + csymp->symbol.name = ".bf";
5208 + csymp->native->u.syment.n_sclass = C_FCN;
5209 + csymp->native->u.syment.n_numaux = 1;
5210 + csymp->symbol.value = addr - info->funcsection->vma;
5211 + csymp->symbol.section = info->funcsection;
5212 + csymp->symbol.udata.p = NULL;
5213 + coff_record_symbol (info, csymp);
5216 + if (info->funname == NULL)
5219 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5220 + if (csymp == NULL)
5223 + csymp->symbol.name = ".bb";
5224 + csymp->native->u.syment.n_sclass = C_BLOCK;
5225 + csymp->native->u.syment.n_numaux = 1;
5226 + csymp->symbol.value = addr - info->funcsection->vma;
5227 + csymp->symbol.section = info->funcsection;
5228 + csymp->symbol.udata.p = NULL;
5229 + coff_record_symbol (info, csymp);
5231 + info->flags |= COFF_FL_FIX_BB;
5233 + /* Output any pending function parameters, if any. */
5234 + if (is_start_fcn && info->nfargs)
5236 + for (i = 0; i < info->nfargs; i++)
5237 + coff_record_symbol (info, info->fargs[i]);
5239 + free (info->fargs);
5240 + info->fargs = NULL;
5250 +coff_end_block (p, addr)
5254 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5255 + coff_symbol_type *csymp;
5256 + union internal_auxent *aux;
5259 + printf ("coff_end_block(%#x)\n", (int)addr);
5262 + if (info->funname == NULL)
5265 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5266 + if (csymp == NULL)
5269 + csymp->symbol.name = ".eb";
5270 + csymp->symbol.value = addr - info->funcsection->vma;
5271 + csymp->native->u.syment.n_sclass = C_BLOCK;
5272 + csymp->native->u.syment.n_numaux = 1;
5273 + csymp->symbol.udata.p = NULL;
5274 + csymp->symbol.section = info->funcsection;
5275 + aux = &((csymp->native + 1)->u.auxent);
5276 + aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno;
5277 + coff_record_symbol (info, csymp);
5279 + info->endaddr = addr;
5284 +/* End a function. */
5287 +coff_end_function (p)
5290 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5291 + coff_symbol_type *csymp;
5292 + union internal_auxent *aux;
5295 + printf ("coff_end_function()\n");
5298 + if (info->funname == NULL)
5301 + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5302 + if (csymp == NULL)
5305 + csymp->symbol.name = ".ef";
5306 + csymp->symbol.value = info->endaddr - info->funcsection->vma;
5307 + csymp->native->u.syment.n_sclass = C_FCN;
5308 + csymp->native->u.syment.n_numaux = 1;
5309 + csymp->symbol.udata.p = NULL;
5310 + csymp->symbol.section = info->funcsection;
5311 + aux = &((csymp->native + 1)->u.auxent);
5312 + aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno;
5314 + coff_record_symbol (info, csymp);
5316 + csymp = (coff_symbol_type *) info->syms[info->funcindex];
5317 + aux = &((csymp->native + 1)->u.auxent);
5318 + aux->x_sym.x_misc.x_fsize = info->endaddr - csymp->symbol.value;
5320 + info->flags |= COFF_FL_FIX_ENDNDX;
5321 + info->funname = NULL;
5326 +/* Output a line number. */
5329 +coff_lineno (p, file, lineno, addr)
5331 + const char *file ATTRIBUTE_UNUSED;
5332 + unsigned long lineno;
5335 + struct coff_write_handle *info = (struct coff_write_handle *) p;
5336 + coff_symbol_type *csymp;
5337 + union internal_auxent *aux;
5341 + printf ("coff_lineno(%s, %ld, %d)\n",
5342 + file, lineno, (int)addr);
5345 + /* COFF can inherently only handle line numbers inside of functions.
5346 + If we are not inside a function, punt. */
5347 + if (info->funname == NULL)
5350 + if (info->nlnos == 2)
5352 + /* This is the first line number of this function. Fix the line
5353 + number for the .bf symbol immediately following the start of
5354 + function. We also have to remember the starting line number
5355 + of our function since all line number entries are relative to
5356 + it in COFF. Since regular line numbers must always be
5357 + non-zero, we artificially force the function to start one
5359 + csymp = (coff_symbol_type *) info->syms[info->funcindex + 1];
5360 + aux = &((csymp->native + 1)->u.auxent);
5361 + aux->x_sym.x_misc.x_lnsz.x_lnno = lineno;
5362 + info->funlno = lineno - 1;
5365 + if (info->flags & COFF_FL_FIX_BB)
5367 + /* This is the first line number after one (or more) .bb
5368 + symbols. Fix them. In order to cope with multiple blocks
5369 + starting at the same line number, we walk back the list of
5370 + symbols until we find a C_BLOCK one that had already been
5371 + fixed, or until we find a C_FCN symbol (presumably, the start
5372 + of our current function). */
5373 + info->flags &= ~COFF_FL_FIX_BB;
5375 + for (i = info->nsyms - 1; i >= 0; i--)
5377 + csymp = (coff_symbol_type *) info->syms[i];
5378 + if (csymp->native->u.syment.n_sclass == C_FCN)
5380 + if (csymp->native->u.syment.n_sclass == C_BLOCK)
5382 + aux = &((csymp->native + 1)->u.auxent);
5383 + if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0)
5384 + /* already set up properly */
5386 + aux->x_sym.x_misc.x_lnsz.x_lnno = lineno;
5391 + csymp = (coff_symbol_type *) info->syms[info->funcindex];
5392 + csymp->lineno = (alent *) xrealloc (csymp->lineno,
5393 + ++info->nlnos * sizeof (alent));
5394 + memset (csymp->lineno + info->nlnos - 1, 0, sizeof (alent));
5395 + if (lineno > info->funlno)
5396 + csymp->lineno[info->nlnos - 2].line_number = lineno - info->funlno;
5398 + /* Line number unreasonable. Can e. g. happen for a line number
5399 + from an include file, which we cannot process in COFF. Just
5400 + set it to the first line, to avoid generating a large unsigned
5401 + short (~ 65000) line number. */
5402 + csymp->lineno[info->nlnos - 2].line_number = 1;
5403 + csymp->lineno[info->nlnos - 2].u.offset = addr;
5405 + info->lastlno = lineno;
5410 diff -uNdr binutils-2.17.50.0.18-old/include/coff/avr.h binutils-2.17.50.0.18/include/coff/avr.h
5411 --- binutils-2.17.50.0.18-old/include/coff/avr.h 1970-01-01 01:00:00.000000000 +0100
5412 +++ binutils-2.17.50.0.18/include/coff/avr.h 2007-10-20 16:45:33.000000000 +0200
5414 +/* coff information for Atmel AVR.
5416 + Copyright 2001 Free Software Foundation, Inc.
5418 + This program is free software; you can redistribute it and/or modify
5419 + it under the terms of the GNU General Public License as published by
5420 + the Free Software Foundation; either version 2 of the License, or
5421 + (at your option) any later version.
5423 + This program is distributed in the hope that it will be useful,
5424 + but WITHOUT ANY WARRANTY; without even the implied warranty of
5425 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5426 + GNU General Public License for more details.
5428 + You should have received a copy of the GNU General Public License
5429 + along with this program; if not, write to the Free Software
5430 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
5432 +/* This file was hacked from i860.h */
5434 +#define L_LNNO_SIZE 2
5435 +#include "coff/external.h"
5437 +/* Bits for f_flags:
5438 + F_RELFLG relocation info stripped from file
5439 + F_EXEC file is executable (no unresolved external references)
5440 + F_LNNO line numbers stripped from file
5441 + F_LSYMS local symbols stripped from file */
5443 +#define F_RELFLG (0x0001)
5444 +#define F_EXEC (0x0002)
5445 +#define F_LNNO (0x0004)
5446 +#define F_LSYMS (0x0008)
5447 +/* Upper nibble of flags always needs to be set. This used to be
5448 + * undocumented, recent information from Atmel says that bit 7 used to
5449 + * differentiate between an old vendor-specific deviation of the
5450 + * format and the current format. */
5451 +#define F_JUNK (0x00f0)
5452 +#define F_UNUSED (0xff00)
5454 +#define AVRMAGIC 0xa12
5457 +#ifdef AVR_EXT_COFF
5459 +/* AVR "extended" COFF format. This uses the optional header ("a.out"
5460 + header) to inform the consumer about some additional features that
5462 +#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */
5463 +#define AOUTSZ 28 /* size of optional header in "extended" COFF */
5465 +/* Flags in the optional header; they are stored in the vstamp field. */
5466 +#define F_FULLPATHS 0x0001 /* long filenames supported */
5467 +#define F_STRUCTINFO 0x0002 /* structure information contained */
5468 +#define F_PTRINFO 0x0004 /* inter-segment pointers supported */
5470 +#else /* old AVR COFF */
5472 +#define AOUTSZ 0 /* no a.out for AVR */
5475 +/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */
5477 + * The following magic number causes AVR Studio 4.x to recognize
5478 + * avr-gcc/GNU binutils produced AVR extended COFF files. By now,
5479 + * the only special treatment for them is that the contents of .data
5480 + * will be appended after .text in the simulator flash.
5482 + * 0x9cc has been chosen since it resembles "gcc". ;-)
5484 +#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */
5486 +/* By matching not only the magic number, but also the size of the
5487 + optional a.out header, we can differentiate between both
5489 +#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ)
5491 +/* AVR COFF has several anomalities in the way the handle the derived
5492 + type information, and AUX entries, mainly because they apparently
5493 + didn't bother to learn how COFF is supposed to work before they
5494 + started. We fix many of them at the export/import boundary, so all
5495 + the internal generic COFF handling will work mostly as designed. */
5497 +/* NB: these functions are only defined in bfd/coff-avr.c, but also
5498 + used in coff-ext-avr.c, so the latter can only be configured if the
5499 + former is also present. This is certainly always the case
5501 +extern void avr_coff_adjust_sym_in_post
5502 + PARAMS((bfd *, PTR, PTR));
5504 +extern void avr_coff_adjust_sym_out_post
5505 + PARAMS((bfd *, PTR, PTR));
5507 +#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \
5508 + avr_coff_adjust_sym_in_post (ABFD, EXT, INT)
5510 +#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \
5511 + avr_coff_adjust_sym_out_post (ABFD, INT, EXT)
5513 +/********************** RELOCATION DIRECTIVES **********************/
5515 +struct external_reloc
5522 +#define RELOC struct external_reloc
5524 diff -uNdr binutils-2.17.50.0.18-old/include/coff/internal.h binutils-2.17.50.0.18/include/coff/internal.h
5525 --- binutils-2.17.50.0.18-old/include/coff/internal.h 2007-08-01 15:11:51.000000000 +0200
5526 +++ binutils-2.17.50.0.18/include/coff/internal.h 2007-10-20 16:45:33.000000000 +0200
5531 +#define NAUXENTS 10 /* number of pre-allocated aux entries */
5533 /********************** RELOCATION DIRECTIVES **********************/
5535 struct internal_reloc