]> git.pld-linux.org Git - packages/crossavr-binutils.git/blame - crossavr-binutils-coff-avr.patch
- outdated
[packages/crossavr-binutils.git] / crossavr-binutils-coff-avr.patch
CommitLineData
f33182aa 1diff -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
4@@ -208,6 +208,8 @@
5 coff-apollo.lo \
6 coff-arm.lo \
7 coff-aux.lo \
8+ coff-avr.lo \
9+ coff-ext-avr.lo \
10 coff-h8300.lo \
11 coff-h8500.lo \
12 coff-i386.lo \
13@@ -387,6 +389,8 @@
14 coff-apollo.c \
15 coff-arm.c \
16 coff-aux.c \
17+ coff-avr.c \
18+ coff-ext-avr.c \
19 coff-h8300.c \
20 coff-h8500.c \
21 coff-i386.c \
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 \
25 coffcode.h coffswap.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 \
35diff -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
38@@ -458,6 +458,8 @@
39 coff-apollo.lo \
40 coff-arm.lo \
41 coff-aux.lo \
42+ coff-avr.lo \
43+ coff-ext-avr.lo \
44 coff-h8300.lo \
45 coff-h8500.lo \
46 coff-i386.lo \
47@@ -637,6 +639,8 @@
48 coff-apollo.c \
49 coff-arm.c \
50 coff-aux.c \
51+ coff-avr.c \
52+ coff-ext-avr.c \
53 coff-h8300.c \
54 coff-h8500.c \
55 coff-i386.c \
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 \
59 coffcode.h coffswap.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 \
69diff -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
72@@ -0,0 +1,609 @@
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
4cd5ba0f 77+
f33182aa 78+This file is part of BFD, the Binary File Descriptor library.
4cd5ba0f 79+
f33182aa 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.
4cd5ba0f 84+
f33182aa 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.
4cd5ba0f 89+
f33182aa 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. */
4cd5ba0f 93+
f33182aa 94+#include "bfd.h"
95+#include "sysdep.h"
96+#include "libbfd.h"
4cd5ba0f 97+
f33182aa 98+#include "coff/avr.h"
4cd5ba0f 99+
f33182aa 100+#include "coff/internal.h"
4cd5ba0f 101+
f33182aa 102+#include "libcoff.h"
4cd5ba0f 103+
f33182aa 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 *,
109+ bfd_vma *));
110+static const bfd_target * coff_avr_object_p PARAMS ((bfd *));
4cd5ba0f 111+
f33182aa 112+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
113+/* The page size is a guess based on ELF. */
4cd5ba0f 114+
f33182aa 115+#define COFF_PAGE_SIZE 0x1000
4cd5ba0f 116+
f33182aa 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. */
4cd5ba0f 120+
f33182aa 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. */
4cd5ba0f 125+
f33182aa 126+static bfd_reloc_status_type
127+coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
128+ error_message)
129+ bfd *abfd;
130+ arelent *reloc_entry;
131+ asymbol *symbol;
132+ PTR data;
133+ asection *input_section ATTRIBUTE_UNUSED;
134+ bfd *output_bfd;
135+ char **error_message ATTRIBUTE_UNUSED;
136+{
137+ symvalue diff;
4cd5ba0f 138+
f33182aa 139+ if (output_bfd == (bfd *) NULL)
140+ return bfd_reloc_continue;
4cd5ba0f 141+
f33182aa 142+ if (bfd_is_com_section (symbol->section))
143+ {
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;
156+ }
157+ else
158+ {
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;
164+ }
165+
166+#define DOIT(x) \
167+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
168+
169+ if (diff != 0)
170+ {
171+ reloc_howto_type *howto = reloc_entry->howto;
172+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
173+
174+ switch (howto->size)
4cd5ba0f 175+ {
f33182aa 176+ case 0:
177+ {
178+ char x = bfd_get_8 (abfd, addr);
179+ DOIT (x);
180+ bfd_put_8 (abfd, x, addr);
181+ }
182+ break;
4cd5ba0f 183+
f33182aa 184+ case 1:
185+ {
186+ short x = bfd_get_16 (abfd, addr);
187+ DOIT (x);
188+ bfd_put_16 (abfd, (bfd_vma) x, addr);
189+ }
190+ break;
4cd5ba0f 191+
f33182aa 192+ case 2:
193+ {
194+ long x = bfd_get_32 (abfd, addr);
195+ DOIT (x);
196+ bfd_put_32 (abfd, (bfd_vma) x, addr);
197+ }
198+ break;
4cd5ba0f 199+
f33182aa 200+ default:
201+ abort ();
4cd5ba0f 202+ }
f33182aa 203+ }
4cd5ba0f 204+
f33182aa 205+ /* Now let bfd_perform_relocation finish everything up. */
206+ return bfd_reloc_continue;
207+}
486e8626 208+
f33182aa 209+#ifndef PCRELOFFSET
210+#define PCRELOFFSET FALSE
211+#endif
212+
213+static reloc_howto_type howto_table[] =
4cd5ba0f 214+{
f33182aa 215+ EMPTY_HOWTO (0),
216+ EMPTY_HOWTO (1),
217+ EMPTY_HOWTO (2),
218+ EMPTY_HOWTO (3),
219+ EMPTY_HOWTO (4),
220+ EMPTY_HOWTO (5),
221+ HOWTO (R_DIR32, /* type */
222+ 0, /* rightshift */
223+ 2, /* size (0 = byte, 1 = short, 2 = long) */
224+ 32, /* bitsize */
225+ FALSE, /* pc_relative */
226+ 0, /* bitpos */
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 */
234+ /* {7}, */
235+ HOWTO (R_IMAGEBASE, /* type */
236+ 0, /* rightshift */
237+ 2, /* size (0 = byte, 1 = short, 2 = long) */
238+ 32, /* bitsize */
239+ FALSE, /* pc_relative */
240+ 0, /* bitpos */
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 */
248+ EMPTY_HOWTO (010),
249+ EMPTY_HOWTO (011),
250+ EMPTY_HOWTO (012),
251+ EMPTY_HOWTO (013),
252+ EMPTY_HOWTO (014),
253+ EMPTY_HOWTO (015),
254+ EMPTY_HOWTO (016),
255+ HOWTO (R_RELBYTE, /* type */
256+ 0, /* rightshift */
257+ 0, /* size (0 = byte, 1 = short, 2 = long) */
258+ 8, /* bitsize */
259+ FALSE, /* pc_relative */
260+ 0, /* bitpos */
261+ complain_overflow_bitfield, /* complain_on_overflow */
262+ coff_avr_reloc, /* special_function */
263+ "8", /* name */
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) */
271+ 16, /* bitsize */
272+ FALSE, /* pc_relative */
273+ 0, /* bitpos */
274+ complain_overflow_bitfield, /* complain_on_overflow */
275+ coff_avr_reloc, /* special_function */
276+ "16", /* name */
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) */
284+ 32, /* bitsize */
285+ FALSE, /* pc_relative */
286+ 0, /* bitpos */
287+ complain_overflow_bitfield, /* complain_on_overflow */
288+ coff_avr_reloc, /* special_function */
289+ "32", /* name */
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) */
297+ 8, /* bitsize */
298+ TRUE, /* pc_relative */
299+ 0, /* bitpos */
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) */
310+ 16, /* bitsize */
311+ TRUE, /* pc_relative */
312+ 0, /* bitpos */
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) */
323+ 32, /* bitsize */
324+ TRUE, /* pc_relative */
325+ 0, /* bitpos */
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 */
333+};
4cd5ba0f 334+
f33182aa 335+/* Turn a howto into a reloc nunmber */
4cd5ba0f 336+
f33182aa 337+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
338+#define BADMAG(x) AVRBADMAG(x)
339+#define AVR 1 /* Customize coffcode.h */
4cd5ba0f 340+
f33182aa 341+#define RTYPE2HOWTO(cache_ptr, dst) \
342+ (cache_ptr)->howto = howto_table + (dst)->r_type;
4cd5ba0f 343+
f33182aa 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
346+ STYP_NOLOAD. */
347+#define BSS_NOLOAD_IS_SHARED_LIBRARY
4cd5ba0f 348+
f33182aa 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. */
4cd5ba0f 361+
f33182aa 362+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
363+ { \
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)); \
368+ else if (ptr) \
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); \
376+ else \
377+ cache_ptr->addend = 0; \
378+ if (ptr && howto_table[reloc.r_type].pc_relative) \
379+ cache_ptr->addend += asect->vma; \
380+ }
4cd5ba0f 381+
f33182aa 382+/* We use the special COFF backend linker. */
383+#define coff_relocate_section _bfd_coff_generic_relocate_section
4cd5ba0f 384+
f33182aa 385+static reloc_howto_type *
386+coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
387+ bfd *abfd ATTRIBUTE_UNUSED;
388+ asection *sec;
389+ struct internal_reloc *rel;
390+ struct coff_link_hash_entry *h;
391+ struct internal_syment *sym;
392+ bfd_vma *addendp;
393+{
4cd5ba0f 394+
f33182aa 395+ reloc_howto_type *howto;
4cd5ba0f 396+
f33182aa 397+ howto = howto_table + rel->r_type;
4cd5ba0f 398+
f33182aa 399+ if (howto->pc_relative)
400+ *addendp += sec->vma;
4cd5ba0f 401+
f33182aa 402+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
403+ {
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
408+ correct result. */
4cd5ba0f 409+
f33182aa 410+ BFD_ASSERT (h != NULL);
4cd5ba0f 411+
f33182aa 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;
419+ }
4cd5ba0f 420+
f33182aa 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
423+ common symbol. */
424+ if (h != NULL && h->root.type == bfd_link_hash_common)
425+ *addendp += h->root.u.c.size;
4cd5ba0f 426+
f33182aa 427+ return howto;
428+}
4cd5ba0f 429+
f33182aa 430+#define coff_rtype_to_howto coff_avr_rtype_to_howto
4cd5ba0f 431+
f33182aa 432+#include "coffcode.h"
433+
434+static const bfd_target *
435+coff_avr_object_p(a)
436+ bfd *a;
4cd5ba0f 437+{
f33182aa 438+ return coff_object_p (a);
439+}
4cd5ba0f 440+
f33182aa 441+/* Handle all the abominations of AVR COFF:
4cd5ba0f 442+
f33182aa 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).
4cd5ba0f 450+
f33182aa 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.
4cd5ba0f 465+
f33182aa 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. */
4cd5ba0f 470+
f33182aa 471+void
472+avr_coff_adjust_sym_in_post (abfd, ext, in)
473+ bfd *abfd;
474+ PTR ext;
475+ PTR in;
476+{
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);
481+
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. */
487+ if (bt == T_NULL)
488+ switch (dst->n_sclass)
4cd5ba0f 489+ {
f33182aa 490+ case C_STRTAG:
491+ bt = T_STRUCT;
492+ break;
493+
494+ case C_UNTAG:
495+ bt = T_UNION;
496+ break;
497+
498+ case C_ENTAG:
499+ bt = T_ENUM;
500+ break;
4cd5ba0f 501+ }
4cd5ba0f 502+
f33182aa 503+ /* Swap the derived type slots. */
504+ if (dt != 0)
4cd5ba0f 505+ {
f33182aa 506+ ndt = 0;
507+ while (dt != 0)
508+ {
509+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
510+ dt >>= N_TSHIFT;
511+ }
512+ dst->n_type = (ndt << N_BTSHFT) | bt;
4cd5ba0f 513+ }
f33182aa 514+ else
515+ dst->n_type = bt;
4cd5ba0f 516+
f33182aa 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.
4cd5ba0f 520+
f33182aa 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)
4cd5ba0f 528+ {
f33182aa 529+ AUXENT caux, *auxp1, *auxp2;
530+ size_t symesz;
531+ unsigned int i;
4cd5ba0f 532+
f33182aa 533+ symesz = bfd_coff_symesz (abfd);
534+ i = dst->n_numaux;
4cd5ba0f 535+
f33182aa 536+ auxp1 = (AUXENT *)((char *)ext + symesz);
537+ auxp2 = (AUXENT *)((char *)ext + i * symesz);
4cd5ba0f 538+
f33182aa 539+ if (ISFCN (dst->n_type)
540+ || (ISPTR(dst->n_type)
541+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)))
542+ {
543+ caux = *auxp2;
544+ *auxp2 = *auxp1;
545+ *auxp1 = caux;
546+ }
547+ else
548+ caux = *auxp1;
4cd5ba0f 549+
f33182aa 550+ if ((ISFCN (dst->n_type) || ISARY (dst->n_type))
551+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))
552+ {
553+ while (i > 1)
554+ {
555+ auxp2 = (AUXENT *)((char *)ext + i * symesz);
4cd5ba0f 556+
f33182aa 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)
559+ {
560+ memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx,
561+ 4 * sizeof (char));
562+ break;
563+ }
564+ i--;
565+ }
566+ if (i > 1)
567+ *auxp1 = caux;
568+ }
569+ }
570+}
4cd5ba0f 571+
f33182aa 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. */
578+void
579+avr_coff_adjust_sym_out_post (abfd, in, ext)
580+ bfd *abfd;
581+ PTR in;
582+ PTR ext;
4cd5ba0f 583+{
f33182aa 584+ struct internal_syment *src = (struct internal_syment *)(in);
585+ struct external_syment *dst = (struct external_syment *)(ext);
586+ unsigned short dt, bt, ndt;
4cd5ba0f 587+
f33182aa 588+ dt = src->n_type & ~N_BTMASK;
589+ bt = BTYPE (src->n_type);
4cd5ba0f 590+
f33182aa 591+ if (dt != 0)
592+ {
593+ ndt = 0;
594+ while (dt != 0)
595+ {
596+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
597+ dt >>= N_TSHIFT;
598+ }
599+ H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type);
600+ }
4cd5ba0f 601+
f33182aa 602+ if (src->n_numaux > 1 && src->n_sclass != C_FILE)
603+ {
604+ combined_entry_type *srce, *dste;
605+ char *hackp;
606+ unsigned int i;
4cd5ba0f 607+
f33182aa 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;
612+ srce++;
613+
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++)
621+ {
622+ dste = srce + i;
623+ *dste = *srce;
624+ }
625+ }
626+}
627+
628+const bfd_target
629+#ifdef TARGET_SYM
630+ TARGET_SYM =
631+#else
632+ avrcoff_vec =
633+#endif
4cd5ba0f 634+{
f33182aa 635+#ifdef TARGET_NAME
636+ TARGET_NAME,
637+#else
638+ "coff-avr", /* name */
639+#endif
640+ bfd_target_coff_flavour,
641+ BFD_ENDIAN_LITTLE, /* data byte order is little */
642+ BFD_ENDIAN_LITTLE, /* header byte order is little */
4cd5ba0f 643+
f33182aa 644+ (HAS_RELOC | EXEC_P | /* object flags */
645+ HAS_LINENO | HAS_DEBUG |
646+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
4cd5ba0f 647+
f33182aa 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 */
4cd5ba0f 652+
f33182aa 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 */
4cd5ba0f 659+
f33182aa 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 */
664+ bfd_false},
665+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
666+ _bfd_write_archive_contents, bfd_false},
4cd5ba0f 667+
f33182aa 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),
4cd5ba0f 677+
f33182aa 678+ NULL,
4cd5ba0f 679+
f33182aa 680+ COFF_SWAP_TABLE
681+};
682diff -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
685@@ -0,0 +1,424 @@
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.
4cd5ba0f 691+
f33182aa 692+This file is part of BFD, the Binary File Descriptor library.
4cd5ba0f 693+
f33182aa 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.
4cd5ba0f 698+
f33182aa 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.
4cd5ba0f 703+
f33182aa 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. */
4cd5ba0f 707+
f33182aa 708+#include "bfd.h"
709+#include "sysdep.h"
710+#include "libbfd.h"
4cd5ba0f 711+
f33182aa 712+#define AVR_EXT_COFF 1
713+#include "coff/avr.h"
4cd5ba0f 714+
f33182aa 715+#include "coff/internal.h"
4cd5ba0f 716+
f33182aa 717+#include "libcoff.h"
4cd5ba0f 718+
f33182aa 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 *,
724+ bfd_vma *));
725+static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *));
4cd5ba0f 726+
f33182aa 727+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
728+/* The page size is a guess based on ELF. */
4cd5ba0f 729+
f33182aa 730+#define COFF_PAGE_SIZE 0x1000
4cd5ba0f 731+
f33182aa 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. */
4cd5ba0f 735+
f33182aa 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. */
4cd5ba0f 740+
f33182aa 741+static bfd_reloc_status_type
742+coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
743+ error_message)
744+ bfd *abfd;
745+ arelent *reloc_entry;
746+ asymbol *symbol;
747+ PTR data;
748+ asection *input_section ATTRIBUTE_UNUSED;
749+ bfd *output_bfd;
750+ char **error_message ATTRIBUTE_UNUSED;
4cd5ba0f 751+{
f33182aa 752+ symvalue diff;
4cd5ba0f 753+
f33182aa 754+ if (output_bfd == (bfd *) NULL)
755+ return bfd_reloc_continue;
4cd5ba0f 756+
f33182aa 757+ if (bfd_is_com_section (symbol->section))
4cd5ba0f 758+ {
f33182aa 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;
4cd5ba0f 771+ }
f33182aa 772+ else
4cd5ba0f 773+ {
f33182aa 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;
779+ }
4cd5ba0f 780+
f33182aa 781+#define DOIT(x) \
782+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
4cd5ba0f 783+
f33182aa 784+ if (diff != 0)
785+ {
786+ reloc_howto_type *howto = reloc_entry->howto;
787+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
4cd5ba0f 788+
f33182aa 789+ switch (howto->size)
790+ {
791+ case 0:
792+ {
793+ char x = bfd_get_8 (abfd, addr);
794+ DOIT (x);
795+ bfd_put_8 (abfd, x, addr);
796+ }
797+ break;
4cd5ba0f 798+
f33182aa 799+ case 1:
800+ {
801+ short x = bfd_get_16 (abfd, addr);
802+ DOIT (x);
803+ bfd_put_16 (abfd, (bfd_vma) x, addr);
804+ }
805+ break;
4cd5ba0f 806+
f33182aa 807+ case 2:
808+ {
809+ long x = bfd_get_32 (abfd, addr);
810+ DOIT (x);
811+ bfd_put_32 (abfd, (bfd_vma) x, addr);
812+ }
813+ break;
4cd5ba0f 814+
f33182aa 815+ default:
816+ abort ();
817+ }
818+ }
4cd5ba0f 819+
f33182aa 820+ /* Now let bfd_perform_relocation finish everything up. */
821+ return bfd_reloc_continue;
4cd5ba0f
ER
822+}
823+
f33182aa 824+#ifndef PCRELOFFSET
825+#define PCRELOFFSET FALSE
826+#endif
4cd5ba0f 827+
f33182aa 828+static reloc_howto_type howto_table[] =
4cd5ba0f 829+{
f33182aa 830+ EMPTY_HOWTO (0),
831+ EMPTY_HOWTO (1),
832+ EMPTY_HOWTO (2),
833+ EMPTY_HOWTO (3),
834+ EMPTY_HOWTO (4),
835+ EMPTY_HOWTO (5),
836+ HOWTO (R_DIR32, /* type */
837+ 0, /* rightshift */
838+ 2, /* size (0 = byte, 1 = short, 2 = long) */
839+ 32, /* bitsize */
840+ FALSE, /* pc_relative */
841+ 0, /* bitpos */
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 */
849+ /* {7}, */
850+ HOWTO (R_IMAGEBASE, /* type */
851+ 0, /* rightshift */
852+ 2, /* size (0 = byte, 1 = short, 2 = long) */
853+ 32, /* bitsize */
854+ FALSE, /* pc_relative */
855+ 0, /* bitpos */
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 */
863+ EMPTY_HOWTO (010),
864+ EMPTY_HOWTO (011),
865+ EMPTY_HOWTO (012),
866+ EMPTY_HOWTO (013),
867+ EMPTY_HOWTO (014),
868+ EMPTY_HOWTO (015),
869+ EMPTY_HOWTO (016),
870+ HOWTO (R_RELBYTE, /* type */
871+ 0, /* rightshift */
872+ 0, /* size (0 = byte, 1 = short, 2 = long) */
873+ 8, /* bitsize */
874+ FALSE, /* pc_relative */
875+ 0, /* bitpos */
876+ complain_overflow_bitfield, /* complain_on_overflow */
877+ coff_ext_avr_reloc, /* special_function */
878+ "8", /* name */
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) */
886+ 16, /* bitsize */
887+ FALSE, /* pc_relative */
888+ 0, /* bitpos */
889+ complain_overflow_bitfield, /* complain_on_overflow */
890+ coff_ext_avr_reloc, /* special_function */
891+ "16", /* name */
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) */
899+ 32, /* bitsize */
900+ FALSE, /* pc_relative */
901+ 0, /* bitpos */
902+ complain_overflow_bitfield, /* complain_on_overflow */
903+ coff_ext_avr_reloc, /* special_function */
904+ "32", /* name */
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) */
912+ 8, /* bitsize */
913+ TRUE, /* pc_relative */
914+ 0, /* bitpos */
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) */
925+ 16, /* bitsize */
926+ TRUE, /* pc_relative */
927+ 0, /* bitpos */
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) */
938+ 32, /* bitsize */
939+ TRUE, /* pc_relative */
940+ 0, /* bitpos */
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 */
948+};
4cd5ba0f 949+
f33182aa 950+/* Turn a howto into a reloc nunmber */
4cd5ba0f 951+
f33182aa 952+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
953+#define BADMAG(x) AVRBADMAG(x)
954+#define AVR 1 /* Customize coffcode.h */
4cd5ba0f 955+
f33182aa 956+#define RTYPE2HOWTO(cache_ptr, dst) \
957+ (cache_ptr)->howto = howto_table + (dst)->r_type;
4cd5ba0f 958+
f33182aa 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
961+ STYP_NOLOAD. */
962+#define BSS_NOLOAD_IS_SHARED_LIBRARY
4cd5ba0f 963+
f33182aa 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. */
4cd5ba0f 976+
f33182aa 977+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
978+ { \
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)); \
983+ else if (ptr) \
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); \
991+ else \
992+ cache_ptr->addend = 0; \
993+ if (ptr && howto_table[reloc.r_type].pc_relative) \
994+ cache_ptr->addend += asect->vma; \
995+ }
4cd5ba0f 996+
f33182aa 997+/* We use the special COFF backend linker. */
998+#define coff_relocate_section _bfd_coff_generic_relocate_section
4cd5ba0f 999+
f33182aa 1000+static reloc_howto_type *
1001+coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
1002+ bfd *abfd ATTRIBUTE_UNUSED;
1003+ asection *sec;
1004+ struct internal_reloc *rel;
1005+ struct coff_link_hash_entry *h;
1006+ struct internal_syment *sym;
1007+ bfd_vma *addendp;
4cd5ba0f 1008+{
4cd5ba0f 1009+
f33182aa 1010+ reloc_howto_type *howto;
4cd5ba0f 1011+
f33182aa 1012+ howto = howto_table + rel->r_type;
4cd5ba0f 1013+
f33182aa 1014+ if (howto->pc_relative)
1015+ *addendp += sec->vma;
4cd5ba0f 1016+
f33182aa 1017+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
1018+ {
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. */
4cd5ba0f 1024+
f33182aa 1025+ BFD_ASSERT (h != NULL);
4cd5ba0f 1026+
f33182aa 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;
1034+ }
4cd5ba0f 1035+
f33182aa 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
1038+ common symbol. */
1039+ if (h != NULL && h->root.type == bfd_link_hash_common)
1040+ *addendp += h->root.u.c.size;
4cd5ba0f 1041+
f33182aa 1042+ return howto;
4cd5ba0f
ER
1043+}
1044+
f33182aa 1045+#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto
4cd5ba0f 1046+
f33182aa 1047+#include "coffcode.h"
4cd5ba0f 1048+
f33182aa 1049+static const bfd_target *
1050+coff_ext_avr_object_p(a)
1051+ bfd *a;
4cd5ba0f 1052+{
f33182aa 1053+ return coff_object_p (a);
4cd5ba0f
ER
1054+}
1055+
f33182aa 1056+const bfd_target
1057+#ifdef TARGET_SYM
1058+ TARGET_SYM =
1059+#else
1060+ avrextcoff_vec =
1061+#endif
4cd5ba0f 1062+{
f33182aa 1063+#ifdef TARGET_NAME
1064+ TARGET_NAME,
1065+#else
1066+ "coff-ext-avr", /* name */
1067+#endif
1068+ bfd_target_coff_flavour,
1069+ BFD_ENDIAN_LITTLE, /* data byte order is little */
1070+ BFD_ENDIAN_LITTLE, /* header byte order is little */
4cd5ba0f 1071+
f33182aa 1072+ (HAS_RELOC | EXEC_P | /* object flags */
1073+ HAS_LINENO | HAS_DEBUG |
1074+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
4cd5ba0f 1075+
f33182aa 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 */
4cd5ba0f 1080+
f33182aa 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 */
4cd5ba0f 1087+
f33182aa 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 */
1092+ bfd_false},
1093+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
1094+ _bfd_write_archive_contents, bfd_false},
4cd5ba0f 1095+
f33182aa 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),
4cd5ba0f 1105+
f33182aa 1106+ NULL,
4cd5ba0f 1107+
f33182aa 1108+ COFF_SWAP_TABLE
1109+};
1110diff -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
1113@@ -1,3 +1,4 @@
4cd5ba0f 1114+
f33182aa 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;
1121
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);
4cd5ba0f 1132+
f33182aa 1133 /* make_abs_section(abfd);*/
1134
1135 return TRUE;
1136@@ -1791,17 +1803,6 @@
1137
1138 coff->sym_filepos = internal_f->f_symptr;
1139
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);
1150-
1151 coff->timestamp = internal_f->f_timdat;
1152
1153 obj_raw_syment_count (abfd) =
1154@@ -1928,6 +1929,11 @@
1155 }
1156 break;
1157 #endif
1158+#ifdef AVRMAGIC
1159+ case AVRMAGIC:
1160+ arch = bfd_arch_avr;
1161+ break;
1162+#endif
1163 #ifdef MC68MAGIC
1164 case MC68MAGIC:
1165 case M68MAGIC:
1166@@ -2724,6 +2730,13 @@
1167 return TRUE;
1168 #endif
1169
1170+#ifdef AVRMAGIC
1171+ case bfd_arch_avr:
1172+ *magicp = AVRMAGIC;
1173+ return TRUE;
1174+ break;
1175+#endif
4cd5ba0f 1176+
f33182aa 1177 #ifdef PPCMAGIC
1178 case bfd_arch_powerpc:
1179 *magicp = PPCMAGIC;
1180@@ -3520,6 +3533,11 @@
1181 section.s_page = coff_get_section_load_page (current);
1182 #endif
1183
1184+#ifdef AVR
1185+ /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively
1186+ ignores s_vaddr. */
1187+ section.s_paddr = current->vma;
1188+#endif
1189 #ifdef COFF_WITH_PE
1190 section.s_paddr = 0;
1191 #endif
1192@@ -3864,6 +3882,17 @@
1193 internal_a.magic = ZMAGIC;
1194 #endif
1195
1196+#ifdef AVR
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__
1205+#endif /* AVR */
4cd5ba0f 1206+
f33182aa 1207 #if defined(PPC_PE)
1208 #define __A_MAGIC_SET__
1209 internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
1210@@ -3931,8 +3960,16 @@
1211 #endif
1212 }
1213
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
1218+ in. */
1219+ internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO;
1220+#else
1221 /* FIXME: Does anybody ever set this to another value? */
1222 internal_a.vstamp = 0;
1223+#endif
1224
1225 /* Now should write relocs, strings, syms. */
1226 obj_sym_filepos (abfd) = sym_base;
1227@@ -4118,22 +4155,29 @@
1228 char * buff;
1229 bfd_size_type amount = bfd_coff_aoutsz (abfd);
1230
1231- buff = bfd_malloc (amount);
1232- if (buff == NULL)
1233- return FALSE;
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. */
1238+ if (amount != 0)
4cd5ba0f 1239+ {
f33182aa 1240+ buff = bfd_malloc (amount);
1241+ if (buff == NULL)
1242+ return FALSE;
1243
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);
1248
1249- free (buff);
1250+ free (buff);
1251
1252- if (amount != bfd_coff_aoutsz (abfd))
1253- return FALSE;
1254+ if (amount != bfd_coff_aoutsz (abfd))
1255+ return FALSE;
1256
1257 #ifdef COFF_IMAGE_WITH_PE
1258- if (! coff_apply_checksum (abfd))
1259- return FALSE;
1260+ if (! coff_apply_checksum (abfd))
1261+ return FALSE;
1262 #endif
1263+ }
1264 }
1265 #ifdef RS6000COFF_C
1266 else
1267@@ -4414,6 +4458,10 @@
1268 /* In PE, 0x69 (105) denotes a weak external symbol. */
1269 case C_NT_WEAK:
1270 #endif
1271+#ifdef AVR
1272+ /* Some AVR COFF compilers handle EXTDEF like EXT. */
1273+ case C_EXTDEF: /* external definition */
1274+#endif
1275 switch (coff_classify_symbol (abfd, &src->u.syment))
1276 {
1277 case COFF_SYMBOL_GLOBAL:
1278@@ -4637,7 +4685,9 @@
1279 && src->u.syment.n_scnum == 0)
1280 break;
1281 /* Fall through. */
1282+#if !defined(AVR)
1283 case C_EXTDEF: /* External definition. */
1284+#endif
1285 case C_ULABEL: /* Undefined label. */
1286 case C_USTATIC: /* Undefined static. */
1287 #ifndef COFF_WITH_PE
1288diff -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)
1298+ {
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
1302+ for them. */
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;
4cd5ba0f 1306+
f33182aa 1307+ s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n;
1308+ }
1309 }
1310 else
1311 /* Modify the symbol values according to their section and
1312@@ -815,6 +829,20 @@
1313 {
1314 if (name_length <= filnmlen)
1315 strncpy (auxent->x_file.x_fname, name, filnmlen);
1316+ else if (bfd_get_arch (abfd) == bfd_arch_avr)
4cd5ba0f 1317+ {
f33182aa 1318+ /* AVR COFF records long filenames in successive aux records. */
1319+ int i = 1;
1320+ while (name_length > filnmlen && i < NAUXENTS)
1321+ {
1322+ strncpy (auxent->x_file.x_fname, name, filnmlen);
1323+ name += filnmlen;
1324+ name_length -= filnmlen;
1325+ i++;
1326+ auxent = &(native + i)->u.auxent;
1327+ }
1328+ strncpy (auxent->x_file.x_fname, name, filnmlen);
4cd5ba0f 1329+ }
f33182aa 1330 else
1331 {
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)
1335 return FALSE;
1336 }
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;
1341+ else
1342+ maxlen = bfd_coff_filnmlen (abfd);
1343 }
1344 else
1345 maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
1346@@ -1655,14 +1687,27 @@
1347 {
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 =
1354- ((bfd_hostptr_t)
1355- copy_name (abfd,
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)))
1363+ {
1364+ char *b;
1365+ unsigned int i;
1366+
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);
1378+ }
1379 else
1380 internal_ptr->u.syment._n._n_n._n_offset =
1381 ((bfd_hostptr_t)
1382@@ -1768,9 +1813,9 @@
1383
1384 if (new == NULL)
1385 return NULL;
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);
1393 if (!new->native)
1394 return NULL;
1395diff -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 @@
1399 void * ext1,
1400 int type,
1401 int class,
1402- int indx,
1403+ int indx
1404+#if defined(AVR) && __GNUC__
1405+ __attribute__((unused))
1406+#endif
1407+ ,
1408 int numaux,
1409 void * in1)
1410 {
1411@@ -409,9 +413,13 @@
1412 #else
1413 if (numaux > 1)
1414 {
1415+#if defined(AVR)
1416+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT));
1417+#else
1418 if (indx == 0)
1419 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
1420 numaux * sizeof (AUXENT));
1421+#endif
1422 }
1423 else
1424 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
1425diff -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
1428@@ -327,6 +327,7 @@
1429
1430 avr-*-*)
1431 targ_defvec=bfd_elf32_avr_vec
1432+ targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec"
1433 ;;
1434
1435 bfin-*-*)
1436diff -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" ;;
1448diff -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
1451@@ -612,6 +612,8 @@
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" ;;
1460diff -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
1463@@ -558,6 +558,8 @@
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;
1472@@ -876,6 +878,8 @@
1473 &armpe_little_vec,
1474 &armpei_big_vec,
1475 &armpei_little_vec,
1476+ &avrcoff_vec,
1477+ &avrextcoff_vec,
1478 &b_out_vec_big_host,
1479 &b_out_vec_little_host,
1480 &bfd_efi_app_ia32_vec,
1481diff -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
1484@@ -98,7 +98,7 @@
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 \
1490 windmc.c mclex.c
1491
1492 GENERATED_CFILES = \
1493@@ -106,7 +106,7 @@
1494 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1495
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
1499
1500 # Code shared by all the binutils.
1501 BULIBS = bucomm.c version.c filemode.c
1502diff -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
1505@@ -129,7 +129,7 @@
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)
1514@@ -418,7 +418,7 @@
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 \
1520 windmc.c mclex.c
1521
1522 GENERATED_CFILES = \
1523@@ -426,7 +426,7 @@
1524 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1525
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
1529
1530 # Code shared by all the binutils.
1531 BULIBS = bucomm.c version.c filemode.c
1532diff -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 @@
1536 return ret;
1537 }
1538
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)? */
1542+const char *
1543+bu_basename (file)
1544+ const char *file;
1545+{
1546+ const char *filename = strrchr (file, '/');
4cd5ba0f 1547+
f33182aa 1548+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
1549+ {
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;
1556+ }
1557+#endif
1558+ if (filename != (char *) NULL)
1559+ filename++;
1560+ else
1561+ filename = file;
1562+ return filename;
1563+}
4cd5ba0f 1564+
f33182aa 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. */
1568diff -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
1571@@ -54,6 +54,8 @@
1572
1573 off_t get_file_size (const char *);
1574
1575+const char *bu_basename PARAMS ((const char *));
4cd5ba0f 1576+
f33182aa 1577 extern char *program_name;
1578
1579 /* filemode.c */
1580diff -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
1583@@ -51,8 +51,11 @@
1584
1585 extern bfd_boolean write_ieee_debugging_info (bfd *, void *);
1586
1587-/* Routine used to read COFF debugging information. */
1588+/* Routine used to read and write COFF debugging information. */
1589
1590 extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *);
1591
1592+extern bfd_boolean write_coff_debugging_info
1593+ (bfd *abfd, void *, long *symcountp, asymbol ***);
4cd5ba0f 1594+
f33182aa 1595 #endif
1596diff -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
1599@@ -31,6 +31,7 @@
1600 #include <assert.h>
1601 #include "bfd.h"
1602 #include "libiberty.h"
1603+#include "bucomm.h"
1604 #include "debug.h"
1605
1606 /* Global information we keep for debugging. A pointer to this
1607@@ -552,6 +553,19 @@
1608 struct debug_type *t;
1609 };
1610
1611+/* Simple list, used for pathname translations. */
1612+struct xlat_list
1613+{
1614+ /* Next string on list. */
1615+ struct xlat_list *next;
1616+ /* Old part to match against. */
1617+ const char *old;
1618+ size_t olen;
1619+ /* New part to replace. */
1620+ const char *newstr;
1621+ size_t nlen;
1622+};
4cd5ba0f 1623+
f33182aa 1624 /* Local functions. */
1625
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 *);
4cd5ba0f 1632+
f33182aa 1633+/* List of pathname translations. */
1634+static struct xlat_list *xlat, *xltail;
1635+static bfd_boolean xlat_basename;
1636 \f
1637 /* Issue an error message. */
1638
1639@@ -680,6 +699,8 @@
1640
1641 if (name == NULL)
1642 name = "";
1643+ else
1644+ name = debug_xlat_pathname (name);
1645
1646 nfile = (struct debug_file *) xmalloc (sizeof *nfile);
1647 memset (nfile, 0, sizeof *nfile);
1648@@ -720,6 +741,8 @@
1649
1650 if (name == NULL)
1651 name = "";
1652+ else
1653+ name = debug_xlat_pathname (name);
1654
1655 if (info->current_unit == NULL)
1656 {
1657@@ -3370,3 +3393,69 @@
1658
1659 return TRUE;
1660 }
4cd5ba0f 1661+
f33182aa 1662+/* Register a pathname translation. */
1663+void
1664+debug_register_pathname_xlat (oname, nname)
1665+ const char *oname;
1666+ const char *nname;
1667+{
1668+ struct xlat_list *xlp;
4cd5ba0f 1669+
f33182aa 1670+ /* Special case: if oname is given as NULL, this means the
1671+ --basename option has been given to objcopy. */
1672+ if (oname == NULL)
4cd5ba0f 1673+ {
f33182aa 1674+ xlat_basename = TRUE;
1675+ return;
4cd5ba0f
ER
1676+ }
1677+
f33182aa 1678+ xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list));
1679+ xlp->next = NULL;
1680+ if (xlat == NULL)
1681+ xlat = xltail = xlp;
1682+ else
4cd5ba0f 1683+ {
f33182aa 1684+ xltail->next = xlp;
1685+ xltail = xlp;
4cd5ba0f 1686+ }
f33182aa 1687+ xlp->old = oname;
1688+ xlp->newstr = nname;
1689+ xlp->olen = strlen (oname);
1690+ xlp->nlen = strlen (nname);
1691+}
4cd5ba0f 1692+
f33182aa 1693+/* Try to translate a pathname. */
1694+static const char *
1695+debug_xlat_pathname (oname)
1696+ const char *oname;
1697+{
1698+ struct xlat_list *xlp;
1699+ char *cp;
1700+ size_t olen;
4cd5ba0f 1701+
f33182aa 1702+ if (xlat_basename)
1703+ return bu_basename (oname);
4cd5ba0f 1704+
f33182aa 1705+ olen = strlen (oname);
1706+ for (xlp = xlat; xlp; xlp = xlp->next)
4cd5ba0f 1707+ {
f33182aa 1708+ if (xlp->olen > olen)
1709+ /* This cannot be our turn. */
1710+ continue;
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)
1715+ {
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);
1720+ return cp;
1721+ }
4cd5ba0f
ER
1722+ }
1723+
f33182aa 1724+ /* Not found, pass the original name on. */
1725+ return oname;
4cd5ba0f 1726+}
f33182aa 1727diff -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 @@
1731
1732 extern bfd_boolean debug_start_source (void *, const char *);
1733
1734+/* Register a pathname translation for source (and include) filenames.
1735+ This is used by the --change-pathname option of objcopy. */
4cd5ba0f 1736+
f33182aa 1737+extern void debug_register_pathname_xlat
1738+ PARAMS ((const char *, const char *));
4cd5ba0f 1739+
f33182aa 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.
1743diff -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
1746@@ -32,6 +32,7 @@
1747 #include "elf-bfd.h"
1748 #include <sys/stat.h>
1749 #include "libbfd.h"
1750+#include "debug.h"
1751
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
1754@@ -272,7 +273,9 @@
1755 OPTION_PURE,
1756 OPTION_IMPURE,
1757 OPTION_EXTRACT_SYMBOL,
1758- OPTION_REVERSE_BYTES
1759+ OPTION_REVERSE_BYTES,
1760+ OPTION_CHANGE_PATHNAME,
1761+ OPTION_BASENAME
1762 };
1763
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},
1778@@ -504,6 +509,8 @@
1779 --prefix-alloc-sections <prefix>\n\
1780 Add <prefix> to start of every allocatable\n\
1781 section name\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\
1787@@ -911,6 +918,8 @@
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;
1793
1794 for (; src_count < symcount; src_count++)
1795 {
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);
1812
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);
4cd5ba0f 1816+
f33182aa 1817+ if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1818 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1819 {
1820 bfd_byte *syms, *strings;
1821@@ -3280,6 +3294,30 @@
1822 prefix_alloc_sections_string = optarg;
1823 break;
1824
1825+ case OPTION_CHANGE_PATHNAME:
4cd5ba0f 1826+ {
f33182aa 1827+ const char *s;
1828+ int len;
1829+ char *name;
4cd5ba0f 1830+
f33182aa 1831+ s = strchr (optarg, '=');
1832+ if (s == NULL)
1833+ fatal (_("bad format for %s"), "--change-pathname");
4cd5ba0f 1834+
f33182aa 1835+ len = s - optarg;
1836+ name = (char *) xmalloc (len + 1);
1837+ strncpy (name, optarg, len);
1838+ name[len] = '\0';
4cd5ba0f 1839+
f33182aa 1840+ debug_register_pathname_xlat (name, s + 1);
1841+ }
1842+ break;
4cd5ba0f 1843+
f33182aa 1844+ case OPTION_BASENAME:
1845+ /* very special case of pathname translation */
1846+ debug_register_pathname_xlat (NULL, NULL);
1847+ break;
4cd5ba0f 1848+
f33182aa 1849 case OPTION_READONLY_TEXT:
1850 bfd_flags_to_set |= WP_TEXT;
1851 bfd_flags_to_clear &= ~WP_TEXT;
1852diff -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
1855@@ -82,6 +82,9 @@
1856 struct coff_slots *slots;
1857 /* Basic types. */
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) */
1862 };
1863
1864 static debug_type *coff_get_slot (struct coff_types *, int);
1865@@ -101,6 +104,7 @@
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);
1870 \f
1871 /* Return the slot for a type. */
1872
1873@@ -271,8 +275,7 @@
1874 break;
1875
1876 case T_INT:
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);
1880 name = "int";
1881 break;
1882
1883@@ -287,7 +290,7 @@
1884 break;
1885
1886 case T_DOUBLE:
1887- ret = debug_make_float_type (dhandle, 8);
1888+ ret = debug_make_float_type (dhandle, types->doublesize);
1889 name = "double";
1890 break;
1891
1892@@ -307,7 +310,7 @@
1893 break;
1894
1895 case T_UINT:
1896- ret = debug_make_int_type (dhandle, 4, TRUE);
1897+ ret = debug_make_int_type (dhandle, types->intsize, TRUE);
1898 name = "unsigned int";
1899 break;
1900
1901@@ -565,6 +568,8 @@
1902
1903 case C_WEAKEXT:
1904 case C_EXT:
1905+ /* AVR COFF abuses C_EXTDEF */
1906+ case C_EXTDEF:
1907 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
1908 DEBUG_GLOBAL, bfd_asymbol_value (sym)))
1909 return FALSE;
1910@@ -580,9 +585,9 @@
1911 break;
1912
1913 case C_REG:
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)))
1917+ DEBUG_REGISTER,
1918+ coff_convert_register (abfd, bfd_asymbol_value (sym))))
1919 return FALSE;
1920 break;
1921
1922@@ -596,9 +601,9 @@
1923 break;
1924
1925 case C_REGPARM:
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)))
1929+ DEBUG_PARM_REG,
1930+ coff_convert_register (abfd, bfd_asymbol_value (sym))))
1931 return FALSE;
1932 break;
1933
1934@@ -648,6 +653,28 @@
1935 return FALSE;
1936 }
1937
1938+static bfd_vma
1939+coff_convert_register (abfd, val)
1940+ bfd *abfd;
1941+ bfd_vma val;
1942+{
4cd5ba0f 1943+
f33182aa 1944+ switch (bfd_get_arch (abfd))
4cd5ba0f 1945+ {
f33182aa 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
1952+ it anyway. */
1953+ return val & 0xff;
4cd5ba0f 1954+
f33182aa 1955+ default:
1956+ return val;
1957+ }
4cd5ba0f
ER
1958+}
1959+
f33182aa 1960 /* This is the main routine. It looks through all the symbols and
1961 handles them. */
1962
1963@@ -674,6 +701,17 @@
1964 types.slots = NULL;
1965 for (i = 0; i <= T_MAX; i++)
1966 types.basic[i] = DEBUG_TYPE_NULL;
1967+ switch (bfd_get_arch (abfd))
1968+ {
1969+ case bfd_arch_avr:
1970+ types.intsize = 2;
1971+ types.doublesize = 4;
1972+ break;
4cd5ba0f 1973+
f33182aa 1974+ default:
1975+ types.intsize = 4;
1976+ types.doublesize = 8;
1977+ }
1978
1979 next_c_file = -1;
1980 fnname = NULL;
1981@@ -734,7 +772,6 @@
1982 switch (syment.n_sclass)
1983 {
1984 case C_EFCN:
1985- case C_EXTDEF:
1986 case C_ULABEL:
1987 case C_USTATIC:
1988 case C_LINE:
1989@@ -757,6 +794,8 @@
1990 /* Fall through. */
1991 case C_WEAKEXT:
1992 case C_EXT:
1993+ /* AVR COFF abuses C_EXTDEF for C_EXT */
1994+ case C_EXTDEF:
1995 if (ISFCN (syment.n_type))
1996 {
1997 fnname = name;
1998diff -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
2001@@ -0,0 +1,3408 @@
2002+/* wrcoff.c -- Generate (AVR) COFF debugging information
2003+ Copyright 2003 Free Software Foundation, Inc.
4cd5ba0f 2004+
f33182aa 2005+ Written by Joerg Wunsch.
4cd5ba0f 2006+
f33182aa 2007+ This file is part of GNU Binutils.
4cd5ba0f 2008+
f33182aa 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.
4cd5ba0f 2013+
f33182aa 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.
4cd5ba0f 2018+
f33182aa 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. */
4cd5ba0f 2023+
f33182aa 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. */
4cd5ba0f 2028+
f33182aa 2029+#include <assert.h>
2030+#include "sysdep.h"
2031+#include "bfd.h"
2032+#include "coff/internal.h"
2033+#include "bucomm.h"
2034+#include "libiberty.h"
2035+#include "safe-ctype.h"
2036+#include "debug.h"
2037+#include "budbg.h"
4cd5ba0f 2038+
f33182aa 2039+/* Enabling COFF_DEBUG will trace the internal callback functions and
2040+ their parameters as debug_write() calls them. */
2041+//#define COFF_DEBUG 1
4cd5ba0f 2042+
f33182aa 2043+#include "libcoff.h"
4cd5ba0f 2044+
f33182aa 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)
4cd5ba0f 2049+
f33182aa 2050+/* Structure of local symbols per compilation unit. */
2051+struct coff_compilation_unit
4cd5ba0f 2052+{
f33182aa 2053+ const char *fname;
2054+ asymbol **syms;
2055+ long nsyms, totsyms;
2056+};
4cd5ba0f 2057+
f33182aa 2058+enum ts_kind
2059+{
2060+ TS_EMPTY,
2061+ TS_VOID,
2062+ TS_INT,
2063+ TS_FLOAT,
2064+ TS_COMPLEX,
2065+ TS_ENUM,
2066+ TS_POINTER,
2067+ TS_FUNC,
2068+ TS_ARRAY,
2069+ TS_STRUCT,
2070+ TS_NONE = -1
2071+};
4cd5ba0f 2072+
f33182aa 2073+/* Structure defining the pre-defined types. */
2074+struct coff_predef_type
2075+{
2076+ enum ts_kind kind;
2077+ unsigned int size; /* in bytes */
2078+ bfd_boolean isunsigned;
2079+ int slot;
2080+};
4cd5ba0f 2081+
f33182aa 2082+struct coff_type_stack;
2083+struct coff_hash_entry;
4cd5ba0f 2084+
f33182aa 2085+struct coff_struct_fields
4cd5ba0f 2086+{
f33182aa 2087+ const char *name;
2088+ bfd_vma bitpos;
2089+ bfd_vma bitsize;
2090+ enum debug_visibility visibility;
2091+ struct coff_type_stack *types;
2092+};
4cd5ba0f 2093+
f33182aa 2094+/* Our type stack. */
2095+struct coff_type_stack
2096+{
2097+ struct coff_type_stack *next;
2098+ enum ts_kind tsk;
2099+ union
2100+ {
2101+ /* TS_INT */
2102+ struct
2103+ {
2104+ unsigned int size;
2105+ bfd_boolean isunsigned;
2106+ }
2107+ ts_int;
4cd5ba0f 2108+
f33182aa 2109+ /* TS_FLOAT */
2110+ struct
2111+ {
2112+ unsigned int size;
2113+ }
2114+ ts_float;
4cd5ba0f 2115+
f33182aa 2116+ /* TS_ENUM */
2117+ struct
4cd5ba0f 2118+ {
f33182aa 2119+ union
4cd5ba0f 2120+ {
f33182aa 2121+ const char *fixtag;
2122+ char *malloctag;
4cd5ba0f 2123+ }
f33182aa 2124+ tag;
2125+ bfd_boolean tagismalloced;
2126+ const char **names;
2127+ bfd_signed_vma *vals;
2128+ struct coff_enum_hash_entry *ehash;
2129+ }
2130+ ts_enum;
4cd5ba0f 2131+
f33182aa 2132+ /* TS_FUNC */
2133+ struct
4cd5ba0f 2134+ {
f33182aa 2135+ struct coff_type_stack *savedts;
4cd5ba0f 2136+ }
f33182aa 2137+ ts_func;
4cd5ba0f 2138+
f33182aa 2139+ /* TS_ARRAY */
2140+ struct
4cd5ba0f 2141+ {
f33182aa 2142+ bfd_signed_vma low;
2143+ bfd_signed_vma high;
4cd5ba0f 2144+ }
f33182aa 2145+ ts_array;
4cd5ba0f 2146+
f33182aa 2147+ /* TS_STRUCT */
2148+ struct
4cd5ba0f 2149+ {
f33182aa 2150+ union
2151+ {
2152+ const char *fixtag;
2153+ char *malloctag;
2154+ }
2155+ tag;
2156+ bfd_boolean tagismalloced;
2157+ unsigned int id;
2158+ bfd_boolean isstruct;
2159+ unsigned int size;
2160+ long nfields;
2161+ struct coff_struct_fields *fields;
2162+ struct coff_type_stack *savedts;
2163+ struct coff_struct_hash_entry *shash;
4cd5ba0f 2164+ }
f33182aa 2165+ ts_struct;
2166+ }
2167+ u;
2168+};
4cd5ba0f 2169+
f33182aa 2170+struct coff_name_type_hash_table
2171+{
2172+ struct bfd_hash_table root;
2173+};
4cd5ba0f 2174+
f33182aa 2175+struct coff_name_type_hash_entry
2176+{
2177+ struct bfd_hash_entry root;
2178+ /* Information for this name. */
2179+ struct coff_type_stack *types;
2180+ bfd_boolean emitted;
2181+};
4cd5ba0f 2182+
f33182aa 2183+struct coff_struct_hash_table
2184+{
2185+ struct bfd_hash_table root;
2186+};
4cd5ba0f 2187+
f33182aa 2188+struct coff_struct_hash_entry
2189+{
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 */
2196+ long *fixidxs;
2197+ unsigned nfixidxs;
2198+};
4cd5ba0f 2199+
f33182aa 2200+struct coff_enum_hash_table
2201+{
2202+ struct bfd_hash_table root;
2203+};
4cd5ba0f 2204+
f33182aa 2205+struct coff_enum_hash_entry
4cd5ba0f 2206+{
f33182aa 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 */
2213+ long *fixidxs;
2214+ unsigned nfixidxs;
2215+};
4cd5ba0f 2216+
f33182aa 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
2221+{
2222+ unsigned int size; /* size of symbol, used in AVR register
2223+ translation */
2224+ struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */
2225+ struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */
2226+};
4cd5ba0f 2227+
f33182aa 2228+/* Stack of tags that need endndx fixing. */
2229+struct coff_fix_stack
2230+{
2231+ struct coff_fix_stack *next;
2232+ combined_entry_type *native;
2233+};
4cd5ba0f 2234+
f33182aa 2235+/* This is the handle passed through debug_write. */
4cd5ba0f 2236+
f33182aa 2237+struct coff_write_handle
4cd5ba0f 2238+{
f33182aa 2239+ /* The BFD. */
2240+ bfd *abfd;
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;
2256+ long nunits;
2257+ struct coff_compilation_unit *currentfile;
2258+ /* Global symbols from input symbol table. */
2259+ asymbol **globals;
2260+ long nglobals;
2261+ /* Section syms for named sections. */
2262+ coff_symbol_type **secsyms;
2263+ long nsecsyms;
2264+ /* Our COFF symbols. */
2265+ asymbol **syms;
2266+ long nsyms;
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;
2294+};
4cd5ba0f 2295+
f33182aa 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[] =
4cd5ba0f 2302+{
f33182aa 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 */
2313+};
4cd5ba0f 2314+
f33182aa 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));
4cd5ba0f 2346+
f33182aa 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,
2375+ 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));
4cd5ba0f 2406+
f33182aa 2407+static const struct debug_write_fns coff_fns =
4cd5ba0f 2408+{
f33182aa 2409+ coff_start_compilation_unit,
2410+ coff_start_source,
2411+ coff_empty_type,
2412+ coff_void_type,
2413+ coff_int_type,
2414+ coff_float_type,
2415+ coff_complex_type,
2416+ coff_bool_type,
2417+ coff_enum_type,
2418+ coff_pointer_type,
2419+ coff_function_type,
2420+ coff_reference_type,
2421+ coff_range_type,
2422+ coff_array_type,
2423+ coff_set_type,
2424+ coff_offset_type,
2425+ coff_method_type,
2426+ coff_const_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,
2440+ coff_tag_type,
2441+ coff_typdef,
2442+ coff_tag,
2443+ coff_int_constant,
2444+ coff_float_constant,
2445+ coff_typed_constant,
2446+ coff_variable,
2447+ coff_start_function,
2448+ coff_function_parameter,
2449+ coff_start_block,
2450+ coff_end_block,
2451+ coff_end_function,
2452+ coff_lineno
2453+};
2454+\f
2455+/*
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.
2459+ */
4cd5ba0f 2460+static bfd_boolean
f33182aa 2461+coff_copy_symbols (info, count, sympp)
2462+ struct coff_write_handle *info;
2463+ long count;
2464+ asymbol **sympp;
4cd5ba0f 2465+{
f33182aa 2466+ asymbol *osym;
2467+ long i;
2468+ struct coff_compilation_unit *up;
4cd5ba0f 2469+
f33182aa 2470+ up = NULL;
4cd5ba0f 2471+
f33182aa 2472+ for (i = 0; i < count; i++)
2473+ {
2474+ osym = sympp[i];
4cd5ba0f 2475+
f33182aa 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
2481+ only. */
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;
4cd5ba0f 2488+
f33182aa 2489+ if (osym->flags & BSF_FILE)
2490+ {
2491+ /* New file name. */
2492+ long l;
4cd5ba0f 2493+
f33182aa 2494+ up = NULL;
4cd5ba0f 2495+
f33182aa 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
2499+ (like crt1.S). */
2500+ for (l = 0; l < info->nunits; l++)
2501+ {
2502+ if (strcmp (info->units[l].fname, osym->name) == 0)
2503+ {
2504+ up = info->units + l;
2505+ break;
2506+ }
2507+ }
4cd5ba0f 2508+
f33182aa 2509+ if (up == NULL)
2510+ {
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;
2516+ up->syms = NULL;
2517+ up->nsyms = up->totsyms = 0;
2518+ }
2519+ }
2520+ else if (osym->flags & (BSF_GLOBAL | BSF_WEAK))
2521+ {
2522+ /* Global (or weak) symbols are recorded outside compilation
2523+ units. */
2524+ info->globals = (asymbol **)
2525+ xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *));
2526+ info->globals[info->nglobals - 1] = osym;
2527+ continue;
2528+ }
2529+ else if (!bfd_is_const_section(osym->section))
2530+ {
2531+ if (osym->flags & BSF_SECTION_SYM)
2532+ {
2533+ coff_symbol_type *csymp;
2534+ /* Just record them by now, they'll be fixed up later. */
4cd5ba0f 2535+
f33182aa 2536+ if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0)
2537+ {
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)
2544+ return FALSE;
4cd5ba0f 2545+
f33182aa 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);
2553+ }
4cd5ba0f 2554+
f33182aa 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)
2559+ return FALSE;
4cd5ba0f 2560+
f33182aa 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;
4cd5ba0f 2570+
f33182aa 2571+ coff_record_symbol (info, csymp);
4cd5ba0f 2572+
f33182aa 2573+ info->secsyms = (coff_symbol_type **)
2574+ xrealloc (info->secsyms,
2575+ ++info->nsecsyms * sizeof(coff_symbol_type *));
2576+ info->secsyms[info->nsecsyms - 1] = csymp;
2577+ }
2578+ else
2579+ {
2580+ /* Local symbol in a named section, will be recorded
2581+ within the respective compilation unit. */
2582+ if (up == NULL)
2583+ {
2584+ fprintf (stderr,
2585+ _("Discarding local symbol outside any compilation unit"));
2586+ if (osym->name)
2587+ fprintf (stderr, ": %s", osym->name);
2588+ putc ('\n', stderr);
2589+ }
2590+ else
2591+ {
2592+ up->syms = (asymbol **)
2593+ xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *));
2594+ up->syms[up->nsyms - 1] = osym;
2595+ up->totsyms = up->nsyms;
2596+ continue;
2597+ }
2598+ }
2599+ }
2600+ }
4cd5ba0f
ER
2601+
2602+ return TRUE;
2603+}
2604+
f33182aa 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. */
2608+static asymbol *
2609+coff_find_symbol (info, name, isfunction, global)
2610+ struct coff_write_handle *info;
2611+ const char *name;
2612+ bfd_boolean isfunction;
2613+ bfd_boolean global;
2614+{
2615+ asymbol *symp;
2616+ long i;
2617+ size_t namelen;
4cd5ba0f 2618+
f33182aa 2619+ if (global)
2620+ {
2621+ for (i = 0; i < info->nglobals; i++)
2622+ {
2623+ symp = info->globals[i];
2624+ if (symp == NULL)
2625+ continue;
2626+ if (strcmp (name, symp->name) == 0
2627+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
2628+ {
2629+ info->globals[i] = NULL;
2630+ return symp;
2631+ }
2632+ }
2633+ return NULL;
2634+ }
4cd5ba0f 2635+
f33182aa 2636+ if (info->currentfile == NULL)
2637+ return NULL;
4cd5ba0f 2638+
f33182aa 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++)
4cd5ba0f 2645+ {
f33182aa 2646+ symp = info->currentfile->syms[i];
2647+ if (symp == NULL)
2648+ continue;
2649+ if (strncmp (name, symp->name, namelen) == 0
2650+ && (symp->name[namelen] == '\0' || symp->name[namelen] == '.')
2651+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
2652+ {
2653+ info->currentfile->syms[i] = NULL;
2654+ info->currentfile->totsyms--;
2655+ return symp;
2656+ }
4cd5ba0f 2657+ }
f33182aa 2658+ return NULL;
4cd5ba0f
ER
2659+}
2660+
f33182aa 2661+static void
2662+coff_record_symbol (info, csymp)
2663+ struct coff_write_handle *info;
2664+ coff_symbol_type *csymp;
4cd5ba0f 2665+{
f33182aa 2666+ struct coff_private_symdata *priv;
4cd5ba0f 2667+
f33182aa 2668+ info->syms = (asymbol **) xrealloc (info->syms,
2669+ ++info->nsyms * sizeof (asymbol *));
2670+ info->syms[info->nsyms - 1] = (asymbol *)csymp;
4cd5ba0f 2671+
f33182aa 2672+ if ((priv = csymp->symbol.udata.p) != NULL)
2673+ {
2674+ if (priv->shash != NULL)
2675+ {
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;
2680+ }
2681+ if (priv->ehash != NULL)
2682+ {
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;
2687+ }
2688+ free (priv);
2689+ csymp->symbol.udata.p = NULL;
2690+ }
4cd5ba0f 2691+
f33182aa 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.
4cd5ba0f 2703+
f33182aa 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.
4cd5ba0f 2706+
f33182aa 2707+ Note that bfd/coffgen.c converts that csymp->native into a
2708+ symtable slot number after coff_renumber_symbols() has been
2709+ run. */
2710+ if (info->flags & COFF_FL_FIX_ENDNDX)
2711+ {
2712+ struct coff_fix_stack *fsp, *ofsp;
2713+ union internal_auxent *aux;
4cd5ba0f 2714+
f33182aa 2715+ assert (info->fixes != NULL);
4cd5ba0f 2716+
f33182aa 2717+ fsp = info->fixes;
2718+ ofsp = NULL;
2719+ while (fsp->next != NULL)
2720+ {
2721+ ofsp = fsp;
2722+ fsp = fsp->next;
2723+ }
2724+ if (ofsp == NULL)
2725+ info->fixes = NULL;
2726+ else
2727+ ofsp->next = NULL;
4cd5ba0f 2728+
f33182aa 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;
2732+ free (fsp);
4cd5ba0f 2733+
f33182aa 2734+ info->flags &= ~COFF_FL_FIX_ENDNDX;
2735+ }
4cd5ba0f
ER
2736+}
2737+
f33182aa 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
2741+ 0xff. */
2742+static symvalue
2743+coff_fixup_avr_register (val, size)
2744+ symvalue val;
2745+ int size;
4cd5ba0f 2746+{
f33182aa 2747+ union
2748+ {
2749+ unsigned char c[4];
2750+ symvalue v;
2751+ } u;
4cd5ba0f 2752+
f33182aa 2753+ u.c[1] = u.c[2] = u.c[3] = 0xff;
2754+ u.c[0] = val;
2755+ if (size > 8)
2756+ u.c[1] = val + 1;
2757+ if (size > 16)
2758+ {
2759+ u.c[2] = val + 2;
2760+ u.c[3] = val + 3;
2761+ }
4cd5ba0f 2762+
f33182aa 2763+ return u.v;
4cd5ba0f
ER
2764+}
2765+
f33182aa 2766+/* Initialize an entry in the hash tables. */
4cd5ba0f 2767+
f33182aa 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;
4cd5ba0f 2773+{
f33182aa 2774+ struct coff_name_type_hash_entry *ret =
2775+ (struct coff_name_type_hash_entry *) entry;
4cd5ba0f 2776+
f33182aa 2777+ /* Allocate the structure if it has not already been allocated by a
2778+ subclass. */
2779+ if (ret == NULL)
2780+ ret = ((struct coff_name_type_hash_entry *)
2781+ bfd_hash_allocate (table, sizeof *ret));
2782+ if (ret == NULL)
2783+ return NULL;
4cd5ba0f 2784+
f33182aa 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));
2788+ if (ret)
2789+ {
2790+ /* Set local fields. */
2791+ ret->types = NULL;
2792+ ret->emitted = FALSE;
2793+ }
4cd5ba0f 2794+
f33182aa 2795+ return (struct bfd_hash_entry *) ret;
4cd5ba0f
ER
2796+}
2797+
f33182aa 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;
4cd5ba0f 2803+{
f33182aa 2804+ struct coff_struct_hash_entry *ret =
2805+ (struct coff_struct_hash_entry *) entry;
4cd5ba0f 2806+
f33182aa 2807+ /* Allocate the structure if it has not already been allocated by a
2808+ subclass. */
2809+ if (ret == NULL)
2810+ ret = ((struct coff_struct_hash_entry *)
2811+ bfd_hash_allocate (table, sizeof *ret));
2812+ if (ret == NULL)
2813+ return NULL;
4cd5ba0f 2814+
f33182aa 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));
2818+ if (ret)
4cd5ba0f 2819+ {
f33182aa 2820+ /* Set local fields. */
2821+ ret->types = NULL;
2822+ ret->emitted = FALSE;
2823+ ret->fixidxs = NULL;
2824+ ret->nfixidxs = 0;
2825+ ret->native = NULL;
4cd5ba0f
ER
2826+ }
2827+
f33182aa 2828+ return (struct bfd_hash_entry *) ret;
4cd5ba0f
ER
2829+}
2830+
f33182aa 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;
4cd5ba0f 2836+{
f33182aa 2837+ struct coff_enum_hash_entry *ret =
2838+ (struct coff_enum_hash_entry *) entry;
4cd5ba0f 2839+
f33182aa 2840+ /* Allocate the structure if it has not already been allocated by a
2841+ subclass. */
2842+ if (ret == NULL)
2843+ ret = ((struct coff_enum_hash_entry *)
2844+ bfd_hash_allocate (table, sizeof *ret));
2845+ if (ret == NULL)
2846+ return NULL;
4cd5ba0f 2847+
f33182aa 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));
2851+ if (ret)
2852+ {
2853+ /* Set local fields. */
2854+ ret->types = NULL;
2855+ ret->emitted = FALSE;
2856+ ret->fixidxs = NULL;
2857+ ret->nfixidxs = 0;
2858+ ret->native = NULL;
2859+ }
4cd5ba0f 2860+
f33182aa 2861+ return (struct bfd_hash_entry *) ret;
4cd5ba0f
ER
2862+}
2863+
f33182aa 2864+/* Look up an entry in the hash tables. */
4cd5ba0f 2865+
f33182aa 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)))
4cd5ba0f 2869+
f33182aa 2870+/* Traverse the hash table. */
4cd5ba0f 2871+
f33182aa 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), \
2876+ (info)))
4cd5ba0f 2877+
f33182aa 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)))
4cd5ba0f 2881+
f33182aa 2882+/* Traverse the hash table. */
4cd5ba0f 2883+
f33182aa 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), \
2888+ (info)))
4cd5ba0f 2889+
f33182aa 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)))
4cd5ba0f 2893+
f33182aa 2894+/* Traverse the hash table. */
4cd5ba0f 2895+
f33182aa 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), \
2900+ (info)))
4cd5ba0f 2901+
f33182aa 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
2908+
2909+#define coff_pop_type() \
2910+ tst = info->tstack; \
2911+ if (tst == NULL) { \
2912+ fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \
2913+ return FALSE; \
2914+ } \
2915+ info->tstack = tst->next; \
2916+ tst->next = NULL
2917+
2918+#define coff_complain_unsupp(s) \
2919+ fprintf (stderr, _("%s type not supported in %s\n"), \
2920+ s, info->abfd->xvec->name); \
2921+ return FALSE
4cd5ba0f 2922+
f33182aa 2923+/* These function is called via the hash traverse routine when freeing
2924+ a hash table (at the end of a translation unit). */
4cd5ba0f 2925+static bfd_boolean
f33182aa 2926+coff_free_type_info (h, p)
2927+ struct coff_name_type_hash_entry *h;
4cd5ba0f
ER
2928+ PTR p ATTRIBUTE_UNUSED;
2929+{
f33182aa 2930+ struct coff_type_stack *tst, *otst;
4cd5ba0f 2931+
f33182aa 2932+ for (tst = h->types; tst != NULL;)
2933+ {
2934+ otst = tst;
2935+ tst = tst->next;
2936+ free (otst);
2937+ }
4cd5ba0f
ER
2938+ return TRUE;
2939+}
2940+
4cd5ba0f 2941+static bfd_boolean
f33182aa 2942+coff_free_struct_info (h, p)
2943+ struct coff_struct_hash_entry *h;
4cd5ba0f
ER
2944+ PTR p ATTRIBUTE_UNUSED;
2945+{
f33182aa 2946+ struct coff_type_stack *tst, *otst, *xtst, *xotst;
2947+ struct coff_struct_fields *fp;
2948+ long i;
4cd5ba0f 2949+
f33182aa 2950+ for (tst = h->types; tst != NULL;)
2951+ {
2952+ otst = tst;
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;
2957+ i++, fp++)
2958+ {
2959+ xtst = fp->types;
2960+ while (xtst != NULL)
2961+ {
2962+ xotst = xtst->next;
2963+ free (xtst);
2964+ xtst = xotst;
2965+ }
2966+ }
2967+ free (tst->u.ts_struct.fields);
2968+ tst = tst->next;
2969+ free (otst);
2970+ }
4cd5ba0f
ER
2971+ return TRUE;
2972+}
2973+
4cd5ba0f 2974+static bfd_boolean
f33182aa 2975+coff_free_enum_info (h, p)
2976+ struct coff_enum_hash_entry *h;
2977+ PTR p ATTRIBUTE_UNUSED;
4cd5ba0f 2978+{
f33182aa 2979+ struct coff_type_stack *tst, *otst;
4cd5ba0f 2980+
f33182aa 2981+ for (tst = h->types; tst != NULL;)
4cd5ba0f 2982+ {
f33182aa 2983+ otst = tst;
2984+ if (tst->u.ts_enum.tagismalloced)
2985+ free (tst->u.ts_enum.tag.malloctag);
2986+ tst = tst->next;
2987+ free (otst);
4cd5ba0f 2988+ }
f33182aa 2989+ return TRUE;
2990+}
4cd5ba0f 2991+
f33182aa 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;
2996+{
2997+ size_t i;
2998+
2999+ /* See if one of our predefined types will fit. */
3000+ if (tst->tsk == TS_INT)
4cd5ba0f 3001+ {
f33182aa 3002+ for (i = 0;
3003+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
3004+ i++)
4cd5ba0f 3005+ {
f33182aa 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;
4cd5ba0f 3010+ }
f33182aa 3011+ fprintf (stderr,
3012+ _("%ssigned %d-bit integer type not available in COFF\n"),
3013+ tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8);
4cd5ba0f 3014+ }
f33182aa 3015+ else
4cd5ba0f 3016+ {
f33182aa 3017+ for (i = 0;
3018+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
3019+ i++)
4cd5ba0f 3020+ {
f33182aa 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;
4cd5ba0f 3024+ }
f33182aa 3025+ fprintf (stderr, _("%d-bit float type not available in COFF\n"),
3026+ tst->u.ts_float.size * 8);
4cd5ba0f
ER
3027+ }
3028+
f33182aa 3029+ return T_NULL;
4cd5ba0f
ER
3030+}
3031+
4cd5ba0f 3032+static bfd_boolean
f33182aa 3033+coff_make_typed_symbol (info, csympp, stopat)
3034+ struct coff_write_handle *info;
3035+ coff_symbol_type **csympp;
3036+ enum ts_kind stopat;
4cd5ba0f 3037+{
f33182aa 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;
3044+ const char *name;
3045+ bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR))
3046+ == COFF_FL_AVR;
4cd5ba0f 3047+
f33182aa 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)
3051+ return FALSE;
4cd5ba0f 3052+
f33182aa 3053+ priv = (struct coff_private_symdata *) xmalloc (sizeof *priv);
3054+ memset (priv, 0, sizeof *priv);
4cd5ba0f 3055+
f33182aa 3056+ type = arydim = size = nderived = 0;
4cd5ba0f 3057+
f33182aa 3058+ aux = &(((*csympp)->native + 1)->u.auxent);
4cd5ba0f 3059+
f33182aa 3060+ /* Now, walk the type stack, and see how we could convert the info
3061+ we've got to what COFF understands. */
3062+ for (;;)
3063+ {
3064+ if (info->tstack == NULL)
3065+ break;
4cd5ba0f 3066+
f33182aa 3067+ /* If we have been advised to not pop the entire stack, stop
3068+ here. */
3069+ if (info->tstack->tsk == stopat && info->tstack->next == NULL)
3070+ break;
4cd5ba0f 3071+
f33182aa 3072+ coff_pop_type ();
4cd5ba0f 3073+
f33182aa 3074+ switch (tst->tsk)
3075+ {
3076+ case TS_NONE:
3077+ /* cannot happen */
3078+ break;
4cd5ba0f 3079+
f33182aa 3080+ case TS_EMPTY:
3081+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3082+ fprintf (stderr, _("empty type not last on type stack\n"));
3083+ /* type |= T_NULL; */
3084+ break;
4cd5ba0f 3085+
f33182aa 3086+ case TS_VOID:
3087+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3088+ fprintf (stderr, _("void type not last on type stack\n"));
3089+ type |= T_VOID;
3090+ break;
4cd5ba0f 3091+
f33182aa 3092+ case TS_INT:
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);
3096+ if (size == 0)
3097+ size = tst->u.ts_int.size;
3098+ break;
4cd5ba0f 3099+
f33182aa 3100+ case TS_FLOAT:
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);
3104+ if (size == 0)
3105+ size = tst->u.ts_float.size;
3106+ break;
4cd5ba0f 3107+
f33182aa 3108+ case TS_POINTER:
3109+ nderived++;
3110+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT);
3111+ size = info->pointersize;
3112+ break;
4cd5ba0f 3113+
f33182aa 3114+ case TS_FUNC:
3115+ nderived++;
3116+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT);
3117+ /* AUX entry for DT_FCN will be filled in elsewhere. */
3118+ break;
4cd5ba0f 3119+
f33182aa 3120+ case TS_ARRAY:
3121+ /* We need to limit arydim so the assignment below won't
3122+ overwrite random locations. */
3123+ if (arydim >= DIMNUM)
3124+ {
3125+ fprintf (stderr,
3126+ _("More than %d array dimensions, result is invalid.\n"),
3127+ DIMNUM);
3128+ arydim = DIMNUM - 1;
3129+ }
3130+ nderived++;
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;
4cd5ba0f 3134+
f33182aa 3135+ break;
4cd5ba0f 3136+
f33182aa 3137+ case TS_COMPLEX:
3138+ coff_complain_unsupp (_("complex"));
4cd5ba0f 3139+
f33182aa 3140+ case TS_ENUM:
3141+ type |= T_ENUM;
3142+ if (size == 0)
3143+ size = info->enumsize;
4cd5ba0f 3144+
f33182aa 3145+ if (tst->u.ts_enum.ehash != NULL)
3146+ {
3147+ /* enum tag will be fixed later. */
3148+ priv->ehash = tst->u.ts_enum.ehash;
3149+ break;
3150+ }
3151+ if (tst->u.ts_enum.tagismalloced)
3152+ name = tst->u.ts_enum.tag.malloctag;
3153+ else
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)
3158+ return FALSE;
3159+ if (!ehash->emitted)
3160+ {
3161+ if (ehash->types == NULL)
3162+ {
3163+ ehash->types = (struct coff_type_stack *)
3164+ xmalloc (sizeof (struct coff_type_stack));
3165+ memcpy (ehash->types, tst, sizeof (struct coff_type_stack));
3166+ }
3167+ ehash->emitted = TRUE;
3168+ coff_emit_enum (info, tst, ehash);
3169+ if (ehash->nfixidxs != 0)
3170+ {
3171+ coff_symbol_type *symp;
3172+ unsigned i;
4cd5ba0f 3173+
f33182aa 3174+ for (i = 0; i < ehash->nfixidxs; i++)
3175+ {
3176+ combined_entry_type *np;
4cd5ba0f 3177+
f33182aa 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;
4cd5ba0f 3181+
f33182aa 3182+ if (oldavrcoff)
3183+ continue;
4cd5ba0f 3184+
f33182aa 3185+ np = symp->native + 1;
3186+ np->fix_tag = 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;
3190+ }
4cd5ba0f 3191+
f33182aa 3192+ free (ehash->fixidxs);
3193+ ehash->nfixidxs = 0;
3194+ }
3195+ }
3196+ if (!oldavrcoff)
3197+ {
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;
3202+ }
3203+ break;
4cd5ba0f 3204+
f33182aa 3205+ case TS_STRUCT:
3206+ if (tst->u.ts_struct.isstruct)
3207+ type |= T_STRUCT;
3208+ else
3209+ type |= T_UNION;
3210+ if (size == 0)
3211+ size = tst->u.ts_struct.size;
4cd5ba0f 3212+
f33182aa 3213+ if (tst->u.ts_struct.shash != NULL)
3214+ {
3215+ /* struct tag will be fixed later. */
3216+ priv->shash = tst->u.ts_struct.shash;
3217+ break;
3218+ }
3219+ if (tst->u.ts_struct.tagismalloced)
3220+ name = tst->u.ts_struct.tag.malloctag;
3221+ else
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)
3226+ return FALSE;
3227+ if (!shash->emitted)
3228+ {
3229+ if (shash->types == NULL)
3230+ {
3231+ shash->types = (struct coff_type_stack *)
3232+ xmalloc (sizeof (struct coff_type_stack));
3233+ memcpy (shash->types, tst, sizeof (struct coff_type_stack));
3234+ }
3235+ shash->emitted = TRUE;
3236+ coff_emit_struct (info, tst, shash);
3237+ if (shash->nfixidxs != 0)
3238+ {
3239+ coff_symbol_type *symp;
3240+ unsigned i;
4cd5ba0f 3241+
f33182aa 3242+ for (i = 0; i < shash->nfixidxs; i++)
3243+ {
3244+ combined_entry_type *np;
4cd5ba0f 3245+
f33182aa 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;
3250+ else
3251+ symp->native->u.syment.n_type |= T_UNION;
4cd5ba0f 3252+
f33182aa 3253+ if (oldavrcoff)
3254+ continue;
4cd5ba0f 3255+
f33182aa 3256+ np = symp->native + 1;
3257+ np->fix_tag = 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;
3261+ }
4cd5ba0f 3262+
f33182aa 3263+ free (shash->fixidxs);
3264+ shash->nfixidxs = 0;
3265+ }
3266+ }
3267+ if (!oldavrcoff)
3268+ {
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;
3273+ }
3274+ break;
3275+ }
3276+ free (tst);
3277+ }
4cd5ba0f 3278+
f33182aa 3279+ if (nderived > 6)
3280+ fprintf (stderr,
3281+ _("More than 6 derived type specifiers, result is invalid.\n"));
4cd5ba0f 3282+
f33182aa 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. */
3286+ if (nderived > 1)
3287+ {
3288+ unsigned int nty, bty;
3289+ bty = type & N_BTMASK;
3290+ type = type >> N_BTSHFT;
3291+ nty = 0;
3292+ while (nderived-- > 0)
3293+ {
3294+ nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT));
3295+ type >>= N_TSHIFT;
3296+ }
3297+ type = (nty << N_BTSHFT) | bty;
3298+ }
4cd5ba0f 3299+
f33182aa 3300+ if (ISARY (type))
3301+ {
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;
3306+ }
4cd5ba0f 3307+
f33182aa 3308+ numaux = 0;
3309+ if (ISARY (type) || ISFCN (type))
3310+ numaux++;
3311+ if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION
3312+ || BTYPE (type) == T_ENUM)
3313+ && !oldavrcoff)
3314+ numaux++;
3315+ /* Only AVR COFF uses multiple AUX entries. */
3316+ if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0)
3317+ numaux = 1;
4cd5ba0f 3318+
f33182aa 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;
4cd5ba0f 3323+
f33182aa 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)
3328+ {
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;
3332+ }
4cd5ba0f 3333+
f33182aa 3334+ return TRUE;
3335+}
4cd5ba0f 3336+
f33182aa 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;
3341+{
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;
3350+ long i;
4cd5ba0f 3351+
f33182aa 3352+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3353+ COFF_FL_AVR)
3354+ /* old AVR COFF doesn't support struct debugging */
3355+ return TRUE;
4cd5ba0f 3356+
f33182aa 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)
3360+ return FALSE;
4cd5ba0f 3361+
f33182aa 3362+ if (tst->u.ts_struct.tagismalloced)
3363+ scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag);
3364+ else
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;
4cd5ba0f 3373+
f33182aa 3374+ shash->native = scsymp->native;
4cd5ba0f 3375+
f33182aa 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)
3379+ return FALSE;
4cd5ba0f 3380+
f33182aa 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
3385+ value. */
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;
4cd5ba0f 3395+
f33182aa 3396+ coff_record_symbol (info, scsymp);
4cd5ba0f 3397+
f33182aa 3398+ savedtst = info->tstack;
4cd5ba0f 3399+
f33182aa 3400+ if (isstruct)
4cd5ba0f 3401+ {
f33182aa 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;
3406+ i++, fp++)
3407+ if (fp->bitsize % 8 != 0)
3408+ {
3409+ isbitfield = TRUE;
3410+ break;
3411+ }
4cd5ba0f
ER
3412+ }
3413+
f33182aa 3414+ sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU;
3415+
3416+ for (i = 0, fp = tst->u.ts_struct.fields;
3417+ i < tst->u.ts_struct.nfields;
3418+ i++, fp++)
4cd5ba0f 3419+ {
f33182aa 3420+ if (strlen (fp->name) == 0)
4cd5ba0f 3421+ {
f33182aa 3422+ /* empty name could happen inside bitfield */
3423+ fp->types = NULL;
3424+ continue;
4cd5ba0f 3425+ }
4cd5ba0f 3426+
f33182aa 3427+ info->tstack = fp->types;
3428+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
3429+ return FALSE;
4cd5ba0f 3430+
f33182aa 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;
3436+ if (isbitfield)
4cd5ba0f 3437+ {
f33182aa 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;
4cd5ba0f 3441+ }
4cd5ba0f 3442+
f33182aa 3443+ coff_record_symbol (info, csymp);
3444+
3445+ fp->types = NULL;
3446+ }
3447+
3448+ info->tstack = savedtst;
3449+
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;
3456+ else
3457+ {
3458+ for (ofp = info->fixes; ofp->next != NULL;)
3459+ ofp = ofp->next;
3460+ ofp->next = fixp;
4cd5ba0f 3461+ }
f33182aa 3462+
3463+ coff_record_symbol (info, ecsymp);
3464+ info->flags |= COFF_FL_FIX_ENDNDX;
3465+
4cd5ba0f
ER
3466+ return TRUE;
3467+}
3468+
f33182aa 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;
4cd5ba0f 3473+{
f33182aa 3474+ coff_symbol_type *csymp, *scsymp, *ecsymp;
3475+ union internal_auxent *aux;
3476+ struct coff_fix_stack *fixp, *ofp;
3477+ int i;
4cd5ba0f 3478+
f33182aa 3479+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3480+ COFF_FL_AVR)
3481+ /* old AVR COFF doesn't support enum debugging */
3482+ return TRUE;
4cd5ba0f 3483+
f33182aa 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)
3487+ return FALSE;
4cd5ba0f 3488+
f33182aa 3489+ if (tst->u.ts_enum.tagismalloced)
3490+ scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag);
4cd5ba0f 3491+ else
f33182aa 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;
3500+
3501+ ehash->native = scsymp->native;
3502+
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)
4cd5ba0f 3506+ return FALSE;
4cd5ba0f 3507+
f33182aa 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
3512+ value. */
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;
4cd5ba0f 3522+
f33182aa 3523+ coff_record_symbol (info, scsymp);
4cd5ba0f 3524+
f33182aa 3525+ for (i = 0;; i++)
3526+ {
3527+ const char *name = tst->u.ts_enum.names[i];
3528+ if (name == NULL)
3529+ break;
3530+
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)
4cd5ba0f
ER
3534+ return FALSE;
3535+
3536+ csymp->symbol.name = xstrdup (name);
3537+ csymp->symbol.flags = BSF_NOT_AT_END;
3538+ csymp->symbol.section = bfd_com_section_ptr;
f33182aa 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];
4cd5ba0f
ER
3542+
3543+ coff_record_symbol (info, csymp);
3544+ }
4cd5ba0f 3545+
f33182aa 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;
3552+ else
4cd5ba0f 3553+ {
f33182aa 3554+ for (ofp = info->fixes; ofp->next != NULL;)
3555+ ofp = ofp->next;
3556+ ofp->next = fixp;
4cd5ba0f
ER
3557+ }
3558+
f33182aa 3559+ coff_record_symbol (info, ecsymp);
3560+ info->flags |= COFF_FL_FIX_ENDNDX;
4cd5ba0f
ER
3561+
3562+ return TRUE;
3563+}
3564+
f33182aa 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. */
4cd5ba0f 3567+static bfd_boolean
f33182aa 3568+coff_emit_ndebug_sym (info, osymp, localp)
3569+ struct coff_write_handle *info;
3570+ asymbol *osymp;
3571+ bfd_boolean localp;
4cd5ba0f 3572+{
f33182aa 3573+ coff_symbol_type *csymp;
4cd5ba0f 3574+
f33182aa 3575+ /* Create new COFF symbol. */
3576+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3577+ if (csymp == NULL)
3578+ return FALSE;
4cd5ba0f 3579+
f33182aa 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;
3587+
3588+ coff_record_symbol (info, csymp);
4cd5ba0f
ER
3589+
3590+ return TRUE;
3591+}
f33182aa 3592+\f
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
3599+ exit. */
4cd5ba0f 3600+
f33182aa 3601+bfd_boolean
3602+write_coff_debugging_info (abfd, dhandle, symcountp, symppp)
3603+ bfd *abfd;
3604+ PTR dhandle;
3605+ long *symcountp;
3606+ asymbol ***symppp;
4cd5ba0f 3607+{
f33182aa 3608+ struct coff_write_handle info;
3609+ long i, l;
3610+ asymbol *symp;
3611+ struct coff_compilation_unit *up;
3612+ coff_symbol_type *csymp;
4cd5ba0f 3613+
f33182aa 3614+ memset ((void *)&info, 0, sizeof info);
4cd5ba0f 3615+
f33182aa 3616+ info.abfd = abfd;
4cd5ba0f 3617+
f33182aa 3618+ info.pointersize = info.enumsize = 4;
4cd5ba0f 3619+
f33182aa 3620+ switch (bfd_get_arch (abfd))
3621+ {
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;
3631+ break;
4cd5ba0f 3632+
f33182aa 3633+ default:
3634+ ;
3635+ }
4cd5ba0f 3636+
f33182aa 3637+ coff_copy_symbols(&info, *symcountp, *symppp);
4cd5ba0f 3638+
f33182aa 3639+ if (info.textsect == NULL)
3640+ {
3641+ fprintf (stderr, _("Warning: no \"text\" section found in output file\n"));
3642+ info.textsect = bfd_abs_section_ptr;
3643+ }
3644+ if (info.datasect == NULL)
3645+ {
3646+ fprintf (stderr, _("Warning: no \"data\" section found in output file\n"));
3647+ info.datasect = bfd_abs_section_ptr;
3648+ }
4cd5ba0f 3649+
f33182aa 3650+ if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc,
3651+ sizeof(struct coff_name_type_hash_entry)))
3652+ return FALSE;
4cd5ba0f 3653+
f33182aa 3654+ if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc,
3655+ sizeof(struct coff_struct_hash_entry)))
3656+ return FALSE;
4cd5ba0f 3657+
f33182aa 3658+ if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc,
3659+ sizeof(struct coff_enum_hash_entry)))
3660+ return FALSE;
4cd5ba0f 3661+
f33182aa 3662+ if (! debug_write (dhandle, &coff_fns, (PTR) &info))
3663+ return FALSE;
4cd5ba0f 3664+
f33182aa 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++)
3669+ {
3670+ up = info.currentfile;
4cd5ba0f 3671+
f33182aa 3672+ if (up->syms[i] != NULL)
3673+ {
3674+ coff_emit_ndebug_sym (&info, up->syms[i], TRUE);
3675+ up->syms[i] = NULL;
3676+ up->totsyms--;
3677+ }
3678+ }
4cd5ba0f 3679+
f33182aa 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.
4cd5ba0f 3688+
f33182aa 3689+ Finally, put out all remaining global non-debugging symbols. */
3690+ for (l = 0; l < info.nunits; l++)
3691+ {
3692+ const char *bn;
4cd5ba0f 3693+
f33182aa 3694+ up = info.units + l;
3695+ if (up->totsyms == 0)
3696+ continue;
4cd5ba0f 3697+
f33182aa 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)
3701+ return FALSE;
4cd5ba0f 3702+
f33182aa 3703+ bn = bu_basename (up->fname);
4cd5ba0f 3704+
f33182aa 3705+ if (bfd_coff_long_filenames (info.abfd))
3706+ csymp->symbol.name = up->fname;
3707+ else
3708+ csymp->symbol.name = bn;
4cd5ba0f 3709+
f33182aa 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);
3715+
3716+ for (i = 0; i < up->nsyms; i++)
4cd5ba0f 3717+ {
f33182aa 3718+ symp = up->syms[i];
3719+ if (symp == NULL)
3720+ continue;
3721+
3722+ coff_emit_ndebug_sym (&info, symp, TRUE);
4cd5ba0f
ER
3723+ }
3724+ }
3725+
f33182aa 3726+ for (i = 0; i < info.nglobals; i++)
3727+ {
3728+ symp = info.globals[i];
3729+ if (symp == NULL)
3730+ continue;
4cd5ba0f 3731+
f33182aa 3732+ coff_emit_ndebug_sym (&info, symp, FALSE);
3733+ }
4cd5ba0f 3734+
f33182aa 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++)
3740+ {
3741+ union internal_auxent *aux;
4cd5ba0f 3742+
f33182aa 3743+ csymp = info.secsyms[i];
4cd5ba0f 3744+
f33182aa 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;
3750+ }
3751+ free (info.secsyms);
4cd5ba0f 3752+
f33182aa 3753+ coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL);
3754+ bfd_hash_table_free (&info.types.root);
4cd5ba0f 3755+
f33182aa 3756+ coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL);
3757+ bfd_hash_table_free (&info.structs.root);
4cd5ba0f 3758+
f33182aa 3759+ coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL);
3760+ bfd_hash_table_free (&info.enums.root);
3761+
3762+ /* FIXME: free all the other stuff remembered in "info". */
3763+
3764+ free (*symppp);
3765+
3766+ *symcountp = info.nsyms;
3767+ *symppp = (asymbol **)info.syms;
4cd5ba0f
ER
3768+
3769+ return TRUE;
3770+}
3771+
f33182aa 3772+/* Start writing out information for a compilation unit. */
4cd5ba0f
ER
3773+
3774+static bfd_boolean
f33182aa 3775+coff_start_compilation_unit (p, filename)
4cd5ba0f 3776+ PTR p;
f33182aa 3777+ const char *filename;
4cd5ba0f
ER
3778+{
3779+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 3780+ long i;
3781+ const char *bn;
3782+ bfd_boolean found;
4cd5ba0f 3783+ coff_symbol_type *csymp;
4cd5ba0f
ER
3784+
3785+#if COFF_DEBUG
f33182aa 3786+ printf ("coff_start_compilation_unit(%s)\n", filename);
4cd5ba0f
ER
3787+#endif
3788+
f33182aa 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++)
3793+ {
3794+ struct coff_compilation_unit *up = info->currentfile;
4cd5ba0f 3795+
f33182aa 3796+ if (up->syms[i] != NULL)
3797+ {
3798+ coff_emit_ndebug_sym (info, up->syms[i], TRUE);
3799+ up->syms[i] = NULL;
3800+ up->totsyms--;
3801+ }
3802+ }
4cd5ba0f 3803+
f33182aa 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);
4cd5ba0f 3807+
f33182aa 3808+ for (i = 0, found = FALSE; i < info->nunits; i++)
4cd5ba0f 3809+ {
f33182aa 3810+ if (strcmp (info->units[i].fname, bn) == 0)
3811+ {
3812+ info->currentfile = info->units + i;
3813+ found = TRUE;
3814+ break;
3815+ }
3816+ }
3817+ if (!found)
3818+ {
3819+ fprintf(stderr,
3820+ _("Warning: file %s not found in symbol table, ignoring\n"),
3821+ filename);
3822+ info->currentfile = NULL;
3823+ return TRUE;
4cd5ba0f
ER
3824+ }
3825+
f33182aa 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)
3829+ return FALSE;
4cd5ba0f 3830+
f33182aa 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;
3839+ else
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);
4cd5ba0f
ER
3846+
3847+ return TRUE;
3848+}
3849+
f33182aa 3850+/* Start writing out information for a particular source file. */
4cd5ba0f
ER
3851+
3852+static bfd_boolean
f33182aa 3853+coff_start_source (p, filename)
3854+ PTR p ATTRIBUTE_UNUSED;
3855+ const char *filename ATTRIBUTE_UNUSED;
4cd5ba0f 3856+{
4cd5ba0f
ER
3857+
3858+#if COFF_DEBUG
f33182aa 3859+ printf ("coff_start_source(%s)\n", filename);
4cd5ba0f
ER
3860+#endif
3861+
f33182aa 3862+ /* COFF cannot handle include filenames. */
4cd5ba0f 3863+
f33182aa 3864+ return TRUE;
3865+}
4cd5ba0f 3866+
f33182aa 3867+/* Push an empty type. This shouldn't normally happen. */
4cd5ba0f 3868+
f33182aa 3869+static bfd_boolean
3870+coff_empty_type (p)
3871+ PTR p;
3872+{
3873+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3874+ struct coff_type_stack *tst;
4cd5ba0f 3875+
f33182aa 3876+#if COFF_DEBUG
3877+ printf ("coff_empty_type()\n");
3878+#endif
4cd5ba0f 3879+
f33182aa 3880+ coff_push_type (TS_EMPTY);
4cd5ba0f
ER
3881+
3882+ return TRUE;
3883+}
3884+
f33182aa 3885+/* Push a void type. */
4cd5ba0f
ER
3886+
3887+static bfd_boolean
f33182aa 3888+coff_void_type (p)
4cd5ba0f 3889+ PTR p;
4cd5ba0f
ER
3890+{
3891+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 3892+ struct coff_type_stack *tst;
4cd5ba0f
ER
3893+
3894+#if COFF_DEBUG
f33182aa 3895+ printf ("coff_void_type()\n");
4cd5ba0f
ER
3896+#endif
3897+
f33182aa 3898+ coff_push_type (TS_VOID);
4cd5ba0f
ER
3899+
3900+ return TRUE;
3901+}
3902+
f33182aa 3903+/* Push an integer type. */
4cd5ba0f
ER
3904+
3905+static bfd_boolean
f33182aa 3906+coff_int_type (p, size, unsignedp)
4cd5ba0f 3907+ PTR p;
f33182aa 3908+ unsigned int size;
3909+ bfd_boolean unsignedp;
4cd5ba0f
ER
3910+{
3911+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 3912+ struct coff_type_stack *tst;
4cd5ba0f
ER
3913+
3914+#if COFF_DEBUG
f33182aa 3915+ printf ("coff_int_type(%d, %d)\n", size, unsignedp);
4cd5ba0f
ER
3916+#endif
3917+
f33182aa 3918+ coff_push_type (TS_INT);
3919+ tst->u.ts_int.size = size;
3920+ tst->u.ts_int.isunsigned = unsignedp;
4cd5ba0f 3921+
f33182aa 3922+ return TRUE;
3923+}
4cd5ba0f 3924+
f33182aa 3925+/* Push a floating point type. */
4cd5ba0f 3926+
f33182aa 3927+static bfd_boolean
3928+coff_float_type (p, size)
3929+ PTR p;
3930+ unsigned int size;
3931+{
3932+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3933+ struct coff_type_stack *tst;
4cd5ba0f 3934+
f33182aa 3935+#if COFF_DEBUG
3936+ printf ("coff_float_type(%d)\n", size);
3937+#endif
4cd5ba0f 3938+
f33182aa 3939+ coff_push_type (TS_FLOAT);
3940+ tst->u.ts_float.size = size;
4cd5ba0f
ER
3941+
3942+ return TRUE;
3943+}
3944+
f33182aa 3945+/* Push a complex type. */
4cd5ba0f
ER
3946+
3947+static bfd_boolean
f33182aa 3948+coff_complex_type (p, size)
4cd5ba0f 3949+ PTR p;
f33182aa 3950+ unsigned int size ATTRIBUTE_UNUSED;
4cd5ba0f
ER
3951+{
3952+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 3953+ struct coff_type_stack *tst;
4cd5ba0f
ER
3954+
3955+#if COFF_DEBUG
f33182aa 3956+ printf ("coff_complex_type(%d)\n", size);
4cd5ba0f
ER
3957+#endif
3958+
f33182aa 3959+ coff_push_type (TS_COMPLEX);
4cd5ba0f 3960+
f33182aa 3961+ return TRUE;
3962+}
4cd5ba0f 3963+
f33182aa 3964+/* Push a bfd_boolean type. */
4cd5ba0f 3965+
f33182aa 3966+static bfd_boolean
3967+coff_bool_type (p, size)
3968+ PTR p;
3969+ unsigned int size;
3970+{
3971+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3972+ struct coff_type_stack *tst;
4cd5ba0f 3973+
f33182aa 3974+#if COFF_DEBUG
3975+ printf ("coff_bool_type(%d)\n", size);
3976+#endif
4cd5ba0f 3977+
f33182aa 3978+ coff_push_type (TS_INT);
3979+ tst->u.ts_int.size = size;
3980+ tst->u.ts_int.isunsigned = TRUE;
4cd5ba0f
ER
3981+
3982+ return TRUE;
3983+}
4cd5ba0f 3984+
f33182aa 3985+/* Push an enum type. */
4cd5ba0f 3986+
f33182aa 3987+static bfd_boolean
3988+coff_enum_type (p, tag, names, vals)
3989+ PTR p;
3990+ const char *tag;
3991+ const char **names;
3992+ bfd_signed_vma *vals;
3993+{
3994+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3995+ struct coff_type_stack *tst;
3996+ char buf[20];
4cd5ba0f 3997+
f33182aa 3998+#if COFF_DEBUG
3999+ int idx;
4000+ printf ("coff_enum_type(%s [", tag);
4001+ for (idx = 0; names[idx] != NULL; idx++)
4002+ printf ("%s -> %d, ", names[idx], (int)vals[idx]);
4003+ printf ("])\n");
4004+#endif
4cd5ba0f 4005+
f33182aa 4006+ coff_push_type (TS_ENUM);
4cd5ba0f 4007+
f33182aa 4008+ if (tag == NULL)
4009+ {
4010+ sprintf(buf, ".%dfake", info->nenums++);
4011+ tst->u.ts_enum.tag.malloctag = xstrdup (buf);
4012+ tst->u.ts_enum.tagismalloced = TRUE;
4013+ }
4014+ else
4015+ tst->u.ts_enum.tag.fixtag = tag;
4016+ tst->u.ts_enum.names = names;
4017+ tst->u.ts_enum.vals = vals;
4cd5ba0f 4018+
f33182aa 4019+ return TRUE;
4020+}
4cd5ba0f 4021+
f33182aa 4022+/* Push a pointer type. */
4cd5ba0f 4023+
f33182aa 4024+static bfd_boolean
4025+coff_pointer_type (p)
4026+ PTR p;
4027+{
4028+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4029+ struct coff_type_stack *tst;
4cd5ba0f 4030+
f33182aa 4031+#if COFF_DEBUG
4032+ printf ("coff_pointer_type()\n");
4033+#endif
4cd5ba0f 4034+
f33182aa 4035+ coff_push_type (TS_POINTER);
4cd5ba0f 4036+
f33182aa 4037+ return TRUE;
4038+}
4cd5ba0f 4039+
f33182aa 4040+/* Push a function type. */
4cd5ba0f 4041+
f33182aa 4042+static bfd_boolean
4043+coff_function_type (p, argcount, varargs)
4044+ PTR p;
4045+ int argcount;
4046+ bfd_boolean varargs ATTRIBUTE_UNUSED;
4cd5ba0f 4047+{
f33182aa 4048+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4049+ struct coff_type_stack *tst;
4cd5ba0f 4050+
f33182aa 4051+#if COFF_DEBUG
4052+ printf ("coff_function_type(%d, %d)\n", argcount, varargs);
4053+#endif
4cd5ba0f 4054+
f33182aa 4055+ coff_push_type (TS_FUNC);
4056+
4057+ /* FIXME should properly discard function arguments */
4058+ if (argcount > -1)
4cd5ba0f 4059+ {
f33182aa 4060+ fprintf (stderr,
4061+ _("coff_function_type() called with positive argcount\n"));
4062+ return FALSE;
4cd5ba0f
ER
4063+ }
4064+
f33182aa 4065+ return TRUE;
4066+}
4cd5ba0f 4067+
f33182aa 4068+/* Push a reference type. */
4cd5ba0f 4069+
f33182aa 4070+static bfd_boolean
4071+coff_reference_type (p)
4072+ PTR p;
4073+{
4074+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4075+
f33182aa 4076+#if COFF_DEBUG
4077+ printf ("coff_reference_type()\n");
4078+#endif
4cd5ba0f 4079+
f33182aa 4080+ coff_complain_unsupp (_("reference"));
4cd5ba0f 4081+
f33182aa 4082+ return TRUE;
4cd5ba0f
ER
4083+}
4084+
f33182aa 4085+/* Push a range type. */
4cd5ba0f 4086+
f33182aa 4087+static bfd_boolean
4088+coff_range_type (p, low, high)
4089+ PTR p;
4090+ bfd_signed_vma low ATTRIBUTE_UNUSED;
4091+ bfd_signed_vma high ATTRIBUTE_UNUSED;
4cd5ba0f 4092+{
f33182aa 4093+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4094+
f33182aa 4095+#if COFF_DEBUG
4096+ printf ("coff_range_type([%d..%d)\n", (int)low, (int)high);
4097+#endif
4cd5ba0f 4098+
f33182aa 4099+ coff_complain_unsupp (_("range"));
4cd5ba0f 4100+
f33182aa 4101+ return TRUE;
4102+}
4cd5ba0f 4103+
f33182aa 4104+/* Push an array type. */
4cd5ba0f 4105+
f33182aa 4106+static bfd_boolean
4107+coff_array_type (p, low, high, stringp)
4108+ PTR p;
4109+ bfd_signed_vma low;
4110+ bfd_signed_vma high;
4111+ bfd_boolean stringp;
4112+{
4113+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4114+ struct coff_type_stack *tst;
4cd5ba0f 4115+
f33182aa 4116+#if COFF_DEBUG
4117+ printf ("coff_array_type([%d..%d], %d)\n",
4118+ (int)low, (int)high, stringp);
4119+#endif
4cd5ba0f 4120+
f33182aa 4121+ /* Pop the range type, but ignore it. COFF doesn't use it. */
4122+ coff_pop_type ();
4cd5ba0f 4123+
f33182aa 4124+ /* FIXME What to do here? */
4125+ if (stringp)
4126+ {
4127+ fprintf(stderr, _("coff_array_type(): stringp == TRUE\n"));
4128+ return FALSE;
4129+ }
4130+
4131+ coff_push_type (TS_ARRAY);
4132+ tst->u.ts_array.low = low;
4133+ tst->u.ts_array.high = high;
4134+
4135+ return TRUE;
4136+}
4137+
4138+/* Push a set type. */
4139+
4140+static bfd_boolean
4141+coff_set_type (p, bitstringp)
4142+ PTR p;
4143+ bfd_boolean bitstringp ATTRIBUTE_UNUSED;
4cd5ba0f 4144+{
f33182aa 4145+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4146+
f33182aa 4147+#if COFF_DEBUG
4148+ printf ("coff_set_type(%d)\n", bitstringp);
4149+#endif
4cd5ba0f 4150+
f33182aa 4151+ coff_complain_unsupp (_("set"));
4cd5ba0f 4152+
f33182aa 4153+ return TRUE;
4154+}
4cd5ba0f 4155+
f33182aa 4156+/* Push an offset type. */
4cd5ba0f 4157+
f33182aa 4158+static bfd_boolean
4159+coff_offset_type (p)
4160+ PTR p;
4161+{
4162+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4163+
f33182aa 4164+#if COFF_DEBUG
4165+ printf ("coff_offset_type()\n");
4166+#endif
4cd5ba0f 4167+
f33182aa 4168+ coff_complain_unsupp (_("offset"));
4cd5ba0f 4169+
f33182aa 4170+ return TRUE;
4cd5ba0f
ER
4171+}
4172+
f33182aa 4173+/* Push a method type. */
4cd5ba0f 4174+
f33182aa 4175+static bfd_boolean
4176+coff_method_type (p, domainp, argcount, varargs)
4177+ PTR p;
4178+ bfd_boolean domainp ATTRIBUTE_UNUSED;
4179+ int argcount ATTRIBUTE_UNUSED;
4180+ bfd_boolean varargs ATTRIBUTE_UNUSED;
4cd5ba0f 4181+{
f33182aa 4182+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4183+
f33182aa 4184+#if COFF_DEBUG
4185+ printf ("coff_method_type(%d, %d, %d)\n",
4186+ domainp, argcount, varargs);
4187+#endif
4cd5ba0f 4188+
f33182aa 4189+ coff_complain_unsupp (_("method"));
4cd5ba0f 4190+
f33182aa 4191+ return TRUE;
4192+}
4cd5ba0f 4193+
f33182aa 4194+/* Push a const version of a type. */
4cd5ba0f 4195+
f33182aa 4196+static bfd_boolean
4197+coff_const_type (p)
4198+ PTR p ATTRIBUTE_UNUSED;
4cd5ba0f 4199+{
4cd5ba0f 4200+
f33182aa 4201+#if COFF_DEBUG
4202+ printf ("coff_const_type()\n");
4203+#endif
4cd5ba0f 4204+
f33182aa 4205+ /* const modifier is ignored by COFF */
4cd5ba0f 4206+
f33182aa 4207+ return TRUE;
4208+}
4cd5ba0f 4209+
f33182aa 4210+/* Push a volatile version of a type. */
4cd5ba0f 4211+
f33182aa 4212+static bfd_boolean
4213+coff_volatile_type (p)
4214+ PTR p ATTRIBUTE_UNUSED;
4215+{
4cd5ba0f 4216+
f33182aa 4217+#if COFF_DEBUG
4218+ printf ("coff_volatile_type()\n");
4219+#endif
4cd5ba0f 4220+
f33182aa 4221+ /* volatile modifier is ignored by COFF */
4cd5ba0f 4222+
f33182aa 4223+ return TRUE;
4224+}
4cd5ba0f 4225+
f33182aa 4226+/* Start outputting a struct. */
4cd5ba0f 4227+
f33182aa 4228+static bfd_boolean
4229+coff_start_struct_type (p, tag, id, structp, size)
4230+ PTR p;
4231+ const char *tag;
4232+ unsigned int id;
4233+ bfd_boolean structp;
4234+ unsigned int size;
4235+{
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;
4239+ char buf[20];
4240+ const char *name;
4cd5ba0f 4241+
f33182aa 4242+#if COFF_DEBUG
4243+ printf ("coff_start_struct_type(%s, %d, %d, %d)\n",
4244+ tag, id, structp, size);
4245+#endif
4246+
4247+ savedts = info->tstack;
4248+ info->tstack = NULL;
4249+
4250+ coff_push_type (TS_STRUCT);
4251+
4252+ if (tag == NULL)
4253+ {
4254+ sprintf(buf, ".%dfake", id);
4255+ name = tst->u.ts_struct.tag.malloctag = xstrdup (buf);
4256+ tst->u.ts_struct.tagismalloced = TRUE;
4257+ }
4258+ else
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;
4264+
4265+ shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE);
4266+ if (shash != NULL && shash->types != NULL)
4267+ {
4268+#if COFF_DEBUG
4269+ printf ("new %s definition for %s\n",
4270+ tst->u.ts_struct.isstruct? "struct": "union", name);
4271+#endif
4272+ coff_free_struct_info (shash, NULL);
4273+ shash->types = NULL;
4274+ shash->emitted = FALSE;
4cd5ba0f 4275+ }
f33182aa 4276+ else
4277+ (void)coff_struct_hash_lookup (&info->structs, name,
4278+ TRUE, tst->u.ts_struct.tagismalloced);
4279+
4280+ return TRUE;
4cd5ba0f
ER
4281+}
4282+
f33182aa 4283+/* Add a field to a struct. */
4284+
4285+static bfd_boolean
4286+coff_struct_field (p, name, bitpos, bitsize, visibility)
4287+ PTR p;
4288+ const char *name;
4289+ bfd_vma bitpos;
4290+ bfd_vma bitsize;
4291+ enum debug_visibility visibility;
4cd5ba0f 4292+{
f33182aa 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;
4298+ const char *tag;
4cd5ba0f 4299+
f33182aa 4300+#if COFF_DEBUG
4301+ printf ("coff_struct_field(%s, %d, %d, %d)\n",
4302+ name, (int)bitpos, (int)bitsize, (int)visibility);
4303+#endif
4cd5ba0f 4304+
f33182aa 4305+ /* Find the last element on the type stack. */
4306+ assert (info->tstack != NULL);
4307+ for (tst = info->tstack, otst = NULL; tst->next != NULL;)
4cd5ba0f 4308+ {
f33182aa 4309+ otst = tst;
4310+ tst = tst->next;
4311+ }
4312+ if (otst != NULL)
4313+ otst->next = NULL;
4314+
4315+ if (tst->tsk != TS_STRUCT)
4316+ {
4317+ fprintf (stderr, "coff_struct_field() not within structure definition\n");
4318+ return FALSE;
4319+ }
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);
4324+ fp->name = name;
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)
4332+ {
4333+ if (otst->u.ts_struct.tagismalloced)
4334+ tag = otst->u.ts_struct.tag.malloctag;
4335+ else
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)
4cd5ba0f 4340+ {
f33182aa 4341+ if (shash->types == NULL)
4342+ {
4343+ shash->types = (struct coff_type_stack *)
4344+ xmalloc (sizeof (struct coff_type_stack));
4345+ memcpy (shash->types, otst, sizeof (struct coff_type_stack));
4346+ }
4347+ shash->emitted = TRUE;
4348+ coff_emit_struct (info, otst, shash);
4cd5ba0f 4349+ }
4cd5ba0f 4350+ }
f33182aa 4351+ else if (otst->tsk == TS_ENUM)
4cd5ba0f 4352+ {
f33182aa 4353+ if (otst->u.ts_enum.tagismalloced)
4354+ tag = otst->u.ts_enum.tag.malloctag;
4355+ else
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)
4cd5ba0f 4360+ {
f33182aa 4361+ if (ehash->types == NULL)
4362+ {
4363+ ehash->types = (struct coff_type_stack *)
4364+ xmalloc (sizeof (struct coff_type_stack));
4365+ memcpy (ehash->types, otst, sizeof (struct coff_type_stack));
4366+ }
4367+ ehash->emitted = TRUE;
4368+ coff_emit_enum (info, otst, ehash);
4cd5ba0f
ER
4369+ }
4370+ }
f33182aa 4371+
4372+ info->tstack = tst;
4373+
4374+ return TRUE;
4cd5ba0f
ER
4375+}
4376+
f33182aa 4377+/* Finish up a struct. */
4378+
4379+static bfd_boolean
4380+coff_end_struct_type (p)
4381+ PTR p;
4cd5ba0f 4382+{
f33182aa 4383+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4384+ struct coff_type_stack *tst, *savedts;
4385+
4386+#if COFF_DEBUG
4387+ printf ("coff_end_struct_type()\n");
4cd5ba0f 4388+#endif
4cd5ba0f 4389+
f33182aa 4390+ /* Our struct definition should be the only type stack element by
4391+ now. */
4392+ assert (info->tstack != NULL);
4393+ tst = info->tstack;
4394+ if (tst->tsk != TS_STRUCT || tst->next != NULL)
4395+ {
4396+ fprintf (stderr, "coff_struct_field() not within structure definition\n");
4397+ return FALSE;
4398+ }
4cd5ba0f 4399+
f33182aa 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;
4cd5ba0f 4407+
f33182aa 4408+ return TRUE;
4409+}
4cd5ba0f 4410+
f33182aa 4411+/* Start outputting a class. */
4cd5ba0f 4412+
f33182aa 4413+static bfd_boolean
4414+coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
4415+ PTR p;
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;
4422+{
4423+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4424+
f33182aa 4425+#if COFF_DEBUG
4426+ printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n",
4427+ tag, id, structp, size, vptr, ownvptr);
4428+#endif
4cd5ba0f 4429+
f33182aa 4430+ coff_complain_unsupp (_("class"));
4cd5ba0f 4431+
f33182aa 4432+ return TRUE;
4433+}
4cd5ba0f 4434+
f33182aa 4435+/* Add a static member to the class on the type stack. */
4cd5ba0f 4436+
f33182aa 4437+static bfd_boolean
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;
4443+{
4cd5ba0f 4444+
f33182aa 4445+#if COFF_DEBUG
4446+ printf ("coff_class_static_member(%s, %s, %d)\n",
4447+ name, physname, (int)visibility);
4448+#endif
4cd5ba0f 4449+
f33182aa 4450+ return TRUE;
4451+}
4cd5ba0f 4452+
f33182aa 4453+/* Add a base class to the class on the type stack. */
4cd5ba0f 4454+
f33182aa 4455+static bfd_boolean
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;
4461+{
4cd5ba0f 4462+
f33182aa 4463+#if COFF_DEBUG
4464+ printf ("coff_class_baseclass(%d, %d, %d)\n",
4465+ (int)bitpos, virtual, (int)visibility);
4466+#endif
4cd5ba0f 4467+
f33182aa 4468+ return TRUE;
4469+}
4cd5ba0f 4470+
f33182aa 4471+/* Start adding a method to the class on the type stack. */
4cd5ba0f 4472+
f33182aa 4473+static bfd_boolean
4474+coff_class_start_method (p, name)
4475+ PTR p ATTRIBUTE_UNUSED;
4476+ const char *name ATTRIBUTE_UNUSED;
4477+{
4cd5ba0f 4478+
f33182aa 4479+#if COFF_DEBUG
4480+ printf ("coff_class_start_method(%s)\n", name);
4481+#endif
4cd5ba0f 4482+
f33182aa 4483+ return TRUE;
4484+}
4cd5ba0f 4485+
f33182aa 4486+/* Add a variant to the current method. */
4487+
4488+static bfd_boolean
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;
4cd5ba0f 4498+{
4cd5ba0f 4499+
f33182aa 4500+#if COFF_DEBUG
4501+ printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n",
4502+ physname, (int)visibility, constp, volatilep,
4503+ (int)voffset, contextp);
4504+#endif
4cd5ba0f 4505+
f33182aa 4506+ return TRUE;
4507+}
4cd5ba0f 4508+
f33182aa 4509+/* Add a static variant to the current method. */
4cd5ba0f 4510+
f33182aa 4511+static bfd_boolean
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;
4518+{
4cd5ba0f 4519+
f33182aa 4520+#if COFF_DEBUG
4521+ printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n",
4522+ physname, (int)visibility, constp, volatilep);
4523+#endif
4cd5ba0f 4524+
f33182aa 4525+ return TRUE;
4526+}
4cd5ba0f 4527+
f33182aa 4528+/* Finish up a method. */
4cd5ba0f 4529+
f33182aa 4530+static bfd_boolean
4531+coff_class_end_method (p)
4532+ PTR p ATTRIBUTE_UNUSED;
4533+{
4cd5ba0f 4534+
f33182aa 4535+#if COFF_DEBUG
4536+ printf ("coff_class_end_method()\n");
4537+#endif
4538+
4539+ return TRUE;
4cd5ba0f
ER
4540+}
4541+
f33182aa 4542+/* Finish up a class. */
4543+
4544+static bfd_boolean
4545+coff_end_class_type (p)
4546+ PTR p ATTRIBUTE_UNUSED;
4547+{
4548+
4549+#if COFF_DEBUG
4550+ printf ("coff_end_class_type()\n");
4cd5ba0f
ER
4551+#endif
4552+
f33182aa 4553+ return TRUE;
4554+}
4555+
4556+/* Push a typedef which was previously defined. */
4557+
4558+static bfd_boolean
4559+coff_typedef_type (p, name)
4560+ PTR p;
4561+ const char *name;
4cd5ba0f 4562+{
f33182aa 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;
4cd5ba0f 4566+
f33182aa 4567+#if COFF_DEBUG
4568+ printf ("coff_typedef_type(%s)\n", name);
4569+#endif
4cd5ba0f 4570+
f33182aa 4571+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4cd5ba0f 4572+
f33182aa 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
4575+ yet defined. */
4576+ assert (nthash != NULL);
4cd5ba0f 4577+
f33182aa 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
4582+ them. */
4cd5ba0f 4583+
f33182aa 4584+ for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;)
4cd5ba0f 4585+ {
f33182aa 4586+ temp = newst;
4587+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4588+ if (newchain == NULL)
4589+ newchain = newst;
4590+ memcpy (newst, tst, sizeof (*newst));
4591+ if (temp != NULL)
4592+ temp->next = newst;
4cd5ba0f 4593+
f33182aa 4594+ tst = tst->next;
4cd5ba0f 4595+ }
f33182aa 4596+ newst->next = info->tstack;
4597+ info->tstack = newchain;
4cd5ba0f 4598+
f33182aa 4599+ return TRUE;
4cd5ba0f
ER
4600+}
4601+
f33182aa 4602+/* Push a struct, union or class tag. */
4cd5ba0f 4603+
f33182aa 4604+static bfd_boolean
4605+coff_tag_type (p, name, id, kind)
4606+ PTR p;
4607+ const char *name;
4608+ unsigned int id ATTRIBUTE_UNUSED;
4609+ enum debug_type_kind kind;
4cd5ba0f 4610+{
f33182aa 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;
4615+ char buf[20];
4616+ bfd_boolean needcopy = FALSE;
4617+ bfd_boolean isstruct = TRUE;
4cd5ba0f 4618+
f33182aa 4619+#if COFF_DEBUG
4620+ printf ("coff_tag_type(%s, %d, %d)\n",
4621+ name, id, kind);
4cd5ba0f 4622+#endif
4cd5ba0f 4623+
f33182aa 4624+ if (name == NULL)
4625+ {
4626+ sprintf(buf, ".%dfake", id);
4627+ needcopy = TRUE;
4628+ }
4cd5ba0f 4629+
f33182aa 4630+ switch (kind)
4631+ {
4632+ case DEBUG_KIND_UNION:
4633+ case DEBUG_KIND_UNION_CLASS:
4634+ isstruct = FALSE;
4635+ /* FALLTHROUGH */
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;
4642+ if (tst == NULL)
4643+ {
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;
4652+ }
4653+ docopystack:
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
4658+ them. */
4659+ for (temp = newst = newchain = NULL; tst != NULL;)
4660+ {
4661+ temp = newst;
4662+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4663+ if (newchain == NULL)
4664+ newchain = newst;
4665+ memcpy (newst, tst, sizeof (*newst));
4666+ if (temp != NULL)
4667+ temp->next = newst;
4cd5ba0f 4668+
f33182aa 4669+ tst = tst->next;
4670+ }
4671+ if (newst)
4672+ {
4673+ newst->next = info->tstack;
4674+ info->tstack = newchain;
4675+ }
4676+ break;
4cd5ba0f 4677+
f33182aa 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;
4683+ if (tst == NULL)
4684+ {
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;
4692+ }
4693+ goto docopystack;
4cd5ba0f 4694+
f33182aa 4695+ default:
4696+ fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"),
4697+ (int)kind);
4698+ return FALSE;
4699+ }
4700+ return TRUE;
4701+}
4cd5ba0f 4702+
f33182aa 4703+/* Define a typedef. */
4cd5ba0f 4704+
f33182aa 4705+static bfd_boolean
4706+coff_typdef (p, name)
4707+ PTR p;
4708+ const char *name;
4709+{
4710+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4711+ struct coff_name_type_hash_entry *nthash;
4cd5ba0f 4712+
f33182aa 4713+#if COFF_DEBUG
4714+ printf ("coff_typdef(%s)\n", name);
4cd5ba0f
ER
4715+#endif
4716+
f33182aa 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. */
4cd5ba0f 4727+
f33182aa 4728+ if (info->tstack == NULL)
4729+ {
4730+ fprintf (stderr, _("coff_typdef() on an empty type stack\n"));
4731+ return FALSE;
4732+ }
4733+
4734+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4735+ if (nthash != NULL)
4736+ {
4737+#if COFF_DEBUG
4738+ printf ("new typedef for %s\n", name);
4cd5ba0f 4739+#endif
f33182aa 4740+ coff_free_type_info (nthash, NULL);
4741+ }
4742+ else
4743+ nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE);
4744+ if (nthash == NULL)
4745+ return FALSE;
4746+ nthash->types = info->tstack;
4747+
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))
4755+ {
4756+ struct coff_type_stack *newchain, *otst, *tst, *ntst;
4757+ coff_symbol_type *csymp;
4758+
4759+ nthash->emitted = TRUE;
4760+
4761+ for (tst = info->tstack, newchain = otst = NULL;
4762+ tst != NULL;
4763+ tst = tst->next)
4cd5ba0f 4764+ {
f33182aa 4765+ ntst = (struct coff_type_stack *)
4766+ xmalloc (sizeof (struct coff_type_stack));
4767+ memcpy (ntst, tst, sizeof (struct coff_type_stack));
4768+ if (otst == NULL)
4769+ newchain = ntst;
4770+ else
4771+ otst->next = ntst;
4772+ otst = ntst;
4cd5ba0f 4773+ }
f33182aa 4774+ info->tstack = newchain;
4775+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4776+ return FALSE;
4777+
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;
4783+
4784+ coff_record_symbol (info, csymp);
4785+ }
4786+ info->tstack = NULL;
4787+
4788+ return TRUE;
4789+}
4790+
4791+/* Define a tag. */
4792+
4793+static bfd_boolean
4794+coff_tag (p, tag)
4795+ PTR p;
4796+ const char *tag;
4797+{
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;
4802+
4803+
4804+#if COFF_DEBUG
4805+ printf ("coff_tag(%s)\n", tag);
4cd5ba0f 4806+#endif
f33182aa 4807+
4808+ if (info->tstack == NULL)
4809+ {
4810+ fprintf (stderr, _("coff_tag() called on an empty typestack\n"));
4811+ return FALSE;
4812+ }
4813+
4814+ switch (info->tstack->tsk)
4815+ {
4816+ case TS_STRUCT:
4817+ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE);
4818+ assert (shash != NULL);
4819+ shash->types = info->tstack;
4820+ info->tstack = NULL;
4821+ break;
4822+
4823+ case TS_ENUM:
4824+ ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE);
4825+ if (ehash != NULL && ehash->types != NULL)
4826+ {
4827+#if COFF_DEBUG
4828+ printf ("new enum definition for %s\n", tag);
4cd5ba0f 4829+#endif
f33182aa 4830+ coff_free_enum_info (ehash, NULL);
4831+ }
4832+ else
4833+ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE);
4834+ if (ehash == NULL)
4835+ return FALSE;
4836+ ehash->types = info->tstack;
4837+ info->tstack = NULL;
4838+ break;
4cd5ba0f 4839+
f33182aa 4840+ default:
4841+ fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk);
4842+ return FALSE;
4843+ }
4844+
4845+ return TRUE;
4846+}
4847+
4848+/* Define an integer constant. */
4849+
4850+static bfd_boolean
4851+coff_int_constant (p, name, val)
4852+ PTR p;
4853+ const char *name ATTRIBUTE_UNUSED;
4854+ bfd_vma val ATTRIBUTE_UNUSED;
4855+{
4856+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4857+
4858+#if COFF_DEBUG
4859+ printf ("coff_int_constant(%s, %d)\n", name, (int)val);
4cd5ba0f 4860+#endif
f33182aa 4861+
4862+ coff_complain_unsupp (_("int constant"));
4863+
4864+ return TRUE;
4865+}
4866+
4867+/* Define a floating point constant. */
4868+
4869+static bfd_boolean
4870+coff_float_constant (p, name, val)
4871+ PTR p;
4872+ const char *name ATTRIBUTE_UNUSED;
4873+ double val ATTRIBUTE_UNUSED;
4874+{
4875+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4876+
4877+#if COFF_DEBUG
4878+ printf ("coff_float_constant(%s, %g)\n", name, val);
4879+#endif
4880+
4881+ coff_complain_unsupp (_("float constant"));
4882+
4883+ return TRUE;
4884+}
4885+
4886+/* Define a typed constant. */
4887+
4888+static bfd_boolean
4889+coff_typed_constant (p, name, val)
4890+ PTR p;
4891+ const char *name ATTRIBUTE_UNUSED;
4892+ bfd_vma val ATTRIBUTE_UNUSED;
4893+{
4894+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4895+
4896+#if COFF_DEBUG
4897+ printf ("coff_typed_constant(%s, %d)\n", name, (int)val);
4898+#endif
4899+
4900+ coff_complain_unsupp (_("typed constant"));
4901+
4902+ return TRUE;
4903+}
4904+
4905+/* Record a variable. */
4906+
4907+static bfd_boolean
4908+coff_variable (p, name, kind, val)
4909+ PTR p;
4910+ const char *name;
4911+ enum debug_var_kind kind;
4912+ bfd_vma val;
4913+{
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;
4921+
4922+#if COFF_DEBUG
4923+ printf ("coff_variable(%s, %d, %d)\n",
4924+ name, (int)kind, (int)val);
4925+#endif
4926+
4927+ switch (kind)
4928+ {
4929+ default:
4930+ abort ();
4931+
4932+ case DEBUG_GLOBAL:
4933+ flags = BSF_GLOBAL;
4934+ global = TRUE;
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
4938+ well. */
4939+ class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT;
4940+ break;
4941+
4942+ case DEBUG_STATIC:
4943+ case DEBUG_LOCAL_STATIC:
4944+ class = C_STAT;
4945+ break;
4946+
4947+ case DEBUG_LOCAL:
4948+ class = C_AUTO;
4949+ break;
4950+
4951+ case DEBUG_REGISTER:
4952+ class = C_REG;
4953+ break;
4954+ }
4955+
4956+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4957+ return FALSE;
4958+
4959+ if (class == C_REG && (info->flags & COFF_FL_AVR) != 0)
4960+ {
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);
4964+ }
4965+
4966+ csymp->symbol.name = name;
4967+ csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */
4968+
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)
4976+ {
4977+ symp = coff_find_symbol (info, name, FALSE, global);
4978+ if (symp)
4979+ {
4980+ csymp->symbol.section = symp->section;
4981+ vmadiff = symp->section->vma;
4982+ }
4983+ }
4984+
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);
4989+
4990+ return TRUE;
4991+}
4992+
4993+/* Start outputting a function. */
4994+
4995+static bfd_boolean
4996+coff_start_function (p, name, globalp)
4997+ PTR p;
4998+ const char *name;
4999+ bfd_boolean globalp;
5000+{
5001+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5002+ struct coff_type_stack *tst, *savedts;
5003+
5004+#if COFF_DEBUG
5005+ printf ("coff_start_function(%s, %d)\n",
5006+ name, globalp);
5007+#endif
5008+
5009+ savedts = info->tstack;
5010+ info->tstack = NULL;
5011+
5012+ coff_push_type (TS_FUNC);
5013+
5014+ if (info->funname != NULL)
5015+ {
5016+ fprintf (stderr,
5017+ _("coff_start_function() called twice, pending %s, new %s\n"),
5018+ info->funname, name);
5019+ return FALSE;
5020+ }
5021+ info->funname = name;
5022+ info->funglobal = globalp;
5023+ info->flags |= COFF_FL_START_FCN;
5024+ tst->u.ts_func.savedts = savedts;
5025+
5026+ return TRUE;
5027+}
5028+
5029+/* Output a function parameter. */
5030+
5031+static bfd_boolean
5032+coff_function_parameter (p, name, kind, val)
5033+ PTR p;
5034+ const char *name;
5035+ enum debug_parm_kind kind;
5036+ bfd_vma val;
5037+{
5038+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5039+ coff_symbol_type *csymp;
5040+ unsigned char class;
5041+
5042+#if COFF_DEBUG
5043+ printf ("coff_function_parameter(%s, %d, %d)\n",
5044+ name, (int)kind, (int)val);
5045+#endif
5046+
5047+ switch (kind)
5048+ {
5049+ default:
5050+ abort ();
5051+
5052+ case DEBUG_PARM_STACK:
5053+ class = C_ARG;
5054+ break;
5055+
5056+ case DEBUG_PARM_REG:
5057+ class = C_REGPARM;
5058+ break;
5059+
5060+ case DEBUG_PARM_REFERENCE:
5061+ case DEBUG_PARM_REF_REG:
5062+ fprintf (stderr, _("Reference parameters not available in COFF\n"));
5063+ return TRUE;
5064+ }
5065+
5066+ if (!coff_make_typed_symbol (info, &csymp, TS_FUNC))
5067+ return FALSE;
5068+
5069+ if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0)
5070+ {
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);
5074+ }
5075+
5076+ csymp->symbol.name = name;
5077+ csymp->symbol.value = val;
5078+ csymp->symbol.flags |= BSF_LOCAL;
5079+ csymp->native->u.syment.n_sclass = class;
5080+
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;
5086+
5087+ return TRUE;
5088+}
5089+
5090+/* Start a block. */
5091+
5092+static bfd_boolean
5093+coff_start_block (p, addr)
5094+ PTR p;
5095+ bfd_vma addr;
5096+{
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;
5100+ asymbol *symp;
5101+ coff_symbol_type *csymp;
5102+ unsigned int i;
5103+ bfd_boolean is_start_fcn;
5104+
5105+#if COFF_DEBUG
5106+ printf ("coff_start_block(%#x)\n", (int)addr);
5107+#endif
5108+
5109+ is_start_fcn = info->flags & COFF_FL_START_FCN;
5110+
5111+ if (is_start_fcn)
5112+ {
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;
5118+
5119+ /* Our function definition should be the only type stack element
5120+ by now. */
5121+ assert (info->tstack != NULL);
5122+ tst = info->tstack;
5123+ if (tst->tsk != TS_FUNC || tst->next != NULL)
5124+ {
5125+ fprintf (stderr,
5126+ _("coff_start_block() not within function definition\n"));
5127+ return FALSE;
5128+ }
5129+
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;
5135+
5136+ if (info->currentfile == NULL)
5137+ {
5138+ fprintf (stderr,
5139+ _("Warning: ignoring function %s() outside any compilation unit\n"),
5140+ info->funname);
5141+ for (tst = info->tstack, otst = NULL; tst != NULL;)
5142+ {
5143+ otst = tst;
5144+ tst = otst->next;
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);
5151+ free (otst);
5152+ }
5153+ info->tstack = NULL;
5154+ info->funname = NULL;
5155+
5156+ return TRUE;
5157+ }
5158+
5159+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
5160+ return FALSE;
5161+
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);
5166+ if (symp == NULL)
5167+ {
5168+ fprintf (stderr,
5169+ _("function %s not found in symbol table, defaulting to \"text\" section\n"),
5170+ info->funname);
5171+ csymp->symbol.section = info->funcsection = info->textsect;
5172+ }
5173+ else
5174+ csymp->symbol.section = info->funcsection = symp->section;
5175+
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));
5185+ info->nlnos = 2;
5186+ info->totlnos++;
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;
5196+ else
5197+ {
5198+ for (ofp = info->fixes; ofp->next != NULL;)
5199+ ofp = ofp->next;
5200+ ofp->next = fixp;
5201+ }
5202+
5203+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5204+ if (csymp == NULL)
5205+ return FALSE;
5206+
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);
5214+ }
5215+
5216+ if (info->funname == NULL)
5217+ return TRUE;
5218+
5219+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5220+ if (csymp == NULL)
5221+ return FALSE;
5222+
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);
5230+
5231+ info->flags |= COFF_FL_FIX_BB;
5232+
5233+ /* Output any pending function parameters, if any. */
5234+ if (is_start_fcn && info->nfargs)
5235+ {
5236+ for (i = 0; i < info->nfargs; i++)
5237+ coff_record_symbol (info, info->fargs[i]);
5238+
5239+ free (info->fargs);
5240+ info->fargs = NULL;
5241+ info->nfargs = 0;
5242+ }
5243+
5244+ return TRUE;
5245+}
5246+
5247+/* End a block. */
5248+
5249+static bfd_boolean
5250+coff_end_block (p, addr)
5251+ PTR p;
5252+ bfd_vma addr;
5253+{
5254+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5255+ coff_symbol_type *csymp;
5256+ union internal_auxent *aux;
5257+
5258+#if COFF_DEBUG
5259+ printf ("coff_end_block(%#x)\n", (int)addr);
4cd5ba0f 5260+#endif
f33182aa 5261+
5262+ if (info->funname == NULL)
5263+ return TRUE;
5264+
5265+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5266+ if (csymp == NULL)
5267+ return FALSE;
5268+
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);
5278+
5279+ info->endaddr = addr;
5280+
5281+ return TRUE;
5282+}
5283+
5284+/* End a function. */
5285+
5286+static bfd_boolean
5287+coff_end_function (p)
5288+ PTR p;
5289+{
5290+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5291+ coff_symbol_type *csymp;
5292+ union internal_auxent *aux;
5293+
5294+#if COFF_DEBUG
5295+ printf ("coff_end_function()\n");
5296+#endif
5297+
5298+ if (info->funname == NULL)
5299+ return TRUE;
5300+
5301+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5302+ if (csymp == NULL)
5303+ return FALSE;
5304+
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;
5313+
5314+ coff_record_symbol (info, csymp);
5315+
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;
5319+
5320+ info->flags |= COFF_FL_FIX_ENDNDX;
5321+ info->funname = NULL;
5322+
5323+ return TRUE;
5324+}
5325+
5326+/* Output a line number. */
5327+
5328+static bfd_boolean
5329+coff_lineno (p, file, lineno, addr)
5330+ PTR p;
5331+ const char *file ATTRIBUTE_UNUSED;
5332+ unsigned long lineno;
5333+ bfd_vma addr;
5334+{
5335+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5336+ coff_symbol_type *csymp;
5337+ union internal_auxent *aux;
5338+ long i;
5339+
5340+#if COFF_DEBUG
5341+ printf ("coff_lineno(%s, %ld, %d)\n",
5342+ file, lineno, (int)addr);
5343+#endif
5344+
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)
5348+ return TRUE;
5349+
5350+ if (info->nlnos == 2)
5351+ {
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
5358+ line earlier. */
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;
5363+ }
5364+
5365+ if (info->flags & COFF_FL_FIX_BB)
5366+ {
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;
5374+
5375+ for (i = info->nsyms - 1; i >= 0; i--)
5376+ {
5377+ csymp = (coff_symbol_type *) info->syms[i];
5378+ if (csymp->native->u.syment.n_sclass == C_FCN)
5379+ break;
5380+ if (csymp->native->u.syment.n_sclass == C_BLOCK)
5381+ {
5382+ aux = &((csymp->native + 1)->u.auxent);
5383+ if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0)
5384+ /* already set up properly */
5385+ break;
5386+ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno;
5387+ }
5388+ }
5389+ }
5390+
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;
5397+ else
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;
5404+
5405+ info->lastlno = lineno;
5406+ info->totlnos++;
5407+
5408+ return TRUE;
5409+}
5410diff -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
4cd5ba0f
ER
5413@@ -0,0 +1,110 @@
5414+/* coff information for Atmel AVR.
5415+
5416+ Copyright 2001 Free Software Foundation, Inc.
5417+
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.
5422+
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.
5427+
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. */
5431+
5432+/* This file was hacked from i860.h */
5433+
5434+#define L_LNNO_SIZE 2
5435+#include "coff/external.h"
5436+
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 */
5442+
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)
5453+
5454+#define AVRMAGIC 0xa12
5455+
5456+#undef AOUTSZ
5457+#ifdef AVR_EXT_COFF
5458+
5459+/* AVR "extended" COFF format. This uses the optional header ("a.out"
5460+ header) to inform the consumer about some additional features that
5461+ are supported. */
5462+#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */
5463+#define AOUTSZ 28 /* size of optional header in "extended" COFF */
5464+
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 */
5469+
5470+#else /* old AVR COFF */
5471+
5472+#define AOUTSZ 0 /* no a.out for AVR */
5473+#endif
5474+
5475+/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */
5476+/*
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.
5481+ *
5482+ * 0x9cc has been chosen since it resembles "gcc". ;-)
5483+ */
5484+#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */
5485+
5486+/* By matching not only the magic number, but also the size of the
5487+ optional a.out header, we can differentiate between both
5488+ formats. */
5489+#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ)
5490+
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. */
5496+
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
5500+ anyway. */
5501+extern void avr_coff_adjust_sym_in_post
5502+ PARAMS((bfd *, PTR, PTR));
5503+
5504+extern void avr_coff_adjust_sym_out_post
5505+ PARAMS((bfd *, PTR, PTR));
5506+
5507+#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \
5508+ avr_coff_adjust_sym_in_post (ABFD, EXT, INT)
5509+
5510+#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \
5511+ avr_coff_adjust_sym_out_post (ABFD, INT, EXT)
5512+
5513+/********************** RELOCATION DIRECTIVES **********************/
5514+
5515+struct external_reloc
5516+{
5517+ char r_vaddr[4];
5518+ char r_symndx[4];
5519+ char r_type[2];
5520+};
5521+
5522+#define RELOC struct external_reloc
5523+#define RELSZ 10
f33182aa 5524diff -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
5527@@ -630,6 +630,8 @@
4cd5ba0f
ER
5528
5529 };
5530
5531+#define NAUXENTS 10 /* number of pre-allocated aux entries */
5532+
5533 /********************** RELOCATION DIRECTIVES **********************/
5534
5535 struct internal_reloc
This page took 1.044275 seconds and 4 git commands to generate.