]> git.pld-linux.org Git - packages/crossavr-binutils.git/blame - 301-binutils-2.20.1-avr-coff.patch
- synchronized patches with Atmel official AVR8-GNU toolchain.
[packages/crossavr-binutils.git] / 301-binutils-2.20.1-avr-coff.patch
CommitLineData
3ccd393f 1diff -ruwN bfd/Makefile.am bfd/Makefile.am
2--- bfd/Makefile.am 2009-10-16 17:17:44.000000000 +0530
3+++ bfd/Makefile.am 2010-03-11 12:13:23.069283600 +0530
4@@ -228,6 +228,8 @@
c66cb070 5 coff-apollo.lo \
6 coff-arm.lo \
7 coff-aux.lo \
8+ coff-avr.lo \
9+ coff-ext-avr.lo \
10 coff-go32.lo \
11 coff-h8300.lo \
12 coff-h8500.lo \
3ccd393f 13@@ -411,6 +413,8 @@
c66cb070 14 coff-apollo.c \
15 coff-arm.c \
16 coff-aux.c \
17+ coff-avr.c \
18+ coff-ext-avr.c \
19 coff-go32.c \
20 coff-h8300.c \
21 coff-h8500.c \
3ccd393f 22diff -ruwN bfd/Makefile.in bfd/Makefile.in
23--- bfd/Makefile.in 2009-10-16 17:17:48.000000000 +0530
24+++ bfd/Makefile.in 2010-03-11 12:13:23.084906900 +0530
25@@ -524,6 +524,8 @@
c66cb070 26 coff-apollo.lo \
27 coff-arm.lo \
28 coff-aux.lo \
29+ coff-avr.lo \
30+ coff-ext-avr.lo \
31 coff-go32.lo \
32 coff-h8300.lo \
33 coff-h8500.lo \
3ccd393f 34@@ -707,6 +709,8 @@
c66cb070 35 coff-apollo.c \
36 coff-arm.c \
37 coff-aux.c \
38+ coff-avr.c \
39+ coff-ext-avr.c \
40 coff-go32.c \
41 coff-h8300.c \
42 coff-h8500.c \
3ccd393f 43diff -ruwN bfd/coff-avr.c bfd/coff-avr.c
44--- bfd/coff-avr.c 1970-01-01 05:30:00.000000000 +0530
45+++ bfd/coff-avr.c 2010-03-11 12:13:23.100530200 +0530
c66cb070 46@@ -0,0 +1,613 @@
47+/* BFD back-end for Atmel AVR COFF files.
48+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
49+ Free Software Foundation, Inc.
50+ Created mostly by substituting "avr" for "i860" in coff-i860.c
4cd5ba0f 51+
c66cb070 52+This file is part of BFD, the Binary File Descriptor library.
4cd5ba0f 53+
c66cb070 54+This program is free software; you can redistribute it and/or modify
55+it under the terms of the GNU General Public License as published by
56+the Free Software Foundation; either version 2 of the License, or
57+(at your option) any later version.
4cd5ba0f 58+
c66cb070 59+This program is distributed in the hope that it will be useful,
60+but WITHOUT ANY WARRANTY; without even the implied warranty of
61+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62+GNU General Public License for more details.
4cd5ba0f 63+
c66cb070 64+You should have received a copy of the GNU General Public License
65+along with this program; if not, write to the Free Software
66+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
4cd5ba0f 67+
c66cb070 68+#include "bfd.h"
69+#include "sysdep.h"
70+#include "libbfd.h"
4cd5ba0f 71+
c66cb070 72+#include "coff/avr.h"
4cd5ba0f 73+
c66cb070 74+#include "coff/internal.h"
4cd5ba0f 75+
c66cb070 76+#include "libcoff.h"
4cd5ba0f 77+
c66cb070 78+static bfd_reloc_status_type coff_avr_reloc
79+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
80+static reloc_howto_type *coff_avr_rtype_to_howto
81+ PARAMS ((bfd *, asection *, struct internal_reloc *,
82+ struct coff_link_hash_entry *, struct internal_syment *,
83+ bfd_vma *));
84+static const bfd_target * coff_avr_object_p PARAMS ((bfd *));
4cd5ba0f 85+
c66cb070 86+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
87+/* The page size is a guess based on ELF. */
88+
89+#define COFF_PAGE_SIZE 0x1000
90+
91+/* For some reason when using avr COFF the value stored in the .text
92+ section for a reference to a common symbol is the value itself plus
93+ any desired offset. Ian Taylor, Cygnus Support. */
94+
95+/* If we are producing relocateable output, we need to do some
96+ adjustments to the object file that are not done by the
97+ bfd_perform_relocation function. This function is called by every
98+ reloc type to make any required adjustments. */
99+
100+static bfd_reloc_status_type
101+coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
102+ error_message)
103+ bfd *abfd;
104+ arelent *reloc_entry;
105+ asymbol *symbol;
106+ PTR data;
107+ asection *input_section ATTRIBUTE_UNUSED;
108+ bfd *output_bfd;
109+ char **error_message ATTRIBUTE_UNUSED;
f33182aa 110+{
c66cb070 111+ symvalue diff;
4cd5ba0f 112+
c66cb070 113+ if (output_bfd == (bfd *) NULL)
114+ return bfd_reloc_continue;
4cd5ba0f 115+
c66cb070 116+ if (bfd_is_com_section (symbol->section))
f33182aa 117+ {
c66cb070 118+ /* We are relocating a common symbol. The current value in the
119+ object file is ORIG + OFFSET, where ORIG is the value of the
120+ common symbol as seen by the object file when it was compiled
121+ (this may be zero if the symbol was undefined) and OFFSET is
122+ the offset into the common symbol (normally zero, but may be
123+ non-zero when referring to a field in a common structure).
124+ ORIG is the negative of reloc_entry->addend, which is set by
125+ the CALC_ADDEND macro below. We want to replace the value in
126+ the object file with NEW + OFFSET, where NEW is the value of
127+ the common symbol which we are going to put in the final
128+ object file. NEW is symbol->value. */
129+ diff = symbol->value + reloc_entry->addend;
130+ }
131+ else
132+ {
133+ /* For some reason bfd_perform_relocation always effectively
134+ ignores the addend for a COFF target when producing
135+ relocateable output. This seems to be always wrong for 860
136+ COFF, so we handle the addend here instead. */
137+ diff = reloc_entry->addend;
f33182aa 138+ }
139+
c66cb070 140+#define DOIT(x) \
141+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
4cd5ba0f 142+
c66cb070 143+ if (diff != 0)
144+ {
145+ reloc_howto_type *howto = reloc_entry->howto;
146+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
4cd5ba0f 147+
c66cb070 148+ switch (howto->size)
42dd3303 149+ {
c66cb070 150+ case 0:
151+ {
152+ char x = bfd_get_8 (abfd, addr);
153+ DOIT (x);
154+ bfd_put_8 (abfd, x, addr);
155+ }
156+ break;
4cd5ba0f 157+
c66cb070 158+ case 1:
159+ {
160+ short x = bfd_get_16 (abfd, addr);
161+ DOIT (x);
162+ bfd_put_16 (abfd, (bfd_vma) x, addr);
163+ }
164+ break;
4cd5ba0f 165+
c66cb070 166+ case 2:
167+ {
168+ long x = bfd_get_32 (abfd, addr);
169+ DOIT (x);
170+ bfd_put_32 (abfd, (bfd_vma) x, addr);
171+ }
172+ break;
486e8626 173+
c66cb070 174+ default:
175+ abort ();
42dd3303 176+ }
c66cb070 177+ }
f33182aa 178+
c66cb070 179+ /* Now let bfd_perform_relocation finish everything up. */
180+ return bfd_reloc_continue;
42dd3303 181+}
4cd5ba0f 182+
c66cb070 183+#ifndef PCRELOFFSET
184+#define PCRELOFFSET FALSE
185+#endif
4cd5ba0f 186+
c66cb070 187+static reloc_howto_type howto_table[] =
188+{
189+ EMPTY_HOWTO (0),
190+ EMPTY_HOWTO (1),
191+ EMPTY_HOWTO (2),
192+ EMPTY_HOWTO (3),
193+ EMPTY_HOWTO (4),
194+ EMPTY_HOWTO (5),
195+ HOWTO (R_DIR32, /* type */
196+ 0, /* rightshift */
197+ 2, /* size (0 = byte, 1 = short, 2 = long) */
198+ 32, /* bitsize */
199+ FALSE, /* pc_relative */
200+ 0, /* bitpos */
201+ complain_overflow_bitfield, /* complain_on_overflow */
202+ coff_avr_reloc, /* special_function */
203+ "dir32", /* name */
204+ TRUE, /* partial_inplace */
205+ 0xffffffff, /* src_mask */
206+ 0xffffffff, /* dst_mask */
207+ TRUE), /* pcrel_offset */
208+ /* {7}, */
209+ HOWTO (R_IMAGEBASE, /* type */
210+ 0, /* rightshift */
211+ 2, /* size (0 = byte, 1 = short, 2 = long) */
212+ 32, /* bitsize */
213+ FALSE, /* pc_relative */
214+ 0, /* bitpos */
215+ complain_overflow_bitfield, /* complain_on_overflow */
216+ coff_avr_reloc, /* special_function */
217+ "rva32", /* name */
218+ TRUE, /* partial_inplace */
219+ 0xffffffff, /* src_mask */
220+ 0xffffffff, /* dst_mask */
221+ FALSE), /* pcrel_offset */
222+ EMPTY_HOWTO (010),
223+ EMPTY_HOWTO (011),
224+ EMPTY_HOWTO (012),
225+ EMPTY_HOWTO (013),
226+ EMPTY_HOWTO (014),
227+ EMPTY_HOWTO (015),
228+ EMPTY_HOWTO (016),
229+ HOWTO (R_RELBYTE, /* type */
230+ 0, /* rightshift */
231+ 0, /* size (0 = byte, 1 = short, 2 = long) */
232+ 8, /* bitsize */
233+ FALSE, /* pc_relative */
234+ 0, /* bitpos */
235+ complain_overflow_bitfield, /* complain_on_overflow */
236+ coff_avr_reloc, /* special_function */
237+ "8", /* name */
238+ TRUE, /* partial_inplace */
239+ 0x000000ff, /* src_mask */
240+ 0x000000ff, /* dst_mask */
241+ PCRELOFFSET), /* pcrel_offset */
242+ HOWTO (R_RELWORD, /* type */
243+ 0, /* rightshift */
244+ 1, /* size (0 = byte, 1 = short, 2 = long) */
245+ 16, /* bitsize */
246+ FALSE, /* pc_relative */
247+ 0, /* bitpos */
248+ complain_overflow_bitfield, /* complain_on_overflow */
249+ coff_avr_reloc, /* special_function */
250+ "16", /* name */
251+ TRUE, /* partial_inplace */
252+ 0x0000ffff, /* src_mask */
253+ 0x0000ffff, /* dst_mask */
254+ PCRELOFFSET), /* pcrel_offset */
255+ HOWTO (R_RELLONG, /* type */
256+ 0, /* rightshift */
257+ 2, /* size (0 = byte, 1 = short, 2 = long) */
258+ 32, /* bitsize */
259+ FALSE, /* pc_relative */
260+ 0, /* bitpos */
261+ complain_overflow_bitfield, /* complain_on_overflow */
262+ coff_avr_reloc, /* special_function */
263+ "32", /* name */
264+ TRUE, /* partial_inplace */
265+ 0xffffffff, /* src_mask */
266+ 0xffffffff, /* dst_mask */
267+ PCRELOFFSET), /* pcrel_offset */
268+ HOWTO (R_PCRBYTE, /* type */
269+ 0, /* rightshift */
270+ 0, /* size (0 = byte, 1 = short, 2 = long) */
271+ 8, /* bitsize */
272+ TRUE, /* pc_relative */
273+ 0, /* bitpos */
274+ complain_overflow_signed, /* complain_on_overflow */
275+ coff_avr_reloc, /* special_function */
276+ "DISP8", /* name */
277+ TRUE, /* partial_inplace */
278+ 0x000000ff, /* src_mask */
279+ 0x000000ff, /* dst_mask */
280+ PCRELOFFSET), /* pcrel_offset */
281+ HOWTO (R_PCRWORD, /* type */
282+ 0, /* rightshift */
283+ 1, /* size (0 = byte, 1 = short, 2 = long) */
284+ 16, /* bitsize */
285+ TRUE, /* pc_relative */
286+ 0, /* bitpos */
287+ complain_overflow_signed, /* complain_on_overflow */
288+ coff_avr_reloc, /* special_function */
289+ "DISP16", /* name */
290+ TRUE, /* partial_inplace */
291+ 0x0000ffff, /* src_mask */
292+ 0x0000ffff, /* dst_mask */
293+ PCRELOFFSET), /* pcrel_offset */
294+ HOWTO (R_PCRLONG, /* type */
295+ 0, /* rightshift */
296+ 2, /* size (0 = byte, 1 = short, 2 = long) */
297+ 32, /* bitsize */
298+ TRUE, /* pc_relative */
299+ 0, /* bitpos */
300+ complain_overflow_signed, /* complain_on_overflow */
301+ coff_avr_reloc, /* special_function */
302+ "DISP32", /* name */
303+ TRUE, /* partial_inplace */
304+ 0xffffffff, /* src_mask */
305+ 0xffffffff, /* dst_mask */
306+ PCRELOFFSET) /* pcrel_offset */
307+};
4cd5ba0f 308+
c66cb070 309+/* Turn a howto into a reloc nunmber */
4cd5ba0f 310+
c66cb070 311+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
312+#define BADMAG(x) AVRBADMAG(x)
313+#define AVR 1 /* Customize coffcode.h */
4cd5ba0f 314+
c66cb070 315+#define RTYPE2HOWTO(cache_ptr, dst) \
316+ (cache_ptr)->howto = howto_table + (dst)->r_type;
4cd5ba0f 317+
c66cb070 318+/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
319+ library. On some other COFF targets STYP_BSS is normally
320+ STYP_NOLOAD. */
321+#define BSS_NOLOAD_IS_SHARED_LIBRARY
4cd5ba0f 322+
c66cb070 323+/* Compute the addend of a reloc. If the reloc is to a common symbol,
324+ the object file contains the value of the common symbol. By the
325+ time this is called, the linker may be using a different symbol
326+ from a different object file with a different value. Therefore, we
327+ hack wildly to locate the original symbol from this file so that we
328+ can make the correct adjustment. This macro sets coffsym to the
329+ symbol from the original file, and uses it to set the addend value
330+ correctly. If this is not a common symbol, the usual addend
331+ calculation is done, except that an additional tweak is needed for
332+ PC relative relocs.
333+ FIXME: This macro refers to symbols and asect; these are from the
334+ calling function, not the macro arguments. */
4cd5ba0f 335+
c66cb070 336+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
337+ { \
338+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
339+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
340+ coffsym = (obj_symbols (abfd) \
341+ + (cache_ptr->sym_ptr_ptr - symbols)); \
342+ else if (ptr) \
343+ coffsym = coff_symbol_from (abfd, ptr); \
344+ if (coffsym != (coff_symbol_type *) NULL \
345+ && coffsym->native->u.syment.n_scnum == 0) \
346+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
347+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
348+ && ptr->section != (asection *) NULL) \
349+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
350+ else \
351+ cache_ptr->addend = 0; \
352+ if (ptr && howto_table[reloc.r_type].pc_relative) \
353+ cache_ptr->addend += asect->vma; \
354+ }
42dd3303 355+
c66cb070 356+/* We use the special COFF backend linker. */
357+#define coff_relocate_section _bfd_coff_generic_relocate_section
4cd5ba0f 358+
c66cb070 359+static reloc_howto_type *
360+coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
361+ bfd *abfd ATTRIBUTE_UNUSED;
362+ asection *sec;
363+ struct internal_reloc *rel;
364+ struct coff_link_hash_entry *h;
365+ struct internal_syment *sym;
366+ bfd_vma *addendp;
42dd3303 367+{
4cd5ba0f 368+
c66cb070 369+ reloc_howto_type *howto;
4cd5ba0f 370+
c66cb070 371+ howto = howto_table + rel->r_type;
4cd5ba0f 372+
c66cb070 373+ if (howto->pc_relative)
374+ *addendp += sec->vma;
42dd3303 375+
c66cb070 376+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
f33182aa 377+ {
c66cb070 378+ /* This is a common symbol. The section contents include the
379+ size (sym->n_value) as an addend. The relocate_section
380+ function will be adding in the final value of the symbol. We
381+ need to subtract out the current size in order to get the
382+ correct result. */
4cd5ba0f 383+
c66cb070 384+ BFD_ASSERT (h != NULL);
4cd5ba0f 385+
c66cb070 386+ /* I think we *do* want to bypass this. If we don't, I have seen some data
387+ parameters get the wrong relcation address. If I link two versions
388+ with and without this section bypassed and then do a binary comparison,
389+ the addresses which are different can be looked up in the map. The
390+ case in which this section has been bypassed has addresses which correspond
391+ to values I can find in the map. */
392+ *addendp -= sym->n_value;
f33182aa 393+ }
4cd5ba0f 394+
c66cb070 395+ /* If the output symbol is common (in which case this must be a
396+ relocateable link), we need to add in the final size of the
397+ common symbol. */
398+ if (h != NULL && h->root.type == bfd_link_hash_common)
399+ *addendp += h->root.u.c.size;
4cd5ba0f 400+
c66cb070 401+ return howto;
402+}
4cd5ba0f 403+
c66cb070 404+#define coff_rtype_to_howto coff_avr_rtype_to_howto
4cd5ba0f 405+
c66cb070 406+#ifndef bfd_pe_print_pdata
407+#define bfd_pe_print_pdata NULL
408+#endif
4cd5ba0f 409+
c66cb070 410+#include "coffcode.h"
42dd3303 411+
c66cb070 412+static const bfd_target *
413+coff_avr_object_p(a)
414+ bfd *a;
42dd3303 415+{
c66cb070 416+ return coff_object_p (a);
417+}
42dd3303 418+
c66cb070 419+/* Handle all the abominations of AVR COFF:
42dd3303 420+
c66cb070 421+ Generic COFF always uses the D1 slot to indicate the "most
422+ important" derived type, and the D2...Dn slots for decreasing
423+ importance. E. g., a function symbol will always have its DT_FCN
424+ element in D1, an array its DT_ARY (its first DT_ARY in a
425+ multi-dimensional array). In contrast, AVR COFF expects this most
426+ important derived type specifier in the upmost Dn slot that is
427+ allocated at all (i. e. that is != 0).
42dd3303 428+
c66cb070 429+ Generic COFF says that "Any symbol that satisfies more than one
430+ condition [... for AUX entries] should have a union format in its
431+ auxiliary entry." AVR COFF uses sepearate AUX entries for multiple
432+ derived types, and in some cases (like the ISFCN one), even puts
433+ the most important one into the last allocated AUX entry. We
434+ join/split them here at the border as well. Note that when
435+ generating AUX entries (where we need to split them), the n_numaux
436+ field must already have been set up properly (e. g. in
437+ binutils/wrcoff.c) since the entry renumbering and pointerization
438+ would not work otherwise. Thus, we only split the information into
439+ multiple records if n_numaux > 1. For similar reasons, we keep
440+ n_numaux > 1 on input to keep the appropriate AUX entries
441+ allocated, so a symbol can be reconstructed if it is being passed
442+ through one of the GNU tools.
4cd5ba0f 443+
c66cb070 444+ Note that this adjustment is called after the symbol itself has
445+ been swapped in, but before the AUX entries are swapped in. This
446+ is the only hook available that could swap (or merge) AUX entries
447+ at all, so we have to operate on the external AUX entries still. */
4cd5ba0f 448+
c66cb070 449+void
450+avr_coff_adjust_sym_in_post (abfd, ext, in)
451+ bfd *abfd;
452+ PTR ext;
453+ PTR in;
42dd3303 454+{
c66cb070 455+ struct internal_syment *dst = (struct internal_syment *)in;
456+ unsigned short dt, bt, ndt;
457+ dt = dst->n_type & ~N_BTMASK;
458+ bt = BTYPE (dst->n_type);
4cd5ba0f 459+
c66cb070 460+ /* Some AVR COFF producers seem to violate the COFF specs, and
461+ produce symbols for tag names that have the C_FOO filled in
462+ properly, but T_NULL as the base type value. Patch up here,
463+ since some of our generic COFF tools (in particular
464+ binutils/rdcoff.c) rely on the correct data. */
465+ if (bt == T_NULL)
466+ switch (dst->n_sclass)
467+ {
468+ case C_STRTAG:
469+ bt = T_STRUCT;
470+ break;
4cd5ba0f 471+
c66cb070 472+ case C_UNTAG:
473+ bt = T_UNION;
474+ break;
4cd5ba0f 475+
c66cb070 476+ case C_ENTAG:
477+ bt = T_ENUM;
478+ break;
479+ }
4cd5ba0f 480+
c66cb070 481+ /* Swap the derived type slots. */
482+ if (dt != 0)
483+ {
484+ ndt = 0;
485+ while (dt != 0)
486+ {
487+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
488+ dt >>= N_TSHIFT;
489+ }
490+ dst->n_type = (ndt << N_BTSHFT) | bt;
491+ }
492+ else
493+ dst->n_type = bt;
4cd5ba0f 494+
c66cb070 495+ /* If the derived type is function, and there is more than one AUX
496+ entry, swap the first and the last AUX entry, so the most
497+ interesting one will become the first.
4cd5ba0f 498+
c66cb070 499+ If the fundamental type is a tagged type (struct/union/enum), try
500+ to find the AUX entry describing the tagged type (the one that
501+ has x_sym.x_tagndx filled in), and merge the tag index into the
502+ first AUX entry. Depending on the actual input file, there might
503+ be further DT_PTR entries which we just ignore, since we could
504+ not handle that information anyway. */
505+ if (dst->n_numaux > 1 && dst->n_sclass != C_FILE)
42dd3303 506+ {
c66cb070 507+ AUXENT caux, *auxp1, *auxp2;
508+ size_t symesz;
509+ unsigned int i;
4cd5ba0f 510+
c66cb070 511+ symesz = bfd_coff_symesz (abfd);
512+ i = dst->n_numaux;
42dd3303 513+
c66cb070 514+ auxp1 = (AUXENT *)((char *)ext + symesz);
515+ auxp2 = (AUXENT *)((char *)ext + i * symesz);
42dd3303 516+
c66cb070 517+ if (ISFCN (dst->n_type)
518+ || (ISPTR(dst->n_type)
519+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)))
42dd3303 520+ {
c66cb070 521+ caux = *auxp2;
522+ *auxp2 = *auxp1;
523+ *auxp1 = caux;
42dd3303 524+ }
c66cb070 525+ else
526+ caux = *auxp1;
527+
528+ if ((ISFCN (dst->n_type) || ISARY (dst->n_type))
529+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))
42dd3303 530+ {
c66cb070 531+ while (i > 1)
42dd3303 532+ {
c66cb070 533+ auxp2 = (AUXENT *)((char *)ext + i * symesz);
42dd3303 534+
c66cb070 535+ if (auxp2->x_sym.x_tagndx[0] != 0 || auxp2->x_sym.x_tagndx[1] != 0
536+ || auxp2->x_sym.x_tagndx[2] != 0 || auxp2->x_sym.x_tagndx[3] != 0)
42dd3303 537+ {
c66cb070 538+ memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx,
539+ 4 * sizeof (char));
540+ break;
42dd3303 541+ }
c66cb070 542+ i--;
42dd3303 543+ }
c66cb070 544+ if (i > 1)
545+ *auxp1 = caux;
42dd3303 546+ }
547+ }
f33182aa 548+}
4cd5ba0f 549+
c66cb070 550+/* When exporting an AVR COFF file, just undo all that has been done
551+ above. Again, we are called after the symbol itself has been
552+ swapped out, but before the AUX entries are being written.
553+ Unfortunately, we are only given a pointer to the symbol itself, so
554+ we have to derive the pointer to the respective aux entries from
555+ that address, which is a bit clumsy. */
556+void
557+avr_coff_adjust_sym_out_post (abfd, in, ext)
558+ bfd *abfd;
559+ PTR in;
560+ PTR ext;
42dd3303 561+{
c66cb070 562+ struct internal_syment *src = (struct internal_syment *)(in);
563+ struct external_syment *dst = (struct external_syment *)(ext);
564+ unsigned short dt, bt, ndt;
4cd5ba0f 565+
c66cb070 566+ dt = src->n_type & ~N_BTMASK;
567+ bt = BTYPE (src->n_type);
568+
569+ if (dt != 0)
42dd3303 570+ {
c66cb070 571+ ndt = 0;
572+ while (dt != 0)
42dd3303 573+ {
c66cb070 574+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT));
575+ dt >>= N_TSHIFT;
42dd3303 576+ }
c66cb070 577+ H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type);
42dd3303 578+ }
4cd5ba0f 579+
c66cb070 580+ if (src->n_numaux > 1 && src->n_sclass != C_FILE)
42dd3303 581+ {
c66cb070 582+ combined_entry_type *srce, *dste;
583+ char *hackp;
584+ unsigned int i;
42dd3303 585+
c66cb070 586+ /* Recover the original combinend_entry_type *. */
587+ hackp = (char *)in;
588+ hackp -= offsetof(combined_entry_type, u.syment);
589+ srce = (combined_entry_type *)hackp;
590+ srce++;
4cd5ba0f 591+
c66cb070 592+ /* We simply duplicate the first AUX entry as many times as
593+ needed. Since COFF itself normally uses just a single AUX
594+ entry for all the information, this will work -- each COFF
595+ consumer will then just pick the fields it is particularly
596+ interested in. This would not work for the AVR COFF specific
597+ DT_PTR AUX entries, but we don't support them anyway. */
598+ for (i = 1; i < src->n_numaux; i++)
42dd3303 599+ {
c66cb070 600+ dste = srce + i;
601+ *dste = *srce;
42dd3303 602+ }
42dd3303 603+ }
c66cb070 604+}
42dd3303 605+
c66cb070 606+const bfd_target
607+#ifdef TARGET_SYM
608+ TARGET_SYM =
609+#else
610+ avrcoff_vec =
611+#endif
612+{
613+#ifdef TARGET_NAME
614+ TARGET_NAME,
615+#else
616+ "coff-avr", /* name */
617+#endif
618+ bfd_target_coff_flavour,
619+ BFD_ENDIAN_LITTLE, /* data byte order is little */
620+ BFD_ENDIAN_LITTLE, /* header byte order is little */
42dd3303 621+
c66cb070 622+ (HAS_RELOC | EXEC_P | /* object flags */
623+ HAS_LINENO | HAS_DEBUG |
624+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
42dd3303 625+
c66cb070 626+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
627+ 0, /* leading char */
628+ '/', /* ar_pad_char */
629+ 15, /* ar_max_namelen */
42dd3303 630+
c66cb070 631+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
632+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
633+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
634+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
635+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
636+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
42dd3303 637+
c66cb070 638+/* Note that we allow an object file to be treated as a core file as well. */
639+ {_bfd_dummy_target, coff_avr_object_p, /* bfd_check_format */
640+ bfd_generic_archive_p, coff_avr_object_p},
641+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
642+ bfd_false},
643+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
644+ _bfd_write_archive_contents, bfd_false},
42dd3303 645+
c66cb070 646+ BFD_JUMP_TABLE_GENERIC (coff),
647+ BFD_JUMP_TABLE_COPY (coff),
648+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
649+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
650+ BFD_JUMP_TABLE_SYMBOLS (coff),
651+ BFD_JUMP_TABLE_RELOCS (coff),
652+ BFD_JUMP_TABLE_WRITE (coff),
653+ BFD_JUMP_TABLE_LINK (coff),
654+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
42dd3303 655+
c66cb070 656+ NULL,
4cd5ba0f 657+
c66cb070 658+ COFF_SWAP_TABLE
659+};
3ccd393f 660diff -ruwN bfd/coff-ext-avr.c bfd/coff-ext-avr.c
661--- bfd/coff-ext-avr.c 1970-01-01 05:30:00.000000000 +0530
662+++ bfd/coff-ext-avr.c 2010-03-11 12:13:23.131776800 +0530
c66cb070 663@@ -0,0 +1,428 @@
664+/* BFD back-end for Atmel AVR "extended" COFF files.
665+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003
666+ Free Software Foundation, Inc.
667+ This is mostly the same as avr-coff, except of the presence of the
668+ COFF optional header.
42dd3303 669+
c66cb070 670+This file is part of BFD, the Binary File Descriptor library.
42dd3303 671+
c66cb070 672+This program is free software; you can redistribute it and/or modify
673+it under the terms of the GNU General Public License as published by
674+the Free Software Foundation; either version 2 of the License, or
675+(at your option) any later version.
42dd3303 676+
c66cb070 677+This program is distributed in the hope that it will be useful,
678+but WITHOUT ANY WARRANTY; without even the implied warranty of
679+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
680+GNU General Public License for more details.
4cd5ba0f 681+
c66cb070 682+You should have received a copy of the GNU General Public License
683+along with this program; if not, write to the Free Software
684+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
42dd3303 685+
c66cb070 686+#include "bfd.h"
687+#include "sysdep.h"
688+#include "libbfd.h"
4cd5ba0f 689+
c66cb070 690+#define AVR_EXT_COFF 1
691+#include "coff/avr.h"
42dd3303 692+
c66cb070 693+#include "coff/internal.h"
42dd3303 694+
c66cb070 695+#include "libcoff.h"
42dd3303 696+
c66cb070 697+static bfd_reloc_status_type coff_ext_avr_reloc
698+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
699+static reloc_howto_type *coff_ext_avr_rtype_to_howto
700+ PARAMS ((bfd *, asection *, struct internal_reloc *,
701+ struct coff_link_hash_entry *, struct internal_syment *,
702+ bfd_vma *));
703+static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *));
42dd3303 704+
c66cb070 705+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
706+/* The page size is a guess based on ELF. */
4cd5ba0f 707+
c66cb070 708+#define COFF_PAGE_SIZE 0x1000
4cd5ba0f 709+
c66cb070 710+/* For some reason when using avr COFF the value stored in the .text
711+ section for a reference to a common symbol is the value itself plus
712+ any desired offset. Ian Taylor, Cygnus Support. */
4cd5ba0f 713+
c66cb070 714+/* If we are producing relocateable output, we need to do some
715+ adjustments to the object file that are not done by the
716+ bfd_perform_relocation function. This function is called by every
717+ reloc type to make any required adjustments. */
42dd3303 718+
c66cb070 719+static bfd_reloc_status_type
720+coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
721+ error_message)
722+ bfd *abfd;
723+ arelent *reloc_entry;
724+ asymbol *symbol;
725+ PTR data;
726+ asection *input_section ATTRIBUTE_UNUSED;
727+ bfd *output_bfd;
728+ char **error_message ATTRIBUTE_UNUSED;
f33182aa 729+{
c66cb070 730+ symvalue diff;
4cd5ba0f 731+
c66cb070 732+ if (output_bfd == (bfd *) NULL)
733+ return bfd_reloc_continue;
734+
735+ if (bfd_is_com_section (symbol->section))
4cd5ba0f 736+ {
c66cb070 737+ /* We are relocating a common symbol. The current value in the
738+ object file is ORIG + OFFSET, where ORIG is the value of the
739+ common symbol as seen by the object file when it was compiled
740+ (this may be zero if the symbol was undefined) and OFFSET is
741+ the offset into the common symbol (normally zero, but may be
742+ non-zero when referring to a field in a common structure).
743+ ORIG is the negative of reloc_entry->addend, which is set by
744+ the CALC_ADDEND macro below. We want to replace the value in
745+ the object file with NEW + OFFSET, where NEW is the value of
746+ the common symbol which we are going to put in the final
747+ object file. NEW is symbol->value. */
748+ diff = symbol->value + reloc_entry->addend;
749+ }
750+ else
751+ {
752+ /* For some reason bfd_perform_relocation always effectively
753+ ignores the addend for a COFF target when producing
754+ relocateable output. This seems to be always wrong for 860
755+ COFF, so we handle the addend here instead. */
756+ diff = reloc_entry->addend;
42dd3303 757+ }
4cd5ba0f 758+
c66cb070 759+#define DOIT(x) \
760+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
42dd3303 761+
c66cb070 762+ if (diff != 0)
763+ {
764+ reloc_howto_type *howto = reloc_entry->howto;
765+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
766+
767+ switch (howto->size)
768+ {
769+ case 0:
42dd3303 770+ {
c66cb070 771+ char x = bfd_get_8 (abfd, addr);
772+ DOIT (x);
773+ bfd_put_8 (abfd, x, addr);
42dd3303 774+ }
c66cb070 775+ break;
42dd3303 776+
c66cb070 777+ case 1:
778+ {
779+ short x = bfd_get_16 (abfd, addr);
780+ DOIT (x);
781+ bfd_put_16 (abfd, (bfd_vma) x, addr);
782+ }
783+ break;
4cd5ba0f 784+
c66cb070 785+ case 2:
786+ {
787+ long x = bfd_get_32 (abfd, addr);
788+ DOIT (x);
789+ bfd_put_32 (abfd, (bfd_vma) x, addr);
790+ }
791+ break;
42dd3303 792+
c66cb070 793+ default:
794+ abort ();
795+ }
796+ }
4cd5ba0f 797+
c66cb070 798+ /* Now let bfd_perform_relocation finish everything up. */
799+ return bfd_reloc_continue;
42dd3303 800+}
4cd5ba0f 801+
c66cb070 802+#ifndef PCRELOFFSET
803+#define PCRELOFFSET FALSE
804+#endif
805+
806+static reloc_howto_type howto_table[] =
42dd3303 807+{
c66cb070 808+ EMPTY_HOWTO (0),
809+ EMPTY_HOWTO (1),
810+ EMPTY_HOWTO (2),
811+ EMPTY_HOWTO (3),
812+ EMPTY_HOWTO (4),
813+ EMPTY_HOWTO (5),
814+ HOWTO (R_DIR32, /* type */
815+ 0, /* rightshift */
816+ 2, /* size (0 = byte, 1 = short, 2 = long) */
817+ 32, /* bitsize */
818+ FALSE, /* pc_relative */
819+ 0, /* bitpos */
820+ complain_overflow_bitfield, /* complain_on_overflow */
821+ coff_ext_avr_reloc, /* special_function */
822+ "dir32", /* name */
823+ TRUE, /* partial_inplace */
824+ 0xffffffff, /* src_mask */
825+ 0xffffffff, /* dst_mask */
826+ TRUE), /* pcrel_offset */
827+ /* {7}, */
828+ HOWTO (R_IMAGEBASE, /* type */
829+ 0, /* rightshift */
830+ 2, /* size (0 = byte, 1 = short, 2 = long) */
831+ 32, /* bitsize */
832+ FALSE, /* pc_relative */
833+ 0, /* bitpos */
834+ complain_overflow_bitfield, /* complain_on_overflow */
835+ coff_ext_avr_reloc, /* special_function */
836+ "rva32", /* name */
837+ TRUE, /* partial_inplace */
838+ 0xffffffff, /* src_mask */
839+ 0xffffffff, /* dst_mask */
840+ FALSE), /* pcrel_offset */
841+ EMPTY_HOWTO (010),
842+ EMPTY_HOWTO (011),
843+ EMPTY_HOWTO (012),
844+ EMPTY_HOWTO (013),
845+ EMPTY_HOWTO (014),
846+ EMPTY_HOWTO (015),
847+ EMPTY_HOWTO (016),
848+ HOWTO (R_RELBYTE, /* type */
849+ 0, /* rightshift */
850+ 0, /* size (0 = byte, 1 = short, 2 = long) */
851+ 8, /* bitsize */
852+ FALSE, /* pc_relative */
853+ 0, /* bitpos */
854+ complain_overflow_bitfield, /* complain_on_overflow */
855+ coff_ext_avr_reloc, /* special_function */
856+ "8", /* name */
857+ TRUE, /* partial_inplace */
858+ 0x000000ff, /* src_mask */
859+ 0x000000ff, /* dst_mask */
860+ PCRELOFFSET), /* pcrel_offset */
861+ HOWTO (R_RELWORD, /* type */
862+ 0, /* rightshift */
863+ 1, /* size (0 = byte, 1 = short, 2 = long) */
864+ 16, /* bitsize */
865+ FALSE, /* pc_relative */
866+ 0, /* bitpos */
867+ complain_overflow_bitfield, /* complain_on_overflow */
868+ coff_ext_avr_reloc, /* special_function */
869+ "16", /* name */
870+ TRUE, /* partial_inplace */
871+ 0x0000ffff, /* src_mask */
872+ 0x0000ffff, /* dst_mask */
873+ PCRELOFFSET), /* pcrel_offset */
874+ HOWTO (R_RELLONG, /* type */
875+ 0, /* rightshift */
876+ 2, /* size (0 = byte, 1 = short, 2 = long) */
877+ 32, /* bitsize */
878+ FALSE, /* pc_relative */
879+ 0, /* bitpos */
880+ complain_overflow_bitfield, /* complain_on_overflow */
881+ coff_ext_avr_reloc, /* special_function */
882+ "32", /* name */
883+ TRUE, /* partial_inplace */
884+ 0xffffffff, /* src_mask */
885+ 0xffffffff, /* dst_mask */
886+ PCRELOFFSET), /* pcrel_offset */
887+ HOWTO (R_PCRBYTE, /* type */
888+ 0, /* rightshift */
889+ 0, /* size (0 = byte, 1 = short, 2 = long) */
890+ 8, /* bitsize */
891+ TRUE, /* pc_relative */
892+ 0, /* bitpos */
893+ complain_overflow_signed, /* complain_on_overflow */
894+ coff_ext_avr_reloc, /* special_function */
895+ "DISP8", /* name */
896+ TRUE, /* partial_inplace */
897+ 0x000000ff, /* src_mask */
898+ 0x000000ff, /* dst_mask */
899+ PCRELOFFSET), /* pcrel_offset */
900+ HOWTO (R_PCRWORD, /* type */
901+ 0, /* rightshift */
902+ 1, /* size (0 = byte, 1 = short, 2 = long) */
903+ 16, /* bitsize */
904+ TRUE, /* pc_relative */
905+ 0, /* bitpos */
906+ complain_overflow_signed, /* complain_on_overflow */
907+ coff_ext_avr_reloc, /* special_function */
908+ "DISP16", /* name */
909+ TRUE, /* partial_inplace */
910+ 0x0000ffff, /* src_mask */
911+ 0x0000ffff, /* dst_mask */
912+ PCRELOFFSET), /* pcrel_offset */
913+ HOWTO (R_PCRLONG, /* type */
914+ 0, /* rightshift */
915+ 2, /* size (0 = byte, 1 = short, 2 = long) */
916+ 32, /* bitsize */
917+ TRUE, /* pc_relative */
918+ 0, /* bitpos */
919+ complain_overflow_signed, /* complain_on_overflow */
920+ coff_ext_avr_reloc, /* special_function */
921+ "DISP32", /* name */
922+ TRUE, /* partial_inplace */
923+ 0xffffffff, /* src_mask */
924+ 0xffffffff, /* dst_mask */
925+ PCRELOFFSET) /* pcrel_offset */
926+};
4cd5ba0f 927+
c66cb070 928+/* Turn a howto into a reloc nunmber */
4cd5ba0f 929+
c66cb070 930+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
931+#define BADMAG(x) AVRBADMAG(x)
932+#define AVR 1 /* Customize coffcode.h */
4cd5ba0f 933+
c66cb070 934+#define RTYPE2HOWTO(cache_ptr, dst) \
935+ (cache_ptr)->howto = howto_table + (dst)->r_type;
4cd5ba0f 936+
c66cb070 937+/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
938+ library. On some other COFF targets STYP_BSS is normally
939+ STYP_NOLOAD. */
940+#define BSS_NOLOAD_IS_SHARED_LIBRARY
4cd5ba0f 941+
c66cb070 942+/* Compute the addend of a reloc. If the reloc is to a common symbol,
943+ the object file contains the value of the common symbol. By the
944+ time this is called, the linker may be using a different symbol
945+ from a different object file with a different value. Therefore, we
946+ hack wildly to locate the original symbol from this file so that we
947+ can make the correct adjustment. This macro sets coffsym to the
948+ symbol from the original file, and uses it to set the addend value
949+ correctly. If this is not a common symbol, the usual addend
950+ calculation is done, except that an additional tweak is needed for
951+ PC relative relocs.
952+ FIXME: This macro refers to symbols and asect; these are from the
953+ calling function, not the macro arguments. */
4cd5ba0f 954+
c66cb070 955+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
956+ { \
957+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
958+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
959+ coffsym = (obj_symbols (abfd) \
960+ + (cache_ptr->sym_ptr_ptr - symbols)); \
961+ else if (ptr) \
962+ coffsym = coff_symbol_from (abfd, ptr); \
963+ if (coffsym != (coff_symbol_type *) NULL \
964+ && coffsym->native->u.syment.n_scnum == 0) \
965+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
966+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
967+ && ptr->section != (asection *) NULL) \
968+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
969+ else \
970+ cache_ptr->addend = 0; \
971+ if (ptr && howto_table[reloc.r_type].pc_relative) \
972+ cache_ptr->addend += asect->vma; \
973+ }
4cd5ba0f 974+
c66cb070 975+/* We use the special COFF backend linker. */
976+#define coff_relocate_section _bfd_coff_generic_relocate_section
4cd5ba0f 977+
c66cb070 978+static reloc_howto_type *
979+coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
980+ bfd *abfd ATTRIBUTE_UNUSED;
981+ asection *sec;
982+ struct internal_reloc *rel;
983+ struct coff_link_hash_entry *h;
984+ struct internal_syment *sym;
985+ bfd_vma *addendp;
986+{
4cd5ba0f 987+
c66cb070 988+ reloc_howto_type *howto;
4cd5ba0f 989+
c66cb070 990+ howto = howto_table + rel->r_type;
4cd5ba0f 991+
c66cb070 992+ if (howto->pc_relative)
993+ *addendp += sec->vma;
4cd5ba0f 994+
c66cb070 995+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
996+ {
997+ /* This is a common symbol. The section contents include the
998+ size (sym->n_value) as an addend. The relocate_section
999+ function will be adding in the final value of the symbol. We
1000+ need to subtract out the current size in order to get the
1001+ correct result. */
4cd5ba0f 1002+
c66cb070 1003+ BFD_ASSERT (h != NULL);
4cd5ba0f 1004+
c66cb070 1005+ /* I think we *do* want to bypass this. If we don't, I have seen some data
1006+ parameters get the wrong relcation address. If I link two versions
1007+ with and without this section bypassed and then do a binary comparison,
1008+ the addresses which are different can be looked up in the map. The
1009+ case in which this section has been bypassed has addresses which correspond
1010+ to values I can find in the map. */
1011+ *addendp -= sym->n_value;
1012+ }
4cd5ba0f 1013+
c66cb070 1014+ /* If the output symbol is common (in which case this must be a
1015+ relocateable link), we need to add in the final size of the
1016+ common symbol. */
1017+ if (h != NULL && h->root.type == bfd_link_hash_common)
1018+ *addendp += h->root.u.c.size;
4cd5ba0f 1019+
c66cb070 1020+ return howto;
1021+}
42dd3303 1022+
c66cb070 1023+#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto
42dd3303 1024+
c66cb070 1025+#ifndef bfd_pe_print_pdata
1026+#define bfd_pe_print_pdata NULL
1027+#endif
42dd3303 1028+
c66cb070 1029+#include "coffcode.h"
4cd5ba0f 1030+
c66cb070 1031+static const bfd_target *
1032+coff_ext_avr_object_p(a)
1033+ bfd *a;
1034+{
1035+ return coff_object_p (a);
1036+}
4cd5ba0f 1037+
c66cb070 1038+const bfd_target
1039+#ifdef TARGET_SYM
1040+ TARGET_SYM =
1041+#else
1042+ avrextcoff_vec =
1043+#endif
1044+{
1045+#ifdef TARGET_NAME
1046+ TARGET_NAME,
1047+#else
1048+ "coff-ext-avr", /* name */
1049+#endif
1050+ bfd_target_coff_flavour,
1051+ BFD_ENDIAN_LITTLE, /* data byte order is little */
1052+ BFD_ENDIAN_LITTLE, /* header byte order is little */
4cd5ba0f 1053+
c66cb070 1054+ (HAS_RELOC | EXEC_P | /* object flags */
1055+ HAS_LINENO | HAS_DEBUG |
1056+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
4cd5ba0f 1057+
c66cb070 1058+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1059+ 0, /* leading char */
1060+ '/', /* ar_pad_char */
1061+ 15, /* ar_max_namelen */
4cd5ba0f 1062+
c66cb070 1063+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1064+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1065+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1066+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1067+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1068+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
4cd5ba0f 1069+
c66cb070 1070+/* Note that we allow an object file to be treated as a core file as well. */
1071+ {_bfd_dummy_target, coff_ext_avr_object_p, /* bfd_check_format */
1072+ bfd_generic_archive_p, coff_ext_avr_object_p},
1073+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
1074+ bfd_false},
1075+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
1076+ _bfd_write_archive_contents, bfd_false},
4cd5ba0f 1077+
c66cb070 1078+ BFD_JUMP_TABLE_GENERIC (coff),
1079+ BFD_JUMP_TABLE_COPY (coff),
1080+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
1081+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1082+ BFD_JUMP_TABLE_SYMBOLS (coff),
1083+ BFD_JUMP_TABLE_RELOCS (coff),
1084+ BFD_JUMP_TABLE_WRITE (coff),
1085+ BFD_JUMP_TABLE_LINK (coff),
1086+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
4cd5ba0f 1087+
c66cb070 1088+ NULL,
4cd5ba0f 1089+
c66cb070 1090+ COFF_SWAP_TABLE
1091+};
3ccd393f 1092diff -ruwN bfd/coffcode.h bfd/coffcode.h
1093--- bfd/coffcode.h 2009-09-10 17:17:12.000000000 +0530
1094+++ bfd/coffcode.h 2010-03-11 12:13:23.147400100 +0530
c66cb070 1095@@ -1,3 +1,4 @@
4cd5ba0f 1096+
c66cb070 1097 /* Support for the generic parts of most COFF variants, for BFD.
1098 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3ccd393f 1099 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
1100@@ -1910,6 +1911,17 @@
c66cb070 1101 coff->relocbase = 0;
1102 coff->local_toc_sym_map = 0;
1103
1104+ /* These members communicate important constants about the symbol
1105+ table to GDB's symbol-reading code. These `constants'
1106+ unfortunately vary among coff implementations... */
1107+ coff->local_n_btmask = N_BTMASK;
1108+ coff->local_n_btshft = N_BTSHFT;
1109+ coff->local_n_tmask = N_TMASK;
1110+ coff->local_n_tshift = N_TSHIFT;
1111+ coff->local_symesz = bfd_coff_symesz (abfd);
1112+ coff->local_auxesz = bfd_coff_auxesz (abfd);
1113+ coff->local_linesz = bfd_coff_linesz (abfd);
4cd5ba0f 1114+
c66cb070 1115 /* make_abs_section(abfd);*/
1116
1117 return TRUE;
3ccd393f 1118@@ -1934,17 +1946,6 @@
c66cb070 1119
1120 coff->sym_filepos = internal_f->f_symptr;
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);
1132-
1133 coff->timestamp = internal_f->f_timdat;
1134
1135 obj_raw_syment_count (abfd) =
3ccd393f 1136@@ -2076,6 +2077,11 @@
c66cb070 1137 }
1138 break;
1139 #endif
1140+#ifdef AVRMAGIC
1141+ case AVRMAGIC:
1142+ arch = bfd_arch_avr;
1143+ break;
1144+#endif
1145 #ifdef MC68MAGIC
1146 case MC68MAGIC:
1147 case M68MAGIC:
3ccd393f 1148@@ -2871,6 +2877,13 @@
c66cb070 1149 return TRUE;
1150 #endif
1151
1152+#ifdef AVRMAGIC
1153+ case bfd_arch_avr:
1154+ *magicp = AVRMAGIC;
1155+ return TRUE;
1156+ break;
1157+#endif
4cd5ba0f 1158+
c66cb070 1159 #ifdef PPCMAGIC
1160 case bfd_arch_powerpc:
1161 *magicp = PPCMAGIC;
3ccd393f 1162@@ -3698,6 +3711,11 @@
c66cb070 1163 section.s_page = 0;
1164 #endif
1165
1166+#ifdef AVR
1167+ /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively
1168+ ignores s_vaddr. */
1169+ section.s_paddr = current->vma;
1170+#endif
1171 #ifdef COFF_WITH_PE
1172 section.s_paddr = 0;
1173 #endif
3ccd393f 1174@@ -4042,6 +4060,17 @@
c66cb070 1175 internal_a.magic = ZMAGIC;
1176 #endif
1177
1178+#ifdef AVR
1179+ /* a.out is a dummy for non-extended COFF */
1180+ internal_a.magic = AVRAOUTMAGIC;
1181+ /* Upper nibble of f_flags must be set for historical reasons.
1182+ The upper byte remains blank on coff-avr, so undo the F_AR32WR
1183+ setting performed above. */
1184+ internal_f.f_flags |= F_JUNK;
1185+ internal_f.f_flags &= ~F_UNUSED;
1186+#define __A_MAGIC_SET__
1187+#endif /* AVR */
4cd5ba0f 1188+
c66cb070 1189 #if defined(PPC_PE)
1190 #define __A_MAGIC_SET__
1191 internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
3ccd393f 1192@@ -4109,8 +4138,16 @@
c66cb070 1193 #endif
1194 }
1195
1196+#ifdef AVR_EXT_COFF
1197+ /* Note that we do not set F_PTRINFO because the GNU toolchain
1198+ doesn't provide any information about the target of a pointer,
1199+ so we cannot derive which section our pointer target would be
1200+ in. */
1201+ internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO;
1202+#else
1203 /* FIXME: Does anybody ever set this to another value? */
1204 internal_a.vstamp = 0;
1205+#endif
1206
1207 /* Now should write relocs, strings, syms. */
1208 obj_sym_filepos (abfd) = sym_base;
3ccd393f 1209@@ -4668,6 +4705,10 @@
c66cb070 1210 /* In PE, 0x69 (105) denotes a weak external symbol. */
1211 case C_NT_WEAK:
1212 #endif
1213+#ifdef AVR
1214+ /* Some AVR COFF compilers handle EXTDEF like EXT. */
1215+ case C_EXTDEF: /* external definition */
1216+#endif
1217 switch (coff_classify_symbol (abfd, &src->u.syment))
1218 {
1219 case COFF_SYMBOL_GLOBAL:
3ccd393f 1220@@ -4891,7 +4932,9 @@
c66cb070 1221 && src->u.syment.n_scnum == 0)
1222 break;
1223 /* Fall through. */
1224+#if !defined(AVR)
1225 case C_EXTDEF: /* External definition. */
1226+#endif
1227 case C_ULABEL: /* Undefined label. */
1228 case C_USTATIC: /* Undefined static. */
1229 #ifndef COFF_WITH_PE
3ccd393f 1230diff -ruwN bfd/coffgen.c bfd/coffgen.c
1231--- bfd/coffgen.c 2009-09-10 17:17:12.000000000 +0530
1232+++ bfd/coffgen.c 2010-03-11 12:13:23.163023400 +0530
c66cb070 1233@@ -699,6 +699,20 @@
1234 if (last_file != NULL)
1235 last_file->n_value = native_index;
1236 last_file = &(s->u.syment);
1237+ if (bfd_get_arch (bfd_ptr) == bfd_arch_avr
1238+ && bfd_coff_long_filenames (bfd_ptr)
1239+ && s->u.syment.n_numaux > 0)
1240+ {
1241+ /* AVR COFF records long filenames in successive aux
1242+ records. Adjust the number of aux records
1243+ required here, so the renumbering will account
1244+ for them. */
1245+ unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr);
1246+ unsigned int namelen = strlen (coff_symbol_ptr->symbol.name);
1247+ unsigned int n = (namelen + filnmlen - 1) / filnmlen;
42dd3303 1248+
c66cb070 1249+ s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n;
1250+ }
1251 }
1252 else
1253 /* Modify the symbol values according to their section and
1254@@ -827,6 +841,20 @@
1255 {
1256 if (name_length <= filnmlen)
1257 strncpy (auxent->x_file.x_fname, name, filnmlen);
1258+ else if (bfd_get_arch (abfd) == bfd_arch_avr)
1259+ {
1260+ /* AVR COFF records long filenames in successive aux records. */
1261+ int i = 1;
1262+ while (name_length > filnmlen && i < NAUXENTS)
1263+ {
1264+ strncpy (auxent->x_file.x_fname, name, filnmlen);
1265+ name += filnmlen;
1266+ name_length -= filnmlen;
1267+ i++;
1268+ auxent = &(native + i)->u.auxent;
1269+ }
1270+ strncpy (auxent->x_file.x_fname, name, filnmlen);
1271+ }
1272 else
1273 {
1274 auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
1275@@ -1272,6 +1300,10 @@
1276 if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
1277 return FALSE;
1278 }
1279+ if (bfd_get_arch (abfd) == bfd_arch_avr)
1280+ /* AVR COFF handles long file names in aux records. */
1281+ maxlen = name_length;
1282+ else
1283 maxlen = bfd_coff_filnmlen (abfd);
1284 }
1285 else
1286@@ -1710,14 +1742,27 @@
1287 {
1288 /* Ordinary short filename, put into memory anyway. The
1289 Microsoft PE tools sometimes store a filename in
1290- multiple AUX entries. */
1291+ multiple AUX entries.
1292+ AVR COFF does it that way, too. */
1293 if (internal_ptr->u.syment.n_numaux > 1
1294- && coff_data (abfd)->pe)
1295- internal_ptr->u.syment._n._n_n._n_offset =
1296- ((bfd_hostptr_t)
1297- copy_name (abfd,
1298- (internal_ptr + 1)->u.auxent.x_file.x_fname,
1299- internal_ptr->u.syment.n_numaux * symesz));
1300+ && (coff_data (abfd)->pe
1301+ || (bfd_get_arch (abfd) == bfd_arch_avr)))
1302+ {
1303+ char *b;
1304+ unsigned int i;
42dd3303 1305+
c66cb070 1306+ /* We allocate enough storage to fit the contents of
1307+ this many aux records, and simply append a \0.
1308+ This ensures the string will always be
1309+ terminated, even in the case where it just fit
1310+ into the aux records. */
1311+ b = (char *) bfd_alloc (abfd,
1312+ internal_ptr->u.syment.n_numaux * FILNMLEN + 1);
1313+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) b;
1314+ b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0';
1315+ for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN)
1316+ memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN);
1317+ }
1318 else
1319 internal_ptr->u.syment._n._n_n._n_offset =
1320 ((bfd_hostptr_t)
1321@@ -1823,9 +1868,9 @@
1322
1323 if (new_symbol == NULL)
1324 return NULL;
1325- /* @@ The 10 is a guess at a plausible maximum number of aux entries
1326+ /* @@ The NAUXENTS is a guess at a plausible maximum number of aux entries
1327 (but shouldn't be a constant). */
1328- amt = sizeof (combined_entry_type) * 10;
1329+ amt = sizeof (combined_entry_type) * (NAUXENTS + 1);
1330 new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
1331 if (!new_symbol->native)
1332 return NULL;
3ccd393f 1333diff -ruwN bfd/coffswap.h bfd/coffswap.h
1334--- bfd/coffswap.h 2009-09-07 13:45:15.000000000 +0530
1335+++ bfd/coffswap.h 2010-03-11 12:13:23.178646700 +0530
c66cb070 1336@@ -383,7 +383,11 @@
1337 void * ext1,
1338 int type,
1339 int in_class,
1340- int indx,
1341+ int indx
1342+#if defined(AVR) && __GNUC__
1343+ __attribute__((unused))
1344+#endif
1345+ ,
1346 int numaux,
1347 void * in1)
1348 {
1349@@ -409,9 +413,13 @@
1350 #else
1351 if (numaux > 1)
1352 {
1353+#if defined(AVR)
1354+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT));
1355+#else
1356 if (indx == 0)
1357 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
1358 numaux * sizeof (AUXENT));
1359+#endif
1360 }
1361 else
1362 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
3ccd393f 1363diff -ruwN bfd/config.bfd bfd/config.bfd
1364--- bfd/config.bfd 2009-08-06 23:08:00.000000000 +0530
1365+++ bfd/config.bfd 2010-03-11 12:13:23.178646700 +0530
1366@@ -339,6 +339,7 @@
c66cb070 1367
1368 avr-*-*)
1369 targ_defvec=bfd_elf32_avr_vec
1370+ targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec"
1371 ;;
1372
1373 bfin-*-*)
3ccd393f 1374diff -ruwN bfd/configure bfd/configure
1375--- bfd/configure 2009-10-16 17:17:47.000000000 +0530
1376+++ bfd/configure 2010-03-11 12:13:23.209893300 +0530
1377@@ -14782,6 +14782,8 @@
c66cb070 1378 armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
1379 armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1380 armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1381+ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;;
1382+ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;;
1383 b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
1384 b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
1385 bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
3ccd393f 1386diff -ruwN bfd/configure.in bfd/configure.in
1387--- bfd/configure.in 2009-10-16 17:17:44.000000000 +0530
1388+++ bfd/configure.in 2010-03-11 12:13:23.209893300 +0530
c66cb070 1389@@ -670,6 +670,8 @@
1390 armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
1391 armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1392 armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
1393+ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;;
1394+ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;;
1395 b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
1396 b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
1397 bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
3ccd393f 1398diff -ruwN bfd/targets.c bfd/targets.c
1399--- bfd/targets.c 2009-09-10 17:17:13.000000000 +0530
1400+++ bfd/targets.c 2010-03-11 12:13:23.225516600 +0530
1401@@ -564,6 +564,8 @@
c66cb070 1402 extern const bfd_target armpe_little_vec;
1403 extern const bfd_target armpei_big_vec;
1404 extern const bfd_target armpei_little_vec;
1405+extern const bfd_target avrcoff_vec;
1406+extern const bfd_target avrextcoff_vec;
1407 extern const bfd_target b_out_vec_big_host;
1408 extern const bfd_target b_out_vec_little_host;
1409 extern const bfd_target bfd_pei_ia64_vec;
3ccd393f 1410@@ -890,6 +892,8 @@
c66cb070 1411 &armpe_little_vec,
1412 &armpei_big_vec,
1413 &armpei_little_vec,
1414+ &avrcoff_vec,
1415+ &avrextcoff_vec,
1416 &b_out_vec_big_host,
1417 &b_out_vec_little_host,
1418 #ifdef BFD64
3ccd393f 1419diff -ruwN binutils/Makefile.am binutils/Makefile.am
1420--- binutils/Makefile.am 2009-09-09 13:43:23.000000000 +0530
1421+++ binutils/Makefile.am 2010-03-11 12:13:23.241139900 +0530
1422@@ -101,7 +101,7 @@
c66cb070 1423 resbin.c rescoff.c resrc.c resres.c \
1424 size.c srconv.c stabs.c strings.c sysdump.c \
3ccd393f 1425 unwind-ia64.c version.c \
c66cb070 1426- windres.c winduni.c wrstabs.c \
1427+ windres.c winduni.c wrcoff.c wrstabs.c \
1428 windmc.c mclex.c
1429
1430 GENERATED_CFILES = \
3ccd393f 1431@@ -109,7 +109,7 @@
c66cb070 1432 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1433
1434 DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
1435-WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
1436+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c
1437
1438 # Code shared by all the binutils.
1439 BULIBS = bucomm.c version.c filemode.c
3ccd393f 1440diff -ruwN binutils/Makefile.in binutils/Makefile.in
1441--- binutils/Makefile.in 2009-09-09 13:43:23.000000000 +0530
1442+++ binutils/Makefile.in 2010-03-11 12:13:23.241139900 +0530
1443@@ -126,7 +126,7 @@
c66cb070 1444 nm_new_OBJECTS = $(am_nm_new_OBJECTS)
1445 nm_new_LDADD = $(LDADD)
1446 am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \
1447- ieee.$(OBJEXT) rdcoff.$(OBJEXT)
1448+ ieee.$(OBJEXT) rdcoff.$(OBJEXT) wrcoff.$(OBJEXT)
1449 am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT)
1450 am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \
1451 rename.$(OBJEXT) $(am__objects_3) $(am__objects_1)
3ccd393f 1452@@ -439,7 +439,7 @@
c66cb070 1453 resbin.c rescoff.c resrc.c resres.c \
1454 size.c srconv.c stabs.c strings.c sysdump.c \
3ccd393f 1455 unwind-ia64.c version.c \
c66cb070 1456- windres.c winduni.c wrstabs.c \
1457+ windres.c winduni.c wrcoff.c wrstabs.c \
1458 windmc.c mclex.c
1459
1460 GENERATED_CFILES = \
3ccd393f 1461@@ -447,7 +447,7 @@
c66cb070 1462 defparse.c deflex.c nlmheader.c rcparse.c mcparse.c
1463
1464 DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
1465-WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
1466+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c
1467
1468 # Code shared by all the binutils.
1469 BULIBS = bucomm.c version.c filemode.c
3ccd393f 1470diff -ruwN binutils/bucomm.c binutils/bucomm.c
1471--- binutils/bucomm.c 2009-09-14 17:13:26.000000000 +0530
1472+++ binutils/bucomm.c 2010-03-11 12:13:23.256763200 +0530
1473@@ -550,6 +550,32 @@
c66cb070 1474 return ret;
1475 }
1476
1477+/* Return the basename of "file", i. e. everything minus whatever
1478+ directory part has been provided. Stolen from bfd/archive.c.
1479+ Should we also handle the VMS case (as in bfd/archive.c)? */
1480+const char *
1481+bu_basename (file)
1482+ const char *file;
4cd5ba0f 1483+{
c66cb070 1484+ const char *filename = strrchr (file, '/');
42dd3303 1485+
c66cb070 1486+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
1487+ {
1488+ /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
1489+ char *bslash = strrchr (file, '\\');
1490+ if (filename == NULL || (bslash != NULL && bslash > filename))
1491+ filename = bslash;
1492+ if (filename == NULL && file[0] != '\0' && file[1] == ':')
1493+ filename = file + 1;
1494+ }
1495+#endif
1496+ if (filename != (char *) NULL)
1497+ filename++;
42dd3303 1498+ else
c66cb070 1499+ filename = file;
1500+ return filename;
1501+}
42dd3303 1502+
c66cb070 1503 /* Returns the size of the named file. If the file does not
1504 exist, or if it is not a real file, then a suitable non-fatal
3ccd393f 1505 error message is printed and zero is returned. */
1506diff -ruwN binutils/bucomm.h binutils/bucomm.h
1507--- binutils/bucomm.h 2009-09-02 12:52:31.000000000 +0530
1508+++ binutils/bucomm.h 2010-03-11 12:13:23.272386500 +0530
c66cb070 1509@@ -58,6 +58,8 @@
1510
1511 off_t get_file_size (const char *);
1512
1513+const char *bu_basename PARAMS ((const char *));
42dd3303 1514+
c66cb070 1515 extern char *program_name;
1516
1517 /* filemode.c */
3ccd393f 1518diff -ruwN binutils/budbg.h binutils/budbg.h
1519--- binutils/budbg.h 2009-09-02 12:52:31.000000000 +0530
1520+++ binutils/budbg.h 2010-03-11 12:13:23.272386500 +0530
c66cb070 1521@@ -52,8 +52,11 @@
1522
1523 extern bfd_boolean write_ieee_debugging_info (bfd *, void *);
1524
1525-/* Routine used to read COFF debugging information. */
1526+/* Routine used to read and write COFF debugging information. */
1527
1528 extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *);
1529
1530+extern bfd_boolean write_coff_debugging_info
1531+ (bfd *abfd, void *, long *symcountp, asymbol ***);
1532+
1533 #endif
3ccd393f 1534diff -ruwN binutils/debug.c binutils/debug.c
1535--- binutils/debug.c 2009-09-14 17:13:26.000000000 +0530
1536+++ binutils/debug.c 2010-03-11 12:13:23.288009800 +0530
c66cb070 1537@@ -31,6 +31,7 @@
1538 #include <assert.h>
1539 #include "bfd.h"
1540 #include "libiberty.h"
1541+#include "bucomm.h"
1542 #include "debug.h"
1543
1544 /* Global information we keep for debugging. A pointer to this
1545@@ -552,6 +553,19 @@
1546 struct debug_type_s *t;
1547 };
1548
1549+/* Simple list, used for pathname translations. */
1550+struct xlat_list
1551+{
1552+ /* Next string on list. */
1553+ struct xlat_list *next;
1554+ /* Old part to match against. */
1555+ const char *old;
1556+ size_t olen;
1557+ /* New part to replace. */
1558+ const char *newstr;
1559+ size_t nlen;
1560+};
42dd3303 1561+
c66cb070 1562 /* Local functions. */
1563
1564 static void debug_error (const char *);
1565@@ -588,6 +602,11 @@
1566 (struct debug_handle *, struct debug_type_s *, struct debug_type_s *);
1567 static bfd_boolean debug_class_type_samep
1568 (struct debug_handle *, struct debug_type_s *, struct debug_type_s *);
1569+static const char *debug_xlat_pathname (const char *);
42dd3303 1570+
c66cb070 1571+/* List of pathname translations. */
1572+static struct xlat_list *xlat, *xltail;
1573+static bfd_boolean xlat_basename;
1574 \f
1575 /* Issue an error message. */
1576
1577@@ -680,6 +699,8 @@
1578
1579 if (name == NULL)
1580 name = "";
1581+ else
1582+ name = debug_xlat_pathname (name);
1583
1584 nfile = (struct debug_file *) xmalloc (sizeof *nfile);
1585 memset (nfile, 0, sizeof *nfile);
1586@@ -720,6 +741,8 @@
1587
1588 if (name == NULL)
1589 name = "";
1590+ else
1591+ name = debug_xlat_pathname (name);
1592
1593 if (info->current_unit == NULL)
1594 {
1595@@ -3370,3 +3393,69 @@
1596
1597 return TRUE;
1598 }
4cd5ba0f 1599+
c66cb070 1600+/* Register a pathname translation. */
1601+void
1602+debug_register_pathname_xlat (oname, nname)
1603+ const char *oname;
1604+ const char *nname;
1605+{
1606+ struct xlat_list *xlp;
42dd3303 1607+
c66cb070 1608+ /* Special case: if oname is given as NULL, this means the
1609+ --basename option has been given to objcopy. */
1610+ if (oname == NULL)
f33182aa 1611+ {
c66cb070 1612+ xlat_basename = TRUE;
1613+ return;
42dd3303 1614+ }
4cd5ba0f 1615+
c66cb070 1616+ xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list));
1617+ xlp->next = NULL;
1618+ if (xlat == NULL)
1619+ xlat = xltail = xlp;
1620+ else
42dd3303 1621+ {
c66cb070 1622+ xltail->next = xlp;
1623+ xltail = xlp;
1624+ }
1625+ xlp->old = oname;
1626+ xlp->newstr = nname;
1627+ xlp->olen = strlen (oname);
1628+ xlp->nlen = strlen (nname);
1629+}
4cd5ba0f 1630+
c66cb070 1631+/* Try to translate a pathname. */
1632+static const char *
1633+debug_xlat_pathname (oname)
1634+ const char *oname;
1635+{
1636+ struct xlat_list *xlp;
1637+ char *cp;
1638+ size_t olen;
4cd5ba0f 1639+
c66cb070 1640+ if (xlat_basename)
1641+ return bu_basename (oname);
1642+
1643+ olen = strlen (oname);
1644+ for (xlp = xlat; xlp; xlp = xlp->next)
1645+ {
1646+ if (xlp->olen > olen)
1647+ /* This cannot be our turn. */
1648+ continue;
1649+ /* Since we have pre-computed all our length values to avoid
1650+ repetitively computing them, just use memcmp() since it's
1651+ faster than strcmp(). */
1652+ if (memcmp (xlp->old, oname, xlp->olen) == 0)
f33182aa 1653+ {
c66cb070 1654+ cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1);
1655+ memcpy (cp, xlp->newstr, xlp->nlen);
1656+ memcpy (cp + xlp->nlen, oname + xlp->olen,
1657+ olen - xlp->olen + 1);
1658+ return cp;
f33182aa 1659+ }
42dd3303 1660+ }
4cd5ba0f 1661+
c66cb070 1662+ /* Not found, pass the original name on. */
1663+ return oname;
1664+}
3ccd393f 1665diff -ruwN binutils/debug.h binutils/debug.h
1666--- binutils/debug.h 2009-09-14 17:13:26.000000000 +0530
1667+++ binutils/debug.h 2010-03-11 12:13:23.288009800 +0530
1668@@ -440,6 +440,12 @@
c66cb070 1669
1670 extern bfd_boolean debug_start_source (void *, const char *);
1671
1672+/* Register a pathname translation for source (and include) filenames.
1673+ This is used by the --change-pathname option of objcopy. */
4cd5ba0f 1674+
c66cb070 1675+extern void debug_register_pathname_xlat
1676+ PARAMS ((const char *, const char *));
4cd5ba0f 1677+
c66cb070 1678 /* Record a function definition. This implicitly starts a function
1679 block. The debug_type argument is the type of the return value.
1680 The bfd_boolean indicates whether the function is globally visible.
3ccd393f 1681diff -ruwN binutils/doc/objcopy.1 binutils/doc/objcopy.1
1682--- binutils/doc/objcopy.1 2009-10-16 17:22:19.000000000 +0530
1683+++ binutils/doc/objcopy.1 2010-03-11 12:13:23.303633100 +0530
1684@@ -202,6 +202,8 @@
c66cb070 1685 [\fB\-\-readonly\-text\fR]
1686 [\fB\-\-pure\fR]
1687 [\fB\-\-impure\fR]
1688+ [\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR]
1689+ [\fB\-\-basename\fR]
1690 [\fB\-\-file\-alignment=\fR\fInum\fR]
1691 [\fB\-\-heap=\fR\fIsize\fR]
1692 [\fB\-\-image\-base=\fR\fIaddress\fR]
3ccd393f 1693@@ -885,6 +887,23 @@
c66cb070 1694 It can also be a useful way of reducing the size of a \fB\-\-just\-symbols\fR
1695 linker input file.
1696 .RE
1697+.IP "\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR" 4
1698+.IX Item "--change-pathname old=new"
1699+When converting debugging information using \fB\-\-debugging\fR, for
1700+every pathname that starts with \fIold\fR, replace the matching part
1701+by \fInew\fR. This is intented to map pathnames between different
1702+debugging tools, or when parts of the object file(s) had their
1703+pathnames recorded in a different build environment. Note that only
1704+leading directory name components might be changed that way, since the
1705+trailing filename could be recorded elsewhere as well (depending on the
1706+debugging format of the input file).
1707+.IP "\fB\-\-basename\fR"
1708+.IX Item "--basename"
1709+When converting debugging information using \fB\-\-debugging\fR, for
1710+every pathname, strip all leading directory information. This option
1711+takes precedence over any \fB\-\-change\-pathname\fR option. For some
1712+debugging formats that cannot handle long filenames, this options is
1713+implied (notably, some COFF debugging formats).
3ccd393f 1714 .IP "\fB\-V\fR" 4
1715 .IX Item "-V"
1716 .PD 0
1717diff -ruwN binutils/objcopy.c binutils/objcopy.c
1718--- binutils/objcopy.c 2009-09-14 17:13:26.000000000 +0530
1719+++ binutils/objcopy.c 2010-03-11 12:13:23.319256400 +0530
c66cb070 1720@@ -32,6 +32,7 @@
1721 #include "elf-bfd.h"
1722 #include <sys/stat.h>
1723 #include "libbfd.h"
1724+#include "debug.h"
1725 #include "coff/internal.h"
1726 #include "libcoff.h"
1727
3ccd393f 1728@@ -297,6 +298,8 @@
c66cb070 1729 OPTION_IMPURE,
1730 OPTION_EXTRACT_SYMBOL,
1731 OPTION_REVERSE_BYTES,
1732+ OPTION_CHANGE_PATHNAME,
1733+ OPTION_BASENAME,
1734 OPTION_FILE_ALIGNMENT,
1735 OPTION_HEAP,
1736 OPTION_IMAGE_BASE,
3ccd393f 1737@@ -346,10 +349,12 @@
c66cb070 1738 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
1739 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
1740 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
1741+ {"basename", no_argument, 0, OPTION_BASENAME},
1742 {"binary-architecture", required_argument, 0, 'B'},
1743 {"byte", required_argument, 0, 'b'},
1744 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
1745 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
1746+ {"change-pathname", required_argument, 0, OPTION_CHANGE_PATHNAME},
1747 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
1748 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
1749 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
3ccd393f 1750@@ -543,6 +548,8 @@
c66cb070 1751 --prefix-alloc-sections <prefix>\n\
1752 Add <prefix> to start of every allocatable\n\
1753 section name\n\
1754+ --change-pathname <old>=<new> Change debug pathnames from <old> to <new>\n\
1755+ --basename Strip directory part from debug pathnames\n\
1756 --file-alignment <num> Set PE file alignment to <num>\n\
1757 --heap <reserve>[,<commit>] Set PE reserve/commit heap to <reserve>/\n\
1758 <commit>\n\
3ccd393f 1759@@ -999,6 +1006,8 @@
c66cb070 1760 asymbol **from = isyms, **to = osyms;
1761 long src_count = 0, dst_count = 0;
1762 int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
1763+ bfd_boolean need_for_debugging = convert_debugging
1764+ && bfd_get_arch (abfd) == bfd_arch_avr;
1765
1766 for (; src_count < symcount; src_count++)
1767 {
3ccd393f 1768@@ -1099,7 +1108,8 @@
c66cb070 1769 || bfd_is_com_section (bfd_get_section (sym)))
1770 keep = strip_symbols != STRIP_UNNEEDED;
1771 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
1772- keep = (strip_symbols != STRIP_DEBUG
1773+ keep = need_for_debugging
1774+ || (strip_symbols != STRIP_DEBUG
1775 && strip_symbols != STRIP_UNNEEDED
1776 && ! convert_debugging);
1777 else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
3ccd393f 1778@@ -2817,6 +2827,10 @@
c66cb070 1779 return write_ieee_debugging_info (obfd, dhandle);
1780
1781 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1782+ && bfd_get_arch (obfd) == bfd_arch_avr)
1783+ return write_coff_debugging_info (obfd, dhandle, symcountp, symppp);
1784+
1785+ if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1786 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1787 {
1788 bfd_byte *syms, *strings;
3ccd393f 1789@@ -3641,6 +3655,30 @@
c66cb070 1790 prefix_alloc_sections_string = optarg;
1791 break;
1792
1793+ case OPTION_CHANGE_PATHNAME:
1794+ {
1795+ const char *s;
1796+ int len;
1797+ char *name;
4cd5ba0f 1798+
c66cb070 1799+ s = strchr (optarg, '=');
1800+ if (s == NULL)
1801+ fatal (_("bad format for %s"), "--change-pathname");
42dd3303 1802+
c66cb070 1803+ len = s - optarg;
1804+ name = (char *) xmalloc (len + 1);
1805+ strncpy (name, optarg, len);
1806+ name[len] = '\0';
42dd3303 1807+
c66cb070 1808+ debug_register_pathname_xlat (name, s + 1);
1809+ }
1810+ break;
42dd3303 1811+
c66cb070 1812+ case OPTION_BASENAME:
1813+ /* very special case of pathname translation */
1814+ debug_register_pathname_xlat (NULL, NULL);
1815+ break;
42dd3303 1816+
c66cb070 1817 case OPTION_READONLY_TEXT:
1818 bfd_flags_to_set |= WP_TEXT;
1819 bfd_flags_to_clear &= ~WP_TEXT;
3ccd393f 1820diff -ruwN binutils/rdcoff.c binutils/rdcoff.c
1821--- binutils/rdcoff.c 2009-09-02 12:52:32.000000000 +0530
1822+++ binutils/rdcoff.c 2010-03-11 12:13:23.334879700 +0530
c66cb070 1823@@ -82,6 +82,9 @@
1824 struct coff_slots *slots;
1825 /* Basic types. */
1826 debug_type basic[T_MAX + 1];
1827+ /* Some general information, kept here for convenience. */
1828+ size_t intsize; /* sizeof (int) */
1829+ size_t doublesize; /* sizeof (double) */
1830 };
1831
1832 static debug_type *coff_get_slot (struct coff_types *, int);
1833@@ -101,6 +104,7 @@
1834 (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *,
1835 void *, debug_type, bfd_boolean);
1836 static bfd_boolean external_coff_symbol_p (int sym_class);
1837+static bfd_vma coff_convert_register (bfd *, bfd_vma);
1838 \f
1839 /* Return the slot for a type. */
1840
1841@@ -271,8 +275,7 @@
1842 break;
1843
1844 case T_INT:
1845- /* FIXME: Perhaps the size should depend upon the architecture. */
1846- ret = debug_make_int_type (dhandle, 4, FALSE);
1847+ ret = debug_make_int_type (dhandle, types->intsize, FALSE);
1848 name = "int";
1849 break;
1850
1851@@ -287,7 +290,7 @@
1852 break;
1853
1854 case T_DOUBLE:
1855- ret = debug_make_float_type (dhandle, 8);
1856+ ret = debug_make_float_type (dhandle, types->doublesize);
1857 name = "double";
1858 break;
1859
1860@@ -307,7 +310,7 @@
1861 break;
1862
1863 case T_UINT:
1864- ret = debug_make_int_type (dhandle, 4, TRUE);
1865+ ret = debug_make_int_type (dhandle, types->intsize, TRUE);
1866 name = "unsigned int";
1867 break;
1868
1869@@ -565,6 +568,8 @@
1870
1871 case C_WEAKEXT:
1872 case C_EXT:
1873+ /* AVR COFF abuses C_EXTDEF */
1874+ case C_EXTDEF:
1875 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
1876 DEBUG_GLOBAL, bfd_asymbol_value (sym)))
1877 return FALSE;
1878@@ -580,9 +585,9 @@
1879 break;
1880
1881 case C_REG:
1882- /* FIXME: We may need to convert the register number. */
1883 if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
1884- DEBUG_REGISTER, bfd_asymbol_value (sym)))
1885+ DEBUG_REGISTER,
1886+ coff_convert_register (abfd, bfd_asymbol_value (sym))))
1887 return FALSE;
1888 break;
1889
1890@@ -596,9 +601,9 @@
1891 break;
1892
1893 case C_REGPARM:
1894- /* FIXME: We may need to convert the register number. */
1895 if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
1896- DEBUG_PARM_REG, bfd_asymbol_value (sym)))
1897+ DEBUG_PARM_REG,
1898+ coff_convert_register (abfd, bfd_asymbol_value (sym))))
1899 return FALSE;
1900 break;
1901
1902@@ -648,6 +653,28 @@
1903 return FALSE;
1904 }
1905
1906+static bfd_vma
1907+coff_convert_register (abfd, val)
1908+ bfd *abfd;
1909+ bfd_vma val;
1910+{
42dd3303 1911+
c66cb070 1912+ switch (bfd_get_arch (abfd))
1913+ {
1914+ case bfd_arch_avr:
1915+ /* AVR COFF wants to describe up to four registers by the four
1916+ bytes of the 32-bit value. Unused bytes are filled with
1917+ 0xff. In theory, this would allow for non-contiguous
1918+ register usage to hold a single value, but hopefully, no
1919+ compiler is going to use that feature. We could not handle
1920+ it anyway. */
1921+ return val & 0xff;
42dd3303 1922+
c66cb070 1923+ default:
1924+ return val;
1925+ }
1926+}
42dd3303 1927+
c66cb070 1928 /* This is the main routine. It looks through all the symbols and
1929 handles them. */
1930
1931@@ -674,6 +701,17 @@
1932 types.slots = NULL;
1933 for (i = 0; i <= T_MAX; i++)
1934 types.basic[i] = DEBUG_TYPE_NULL;
1935+ switch (bfd_get_arch (abfd))
1936+ {
1937+ case bfd_arch_avr:
1938+ types.intsize = 2;
1939+ types.doublesize = 4;
1940+ break;
42dd3303 1941+
c66cb070 1942+ default:
1943+ types.intsize = 4;
1944+ types.doublesize = 8;
1945+ }
1946
1947 next_c_file = -1;
1948 fnname = NULL;
1949@@ -734,7 +772,6 @@
1950 switch (syment.n_sclass)
1951 {
1952 case C_EFCN:
1953- case C_EXTDEF:
1954 case C_ULABEL:
1955 case C_USTATIC:
1956 case C_LINE:
1957@@ -757,6 +794,8 @@
1958 /* Fall through. */
1959 case C_WEAKEXT:
1960 case C_EXT:
1961+ /* AVR COFF abuses C_EXTDEF for C_EXT */
1962+ case C_EXTDEF:
1963 if (ISFCN (syment.n_type))
1964 {
1965 fnname = name;
3ccd393f 1966diff -ruwN binutils/wrcoff.c binutils/wrcoff.c
1967--- binutils/wrcoff.c 1970-01-01 05:30:00.000000000 +0530
1968+++ binutils/wrcoff.c 2010-03-11 12:13:23.366126300 +0530
1969@@ -0,0 +1,3410 @@
c66cb070 1970+/* wrcoff.c -- Generate (AVR) COFF debugging information
1971+ Copyright 2003 Free Software Foundation, Inc.
42dd3303 1972+
c66cb070 1973+ Written by Joerg Wunsch.
42dd3303 1974+
c66cb070 1975+ This file is part of GNU Binutils.
42dd3303 1976+
c66cb070 1977+ This program is free software; you can redistribute it and/or modify
1978+ it under the terms of the GNU General Public License as published by
1979+ the Free Software Foundation; either version 2 of the License, or
1980+ (at your option) any later version.
42dd3303 1981+
c66cb070 1982+ This program is distributed in the hope that it will be useful,
1983+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1984+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1985+ GNU General Public License for more details.
42dd3303 1986+
c66cb070 1987+ You should have received a copy of the GNU General Public License
1988+ along with this program; if not, write to the Free Software
1989+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1990+ 02111-1307, USA. */
4cd5ba0f 1991+
c66cb070 1992+/* This file contains code which writes out COFF debugging
1993+ information. By now, this has only been tested on the AVR
1994+ platform, though any attempt has been made to keep the conversion
1995+ applicable to possible other COFF debugging consumers as well. */
42dd3303 1996+
c66cb070 1997+#include <stdio.h>
1998+#include <assert.h>
4cd5ba0f 1999+
c66cb070 2000+#include "sysdep.h"
2001+#include "bfd.h"
2002+#include "coff/internal.h"
2003+#include "bucomm.h"
2004+#include "libiberty.h"
2005+#include "safe-ctype.h"
2006+#include "debug.h"
2007+#include "budbg.h"
4cd5ba0f 2008+
c66cb070 2009+/* Enabling COFF_DEBUG will trace the internal callback functions and
2010+ their parameters as debug_write() calls them. */
2011+//#define COFF_DEBUG 1
4cd5ba0f 2012+
c66cb070 2013+#include "libcoff.h"
4cd5ba0f 2014+
c66cb070 2015+#define N_TMASK (coff_data (info->abfd)->local_n_tmask)
2016+#define N_BTSHFT (coff_data (info->abfd)->local_n_btshft)
2017+#define N_BTMASK (coff_data (info->abfd)->local_n_btmask)
2018+#define N_TSHIFT (coff_data (info->abfd)->local_n_tshift)
42dd3303 2019+
c66cb070 2020+/* Structure of local symbols per compilation unit. */
2021+struct coff_compilation_unit
2022+{
2023+ const char *fname;
2024+ asymbol **syms;
2025+ long nsyms, totsyms;
2026+};
4cd5ba0f 2027+
c66cb070 2028+enum ts_kind
4cd5ba0f 2029+{
c66cb070 2030+ TS_EMPTY,
2031+ TS_VOID,
2032+ TS_INT,
2033+ TS_FLOAT,
2034+ TS_COMPLEX,
2035+ TS_ENUM,
2036+ TS_POINTER,
2037+ TS_FUNC,
2038+ TS_ARRAY,
2039+ TS_STRUCT,
2040+ TS_NONE = -1
2041+};
4cd5ba0f 2042+
c66cb070 2043+/* Structure defining the pre-defined types. */
2044+struct coff_predef_type
2045+{
2046+ enum ts_kind kind;
2047+ unsigned int size; /* in bytes */
2048+ bfd_boolean isunsigned;
2049+ int slot;
2050+};
4cd5ba0f 2051+
c66cb070 2052+struct coff_type_stack;
2053+struct coff_hash_entry;
42dd3303 2054+
c66cb070 2055+struct coff_struct_fields
2056+{
2057+ const char *name;
2058+ bfd_vma bitpos;
2059+ bfd_vma bitsize;
2060+ enum debug_visibility visibility;
2061+ struct coff_type_stack *types;
2062+};
42dd3303 2063+
c66cb070 2064+/* Our type stack. */
2065+struct coff_type_stack
2066+{
2067+ struct coff_type_stack *next;
2068+ enum ts_kind tsk;
2069+ union
2070+ {
2071+ /* TS_INT */
2072+ struct
f33182aa 2073+ {
c66cb070 2074+ unsigned int size;
2075+ bfd_boolean isunsigned;
2076+ }
2077+ ts_int;
4cd5ba0f 2078+
c66cb070 2079+ /* TS_FLOAT */
2080+ struct
2081+ {
2082+ unsigned int size;
42dd3303 2083+ }
c66cb070 2084+ ts_float;
4cd5ba0f 2085+
c66cb070 2086+ /* TS_ENUM */
2087+ struct
2088+ {
2089+ union
2090+ {
2091+ const char *fixtag;
2092+ char *malloctag;
2093+ }
2094+ tag;
2095+ bfd_boolean tagismalloced;
2096+ const char **names;
2097+ bfd_signed_vma *vals;
2098+ struct coff_enum_hash_entry *ehash;
2099+ }
2100+ ts_enum;
4cd5ba0f 2101+
c66cb070 2102+ /* TS_FUNC */
2103+ struct
f33182aa 2104+ {
c66cb070 2105+ struct coff_type_stack *savedts;
42dd3303 2106+ }
c66cb070 2107+ ts_func;
2108+
2109+ /* TS_ARRAY */
2110+ struct
42dd3303 2111+ {
c66cb070 2112+ bfd_signed_vma low;
2113+ bfd_signed_vma high;
2114+ }
2115+ ts_array;
2116+
2117+ /* TS_STRUCT */
2118+ struct
2119+ {
2120+ union
2121+ {
2122+ const char *fixtag;
2123+ char *malloctag;
2124+ }
2125+ tag;
2126+ bfd_boolean tagismalloced;
2127+ unsigned int id;
2128+ bfd_boolean isstruct;
2129+ unsigned int size;
2130+ long nfields;
2131+ struct coff_struct_fields *fields;
2132+ struct coff_type_stack *savedts;
2133+ struct coff_struct_hash_entry *shash;
42dd3303 2134+ }
c66cb070 2135+ ts_struct;
2136+ }
2137+ u;
2138+};
2139+
2140+struct coff_name_type_hash_table
2141+{
2142+ struct bfd_hash_table root;
2143+};
2144+
2145+struct coff_name_type_hash_entry
2146+{
2147+ struct bfd_hash_entry root;
2148+ /* Information for this name. */
2149+ struct coff_type_stack *types;
2150+ bfd_boolean emitted;
2151+};
2152+
2153+struct coff_struct_hash_table
2154+{
2155+ struct bfd_hash_table root;
2156+};
2157+
2158+struct coff_struct_hash_entry
2159+{
2160+ struct bfd_hash_entry root;
2161+ /* Information for this name. */
2162+ struct coff_type_stack *types;
2163+ bfd_boolean emitted;
2164+ combined_entry_type *native;
2165+ /* list of symbol indices that need fixing */
2166+ long *fixidxs;
2167+ unsigned nfixidxs;
2168+};
2169+
2170+struct coff_enum_hash_table
2171+{
2172+ struct bfd_hash_table root;
2173+};
2174+
2175+struct coff_enum_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+ combined_entry_type *native;
2182+ /* list of symbol indices that need fixing */
2183+ long *fixidxs;
2184+ unsigned nfixidxs;
2185+};
2186+
2187+/* COFF private symbol data. Used as a cookie to pass data around
2188+ between various processing stages. The generic COFF handling code
2189+ doesn't use any private data. */
2190+struct coff_private_symdata
2191+{
2192+ unsigned int size; /* size of symbol, used in AVR register
2193+ translation */
2194+ struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */
2195+ struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */
2196+};
2197+
2198+/* Stack of tags that need endndx fixing. */
2199+struct coff_fix_stack
2200+{
2201+ struct coff_fix_stack *next;
2202+ combined_entry_type *native;
2203+};
4cd5ba0f 2204+
c66cb070 2205+/* This is the handle passed through debug_write. */
4cd5ba0f 2206+
c66cb070 2207+struct coff_write_handle
2208+{
2209+ /* The BFD. */
2210+ bfd *abfd;
2211+ /* Pointers to .text and .data sections, can be used as defaults if
2212+ no other information is available. */
2213+ asection *textsect;
2214+ asection *datasect;
2215+ /* Some special flags. */
2216+ unsigned long flags;
2217+ /* Flags describing architecture options. */
2218+#define COFF_FL_AVR 0x0001 /* COFF is for AVR platform. */
2219+#define COFF_FL_EXT_AVR 0x0002 /* AVR "extended" COFF */
2220+ /* Flags describing internal status information. */
2221+#define COFF_FL_FIX_ENDNDX 0x10000 /* apply endndx fix at next symbol */
2222+#define COFF_FL_START_FCN 0x20000 /* begin of function pending */
2223+#define COFF_FL_FIX_BB 0x40000 /* fix last ".bb" symbol */
2224+ /* List of our compilation units, from input symbol table. */
2225+ struct coff_compilation_unit *units;
2226+ long nunits;
2227+ struct coff_compilation_unit *currentfile;
2228+ /* Global symbols from input symbol table. */
2229+ asymbol **globals;
2230+ long nglobals;
2231+ /* Section syms for named sections. */
2232+ coff_symbol_type **secsyms;
2233+ long nsecsyms;
2234+ /* Our COFF symbols. */
2235+ asymbol **syms;
2236+ long nsyms;
2237+ /* Total line number count. */
2238+ unsigned long totlnos;
2239+ /* Size of standard objects on this arch. */
2240+ unsigned int pointersize;
2241+ unsigned int enumsize;
2242+ /* Pending information when starting a function. We have to defer
2243+ almost everything, some actions can be taken when seeing the
2244+ starting block of that function, some will even have to wait
2245+ until we see the end of the function. */
2246+ const char *funname; /* name of function */
2247+ bfd_boolean funglobal; /* global/local function? */
2248+ unsigned int lastlno; /* last line number seen so far */
2249+ long funcindex; /* index of ".func" symbol in syms */
2250+ unsigned int nlnos; /* line numbers recorded for this function*/
2251+ bfd_vma endaddr; /* last .eb address we have seen so far */
2252+ unsigned int funlno; /* first line number in function */
2253+ coff_symbol_type **fargs; /* function arguments */
2254+ unsigned int nfargs;
2255+ asection *funcsection; /* section the current function is using */
2256+ /* Type information */
2257+ struct coff_type_stack *tstack;
2258+ struct coff_name_type_hash_table types;
2259+ struct coff_struct_hash_table structs;
2260+ struct coff_enum_hash_table enums;
2261+ unsigned nenums; /* counter for anonymous enum tags */
2262+ /* Stack of pending endndx fixes, see coff_record_symbol(). */
2263+ struct coff_fix_stack *fixes;
2264+};
4cd5ba0f 2265+
c66cb070 2266+/* Predefined types, default to usual 32-bit architectures.
2267+ Arch-dependant different byte sizes will be tuned upon entering
2268+ write_coff_debugging_info(). The table is looked up from front to
2269+ end, so we put `more popular' types that might have the same size
2270+ as other types first (e. g. "int" precedes "long" and "short"). */
2271+static struct coff_predef_type coff_predef_types[] =
2272+{
2273+ { TS_INT, 4, FALSE, 4 }, /* signed int */
2274+ { TS_INT, 1, FALSE, 2 }, /* signed char */
2275+ { TS_INT, 2, FALSE, 3 }, /* signed short */
2276+ { TS_INT, 4, FALSE, 5 }, /* long int */
2277+ { TS_FLOAT, 8, FALSE, 7 }, /* double */
2278+ { TS_FLOAT, 4, FALSE, 6 }, /* float */
2279+ { TS_INT, 4, TRUE, 14 }, /* unsigned int */
2280+ { TS_INT, 1, TRUE, 12 }, /* unsigned char */
2281+ { TS_INT, 2, TRUE, 13 }, /* unsigned short */
2282+ { TS_INT, 4, TRUE, 15 }, /* unsigned long */
2283+};
4cd5ba0f 2284+
c66cb070 2285+static bfd_boolean coff_copy_symbols
2286+ PARAMS ((struct coff_write_handle *, long, asymbol **));
2287+static asymbol *coff_find_symbol
2288+ PARAMS ((struct coff_write_handle *, const char *, bfd_boolean, bfd_boolean));
2289+static void coff_record_symbol
2290+ PARAMS ((struct coff_write_handle *, coff_symbol_type *));
2291+static symvalue coff_fixup_avr_register PARAMS ((symvalue, int));
2292+static struct bfd_hash_entry *coff_name_type_newfunc
2293+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2294+static bfd_boolean coff_free_type_info
2295+ PARAMS ((struct coff_name_type_hash_entry *, PTR));
2296+static struct bfd_hash_entry *coff_struct_newfunc
2297+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2298+static bfd_boolean coff_free_struct_info
2299+ PARAMS ((struct coff_struct_hash_entry *, PTR));
2300+static struct bfd_hash_entry *coff_enum_newfunc
2301+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
2302+static bfd_boolean coff_free_enum_info
2303+ PARAMS ((struct coff_enum_hash_entry *, PTR));
2304+static unsigned int coff_get_fundamental_type
2305+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *));
2306+static bfd_boolean coff_make_typed_symbol
2307+ PARAMS ((struct coff_write_handle *, coff_symbol_type **, enum ts_kind));
2308+static bfd_boolean coff_emit_struct
2309+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *,
2310+ struct coff_struct_hash_entry *));
2311+static bfd_boolean coff_emit_enum
2312+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *,
2313+ struct coff_enum_hash_entry *));
2314+static bfd_boolean coff_emit_ndebug_sym
2315+ PARAMS ((struct coff_write_handle *, asymbol *, bfd_boolean));
4cd5ba0f 2316+
c66cb070 2317+static bfd_boolean coff_start_compilation_unit PARAMS ((PTR, const char *));
2318+static bfd_boolean coff_start_source PARAMS ((PTR, const char *));
2319+static bfd_boolean coff_empty_type PARAMS ((PTR));
2320+static bfd_boolean coff_void_type PARAMS ((PTR));
2321+static bfd_boolean coff_int_type PARAMS ((PTR, unsigned int, bfd_boolean));
2322+static bfd_boolean coff_float_type PARAMS ((PTR, unsigned int));
2323+static bfd_boolean coff_complex_type PARAMS ((PTR, unsigned int));
2324+static bfd_boolean coff_bool_type PARAMS ((PTR, unsigned int));
2325+static bfd_boolean coff_enum_type
2326+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
2327+static bfd_boolean coff_pointer_type PARAMS ((PTR));
2328+static bfd_boolean coff_function_type PARAMS ((PTR, int, bfd_boolean));
2329+static bfd_boolean coff_reference_type PARAMS ((PTR));
2330+static bfd_boolean coff_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
2331+static bfd_boolean coff_array_type
2332+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean));
2333+static bfd_boolean coff_set_type PARAMS ((PTR, bfd_boolean));
2334+static bfd_boolean coff_offset_type PARAMS ((PTR));
2335+static bfd_boolean coff_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean));
2336+static bfd_boolean coff_const_type PARAMS ((PTR));
2337+static bfd_boolean coff_volatile_type PARAMS ((PTR));
2338+static bfd_boolean coff_start_struct_type
2339+ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int));
2340+static bfd_boolean coff_struct_field
2341+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
2342+static bfd_boolean coff_end_struct_type PARAMS ((PTR));
2343+static bfd_boolean coff_start_class_type
2344+ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean,
2345+ bfd_boolean));
2346+static bfd_boolean coff_class_static_member
2347+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
2348+static bfd_boolean coff_class_baseclass
2349+ PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility));
2350+static bfd_boolean coff_class_start_method PARAMS ((PTR, const char *));
2351+static bfd_boolean coff_class_method_variant
2352+ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
2353+ bfd_vma, bfd_boolean));
2354+static bfd_boolean coff_class_static_method_variant
2355+ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean));
2356+static bfd_boolean coff_class_end_method PARAMS ((PTR));
2357+static bfd_boolean coff_end_class_type PARAMS ((PTR));
2358+static bfd_boolean coff_typedef_type PARAMS ((PTR, const char *));
2359+static bfd_boolean coff_tag_type
2360+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
2361+static bfd_boolean coff_typdef PARAMS ((PTR, const char *));
2362+static bfd_boolean coff_tag PARAMS ((PTR, const char *));
2363+static bfd_boolean coff_int_constant PARAMS ((PTR, const char *, bfd_vma));
2364+static bfd_boolean coff_float_constant PARAMS ((PTR, const char *, double));
2365+static bfd_boolean coff_typed_constant PARAMS ((PTR, const char *, bfd_vma));
2366+static bfd_boolean coff_variable
2367+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
2368+static bfd_boolean coff_start_function PARAMS ((PTR, const char *, bfd_boolean));
2369+static bfd_boolean coff_function_parameter
2370+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
2371+static bfd_boolean coff_start_block PARAMS ((PTR, bfd_vma));
2372+static bfd_boolean coff_end_block PARAMS ((PTR, bfd_vma));
2373+static bfd_boolean coff_end_function PARAMS ((PTR));
2374+static bfd_boolean coff_lineno
2375+ PARAMS ((PTR, const char *, unsigned long, bfd_vma));
4cd5ba0f 2376+
c66cb070 2377+static const struct debug_write_fns coff_fns =
2378+{
2379+ coff_start_compilation_unit,
2380+ coff_start_source,
2381+ coff_empty_type,
2382+ coff_void_type,
2383+ coff_int_type,
2384+ coff_float_type,
2385+ coff_complex_type,
2386+ coff_bool_type,
2387+ coff_enum_type,
2388+ coff_pointer_type,
2389+ coff_function_type,
2390+ coff_reference_type,
2391+ coff_range_type,
2392+ coff_array_type,
2393+ coff_set_type,
2394+ coff_offset_type,
2395+ coff_method_type,
2396+ coff_const_type,
2397+ coff_volatile_type,
2398+ coff_start_struct_type,
2399+ coff_struct_field,
2400+ coff_end_struct_type,
2401+ coff_start_class_type,
2402+ coff_class_static_member,
2403+ coff_class_baseclass,
2404+ coff_class_start_method,
2405+ coff_class_method_variant,
2406+ coff_class_static_method_variant,
2407+ coff_class_end_method,
2408+ coff_end_class_type,
2409+ coff_typedef_type,
2410+ coff_tag_type,
2411+ coff_typdef,
2412+ coff_tag,
2413+ coff_int_constant,
2414+ coff_float_constant,
2415+ coff_typed_constant,
2416+ coff_variable,
2417+ coff_start_function,
2418+ coff_function_parameter,
2419+ coff_start_block,
2420+ coff_end_block,
2421+ coff_end_function,
2422+ coff_lineno
2423+};
2424+\f
2425+/*
2426+ * Copy our input (non-debugging) symbols. Local symbols will be
2427+ * maintained in one bucket per each compilation unit, global (and
2428+ * weak) symbols will be kept in a simple array.
2429+ */
2430+static bfd_boolean
2431+coff_copy_symbols (info, count, sympp)
2432+ struct coff_write_handle *info;
2433+ long count;
2434+ asymbol **sympp;
2435+{
2436+ asymbol *osym;
2437+ long i;
2438+ struct coff_compilation_unit *up;
42dd3303 2439+
c66cb070 2440+ up = NULL;
4cd5ba0f 2441+
c66cb070 2442+ for (i = 0; i < count; i++)
42dd3303 2443+ {
c66cb070 2444+ osym = sympp[i];
4cd5ba0f 2445+
c66cb070 2446+ /* Try to figure out the .text and .data sections from our input
2447+ symbols as we walk them. Unfortunately, this ought to be the
2448+ /input/ section pointers, so their ->output_section is
2449+ non-NULL. That's why we can't simply walk through all the
2450+ sections of our abfd since this is describing the output
2451+ only. */
2452+ if (info->textsect == NULL && osym->section->flags & SEC_CODE)
2453+ /* Assume this to be our .text section. */
2454+ info->textsect = osym->section;
2455+ else if (info->datasect == NULL && osym->section->flags & SEC_DATA)
2456+ /* Assume this to be our .data section. */
2457+ info->datasect = osym->section;
4cd5ba0f 2458+
c66cb070 2459+ if (osym->flags & BSF_FILE)
2460+ {
2461+ /* New file name. */
2462+ long l;
4cd5ba0f 2463+
c66cb070 2464+ up = NULL;
4cd5ba0f 2465+
c66cb070 2466+ /* Well, maybe an old one actually? If so, append it there.
2467+ This can happen for files that contribute to multiple
2468+ (input) sections that were concatenated by the linker
2469+ (like crt1.S). */
2470+ for (l = 0; l < info->nunits; l++)
2471+ {
2472+ if (strcmp (info->units[l].fname, osym->name) == 0)
2473+ {
2474+ up = info->units + l;
2475+ break;
2476+ }
2477+ }
4cd5ba0f 2478+
c66cb070 2479+ if (up == NULL)
2480+ {
2481+ info->units = (struct coff_compilation_unit *)
2482+ xrealloc (info->units,
2483+ ++info->nunits * sizeof(struct coff_compilation_unit));
2484+ up = info->units + (info->nunits - 1);
2485+ up->fname = osym->name;
2486+ up->syms = NULL;
2487+ up->nsyms = up->totsyms = 0;
2488+ }
2489+ }
2490+ else if (osym->flags & (BSF_GLOBAL | BSF_WEAK))
42dd3303 2491+ {
c66cb070 2492+ /* Global (or weak) symbols are recorded outside compilation
2493+ units. */
2494+ info->globals = (asymbol **)
2495+ xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *));
2496+ info->globals[info->nglobals - 1] = osym;
2497+ continue;
42dd3303 2498+ }
c66cb070 2499+ else if (!bfd_is_const_section(osym->section))
2500+ {
2501+ if (osym->flags & BSF_SECTION_SYM)
2502+ {
2503+ coff_symbol_type *csymp;
2504+ /* Just record them by now, they'll be fixed up later. */
4cd5ba0f 2505+
c66cb070 2506+ if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0)
2507+ {
2508+ /* Very first symbol, fake a compilation unit name
2509+ for it. Historical precedence seems to dictate
2510+ this, but AVR COFF does not use that. */
2511+ csymp = (coff_symbol_type *)
2512+ coff_bfd_make_debug_symbol (info->abfd, 0, 0);
2513+ if (csymp == NULL)
2514+ return FALSE;
4cd5ba0f 2515+
c66cb070 2516+ csymp->symbol.name = xstrdup ("<fake>");
2517+ csymp->symbol.value = 0;
2518+ csymp->symbol.udata.p = NULL;
2519+ csymp->native->u.syment.n_sclass = C_FILE;
2520+ /* force filename into aux entry */
2521+ csymp->native->u.syment.n_numaux = 1;
2522+ coff_record_symbol (info, csymp);
2523+ }
4cd5ba0f 2524+
c66cb070 2525+ /* convert to COFF native section symbol */
2526+ csymp = (coff_symbol_type *)
2527+ coff_bfd_make_debug_symbol (info->abfd, 0, 0);
2528+ if (csymp == NULL)
2529+ return FALSE;
4cd5ba0f 2530+
c66cb070 2531+ csymp->symbol.name = xstrdup (osym->section->name);
2532+ csymp->symbol.value = osym->section->output_section->vma;
2533+ csymp->symbol.flags = BSF_DEBUGGING | BSF_SECTION_SYM;
2534+ csymp->symbol.section = osym->section;
2535+ csymp->symbol.udata.p = NULL;
2536+ csymp->native->fix_scnlen = 1;
2537+ csymp->native->u.syment.n_sclass = C_STAT;
2538+ csymp->native->u.syment.n_type = T_NULL;
2539+ csymp->native->u.syment.n_numaux = 1;
4cd5ba0f 2540+
c66cb070 2541+ coff_record_symbol (info, csymp);
4cd5ba0f 2542+
c66cb070 2543+ info->secsyms = (coff_symbol_type **)
2544+ xrealloc (info->secsyms,
2545+ ++info->nsecsyms * sizeof(coff_symbol_type *));
2546+ info->secsyms[info->nsecsyms - 1] = csymp;
2547+ }
2548+ else
2549+ {
2550+ /* Local symbol in a named section, will be recorded
2551+ within the respective compilation unit. */
2552+ if (up == NULL)
2553+ {
2554+ fprintf (stderr,
2555+ _("Discarding local symbol outside any compilation unit"));
2556+ if (osym->name)
2557+ fprintf (stderr, ": %s", osym->name);
2558+ putc ('\n', stderr);
2559+ }
2560+ else
2561+ {
2562+ up->syms = (asymbol **)
2563+ xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *));
2564+ up->syms[up->nsyms - 1] = osym;
2565+ up->totsyms = up->nsyms;
2566+ continue;
2567+ }
2568+ }
2569+ }
2570+ }
4cd5ba0f 2571+
42dd3303 2572+ return TRUE;
2573+}
4cd5ba0f 2574+
c66cb070 2575+/* Find a name in the symbol table. If found, the respective entry in
2576+ the symbol vector is zeroed, so after processing all debugging
2577+ symbols, only non-debugging symbols will remain. */
2578+static asymbol *
2579+coff_find_symbol (info, name, isfunction, global)
2580+ struct coff_write_handle *info;
2581+ const char *name;
2582+ bfd_boolean isfunction;
2583+ bfd_boolean global;
42dd3303 2584+{
c66cb070 2585+ asymbol *symp;
42dd3303 2586+ long i;
c66cb070 2587+ size_t namelen;
4cd5ba0f 2588+
c66cb070 2589+ if (global)
2590+ {
2591+ for (i = 0; i < info->nglobals; i++)
2592+ {
2593+ symp = info->globals[i];
2594+ if (symp == NULL)
2595+ continue;
2596+ if (strcmp (name, symp->name) == 0
2597+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
2598+ {
2599+ info->globals[i] = NULL;
2600+ return symp;
2601+ }
2602+ }
2603+ return NULL;
2604+ }
f33182aa 2605+
c66cb070 2606+ if (info->currentfile == NULL)
2607+ return NULL;
f33182aa 2608+
c66cb070 2609+ /* For local symbols, the match optionally stops at a dot in the
2610+ symtab symbol's name; this is used by gcc to indicate
2611+ function-scope static symbols (e. g. symbol "foo" will become
2612+ "foo.1" in function scope). */
2613+ namelen = strlen (name);
2614+ for (i = 0; i < info->currentfile->nsyms; i++)
42dd3303 2615+ {
c66cb070 2616+ symp = info->currentfile->syms[i];
2617+ if (symp == NULL)
2618+ continue;
2619+ if (strncmp (name, symp->name, namelen) == 0
2620+ && (symp->name[namelen] == '\0' || symp->name[namelen] == '.')
2621+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE))
42dd3303 2622+ {
c66cb070 2623+ info->currentfile->syms[i] = NULL;
2624+ info->currentfile->totsyms--;
2625+ return symp;
42dd3303 2626+ }
2627+ }
c66cb070 2628+ return NULL;
4cd5ba0f
ER
2629+}
2630+
c66cb070 2631+static void
2632+coff_record_symbol (info, csymp)
2633+ struct coff_write_handle *info;
2634+ coff_symbol_type *csymp;
4cd5ba0f 2635+{
c66cb070 2636+ struct coff_private_symdata *priv;
4cd5ba0f 2637+
c66cb070 2638+ info->syms = (asymbol **) xrealloc (info->syms,
2639+ ++info->nsyms * sizeof (asymbol *));
2640+ info->syms[info->nsyms - 1] = (asymbol *)csymp;
42dd3303 2641+
c66cb070 2642+ if ((priv = csymp->symbol.udata.p) != NULL)
2643+ {
2644+ if (priv->shash != NULL)
2645+ {
2646+ struct coff_struct_hash_entry *shash = priv->shash;
2647+ shash->fixidxs = (long *)
2648+ xrealloc (shash->fixidxs, ++shash->nfixidxs * sizeof (long));
2649+ shash->fixidxs[shash->nfixidxs - 1] = info->nsyms - 1;
2650+ }
2651+ if (priv->ehash != NULL)
2652+ {
2653+ struct coff_enum_hash_entry *ehash = priv->ehash;
2654+ ehash->fixidxs = (long *)
2655+ xrealloc (ehash->fixidxs, ++ehash->nfixidxs * sizeof (long));
2656+ ehash->fixidxs[ehash->nfixidxs - 1] = info->nsyms - 1;
2657+ }
2658+ free (priv);
2659+ csymp->symbol.udata.p = NULL;
2660+ }
42dd3303 2661+
c66cb070 2662+ /* If there are any pending endndx fixes, pop the last element from
2663+ that stack, and record the current symbol for fixing. We need to
2664+ do this here since we need to record our current csymp->native
2665+ (where that csymp is completely unrelated to whatever symbol was
2666+ previously generated that requested the fixup). The stack of
2667+ pending fixes is required since several endndx fixes could be
2668+ nested, e. g. the start of a function has a pending fix that
2669+ needs to point to the first symbol after the function, but there
2670+ could be an anonymous struct definition inside that function's
2671+ local variables where the endndx needs to point after the last
2672+ symbol of this struct. Also, structs and unions could be nested.
4cd5ba0f 2673+
c66cb070 2674+ Each call to coff_record_symbol() can fix at most one endndx
2675+ (even if more are pending in the stack), but that's OK.
42dd3303 2676+
c66cb070 2677+ Note that bfd/coffgen.c converts that csymp->native into a
2678+ symtable slot number after coff_renumber_symbols() has been
2679+ run. */
2680+ if (info->flags & COFF_FL_FIX_ENDNDX)
2681+ {
2682+ struct coff_fix_stack *fsp, *ofsp;
2683+ union internal_auxent *aux;
42dd3303 2684+
c66cb070 2685+ assert (info->fixes != NULL);
42dd3303 2686+
c66cb070 2687+ fsp = info->fixes;
2688+ ofsp = NULL;
2689+ while (fsp->next != NULL)
2690+ {
2691+ ofsp = fsp;
2692+ fsp = fsp->next;
2693+ }
2694+ if (ofsp == NULL)
2695+ info->fixes = NULL;
2696+ else
2697+ ofsp->next = NULL;
4cd5ba0f 2698+
c66cb070 2699+ aux = &(fsp->native->u.auxent);
2700+ fsp->native->fix_end = 1;
2701+ aux->x_sym.x_fcnary.x_fcn.x_endndx.p = csymp->native;
2702+ free (fsp);
4cd5ba0f 2703+
c66cb070 2704+ info->flags &= ~COFF_FL_FIX_ENDNDX;
2705+ }
2706+}
42dd3303 2707+
c66cb070 2708+/* Fixup AVR COFF register handling: they don't only mention the
2709+ starting register number, but all registers, each within one byte
2710+ of the value. Unused register positions are filled up with
2711+ 0xff. */
2712+static symvalue
2713+coff_fixup_avr_register (val, size)
2714+ symvalue val;
2715+ int size;
f33182aa 2716+{
c66cb070 2717+ union
2718+ {
2719+ unsigned char c[4];
2720+ symvalue v;
2721+ } u;
4cd5ba0f 2722+
c66cb070 2723+ u.c[1] = u.c[2] = u.c[3] = 0xff;
2724+ u.c[0] = val;
2725+ if (size > 8)
2726+ u.c[1] = val + 1;
2727+ if (size > 16)
2728+ {
2729+ u.c[2] = val + 2;
2730+ u.c[3] = val + 3;
2731+ }
42dd3303 2732+
c66cb070 2733+ return u.v;
4cd5ba0f
ER
2734+}
2735+
c66cb070 2736+/* Initialize an entry in the hash tables. */
42dd3303 2737+
c66cb070 2738+static struct bfd_hash_entry *
2739+coff_name_type_newfunc (entry, table, string)
2740+ struct bfd_hash_entry *entry;
2741+ struct bfd_hash_table *table;
2742+ const char *string;
4cd5ba0f 2743+{
c66cb070 2744+ struct coff_name_type_hash_entry *ret =
2745+ (struct coff_name_type_hash_entry *) entry;
4cd5ba0f 2746+
c66cb070 2747+ /* Allocate the structure if it has not already been allocated by a
2748+ subclass. */
2749+ if (ret == NULL)
2750+ ret = ((struct coff_name_type_hash_entry *)
2751+ bfd_hash_allocate (table, sizeof *ret));
2752+ if (ret == NULL)
2753+ return NULL;
4cd5ba0f 2754+
c66cb070 2755+ /* Call the allocation method of the superclass. */
2756+ ret = ((struct coff_name_type_hash_entry *)
2757+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2758+ if (ret)
2759+ {
2760+ /* Set local fields. */
2761+ ret->types = NULL;
2762+ ret->emitted = FALSE;
2763+ }
4cd5ba0f 2764+
c66cb070 2765+ return (struct bfd_hash_entry *) ret;
42dd3303 2766+}
4cd5ba0f 2767+
c66cb070 2768+static struct bfd_hash_entry *
2769+coff_struct_newfunc (entry, table, string)
2770+ struct bfd_hash_entry *entry;
2771+ struct bfd_hash_table *table;
2772+ const char *string;
42dd3303 2773+{
c66cb070 2774+ struct coff_struct_hash_entry *ret =
2775+ (struct coff_struct_hash_entry *) entry;
4cd5ba0f 2776+
c66cb070 2777+ /* Allocate the structure if it has not already been allocated by a
2778+ subclass. */
2779+ if (ret == NULL)
2780+ ret = ((struct coff_struct_hash_entry *)
2781+ bfd_hash_allocate (table, sizeof *ret));
2782+ if (ret == NULL)
2783+ return NULL;
4cd5ba0f 2784+
c66cb070 2785+ /* Call the allocation method of the superclass. */
2786+ ret = ((struct coff_struct_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+ ret->fixidxs = NULL;
2794+ ret->nfixidxs = 0;
2795+ ret->native = NULL;
2796+ }
4cd5ba0f 2797+
c66cb070 2798+ return (struct bfd_hash_entry *) ret;
2799+}
4cd5ba0f 2800+
c66cb070 2801+static struct bfd_hash_entry *
2802+coff_enum_newfunc (entry, table, string)
2803+ struct bfd_hash_entry *entry;
2804+ struct bfd_hash_table *table;
2805+ const char *string;
42dd3303 2806+{
c66cb070 2807+ struct coff_enum_hash_entry *ret =
2808+ (struct coff_enum_hash_entry *) entry;
4cd5ba0f 2809+
c66cb070 2810+ /* Allocate the structure if it has not already been allocated by a
2811+ subclass. */
2812+ if (ret == NULL)
2813+ ret = ((struct coff_enum_hash_entry *)
2814+ bfd_hash_allocate (table, sizeof *ret));
2815+ if (ret == NULL)
2816+ return NULL;
4cd5ba0f 2817+
c66cb070 2818+ /* Call the allocation method of the superclass. */
2819+ ret = ((struct coff_enum_hash_entry *)
2820+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2821+ if (ret)
2822+ {
2823+ /* Set local fields. */
2824+ ret->types = NULL;
2825+ ret->emitted = FALSE;
2826+ ret->fixidxs = NULL;
2827+ ret->nfixidxs = 0;
2828+ ret->native = NULL;
2829+ }
4cd5ba0f 2830+
c66cb070 2831+ return (struct bfd_hash_entry *) ret;
42dd3303 2832+}
4cd5ba0f 2833+
c66cb070 2834+/* Look up an entry in the hash tables. */
4cd5ba0f 2835+
c66cb070 2836+#define coff_name_type_hash_lookup(table, string, create, copy) \
2837+ ((struct coff_name_type_hash_entry *) \
2838+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
4cd5ba0f 2839+
c66cb070 2840+/* Traverse the hash table. */
4cd5ba0f 2841+
c66cb070 2842+#define coff_name_type_hash_traverse(table, func, info) \
2843+ (bfd_hash_traverse \
2844+ (&(table)->root, \
2845+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2846+ (info)))
4cd5ba0f 2847+
c66cb070 2848+#define coff_struct_hash_lookup(table, string, create, copy) \
2849+ ((struct coff_struct_hash_entry *) \
2850+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
4cd5ba0f 2851+
c66cb070 2852+/* Traverse the hash table. */
4cd5ba0f 2853+
c66cb070 2854+#define coff_struct_hash_traverse(table, func, info) \
2855+ (bfd_hash_traverse \
2856+ (&(table)->root, \
2857+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2858+ (info)))
4cd5ba0f 2859+
c66cb070 2860+#define coff_enum_hash_lookup(table, string, create, copy) \
2861+ ((struct coff_enum_hash_entry *) \
2862+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
4cd5ba0f 2863+
c66cb070 2864+/* Traverse the hash table. */
4cd5ba0f 2865+
c66cb070 2866+#define coff_enum_hash_traverse(table, func, info) \
2867+ (bfd_hash_traverse \
2868+ (&(table)->root, \
2869+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
2870+ (info)))
4cd5ba0f 2871+
c66cb070 2872+#define coff_push_type(kind) \
2873+ tst = (struct coff_type_stack *) xmalloc (sizeof (struct coff_type_stack)); \
2874+ memset (tst, 0, sizeof (*tst)); \
2875+ tst->next = info->tstack; \
2876+ tst->tsk = kind; \
2877+ info->tstack = tst
4cd5ba0f 2878+
c66cb070 2879+#define coff_pop_type() \
2880+ tst = info->tstack; \
2881+ if (tst == NULL) { \
2882+ fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \
2883+ return FALSE; \
2884+ } \
2885+ info->tstack = tst->next; \
2886+ tst->next = NULL
2887+
2888+#define coff_complain_unsupp(s) \
2889+ fprintf (stderr, _("%s type not supported in %s\n"), \
2890+ s, info->abfd->xvec->name); \
2891+ return FALSE
4cd5ba0f 2892+
c66cb070 2893+/* These function is called via the hash traverse routine when freeing
2894+ a hash table (at the end of a translation unit). */
42dd3303 2895+static bfd_boolean
c66cb070 2896+coff_free_type_info (h, p)
2897+ struct coff_name_type_hash_entry *h;
2898+ PTR p ATTRIBUTE_UNUSED;
42dd3303 2899+{
c66cb070 2900+ struct coff_type_stack *tst, *otst;
4cd5ba0f 2901+
c66cb070 2902+ for (tst = h->types; tst != NULL;)
2903+ {
2904+ otst = tst;
2905+ tst = tst->next;
2906+ free (otst);
2907+ }
42dd3303 2908+ return TRUE;
2909+}
4cd5ba0f 2910+
42dd3303 2911+static bfd_boolean
c66cb070 2912+coff_free_struct_info (h, p)
2913+ struct coff_struct_hash_entry *h;
2914+ PTR p ATTRIBUTE_UNUSED;
42dd3303 2915+{
c66cb070 2916+ struct coff_type_stack *tst, *otst, *xtst, *xotst;
2917+ struct coff_struct_fields *fp;
2918+ long i;
42dd3303 2919+
c66cb070 2920+ for (tst = h->types; tst != NULL;)
f33182aa 2921+ {
c66cb070 2922+ otst = tst;
2923+ if (tst->u.ts_struct.tagismalloced)
2924+ free (tst->u.ts_struct.tag.malloctag);
2925+ for (i = 0, fp = tst->u.ts_struct.fields;
2926+ i < tst->u.ts_struct.nfields;
2927+ i++, fp++)
2928+ {
2929+ xtst = fp->types;
2930+ while (xtst != NULL)
2931+ {
2932+ xotst = xtst->next;
2933+ free (xtst);
2934+ xtst = xotst;
2935+ }
2936+ }
2937+ free (tst->u.ts_struct.fields);
2938+ tst = tst->next;
2939+ free (otst);
f33182aa 2940+ }
42dd3303 2941+ return TRUE;
2942+}
4cd5ba0f 2943+
42dd3303 2944+static bfd_boolean
c66cb070 2945+coff_free_enum_info (h, p)
2946+ struct coff_enum_hash_entry *h;
2947+ PTR p ATTRIBUTE_UNUSED;
42dd3303 2948+{
c66cb070 2949+ struct coff_type_stack *tst, *otst;
4cd5ba0f 2950+
c66cb070 2951+ for (tst = h->types; tst != NULL;)
2952+ {
2953+ otst = tst;
2954+ if (tst->u.ts_enum.tagismalloced)
2955+ free (tst->u.ts_enum.tag.malloctag);
2956+ tst = tst->next;
2957+ free (otst);
2958+ }
f33182aa 2959+ return TRUE;
2960+}
4cd5ba0f 2961+
c66cb070 2962+static unsigned int
2963+coff_get_fundamental_type (info, tst)
2964+ struct coff_write_handle *info ATTRIBUTE_UNUSED;
2965+ struct coff_type_stack *tst;
42dd3303 2966+{
c66cb070 2967+ size_t i;
4cd5ba0f 2968+
c66cb070 2969+ /* See if one of our predefined types will fit. */
2970+ if (tst->tsk == TS_INT)
2971+ {
2972+ for (i = 0;
2973+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
2974+ i++)
2975+ {
2976+ if (coff_predef_types[i].kind == TS_INT
2977+ && coff_predef_types[i].size == tst->u.ts_int.size
2978+ && coff_predef_types[i].isunsigned == tst->u.ts_int.isunsigned)
2979+ return coff_predef_types[i].slot;
2980+ }
2981+ fprintf (stderr,
2982+ _("%ssigned %d-bit integer type not available in COFF\n"),
2983+ tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8);
2984+ }
2985+ else
2986+ {
2987+ for (i = 0;
2988+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type);
2989+ i++)
2990+ {
2991+ if (coff_predef_types[i].kind == TS_FLOAT
2992+ && coff_predef_types[i].size == tst->u.ts_float.size)
2993+ return coff_predef_types[i].slot;
2994+ }
2995+ fprintf (stderr, _("%d-bit float type not available in COFF\n"),
2996+ tst->u.ts_float.size * 8);
2997+ }
4cd5ba0f 2998+
c66cb070 2999+ return T_NULL;
42dd3303 3000+}
4cd5ba0f 3001+
42dd3303 3002+static bfd_boolean
c66cb070 3003+coff_make_typed_symbol (info, csympp, stopat)
3004+ struct coff_write_handle *info;
3005+ coff_symbol_type **csympp;
3006+ enum ts_kind stopat;
42dd3303 3007+{
42dd3303 3008+ struct coff_type_stack *tst;
c66cb070 3009+ union internal_auxent *aux;
3010+ struct coff_struct_hash_entry *shash;
3011+ struct coff_enum_hash_entry *ehash;
3012+ struct coff_private_symdata *priv;
3ccd393f 3013+ unsigned int type, numaux, arydim, size, i, nele, nderived;
c66cb070 3014+ const char *name;
3015+ bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR))
3016+ == COFF_FL_AVR;
4cd5ba0f 3017+
c66cb070 3018+ /* Synthesize a new internal COFF symbol. */
3019+ *csympp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3020+ if (*csympp == NULL)
3021+ return FALSE;
4cd5ba0f 3022+
c66cb070 3023+ priv = (struct coff_private_symdata *) xmalloc (sizeof *priv);
3024+ memset (priv, 0, sizeof *priv);
4cd5ba0f 3025+
c66cb070 3026+ type = arydim = size = nderived = 0;
f33182aa 3027+
c66cb070 3028+ aux = &(((*csympp)->native + 1)->u.auxent);
f33182aa 3029+
c66cb070 3030+ /* Now, walk the type stack, and see how we could convert the info
3031+ we've got to what COFF understands. */
3032+ for (;;)
3033+ {
3034+ if (info->tstack == NULL)
3035+ break;
f33182aa 3036+
c66cb070 3037+ /* If we have been advised to not pop the entire stack, stop
3038+ here. */
3039+ if (info->tstack->tsk == stopat && info->tstack->next == NULL)
3040+ break;
f33182aa 3041+
c66cb070 3042+ coff_pop_type ();
f33182aa 3043+
c66cb070 3044+ switch (tst->tsk)
3045+ {
3046+ case TS_NONE:
3047+ /* cannot happen */
3048+ break;
4cd5ba0f 3049+
c66cb070 3050+ case TS_EMPTY:
3051+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3052+ fprintf (stderr, _("empty type not last on type stack\n"));
3053+ /* type |= T_NULL; */
3054+ break;
4cd5ba0f 3055+
c66cb070 3056+ case TS_VOID:
3057+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3058+ fprintf (stderr, _("void type not last on type stack\n"));
3059+ type |= T_VOID;
3060+ break;
4cd5ba0f 3061+
c66cb070 3062+ case TS_INT:
3063+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3064+ fprintf (stderr, _("int type not last on type stack\n"));
3065+ type |= coff_get_fundamental_type (info, tst);
3066+ if (size == 0)
3067+ size = tst->u.ts_int.size;
3068+ break;
4cd5ba0f 3069+
c66cb070 3070+ case TS_FLOAT:
3071+ if (info->tstack != NULL && info->tstack->tsk != stopat)
3072+ fprintf (stderr, _("float type not last on type stack\n"));
3073+ type |= coff_get_fundamental_type (info, tst);
3074+ if (size == 0)
3075+ size = tst->u.ts_float.size;
3076+ break;
f33182aa 3077+
c66cb070 3078+ case TS_POINTER:
3079+ nderived++;
3080+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT);
3081+ size = info->pointersize;
3082+ break;
f33182aa 3083+
c66cb070 3084+ case TS_FUNC:
3085+ nderived++;
3086+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT);
3087+ /* AUX entry for DT_FCN will be filled in elsewhere. */
3088+ break;
4cd5ba0f 3089+
c66cb070 3090+ case TS_ARRAY:
3091+ /* We need to limit arydim so the assignment below won't
3092+ overwrite random locations. */
3093+ if (arydim >= DIMNUM)
3094+ {
3095+ fprintf (stderr,
3096+ _("More than %d array dimensions, result is invalid.\n"),
3097+ DIMNUM);
3098+ arydim = DIMNUM - 1;
3099+ }
3100+ nderived++;
3101+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_ARY << N_BTSHFT);
3102+ aux->x_sym.x_fcnary.x_ary.x_dimen[arydim++] =
3103+ tst->u.ts_array.high - tst->u.ts_array.low + 1;
4cd5ba0f 3104+
c66cb070 3105+ break;
4cd5ba0f 3106+
c66cb070 3107+ case TS_COMPLEX:
3108+ coff_complain_unsupp (_("complex"));
f33182aa 3109+
c66cb070 3110+ case TS_ENUM:
3111+ type |= T_ENUM;
3112+ if (size == 0)
3113+ size = info->enumsize;
4cd5ba0f 3114+
c66cb070 3115+ if (tst->u.ts_enum.ehash != NULL)
3116+ {
3117+ /* enum tag will be fixed later. */
3118+ priv->ehash = tst->u.ts_enum.ehash;
3119+ break;
3120+ }
3121+ if (tst->u.ts_enum.tagismalloced)
3122+ name = tst->u.ts_enum.tag.malloctag;
3123+ else
3124+ name = tst->u.ts_enum.tag.fixtag;
3125+ ehash = coff_enum_hash_lookup (&info->enums, name,
3126+ TRUE, tst->u.ts_enum.tagismalloced);
3127+ if (ehash == NULL)
3128+ return FALSE;
3129+ if (!ehash->emitted)
3130+ {
3131+ if (ehash->types == NULL)
3132+ {
3133+ ehash->types = (struct coff_type_stack *)
3134+ xmalloc (sizeof (struct coff_type_stack));
3135+ memcpy (ehash->types, tst, sizeof (struct coff_type_stack));
3136+ }
3137+ ehash->emitted = TRUE;
3138+ coff_emit_enum (info, tst, ehash);
3139+ if (ehash->nfixidxs != 0)
3140+ {
3141+ coff_symbol_type *symp;
3142+ unsigned i;
4cd5ba0f 3143+
c66cb070 3144+ for (i = 0; i < ehash->nfixidxs; i++)
3145+ {
3146+ combined_entry_type *np;
4cd5ba0f 3147+
c66cb070 3148+ symp = (coff_symbol_type *) info->syms[ehash->fixidxs[i]];
3149+ symp->native->u.syment.n_type &= ~N_BTMASK;
3150+ symp->native->u.syment.n_type |= T_ENUM;
4cd5ba0f 3151+
c66cb070 3152+ if (oldavrcoff)
3153+ continue;
4cd5ba0f 3154+
c66cb070 3155+ np = symp->native + 1;
3156+ np->fix_tag = 1;
3157+ np->u.auxent.x_sym.x_tagndx.p = ehash->native;
3158+ if (np->u.auxent.x_sym.x_misc.x_fsize == 0)
3159+ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size;
3160+ }
4cd5ba0f 3161+
c66cb070 3162+ free (ehash->fixidxs);
3163+ ehash->nfixidxs = 0;
3164+ }
3165+ }
3166+ if (!oldavrcoff)
3167+ {
3168+ ((*csympp)->native + 1)->fix_tag = 1;
3169+ aux->x_sym.x_tagndx.p = ehash->native;
3170+ if (aux->x_sym.x_misc.x_fsize == 0)
3171+ aux->x_sym.x_misc.x_lnsz.x_size = size;
3172+ }
3173+ break;
42dd3303 3174+
c66cb070 3175+ case TS_STRUCT:
3176+ if (tst->u.ts_struct.isstruct)
3177+ type |= T_STRUCT;
3178+ else
3179+ type |= T_UNION;
3180+ if (size == 0)
3181+ size = tst->u.ts_struct.size;
4cd5ba0f 3182+
c66cb070 3183+ if (tst->u.ts_struct.shash != NULL)
3184+ {
3185+ /* struct tag will be fixed later. */
3186+ priv->shash = tst->u.ts_struct.shash;
3187+ break;
3188+ }
3189+ if (tst->u.ts_struct.tagismalloced)
3190+ name = tst->u.ts_struct.tag.malloctag;
3191+ else
3192+ name = tst->u.ts_struct.tag.fixtag;
3193+ shash = coff_struct_hash_lookup (&info->structs, name,
3194+ TRUE, tst->u.ts_struct.tagismalloced);
3195+ if (shash == NULL)
3196+ return FALSE;
3197+ if (!shash->emitted)
3198+ {
3199+ if (shash->types == NULL)
3200+ {
3201+ shash->types = (struct coff_type_stack *)
3202+ xmalloc (sizeof (struct coff_type_stack));
3203+ memcpy (shash->types, tst, sizeof (struct coff_type_stack));
3204+ }
3205+ shash->emitted = TRUE;
3206+ coff_emit_struct (info, tst, shash);
3207+ if (shash->nfixidxs != 0)
3208+ {
3209+ coff_symbol_type *symp;
3210+ unsigned i;
f33182aa 3211+
c66cb070 3212+ for (i = 0; i < shash->nfixidxs; i++)
3213+ {
3214+ combined_entry_type *np;
4cd5ba0f 3215+
c66cb070 3216+ symp = (coff_symbol_type *) info->syms[shash->fixidxs[i]];
3217+ symp->native->u.syment.n_type &= ~N_BTMASK;
3218+ if (tst->u.ts_struct.isstruct)
3219+ symp->native->u.syment.n_type |= T_STRUCT;
3220+ else
3221+ symp->native->u.syment.n_type |= T_UNION;
4cd5ba0f 3222+
c66cb070 3223+ if (oldavrcoff)
3224+ continue;
42dd3303 3225+
c66cb070 3226+ np = symp->native + 1;
3227+ np->fix_tag = 1;
3228+ np->u.auxent.x_sym.x_tagndx.p = shash->native;
3229+ if (np->u.auxent.x_sym.x_misc.x_fsize == 0)
3230+ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size;
3231+ }
4cd5ba0f 3232+
c66cb070 3233+ free (shash->fixidxs);
3234+ shash->nfixidxs = 0;
3235+ }
3236+ }
3237+ if (!oldavrcoff)
3238+ {
3239+ ((*csympp)->native + 1)->fix_tag = 1;
3240+ aux->x_sym.x_tagndx.p = shash->native;
3241+ if (aux->x_sym.x_misc.x_fsize == 0)
3242+ aux->x_sym.x_misc.x_lnsz.x_size = size;
3243+ }
3244+ break;
3245+ }
3246+ free (tst);
3247+ }
4cd5ba0f 3248+
c66cb070 3249+ if (nderived > 6)
3250+ fprintf (stderr,
3251+ _("More than 6 derived type specifiers, result is invalid.\n"));
4cd5ba0f 3252+
c66cb070 3253+ /* Our type computation so far used the reverse order for derived
3254+ type specifiers. Fix this here if there was more than one
3255+ derived type specifier. */
3256+ if (nderived > 1)
3257+ {
3258+ unsigned int nty, bty;
3259+ bty = type & N_BTMASK;
3260+ type = type >> N_BTSHFT;
3261+ nty = 0;
3262+ while (nderived-- > 0)
3263+ {
3264+ nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT));
3265+ type >>= N_TSHIFT;
3266+ }
3267+ type = (nty << N_BTSHFT) | bty;
3268+ }
4cd5ba0f 3269+
c66cb070 3270+ if (ISARY (type))
f33182aa 3271+ {
c66cb070 3272+ /* Compute size of entire array. */
3273+ for (i = 0, nele = 1; i < arydim; i++)
3274+ nele *= aux->x_sym.x_fcnary.x_ary.x_dimen[i];
3275+ aux->x_sym.x_misc.x_lnsz.x_size = size * nele;
42dd3303 3276+ }
4cd5ba0f 3277+
c66cb070 3278+ numaux = 0;
3279+ if (ISARY (type) || ISFCN (type))
3280+ numaux++;
3281+ if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION
3282+ || BTYPE (type) == T_ENUM)
3283+ && !oldavrcoff)
3284+ numaux++;
3285+ /* Only AVR COFF uses multiple AUX entries. */
3286+ if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0)
3287+ numaux = 1;
3288+
3289+ priv->size = size;
3290+ (*csympp)->symbol.udata.p = priv;
3291+ (*csympp)->native->u.syment.n_type = type;
3292+ (*csympp)->native->u.syment.n_numaux = numaux;
3293+
3294+ /* If the fundamental type comes out as T_NULL, this means we don't
3295+ have any type information. Just don't emit any aux entries in
3296+ that case, and drop any derived type information as well. */
3297+ if (BTYPE (type) == T_NULL)
42dd3303 3298+ {
c66cb070 3299+ printf ("coff_make_typed_symbol() -> T_NULL\n");
3300+ //(*csympp)->native->u.syment.n_type = T_NULL;
3301+ (*csympp)->native->u.syment.n_numaux = 0;
f33182aa 3302+ }
4cd5ba0f 3303+
42dd3303 3304+ return TRUE;
3305+}
4cd5ba0f 3306+
c66cb070 3307+static bfd_boolean coff_emit_struct (info, tst, shash)
3308+ struct coff_write_handle *info;
3309+ struct coff_type_stack *tst;
3310+ struct coff_struct_hash_entry *shash;
42dd3303 3311+{
c66cb070 3312+ coff_symbol_type *csymp, *scsymp, *ecsymp;
3313+ union internal_auxent *aux;
3314+ struct coff_fix_stack *fixp, *ofp;
3315+ bfd_boolean isstruct = tst->u.ts_struct.isstruct;
3316+ bfd_boolean isbitfield = FALSE;
3317+ struct coff_type_stack *savedtst;
42dd3303 3318+ struct coff_struct_fields *fp;
c66cb070 3319+ unsigned short sclass;
3320+ long i;
42dd3303 3321+
c66cb070 3322+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3323+ COFF_FL_AVR)
3324+ /* old AVR COFF doesn't support struct debugging */
3325+ return TRUE;
42dd3303 3326+
c66cb070 3327+ /* Synthesize a new internal COFF symbol for the struct/union. */
3328+ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3329+ if (scsymp == NULL)
3330+ return FALSE;
42dd3303 3331+
c66cb070 3332+ if (tst->u.ts_struct.tagismalloced)
3333+ scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag);
3334+ else
3335+ scsymp->symbol.name = tst->u.ts_struct.tag.fixtag;
3336+ scsymp->symbol.flags = BSF_NOT_AT_END;
3337+ scsymp->symbol.section = bfd_und_section_ptr;
3338+ scsymp->native->u.syment.n_sclass = isstruct? C_STRTAG: C_UNTAG;
3339+ scsymp->native->u.syment.n_type = isstruct? T_STRUCT: T_UNION;
3340+ scsymp->native->u.syment.n_numaux = 1;
3341+ scsymp->symbol.udata.p = NULL;
3342+ scsymp->symbol.value = 0;
4cd5ba0f 3343+
c66cb070 3344+ shash->native = scsymp->native;
4cd5ba0f 3345+
c66cb070 3346+ /* Synthesize a new internal COFF symbol for the end of struct/union. */
3347+ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3348+ if (ecsymp == NULL)
3349+ return FALSE;
4cd5ba0f 3350+
c66cb070 3351+ ecsymp->symbol.name = ".eos";
3352+ ecsymp->symbol.flags = BSF_NOT_AT_END;
3353+ /* We need to use the com section here since bfd/coffgen.c
3354+ translates this into an N_UNDEF one without clobbering the
3355+ value. */
3356+ ecsymp->symbol.section = bfd_com_section_ptr;
3357+ ecsymp->native->u.syment.n_sclass = C_EOS;
3358+ ecsymp->symbol.udata.p = NULL;
3359+ ecsymp->symbol.value = tst->u.ts_struct.size;
3360+ ecsymp->native->u.syment.n_numaux = 1;
3361+ (ecsymp->native + 1)->fix_tag = 1;
3362+ aux = &((ecsymp->native + 1)->u.auxent);
3363+ aux->x_sym.x_tagndx.p = scsymp->native;
3364+ aux->x_sym.x_misc.x_lnsz.x_size = tst->u.ts_struct.size;
4cd5ba0f 3365+
c66cb070 3366+ coff_record_symbol (info, scsymp);
4cd5ba0f 3367+
c66cb070 3368+ savedtst = info->tstack;
42dd3303 3369+
c66cb070 3370+ if (isstruct)
f33182aa 3371+ {
c66cb070 3372+ /* First, make a quick walk along all the fields, and figure out
3373+ * whether we've got a genuine struct or a bitfield struct. */
3374+ for (i = 0, fp = tst->u.ts_struct.fields;
3375+ i < tst->u.ts_struct.nfields;
3376+ i++, fp++)
3377+ if (fp->bitsize % 8 != 0)
3378+ {
3379+ isbitfield = TRUE;
3380+ break;
3381+ }
42dd3303 3382+ }
4cd5ba0f 3383+
c66cb070 3384+ sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU;
4cd5ba0f 3385+
c66cb070 3386+ for (i = 0, fp = tst->u.ts_struct.fields;
3387+ i < tst->u.ts_struct.nfields;
3388+ i++, fp++)
3389+ {
3390+ if (strlen (fp->name) == 0)
3391+ {
3392+ /* empty name could happen inside bitfield */
3393+ fp->types = NULL;
3394+ continue;
3395+ }
4cd5ba0f 3396+
c66cb070 3397+ info->tstack = fp->types;
3398+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
3399+ return FALSE;
4cd5ba0f 3400+
c66cb070 3401+ csymp->symbol.name = xstrdup (fp->name);
3402+ csymp->symbol.flags = BSF_NOT_AT_END;
3403+ csymp->symbol.section = bfd_com_section_ptr;
3404+ csymp->native->u.syment.n_sclass = sclass;
3405+ csymp->symbol.value = isbitfield? fp->bitpos: fp->bitpos / 8;
3406+ if (isbitfield)
3407+ {
3408+ csymp->native->u.syment.n_numaux = 1;
3409+ aux = &((csymp->native + 1)->u.auxent);
3410+ aux->x_sym.x_misc.x_lnsz.x_size = fp->bitsize;
3411+ }
4cd5ba0f 3412+
c66cb070 3413+ coff_record_symbol (info, csymp);
f33182aa 3414+
c66cb070 3415+ fp->types = NULL;
3416+ }
3417+
3418+ info->tstack = savedtst;
3419+
3420+ /* Record our endndx field for later fixing. */
3421+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
3422+ fixp->native = scsymp->native + 1; /* points to first AUX */
3423+ fixp->next = NULL;
3424+ if (info->fixes == NULL)
3425+ info->fixes = fixp;
3426+ else
3427+ {
3428+ for (ofp = info->fixes; ofp->next != NULL;)
3429+ ofp = ofp->next;
3430+ ofp->next = fixp;
3431+ }
3432+
3433+ coff_record_symbol (info, ecsymp);
3434+ info->flags |= COFF_FL_FIX_ENDNDX;
f33182aa 3435+
42dd3303 3436+ return TRUE;
3437+}
4cd5ba0f 3438+
c66cb070 3439+static bfd_boolean coff_emit_enum (info, tst, ehash)
3440+ struct coff_write_handle *info;
3441+ struct coff_type_stack *tst;
3442+ struct coff_enum_hash_entry *ehash;
42dd3303 3443+{
c66cb070 3444+ coff_symbol_type *csymp, *scsymp, *ecsymp;
3445+ union internal_auxent *aux;
3446+ struct coff_fix_stack *fixp, *ofp;
3447+ int i;
4cd5ba0f 3448+
c66cb070 3449+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ==
3450+ COFF_FL_AVR)
3451+ /* old AVR COFF doesn't support enum debugging */
3452+ return TRUE;
4cd5ba0f 3453+
c66cb070 3454+ /* Synthesize a new internal COFF symbol for the enum. */
3455+ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3456+ if (scsymp == NULL)
3457+ return FALSE;
4cd5ba0f 3458+
c66cb070 3459+ if (tst->u.ts_enum.tagismalloced)
3460+ scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag);
3461+ else
3462+ scsymp->symbol.name = tst->u.ts_enum.tag.fixtag;
3463+ scsymp->symbol.flags = BSF_NOT_AT_END;
3464+ scsymp->symbol.section = bfd_und_section_ptr;
3465+ scsymp->native->u.syment.n_sclass = C_ENTAG;
3466+ scsymp->native->u.syment.n_type = T_ENUM;
3467+ scsymp->native->u.syment.n_numaux = 1;
3468+ scsymp->symbol.udata.p = NULL;
3469+ scsymp->symbol.value = 0;
4cd5ba0f 3470+
c66cb070 3471+ ehash->native = scsymp->native;
4cd5ba0f 3472+
c66cb070 3473+ /* Synthesize a new internal COFF symbol for the end of struct/union. */
3474+ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3475+ if (ecsymp == NULL)
3476+ return FALSE;
4cd5ba0f 3477+
c66cb070 3478+ ecsymp->symbol.name = ".eos";
3479+ ecsymp->symbol.flags = BSF_NOT_AT_END;
3480+ /* We need to use the com section here since bfd/coffgen.c
3481+ translates this into an N_UNDEF one without clobbering the
3482+ value. */
3483+ ecsymp->symbol.section = bfd_com_section_ptr;
3484+ ecsymp->native->u.syment.n_sclass = C_EOS;
3485+ ecsymp->symbol.udata.p = NULL;
3486+ ecsymp->symbol.value = info->enumsize;
3487+ ecsymp->native->u.syment.n_numaux = 1;
3488+ (ecsymp->native + 1)->fix_tag = 1;
3489+ aux = &((ecsymp->native + 1)->u.auxent);
3490+ aux->x_sym.x_tagndx.p = scsymp->native;
3491+ aux->x_sym.x_misc.x_lnsz.x_size = info->enumsize;
f33182aa 3492+
c66cb070 3493+ coff_record_symbol (info, scsymp);
f33182aa 3494+
c66cb070 3495+ for (i = 0;; i++)
3496+ {
3497+ const char *name = tst->u.ts_enum.names[i];
3498+ if (name == NULL)
3499+ break;
f33182aa 3500+
c66cb070 3501+ /* Synthesize a new internal COFF symbol for the enum. */
3502+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3503+ if (csymp == NULL)
3504+ return FALSE;
4cd5ba0f 3505+
c66cb070 3506+ csymp->symbol.name = xstrdup (name);
3507+ csymp->symbol.flags = BSF_NOT_AT_END;
3508+ csymp->symbol.section = bfd_com_section_ptr;
3509+ csymp->native->u.syment.n_sclass = C_MOE;
3510+ csymp->symbol.udata.p = NULL;
3511+ csymp->symbol.value = tst->u.ts_enum.vals[i];
4cd5ba0f 3512+
c66cb070 3513+ coff_record_symbol (info, csymp);
3514+ }
4cd5ba0f 3515+
c66cb070 3516+ /* Record our endndx field for later fixing. */
3517+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
3518+ fixp->native = scsymp->native + 1; /* points to first AUX */
3519+ fixp->next = NULL;
3520+ if (info->fixes == NULL)
3521+ info->fixes = fixp;
3522+ else
3523+ {
3524+ for (ofp = info->fixes; ofp->next != NULL;)
3525+ ofp = ofp->next;
3526+ ofp->next = fixp;
3527+ }
4cd5ba0f 3528+
c66cb070 3529+ coff_record_symbol (info, ecsymp);
3530+ info->flags |= COFF_FL_FIX_ENDNDX;
4cd5ba0f 3531+
42dd3303 3532+ return TRUE;
3533+}
4cd5ba0f 3534+
c66cb070 3535+/* Emit a non-debugging symbol that came from the input symbol table,
3536+ and has not been claimed by one of the debugging symbols. */
42dd3303 3537+static bfd_boolean
c66cb070 3538+coff_emit_ndebug_sym (info, osymp, localp)
3539+ struct coff_write_handle *info;
3540+ asymbol *osymp;
3541+ bfd_boolean localp;
42dd3303 3542+{
c66cb070 3543+ coff_symbol_type *csymp;
4cd5ba0f 3544+
c66cb070 3545+ /* Create new COFF symbol. */
3546+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3547+ if (csymp == NULL)
3548+ return FALSE;
42dd3303 3549+
c66cb070 3550+ csymp->symbol.name = xstrdup (osymp->name);
3551+ csymp->symbol.value = osymp->value;
3552+ csymp->symbol.flags = localp? BSF_LOCAL: BSF_GLOBAL;
3553+ csymp->symbol.section = osymp->section;
3554+ csymp->symbol.udata.p = NULL;
3555+ csymp->native->u.syment.n_sclass = localp? C_STAT: C_EXT;
3556+ csymp->native->u.syment.n_type = T_NULL;
42dd3303 3557+
c66cb070 3558+ coff_record_symbol (info, csymp);
4cd5ba0f
ER
3559+
3560+ return TRUE;
3561+}
c66cb070 3562+\f
3563+/* The general routine to write out COFF debugging information. This
3564+ synthesizes and accumulates the COFF symbols. Actual symbol table
3565+ output is performed later on by the BFD functions. ABFD is the BFD
3566+ and DHANDLE is the handle for the debugging information. symcountp
3567+ and symppp point to the incoming (parsed) symbol list on entry, and
3568+ will be updated to point to the new symbol table's values upon
3569+ exit. */
4cd5ba0f 3570+
c66cb070 3571+bfd_boolean
3572+write_coff_debugging_info (abfd, dhandle, symcountp, symppp)
3573+ bfd *abfd;
3574+ PTR dhandle;
3575+ long *symcountp;
3576+ asymbol ***symppp;
4cd5ba0f 3577+{
c66cb070 3578+ struct coff_write_handle info;
3579+ long i, l;
3580+ asymbol *symp;
3581+ struct coff_compilation_unit *up;
3582+ coff_symbol_type *csymp;
4cd5ba0f 3583+
c66cb070 3584+ memset ((void *)&info, 0, sizeof info);
4cd5ba0f 3585+
c66cb070 3586+ info.abfd = abfd;
4cd5ba0f 3587+
c66cb070 3588+ info.pointersize = info.enumsize = 4;
4cd5ba0f 3589+
c66cb070 3590+ switch (bfd_get_arch (abfd))
3591+ {
3592+ case bfd_arch_avr:
3593+ info.flags |= COFF_FL_AVR;
3594+ if (strcmp (abfd->xvec->name, "coff-ext-avr") == 0)
3595+ info.flags |= COFF_FL_EXT_AVR;
3596+ /* Fix the builtin type sizes. */
3597+ coff_predef_types[0].size = 2; /* sizeof(int) == 2 */
3598+ coff_predef_types[4].size = 4; /* sizeof(double) == 4 */
3599+ coff_predef_types[6].size = 2; /* sizeof(unsigned int) == 2 */
3600+ info.pointersize = info.enumsize = 2;
3601+ break;
42dd3303 3602+
c66cb070 3603+ default:
3604+ ;
3605+ }
42dd3303 3606+
c66cb070 3607+ coff_copy_symbols(&info, *symcountp, *symppp);
42dd3303 3608+
c66cb070 3609+ if (info.textsect == NULL)
42dd3303 3610+ {
c66cb070 3611+ fprintf (stderr, _("Warning: no \"text\" section found in output file\n"));
3612+ info.textsect = bfd_abs_section_ptr;
3613+ }
3614+ if (info.datasect == NULL)
3615+ {
3616+ fprintf (stderr, _("Warning: no \"data\" section found in output file\n"));
3617+ info.datasect = bfd_abs_section_ptr;
42dd3303 3618+ }
4cd5ba0f 3619+
c66cb070 3620+ if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc,
3621+ sizeof(struct coff_name_type_hash_entry)))
3622+ return FALSE;
4cd5ba0f 3623+
c66cb070 3624+ if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc,
3625+ sizeof(struct coff_struct_hash_entry)))
3626+ return FALSE;
4cd5ba0f 3627+
c66cb070 3628+ if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc,
3629+ sizeof(struct coff_enum_hash_entry)))
3630+ return FALSE;
4cd5ba0f 3631+
c66cb070 3632+ if (! debug_write (dhandle, &coff_fns, (PTR) &info))
3633+ return FALSE;
4cd5ba0f 3634+
c66cb070 3635+ /* If there is an old compilation unit that has got any local
3636+ non-debugging symbols left over, send them out now. */
3637+ if (info.currentfile != NULL && info.currentfile->totsyms != 0)
3638+ for (i = 0; i < info.currentfile->nsyms; i++)
3639+ {
3640+ up = info.currentfile;
42dd3303 3641+
c66cb070 3642+ if (up->syms[i] != NULL)
3643+ {
3644+ coff_emit_ndebug_sym (&info, up->syms[i], TRUE);
3645+ up->syms[i] = NULL;
3646+ up->totsyms--;
3647+ }
3648+ }
42dd3303 3649+
c66cb070 3650+ /* See whether there are any non-debugging symbols left from the
3651+ input symbol table. First look at all local symbols which must
3652+ be from entire compilation units we didn't see yet in the
3653+ debugging information, because anything else has already been
3654+ handled at the end of each compilation unit (like in the loop
3655+ immediately above). Any compilation unit that has already been
3656+ processed that way is supposed to have its "totsyms" counted down
3657+ to 0 now, so we can skip them.
3658+
3659+ Finally, put out all remaining global non-debugging symbols. */
3660+ for (l = 0; l < info.nunits; l++)
3661+ {
3662+ const char *bn;
42dd3303 3663+
c66cb070 3664+ up = info.units + l;
3665+ if (up->totsyms == 0)
3666+ continue;
4cd5ba0f 3667+
c66cb070 3668+ /* Create COFF symbol for this compilation unit. */
3669+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info.abfd, 0, 0);
3670+ if (csymp == NULL)
3671+ return FALSE;
4cd5ba0f 3672+
c66cb070 3673+ bn = bu_basename (up->fname);
4cd5ba0f 3674+
c66cb070 3675+ if (bfd_coff_long_filenames (info.abfd))
3676+ csymp->symbol.name = up->fname;
3677+ else
3678+ csymp->symbol.name = bn;
4cd5ba0f 3679+
c66cb070 3680+ csymp->symbol.value = 0;
3681+ csymp->symbol.udata.p = NULL;
3682+ csymp->native->u.syment.n_sclass = C_FILE;
3683+ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */
3684+ coff_record_symbol (&info, csymp);
4cd5ba0f 3685+
c66cb070 3686+ for (i = 0; i < up->nsyms; i++)
3687+ {
3688+ symp = up->syms[i];
3689+ if (symp == NULL)
3690+ continue;
42dd3303 3691+
c66cb070 3692+ coff_emit_ndebug_sym (&info, symp, TRUE);
3693+ }
42dd3303 3694+ }
3695+
c66cb070 3696+ for (i = 0; i < info.nglobals; i++)
42dd3303 3697+ {
c66cb070 3698+ symp = info.globals[i];
3699+ if (symp == NULL)
3700+ continue;
3701+
3702+ coff_emit_ndebug_sym (&info, symp, FALSE);
42dd3303 3703+ }
42dd3303 3704+
c66cb070 3705+ /* Fixup the AUX entries for the section symbols we have emitted
3706+ earlier (so they are guaranteed to be at the beginning of the
3707+ symbol table). In particular, the line number count (which we
3708+ only have for the text section) is known right now. */
3709+ for (i = 0; i < info.nsecsyms; i++)
42dd3303 3710+ {
c66cb070 3711+ union internal_auxent *aux;
42dd3303 3712+
c66cb070 3713+ csymp = info.secsyms[i];
42dd3303 3714+
c66cb070 3715+ aux = &((csymp->native + 1)->u.auxent);
3716+ aux->x_scn.x_scnlen = csymp->symbol.section->output_section->rawsize;
3717+ aux->x_scn.x_nreloc = csymp->symbol.section->reloc_count;
3718+ if (csymp->symbol.section == info.textsect)
3719+ aux->x_scn.x_nlinno = info.totlnos;
3720+ }
3721+ free (info.secsyms);
42dd3303 3722+
c66cb070 3723+ coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL);
3724+ bfd_hash_table_free (&info.types.root);
42dd3303 3725+
c66cb070 3726+ coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL);
3727+ bfd_hash_table_free (&info.structs.root);
3728+
3729+ coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL);
3730+ bfd_hash_table_free (&info.enums.root);
3731+
3732+ /* FIXME: free all the other stuff remembered in "info". */
3733+
3734+ free (*symppp);
3735+
3736+ *symcountp = info.nsyms;
3737+ *symppp = (asymbol **)info.syms;
4cd5ba0f 3738+
f33182aa 3739+ return TRUE;
3740+}
4cd5ba0f 3741+
c66cb070 3742+/* Start writing out information for a compilation unit. */
4cd5ba0f 3743+
f33182aa 3744+static bfd_boolean
c66cb070 3745+coff_start_compilation_unit (p, filename)
f33182aa 3746+ PTR p;
c66cb070 3747+ const char *filename;
f33182aa 3748+{
3749+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3750+ long i;
3751+ const char *bn;
3752+ bfd_boolean found;
3753+ coff_symbol_type *csymp;
42dd3303 3754+
3755+#if COFF_DEBUG
c66cb070 3756+ printf ("coff_start_compilation_unit(%s)\n", filename);
42dd3303 3757+#endif
3758+
c66cb070 3759+ /* If there is an old compilation unit that has got any local
3760+ non-debugging symbols left over, send them out now. */
3761+ if (info->currentfile != NULL && info->currentfile->totsyms != 0)
3762+ for (i = 0; i < info->currentfile->nsyms; i++)
3763+ {
3764+ struct coff_compilation_unit *up = info->currentfile;
42dd3303 3765+
c66cb070 3766+ if (up->syms[i] != NULL)
3767+ {
3768+ coff_emit_ndebug_sym (info, up->syms[i], TRUE);
3769+ up->syms[i] = NULL;
3770+ up->totsyms--;
3771+ }
3772+ }
4cd5ba0f 3773+
c66cb070 3774+ /* symtab (and thus COFF debugging) symbols can only transfer the
3775+ basename of the file, so strip the dirname */
3776+ bn = bu_basename (filename);
3777+
3778+ for (i = 0, found = FALSE; i < info->nunits; i++)
3779+ {
3780+ if (strcmp (info->units[i].fname, bn) == 0)
42dd3303 3781+ {
c66cb070 3782+ info->currentfile = info->units + i;
3783+ found = TRUE;
3784+ break;
42dd3303 3785+ }
c66cb070 3786+ }
3787+ if (!found)
3788+ {
3789+ fprintf(stderr,
3790+ _("Warning: file %s not found in symbol table, ignoring\n"),
3791+ filename);
3792+ info->currentfile = NULL;
3793+ return TRUE;
3794+ }
3795+
3796+ /* Synthesize a new internal COFF symbol. */
3797+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
3798+ if (csymp == NULL)
3799+ return FALSE;
3800+
3801+ /* Note that coff_fix_symbol_name() [coffgen.c] will fix this for
3802+ us: the symbol name will be replaced by ".file", and the filename
3803+ will be moved to the aux entries. We use the long name obtained
3804+ from the debugging information (that includes the full path) if
3805+ our COFF format supports long filenames, otherwise we only use
3806+ the basename of the file. */
3807+ if (bfd_coff_long_filenames (info->abfd))
3808+ csymp->symbol.name = filename;
3809+ else
3810+ csymp->symbol.name = bn;
3811+ csymp->symbol.value = 0;
3812+ csymp->symbol.udata.p = NULL;
3813+ csymp->native->u.syment.n_sclass = C_FILE;
3814+ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */
3815+ coff_record_symbol (info, csymp);
3816+
3817+ return TRUE;
3818+}
3819+
3820+/* Start writing out information for a particular source file. */
3821+
3822+static bfd_boolean
3823+coff_start_source (p, filename)
3824+ PTR p ATTRIBUTE_UNUSED;
3825+ const char *filename ATTRIBUTE_UNUSED;
3826+{
4cd5ba0f 3827+
c66cb070 3828+#if COFF_DEBUG
3829+ printf ("coff_start_source(%s)\n", filename);
3830+#endif
3831+
3832+ /* COFF cannot handle include filenames. */
4cd5ba0f
ER
3833+
3834+ return TRUE;
3835+}
3836+
c66cb070 3837+/* Push an empty type. This shouldn't normally happen. */
4cd5ba0f
ER
3838+
3839+static bfd_boolean
c66cb070 3840+coff_empty_type (p)
4cd5ba0f 3841+ PTR p;
4cd5ba0f
ER
3842+{
3843+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3844+ struct coff_type_stack *tst;
4cd5ba0f
ER
3845+
3846+#if COFF_DEBUG
c66cb070 3847+ printf ("coff_empty_type()\n");
4cd5ba0f
ER
3848+#endif
3849+
c66cb070 3850+ coff_push_type (TS_EMPTY);
4cd5ba0f 3851+
f33182aa 3852+ return TRUE;
3853+}
4cd5ba0f 3854+
c66cb070 3855+/* Push a void type. */
4cd5ba0f 3856+
f33182aa 3857+static bfd_boolean
c66cb070 3858+coff_void_type (p)
f33182aa 3859+ PTR p;
f33182aa 3860+{
3861+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3862+ struct coff_type_stack *tst;
4cd5ba0f 3863+
f33182aa 3864+#if COFF_DEBUG
c66cb070 3865+ printf ("coff_void_type()\n");
f33182aa 3866+#endif
4cd5ba0f 3867+
c66cb070 3868+ coff_push_type (TS_VOID);
4cd5ba0f
ER
3869+
3870+ return TRUE;
3871+}
4cd5ba0f 3872+
c66cb070 3873+/* Push an integer type. */
4cd5ba0f 3874+
f33182aa 3875+static bfd_boolean
c66cb070 3876+coff_int_type (p, size, unsignedp)
f33182aa 3877+ PTR p;
c66cb070 3878+ unsigned int size;
3879+ bfd_boolean unsignedp;
f33182aa 3880+{
3881+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3882+ struct coff_type_stack *tst;
4cd5ba0f 3883+
f33182aa 3884+#if COFF_DEBUG
c66cb070 3885+ printf ("coff_int_type(%d, %d)\n", size, unsignedp);
f33182aa 3886+#endif
4cd5ba0f 3887+
c66cb070 3888+ coff_push_type (TS_INT);
3889+ tst->u.ts_int.size = size;
3890+ tst->u.ts_int.isunsigned = unsignedp;
4cd5ba0f 3891+
f33182aa 3892+ return TRUE;
3893+}
4cd5ba0f 3894+
c66cb070 3895+/* Push a floating point type. */
4cd5ba0f 3896+
f33182aa 3897+static bfd_boolean
c66cb070 3898+coff_float_type (p, size)
f33182aa 3899+ PTR p;
c66cb070 3900+ unsigned int size;
f33182aa 3901+{
3902+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3903+ struct coff_type_stack *tst;
4cd5ba0f 3904+
f33182aa 3905+#if COFF_DEBUG
c66cb070 3906+ printf ("coff_float_type(%d)\n", size);
f33182aa 3907+#endif
4cd5ba0f 3908+
c66cb070 3909+ coff_push_type (TS_FLOAT);
3910+ tst->u.ts_float.size = size;
4cd5ba0f 3911+
c66cb070 3912+ return TRUE;
3913+}
4cd5ba0f 3914+
c66cb070 3915+/* Push a complex type. */
4cd5ba0f 3916+
c66cb070 3917+static bfd_boolean
3918+coff_complex_type (p, size)
3919+ PTR p;
3920+ unsigned int size ATTRIBUTE_UNUSED;
3921+{
3922+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3923+ struct coff_type_stack *tst;
4cd5ba0f 3924+
c66cb070 3925+#if COFF_DEBUG
3926+ printf ("coff_complex_type(%d)\n", size);
3927+#endif
4cd5ba0f 3928+
c66cb070 3929+ coff_push_type (TS_COMPLEX);
f33182aa 3930+
c66cb070 3931+ return TRUE;
3932+}
4cd5ba0f 3933+
c66cb070 3934+/* Push a bfd_boolean type. */
4cd5ba0f 3935+
c66cb070 3936+static bfd_boolean
3937+coff_bool_type (p, size)
3938+ PTR p;
3939+ unsigned int size;
3940+{
3941+ struct coff_write_handle *info = (struct coff_write_handle *) p;
3942+ struct coff_type_stack *tst;
4cd5ba0f 3943+
c66cb070 3944+#if COFF_DEBUG
3945+ printf ("coff_bool_type(%d)\n", size);
3946+#endif
3947+
3948+ coff_push_type (TS_INT);
3949+ tst->u.ts_int.size = size;
3950+ tst->u.ts_int.isunsigned = TRUE;
4cd5ba0f 3951+
f33182aa 3952+ return TRUE;
4cd5ba0f
ER
3953+}
3954+
c66cb070 3955+/* Push an enum type. */
4cd5ba0f 3956+
f33182aa 3957+static bfd_boolean
c66cb070 3958+coff_enum_type (p, tag, names, vals)
f33182aa 3959+ PTR p;
c66cb070 3960+ const char *tag;
3961+ const char **names;
3962+ bfd_signed_vma *vals;
4cd5ba0f 3963+{
f33182aa 3964+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3965+ struct coff_type_stack *tst;
3966+ char buf[20];
4cd5ba0f 3967+
f33182aa 3968+#if COFF_DEBUG
c66cb070 3969+ int idx;
3970+ printf ("coff_enum_type(%s [", tag);
3971+ for (idx = 0; names[idx] != NULL; idx++)
3972+ printf ("%s -> %d, ", names[idx], (int)vals[idx]);
3973+ printf ("])\n");
f33182aa 3974+#endif
4cd5ba0f 3975+
c66cb070 3976+ coff_push_type (TS_ENUM);
42dd3303 3977+
c66cb070 3978+ if (tag == NULL)
42dd3303 3979+ {
c66cb070 3980+ sprintf(buf, ".%dfake", info->nenums++);
3981+ tst->u.ts_enum.tag.malloctag = xstrdup (buf);
3982+ tst->u.ts_enum.tagismalloced = TRUE;
42dd3303 3983+ }
c66cb070 3984+ else
3985+ tst->u.ts_enum.tag.fixtag = tag;
3986+ tst->u.ts_enum.names = names;
3987+ tst->u.ts_enum.vals = vals;
4cd5ba0f 3988+
f33182aa 3989+ return TRUE;
3990+}
4cd5ba0f 3991+
c66cb070 3992+/* Push a pointer type. */
4cd5ba0f 3993+
f33182aa 3994+static bfd_boolean
c66cb070 3995+coff_pointer_type (p)
f33182aa 3996+ PTR p;
f33182aa 3997+{
3998+ struct coff_write_handle *info = (struct coff_write_handle *) p;
c66cb070 3999+ struct coff_type_stack *tst;
4cd5ba0f 4000+
f33182aa 4001+#if COFF_DEBUG
c66cb070 4002+ printf ("coff_pointer_type()\n");
f33182aa 4003+#endif
4cd5ba0f 4004+
c66cb070 4005+ coff_push_type (TS_POINTER);
42dd3303 4006+
c66cb070 4007+ return TRUE;
4008+}
f33182aa 4009+
c66cb070 4010+/* Push a function type. */
f33182aa 4011+
c66cb070 4012+static bfd_boolean
4013+coff_function_type (p, argcount, varargs)
4014+ PTR p;
4015+ int argcount;
4016+ bfd_boolean varargs ATTRIBUTE_UNUSED;
4017+{
4018+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4019+ struct coff_type_stack *tst;
4cd5ba0f 4020+
c66cb070 4021+#if COFF_DEBUG
4022+ printf ("coff_function_type(%d, %d)\n", argcount, varargs);
4023+#endif
4cd5ba0f 4024+
c66cb070 4025+ coff_push_type (TS_FUNC);
4026+
4027+ /* FIXME should properly discard function arguments */
4028+ if (argcount > -1)
4029+ {
4030+ fprintf (stderr,
4031+ _("coff_function_type() called with positive argcount\n"));
4032+ return FALSE;
4033+ }
4cd5ba0f 4034+
f33182aa 4035+ return TRUE;
4036+}
4cd5ba0f 4037+
c66cb070 4038+/* Push a reference type. */
4cd5ba0f 4039+
f33182aa 4040+static bfd_boolean
c66cb070 4041+coff_reference_type (p)
f33182aa 4042+ PTR p;
4043+{
4044+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4045+
f33182aa 4046+#if COFF_DEBUG
c66cb070 4047+ printf ("coff_reference_type()\n");
f33182aa 4048+#endif
4cd5ba0f 4049+
c66cb070 4050+ coff_complain_unsupp (_("reference"));
4cd5ba0f 4051+
c66cb070 4052+ return TRUE;
4053+}
4cd5ba0f 4054+
c66cb070 4055+/* Push a range type. */
4cd5ba0f 4056+
c66cb070 4057+static bfd_boolean
4058+coff_range_type (p, low, high)
4059+ PTR p;
4060+ bfd_signed_vma low ATTRIBUTE_UNUSED;
4061+ bfd_signed_vma high ATTRIBUTE_UNUSED;
4062+{
4063+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4064+
c66cb070 4065+#if COFF_DEBUG
4066+ printf ("coff_range_type([%d..%d)\n", (int)low, (int)high);
4067+#endif
4cd5ba0f 4068+
c66cb070 4069+ coff_complain_unsupp (_("range"));
4cd5ba0f 4070+
c66cb070 4071+ return TRUE;
4072+}
4cd5ba0f 4073+
c66cb070 4074+/* Push an array type. */
4cd5ba0f 4075+
c66cb070 4076+static bfd_boolean
4077+coff_array_type (p, low, high, stringp)
4078+ PTR p;
4079+ bfd_signed_vma low;
4080+ bfd_signed_vma high;
4081+ bfd_boolean stringp;
4082+{
4083+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4084+ struct coff_type_stack *tst;
4cd5ba0f 4085+
c66cb070 4086+#if COFF_DEBUG
4087+ printf ("coff_array_type([%d..%d], %d)\n",
4088+ (int)low, (int)high, stringp);
4089+#endif
4cd5ba0f 4090+
c66cb070 4091+ /* Pop the range type, but ignore it. COFF doesn't use it. */
4092+ coff_pop_type ();
4cd5ba0f 4093+
c66cb070 4094+ /* FIXME What to do here? */
4095+ if (stringp)
42dd3303 4096+ {
c66cb070 4097+ fprintf(stderr, _("coff_array_type(): stringp == TRUE\n"));
4098+ return FALSE;
42dd3303 4099+ }
4cd5ba0f 4100+
c66cb070 4101+ coff_push_type (TS_ARRAY);
4102+ tst->u.ts_array.low = low;
4103+ tst->u.ts_array.high = high;
4104+
f33182aa 4105+ return TRUE;
4106+}
4cd5ba0f 4107+
c66cb070 4108+/* Push a set type. */
4cd5ba0f 4109+
f33182aa 4110+static bfd_boolean
c66cb070 4111+coff_set_type (p, bitstringp)
f33182aa 4112+ PTR p;
c66cb070 4113+ bfd_boolean bitstringp ATTRIBUTE_UNUSED;
f33182aa 4114+{
4115+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4116+
f33182aa 4117+#if COFF_DEBUG
c66cb070 4118+ printf ("coff_set_type(%d)\n", bitstringp);
f33182aa 4119+#endif
4120+
c66cb070 4121+ coff_complain_unsupp (_("set"));
f33182aa 4122+
4123+ return TRUE;
4cd5ba0f
ER
4124+}
4125+
c66cb070 4126+/* Push an offset type. */
f33182aa 4127+
4128+static bfd_boolean
c66cb070 4129+coff_offset_type (p)
f33182aa 4130+ PTR p;
4cd5ba0f 4131+{
f33182aa 4132+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4133+
f33182aa 4134+#if COFF_DEBUG
c66cb070 4135+ printf ("coff_offset_type()\n");
f33182aa 4136+#endif
4cd5ba0f 4137+
c66cb070 4138+ coff_complain_unsupp (_("offset"));
f33182aa 4139+
c66cb070 4140+ return TRUE;
4141+}
f33182aa 4142+
c66cb070 4143+/* Push a method type. */
42dd3303 4144+
c66cb070 4145+static bfd_boolean
4146+coff_method_type (p, domainp, argcount, varargs)
4147+ PTR p;
4148+ bfd_boolean domainp ATTRIBUTE_UNUSED;
4149+ int argcount ATTRIBUTE_UNUSED;
4150+ bfd_boolean varargs ATTRIBUTE_UNUSED;
4151+{
4152+ struct coff_write_handle *info = (struct coff_write_handle *) p;
42dd3303 4153+
c66cb070 4154+#if COFF_DEBUG
4155+ printf ("coff_method_type(%d, %d, %d)\n",
4156+ domainp, argcount, varargs);
4157+#endif
42dd3303 4158+
c66cb070 4159+ coff_complain_unsupp (_("method"));
f33182aa 4160+
4161+ return TRUE;
4cd5ba0f
ER
4162+}
4163+
c66cb070 4164+/* Push a const version of a type. */
f33182aa 4165+
4166+static bfd_boolean
c66cb070 4167+coff_const_type (p)
4168+ PTR p ATTRIBUTE_UNUSED;
4cd5ba0f 4169+{
f33182aa 4170+
4171+#if COFF_DEBUG
c66cb070 4172+ printf ("coff_const_type()\n");
4cd5ba0f 4173+#endif
4cd5ba0f 4174+
c66cb070 4175+ /* const modifier is ignored by COFF */
42dd3303 4176+
c66cb070 4177+ return TRUE;
4178+}
4cd5ba0f 4179+
c66cb070 4180+/* Push a volatile version of a type. */
4cd5ba0f 4181+
c66cb070 4182+static bfd_boolean
4183+coff_volatile_type (p)
4184+ PTR p ATTRIBUTE_UNUSED;
4185+{
4cd5ba0f 4186+
c66cb070 4187+#if COFF_DEBUG
4188+ printf ("coff_volatile_type()\n");
4189+#endif
4cd5ba0f 4190+
c66cb070 4191+ /* volatile modifier is ignored by COFF */
4cd5ba0f 4192+
f33182aa 4193+ return TRUE;
4194+}
4cd5ba0f 4195+
c66cb070 4196+/* Start outputting a struct. */
4cd5ba0f 4197+
c66cb070 4198+static bfd_boolean
4199+coff_start_struct_type (p, tag, id, structp, size)
4200+ PTR p;
4201+ const char *tag;
4202+ unsigned int id;
4203+ bfd_boolean structp;
4204+ unsigned int size;
4205+{
4206+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4207+ struct coff_type_stack *tst, *savedts;
4208+ struct coff_struct_hash_entry *shash;
4209+ char buf[20];
4210+ const char *name;
4cd5ba0f 4211+
c66cb070 4212+#if COFF_DEBUG
4213+ printf ("coff_start_struct_type(%s, %d, %d, %d)\n",
4214+ tag, id, structp, size);
4215+#endif
4cd5ba0f 4216+
c66cb070 4217+ savedts = info->tstack;
4218+ info->tstack = NULL;
4cd5ba0f 4219+
c66cb070 4220+ coff_push_type (TS_STRUCT);
4cd5ba0f 4221+
c66cb070 4222+ if (tag == NULL)
4223+ {
4224+ sprintf(buf, ".%dfake", id);
4225+ name = tst->u.ts_struct.tag.malloctag = xstrdup (buf);
4226+ tst->u.ts_struct.tagismalloced = TRUE;
4227+ }
4228+ else
4229+ name = tst->u.ts_struct.tag.fixtag = tag;
4230+ tst->u.ts_struct.id = id;
4231+ tst->u.ts_struct.isstruct = structp;
4232+ tst->u.ts_struct.size = size;
4233+ tst->u.ts_struct.savedts = savedts;
4cd5ba0f 4234+
c66cb070 4235+ shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE);
4236+ if (shash != NULL && shash->types != NULL)
4237+ {
4238+#if COFF_DEBUG
4239+ printf ("new %s definition for %s\n",
4240+ tst->u.ts_struct.isstruct? "struct": "union", name);
4241+#endif
4242+ coff_free_struct_info (shash, NULL);
4243+ shash->types = NULL;
4244+ shash->emitted = FALSE;
4245+ }
4246+ else
4247+ (void)coff_struct_hash_lookup (&info->structs, name,
4248+ TRUE, tst->u.ts_struct.tagismalloced);
4cd5ba0f 4249+
c66cb070 4250+ return TRUE;
4251+}
4cd5ba0f 4252+
c66cb070 4253+/* Add a field to a struct. */
f33182aa 4254+
c66cb070 4255+static bfd_boolean
4256+coff_struct_field (p, name, bitpos, bitsize, visibility)
4257+ PTR p;
4258+ const char *name;
4259+ bfd_vma bitpos;
4260+ bfd_vma bitsize;
4261+ enum debug_visibility visibility;
4cd5ba0f 4262+{
c66cb070 4263+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4264+ struct coff_type_stack *tst, *otst;
4265+ struct coff_struct_fields *fp;
4266+ struct coff_struct_hash_entry *shash;
4267+ struct coff_enum_hash_entry *ehash;
4268+ const char *tag;
4cd5ba0f 4269+
c66cb070 4270+#if COFF_DEBUG
4271+ printf ("coff_struct_field(%s, %d, %d, %d)\n",
4272+ name, (int)bitpos, (int)bitsize, (int)visibility);
4273+#endif
4cd5ba0f 4274+
c66cb070 4275+ /* Find the last element on the type stack. */
4276+ assert (info->tstack != NULL);
4277+ for (tst = info->tstack, otst = NULL; tst->next != NULL;)
4278+ {
4279+ otst = tst;
4280+ tst = tst->next;
4281+ }
4282+ if (otst != NULL)
4283+ otst->next = NULL;
4284+
4285+ if (tst->tsk != TS_STRUCT)
4286+ {
4287+ fprintf (stderr, "coff_struct_field() not within structure definition\n");
4288+ return FALSE;
4289+ }
4290+ tst->u.ts_struct.fields = (struct coff_struct_fields *)
4291+ xrealloc (tst->u.ts_struct.fields,
4292+ ++tst->u.ts_struct.nfields * sizeof (struct coff_struct_fields));
4293+ fp = tst->u.ts_struct.fields + (tst->u.ts_struct.nfields - 1);
4294+ fp->name = name;
4295+ fp->bitpos = bitpos;
4296+ fp->bitsize = bitsize;
4297+ fp->visibility = visibility;
4298+ otst = fp->types = info->tstack;
4299+ while (otst->next != NULL)
4300+ otst = otst->next;
4301+ if (otst->tsk == TS_STRUCT && otst->u.ts_struct.shash == NULL)
42dd3303 4302+ {
c66cb070 4303+ if (otst->u.ts_struct.tagismalloced)
4304+ tag = otst->u.ts_struct.tag.malloctag;
4305+ else
4306+ tag = otst->u.ts_struct.tag.fixtag;
4307+ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE);
4308+ assert (shash != NULL);
4309+ if (!shash->emitted)
4310+ {
4311+ if (shash->types == NULL)
4312+ {
4313+ shash->types = (struct coff_type_stack *)
4314+ xmalloc (sizeof (struct coff_type_stack));
4315+ memcpy (shash->types, otst, sizeof (struct coff_type_stack));
4316+ }
4317+ shash->emitted = TRUE;
4318+ coff_emit_struct (info, otst, shash);
4319+ }
42dd3303 4320+ }
c66cb070 4321+ else if (otst->tsk == TS_ENUM)
42dd3303 4322+ {
c66cb070 4323+ if (otst->u.ts_enum.tagismalloced)
4324+ tag = otst->u.ts_enum.tag.malloctag;
4325+ else
4326+ tag = otst->u.ts_enum.tag.fixtag;
4327+ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE);
4328+ assert (ehash != NULL);
4329+ if (!ehash->emitted)
4330+ {
4331+ if (ehash->types == NULL)
4332+ {
4333+ ehash->types = (struct coff_type_stack *)
4334+ xmalloc (sizeof (struct coff_type_stack));
4335+ memcpy (ehash->types, otst, sizeof (struct coff_type_stack));
4336+ }
4337+ ehash->emitted = TRUE;
4338+ coff_emit_enum (info, otst, ehash);
4339+ }
42dd3303 4340+ }
4cd5ba0f 4341+
c66cb070 4342+ info->tstack = tst;
4cd5ba0f 4343+
c66cb070 4344+ return TRUE;
4345+}
4cd5ba0f 4346+
c66cb070 4347+/* Finish up a struct. */
4cd5ba0f 4348+
c66cb070 4349+static bfd_boolean
4350+coff_end_struct_type (p)
4351+ PTR p;
4352+{
4353+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4354+ struct coff_type_stack *tst, *savedts;
4cd5ba0f 4355+
c66cb070 4356+#if COFF_DEBUG
4357+ printf ("coff_end_struct_type()\n");
4358+#endif
4cd5ba0f 4359+
c66cb070 4360+ /* Our struct definition should be the only type stack element by
4361+ now. */
4362+ assert (info->tstack != NULL);
4363+ tst = info->tstack;
4364+ if (tst->tsk != TS_STRUCT || tst->next != NULL)
4365+ {
4366+ fprintf (stderr, "coff_struct_field() not within structure definition\n");
4367+ return FALSE;
4368+ }
f33182aa 4369+
c66cb070 4370+ /* Restore saved type stack, and push our now complete struct
4371+ definition on top. */
4372+ savedts = tst->u.ts_struct.savedts;
4373+ tst->u.ts_struct.savedts = info->tstack;
4374+ info->tstack = savedts;
4375+ tst->next = info->tstack;
4376+ info->tstack = tst;
4377+
4378+ return TRUE;
4cd5ba0f
ER
4379+}
4380+
c66cb070 4381+/* Start outputting a class. */
4cd5ba0f 4382+
c66cb070 4383+static bfd_boolean
4384+coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
4385+ PTR p;
4386+ const char *tag ATTRIBUTE_UNUSED;
4387+ unsigned int id ATTRIBUTE_UNUSED;
4388+ bfd_boolean structp ATTRIBUTE_UNUSED;
4389+ unsigned int size ATTRIBUTE_UNUSED;
4390+ bfd_boolean vptr ATTRIBUTE_UNUSED;
4391+ bfd_boolean ownvptr ATTRIBUTE_UNUSED;
4392+{
4393+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4cd5ba0f 4394+
c66cb070 4395+#if COFF_DEBUG
4396+ printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n",
4397+ tag, id, structp, size, vptr, ownvptr);
4398+#endif
4cd5ba0f 4399+
c66cb070 4400+ coff_complain_unsupp (_("class"));
4cd5ba0f 4401+
c66cb070 4402+ return TRUE;
4403+}
4cd5ba0f 4404+
c66cb070 4405+/* Add a static member to the class on the type stack. */
4cd5ba0f 4406+
c66cb070 4407+static bfd_boolean
4408+coff_class_static_member (p, name, physname, visibility)
4409+ PTR p ATTRIBUTE_UNUSED;
4410+ const char *name ATTRIBUTE_UNUSED;
4411+ const char *physname ATTRIBUTE_UNUSED;
4412+ enum debug_visibility visibility ATTRIBUTE_UNUSED;
4413+{
4cd5ba0f 4414+
c66cb070 4415+#if COFF_DEBUG
4416+ printf ("coff_class_static_member(%s, %s, %d)\n",
4417+ name, physname, (int)visibility);
4418+#endif
4cd5ba0f 4419+
c66cb070 4420+ return TRUE;
4421+}
4cd5ba0f 4422+
c66cb070 4423+/* Add a base class to the class on the type stack. */
4424+
4425+static bfd_boolean
4426+coff_class_baseclass (p, bitpos, virtual, visibility)
4427+ PTR p ATTRIBUTE_UNUSED;
4428+ bfd_vma bitpos ATTRIBUTE_UNUSED;
4429+ bfd_boolean virtual ATTRIBUTE_UNUSED;
4430+ enum debug_visibility visibility ATTRIBUTE_UNUSED;
4cd5ba0f 4431+{
4cd5ba0f 4432+
c66cb070 4433+#if COFF_DEBUG
4434+ printf ("coff_class_baseclass(%d, %d, %d)\n",
4435+ (int)bitpos, virtual, (int)visibility);
4436+#endif
4cd5ba0f 4437+
c66cb070 4438+ return TRUE;
4439+}
4cd5ba0f 4440+
c66cb070 4441+/* Start adding a method to the class on the type stack. */
42dd3303 4442+
c66cb070 4443+static bfd_boolean
4444+coff_class_start_method (p, name)
4445+ PTR p ATTRIBUTE_UNUSED;
4446+ const char *name ATTRIBUTE_UNUSED;
4447+{
42dd3303 4448+
c66cb070 4449+#if COFF_DEBUG
4450+ printf ("coff_class_start_method(%s)\n", name);
4451+#endif
42dd3303 4452+
c66cb070 4453+ return TRUE;
4454+}
42dd3303 4455+
c66cb070 4456+/* Add a variant to the current method. */
42dd3303 4457+
c66cb070 4458+static bfd_boolean
4459+coff_class_method_variant (p, physname, visibility, constp, volatilep,
4460+ voffset, contextp)
4461+ PTR p ATTRIBUTE_UNUSED;
4462+ const char *physname ATTRIBUTE_UNUSED;
4463+ enum debug_visibility visibility ATTRIBUTE_UNUSED;
4464+ bfd_boolean constp ATTRIBUTE_UNUSED;
4465+ bfd_boolean volatilep ATTRIBUTE_UNUSED;
4466+ bfd_vma voffset ATTRIBUTE_UNUSED;
4467+ bfd_boolean contextp ATTRIBUTE_UNUSED;
4468+{
4469+
4470+#if COFF_DEBUG
4471+ printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n",
4472+ physname, (int)visibility, constp, volatilep,
4473+ (int)voffset, contextp);
4474+#endif
4475+
4476+ return TRUE;
f33182aa 4477+}
4cd5ba0f 4478+
c66cb070 4479+/* Add a static variant to the current method. */
4480+
4481+static bfd_boolean
4482+coff_class_static_method_variant (p, physname, visibility, constp, volatilep)
4483+ PTR p ATTRIBUTE_UNUSED;
4484+ const char *physname ATTRIBUTE_UNUSED;
4485+ enum debug_visibility visibility ATTRIBUTE_UNUSED;
4486+ bfd_boolean constp ATTRIBUTE_UNUSED;
4487+ bfd_boolean volatilep ATTRIBUTE_UNUSED;
4488+{
4489+
4490+#if COFF_DEBUG
4491+ printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n",
4492+ physname, (int)visibility, constp, volatilep);
4493+#endif
4494+
4495+ return TRUE;
4496+}
4497+
4498+/* Finish up a method. */
4499+
4500+static bfd_boolean
4501+coff_class_end_method (p)
4502+ PTR p ATTRIBUTE_UNUSED;
4503+{
4504+
4505+#if COFF_DEBUG
4506+ printf ("coff_class_end_method()\n");
4507+#endif
4508+
4509+ return TRUE;
4510+}
4511+
4512+/* Finish up a class. */
4513+
4514+static bfd_boolean
4515+coff_end_class_type (p)
4516+ PTR p ATTRIBUTE_UNUSED;
4517+{
4518+
4519+#if COFF_DEBUG
4520+ printf ("coff_end_class_type()\n");
4521+#endif
4522+
4523+ return TRUE;
4524+}
4525+
4526+/* Push a typedef which was previously defined. */
4527+
4528+static bfd_boolean
4529+coff_typedef_type (p, name)
4530+ PTR p;
4531+ const char *name;
4532+{
4533+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4534+ struct coff_name_type_hash_entry *nthash;
4535+ struct coff_type_stack *tst, *newchain, *newst, *temp;
4536+
4537+#if COFF_DEBUG
4538+ printf ("coff_typedef_type(%s)\n", name);
4539+#endif
4540+
4541+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4542+
4543+ /* nthash should never be NULL, since that would imply that the
4544+ generic debugging code has asked for a typedef which it has not
4545+ yet defined. */
4546+ assert (nthash != NULL);
4547+
4548+ /* Just push the entire type stack snapshot we've got on top of the
4549+ existing typestack. See coff_typdef() below for how this
4550+ works. We need to copy over each element however, since anybody
4551+ popping elements off the typestack is supposed to free() each of
4552+ them. */
4553+
4554+ for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;)
4555+ {
4556+ temp = newst;
4557+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4558+ if (newchain == NULL)
4559+ newchain = newst;
4560+ memcpy (newst, tst, sizeof (*newst));
4561+ if (temp != NULL)
4562+ temp->next = newst;
4563+
4564+ tst = tst->next;
4565+ }
4566+ newst->next = info->tstack;
4567+ info->tstack = newchain;
4568+
4569+ return TRUE;
4570+}
4571+
4572+/* Push a struct, union or class tag. */
4573+
4574+static bfd_boolean
4575+coff_tag_type (p, name, id, kind)
4576+ PTR p;
4577+ const char *name;
4578+ unsigned int id ATTRIBUTE_UNUSED;
4579+ enum debug_type_kind kind;
4580+{
4581+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4582+ struct coff_type_stack *tst, *newchain, *newst, *temp;
4583+ struct coff_struct_hash_entry *shash;
4584+ struct coff_enum_hash_entry *ehash;
4585+ char buf[20];
4586+ bfd_boolean needcopy = FALSE;
4587+ bfd_boolean isstruct = TRUE;
4cd5ba0f 4588+
c66cb070 4589+#if COFF_DEBUG
4590+ printf ("coff_tag_type(%s, %d, %d)\n",
4591+ name, id, kind);
42dd3303 4592+#endif
4593+
c66cb070 4594+ if (name == NULL)
4595+ {
4596+ sprintf(buf, ".%dfake", id);
4597+ needcopy = TRUE;
4598+ }
42dd3303 4599+
c66cb070 4600+ switch (kind)
4601+ {
4602+ case DEBUG_KIND_UNION:
4603+ case DEBUG_KIND_UNION_CLASS:
4604+ isstruct = FALSE;
4605+ /* FALLTHROUGH */
4606+ case DEBUG_KIND_STRUCT:
4607+ case DEBUG_KIND_CLASS:
4608+ shash = coff_struct_hash_lookup (&info->structs,
4609+ name == NULL? buf: name, TRUE, needcopy);
4610+ assert (shash != NULL);
4611+ tst = shash->types;
4612+ if (tst == NULL)
4613+ {
4614+ /* This is a reference to a tag that has not yet been
4615+ defined (i. e., a forward reference). Synthesize a
4616+ ts_struct entry by now, and mark it for later fixup. */
4617+ tst = (struct coff_type_stack *) xmalloc (sizeof *tst);
4618+ memset (tst, 0, sizeof *tst);
4619+ tst->tsk = TS_STRUCT;
4620+ tst->u.ts_struct.isstruct = isstruct;
4621+ tst->u.ts_struct.shash = shash;
4622+ }
4623+ docopystack:
4624+ /* Just push the entire type stack snapshot we've got on top of the
4625+ existing typestack. See coff_typdef() below for how this
4626+ works. We need to copy over each element however, since anybody
4627+ popping elements off the typestack is supposed to free() each of
4628+ them. */
4629+ for (temp = newst = newchain = NULL; tst != NULL;)
4630+ {
4631+ temp = newst;
4632+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst));
4633+ if (newchain == NULL)
4634+ newchain = newst;
4635+ memcpy (newst, tst, sizeof (*newst));
4636+ if (temp != NULL)
4637+ temp->next = newst;
4cd5ba0f 4638+
c66cb070 4639+ tst = tst->next;
4640+ }
4641+ if (newst)
4642+ {
4643+ newst->next = info->tstack;
4644+ info->tstack = newchain;
4645+ }
4646+ break;
4cd5ba0f 4647+
c66cb070 4648+ case DEBUG_KIND_ENUM:
4649+ ehash = coff_enum_hash_lookup (&info->enums,
4650+ name == NULL? buf: name, TRUE, needcopy);
4651+ assert (ehash != NULL);
4652+ tst = ehash->types;
4653+ if (tst == NULL)
4654+ {
4655+ /* This is a reference to a tag that has not yet been
4656+ defined (i. e., a forward reference). Synthesize a
4657+ ts_enum entry by now, and mark it for later fixup. */
4658+ tst = (struct coff_type_stack *) xmalloc (sizeof *tst);
4659+ memset (tst, 0, sizeof *tst);
4660+ tst->tsk = TS_ENUM;
4661+ tst->u.ts_enum.ehash = ehash;
4662+ }
4663+ goto docopystack;
4cd5ba0f 4664+
c66cb070 4665+ default:
4666+ fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"),
4667+ (int)kind);
4668+ return FALSE;
4669+ }
4670+ return TRUE;
4671+}
f33182aa 4672+
c66cb070 4673+/* Define a typedef. */
42dd3303 4674+
c66cb070 4675+static bfd_boolean
4676+coff_typdef (p, name)
4677+ PTR p;
4678+ const char *name;
42dd3303 4679+{
c66cb070 4680+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4681+ struct coff_name_type_hash_entry *nthash;
42dd3303 4682+
c66cb070 4683+#if COFF_DEBUG
4684+ printf ("coff_typdef(%s)\n", name);
4685+#endif
42dd3303 4686+
c66cb070 4687+ /* COFF cannot really handle typedefs. While there is the option to
4688+ mark a symbol using the storage class C_TPDEF (so the COFF reader
4689+ will know that name), there is no way to place a reference to
4690+ that typedef into the just 16 bits COFF reserves for all of its
4691+ type information. Thus, any use of the typedef must always fully
4692+ dereference the typedef again. We do this by "snapshotting" the
4693+ current type stack under the name of our typedef, and later on,
4694+ when BFD debugging tells us to make use of the typedef (in
4695+ coff_typedef_type()), we just look it up, and push all we've got
4696+ completely onto the type stack again. */
42dd3303 4697+
c66cb070 4698+ if (info->tstack == NULL)
4699+ {
4700+ fprintf (stderr, _("coff_typdef() on an empty type stack\n"));
4701+ return FALSE;
4702+ }
42dd3303 4703+
c66cb070 4704+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE);
4705+ if (nthash != NULL)
f33182aa 4706+ {
c66cb070 4707+#if COFF_DEBUG
4708+ printf ("new typedef for %s\n", name);
4709+#endif
4710+ coff_free_type_info (nthash, NULL);
f33182aa 4711+ }
4712+ else
c66cb070 4713+ nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE);
4714+ if (nthash == NULL)
4715+ return FALSE;
4716+ nthash->types = info->tstack;
42dd3303 4717+
c66cb070 4718+ /* If the typestack is "sufficiently complex", emit a C_TPDEF symbol
4719+ for it. We assume it to be sufficiently complex if there are
4720+ either at least two derived types, or one derived type where the
4721+ base type is not a simple scalar one. */
4722+ if (!nthash->emitted
4723+ && info->tstack->next != NULL
4724+ && (info->tstack->next->next != NULL || info->tstack->next->tsk >= TS_ENUM))
f33182aa 4725+ {
c66cb070 4726+ struct coff_type_stack *newchain, *otst, *tst, *ntst;
4727+ coff_symbol_type *csymp;
42dd3303 4728+
c66cb070 4729+ nthash->emitted = TRUE;
f33182aa 4730+
c66cb070 4731+ for (tst = info->tstack, newchain = otst = NULL;
4732+ tst != NULL;
4733+ tst = tst->next)
42dd3303 4734+ {
c66cb070 4735+ ntst = (struct coff_type_stack *)
4736+ xmalloc (sizeof (struct coff_type_stack));
4737+ memcpy (ntst, tst, sizeof (struct coff_type_stack));
4738+ if (otst == NULL)
4739+ newchain = ntst;
4740+ else
4741+ otst->next = ntst;
4742+ otst = ntst;
42dd3303 4743+ }
c66cb070 4744+ info->tstack = newchain;
4745+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4746+ return FALSE;
4747+
4748+ csymp->symbol.name = xstrdup (name);
4749+ csymp->symbol.flags = BSF_NOT_AT_END;
4750+ csymp->symbol.section = bfd_com_section_ptr;
4751+ csymp->native->u.syment.n_sclass = C_TPDEF;
4752+ csymp->symbol.value = 0;
4753+
4754+ coff_record_symbol (info, csymp);
f33182aa 4755+ }
c66cb070 4756+ info->tstack = NULL;
4757+
4758+ return TRUE;
f33182aa 4759+}
4760+
c66cb070 4761+/* Define a tag. */
4762+
4763+static bfd_boolean
4764+coff_tag (p, tag)
4765+ PTR p;
4766+ const char *tag;
f33182aa 4767+{
c66cb070 4768+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4769+ struct coff_type_stack *tst = NULL;
4770+ struct coff_struct_hash_entry *shash;
4771+ struct coff_enum_hash_entry *ehash;
f33182aa 4772+
f33182aa 4773+
c66cb070 4774+#if COFF_DEBUG
4775+ printf ("coff_tag(%s)\n", tag);
4776+#endif
4777+
4778+ if (info->tstack == NULL)
f33182aa 4779+ {
c66cb070 4780+ fprintf (stderr, _("coff_tag() called on an empty typestack\n"));
4781+ return FALSE;
f33182aa 4782+ }
4783+
c66cb070 4784+ switch (info->tstack->tsk)
f33182aa 4785+ {
c66cb070 4786+ case TS_STRUCT:
4787+ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE);
4788+ assert (shash != NULL);
4789+ shash->types = info->tstack;
4790+ info->tstack = NULL;
4791+ break;
42dd3303 4792+
c66cb070 4793+ case TS_ENUM:
4794+ ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE);
4795+ if (ehash != NULL && ehash->types != NULL)
f33182aa 4796+ {
c66cb070 4797+#if COFF_DEBUG
4798+ printf ("new enum definition for %s\n", tag);
4799+#endif
4800+ coff_free_enum_info (ehash, NULL);
f33182aa 4801+ }
c66cb070 4802+ else
4803+ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE);
4804+ if (ehash == NULL)
4805+ return FALSE;
4806+ ehash->types = info->tstack;
4807+ info->tstack = NULL;
4808+ break;
4809+
4810+ default:
4811+ fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk);
4812+ return FALSE;
f33182aa 4813+ }
c66cb070 4814+
4815+ return TRUE;
f33182aa 4816+}
4817+
c66cb070 4818+/* Define an integer constant. */
4819+
4820+static bfd_boolean
4821+coff_int_constant (p, name, val)
4822+ PTR p;
4823+ const char *name ATTRIBUTE_UNUSED;
4824+ bfd_vma val ATTRIBUTE_UNUSED;
f33182aa 4825+{
c66cb070 4826+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 4827+
c66cb070 4828+#if COFF_DEBUG
4829+ printf ("coff_int_constant(%s, %d)\n", name, (int)val);
4830+#endif
f33182aa 4831+
c66cb070 4832+ coff_complain_unsupp (_("int constant"));
f33182aa 4833+
c66cb070 4834+ return TRUE;
4835+}
f33182aa 4836+
c66cb070 4837+/* Define a floating point constant. */
f33182aa 4838+
c66cb070 4839+static bfd_boolean
4840+coff_float_constant (p, name, val)
4841+ PTR p;
4842+ const char *name ATTRIBUTE_UNUSED;
4843+ double val ATTRIBUTE_UNUSED;
4844+{
4845+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 4846+
c66cb070 4847+#if COFF_DEBUG
4848+ printf ("coff_float_constant(%s, %g)\n", name, val);
4849+#endif
f33182aa 4850+
c66cb070 4851+ coff_complain_unsupp (_("float constant"));
f33182aa 4852+
c66cb070 4853+ return TRUE;
4854+}
f33182aa 4855+
c66cb070 4856+/* Define a typed constant. */
f33182aa 4857+
c66cb070 4858+static bfd_boolean
4859+coff_typed_constant (p, name, val)
4860+ PTR p;
4861+ const char *name ATTRIBUTE_UNUSED;
4862+ bfd_vma val ATTRIBUTE_UNUSED;
4863+{
4864+ struct coff_write_handle *info = (struct coff_write_handle *) p;
f33182aa 4865+
c66cb070 4866+#if COFF_DEBUG
4867+ printf ("coff_typed_constant(%s, %d)\n", name, (int)val);
4868+#endif
f33182aa 4869+
c66cb070 4870+ coff_complain_unsupp (_("typed constant"));
f33182aa 4871+
c66cb070 4872+ return TRUE;
4873+}
f33182aa 4874+
c66cb070 4875+/* Record a variable. */
f33182aa 4876+
c66cb070 4877+static bfd_boolean
4878+coff_variable (p, name, kind, val)
4879+ PTR p;
4880+ const char *name;
4881+ enum debug_var_kind kind;
4882+ bfd_vma val;
4883+{
4884+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4885+ unsigned char class;
4886+ asymbol *symp = NULL;
4887+ coff_symbol_type *csymp;
4888+ bfd_boolean global = FALSE;
4889+ flagword flags = BSF_LOCAL;
4890+ bfd_vma vmadiff = 0;
f33182aa 4891+
c66cb070 4892+#if COFF_DEBUG
4893+ printf ("coff_variable(%s, %d, %d)\n",
4894+ name, (int)kind, (int)val);
4895+#endif
f33182aa 4896+
c66cb070 4897+ switch (kind)
4898+ {
4899+ default:
4900+ abort ();
f33182aa 4901+
c66cb070 4902+ case DEBUG_GLOBAL:
4903+ flags = BSF_GLOBAL;
4904+ global = TRUE;
4905+ /* AVR COFF historically used C_EXTDEF for global variables, and
4906+ C_EXT for global functions. Since some AVR COFF consumers
4907+ apparently depend on this, we mimic this behaviour as
4908+ well. */
4909+ class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT;
4910+ break;
f33182aa 4911+
c66cb070 4912+ case DEBUG_STATIC:
4913+ case DEBUG_LOCAL_STATIC:
4914+ class = C_STAT;
4915+ break;
f33182aa 4916+
c66cb070 4917+ case DEBUG_LOCAL:
4918+ class = C_AUTO;
4919+ break;
42dd3303 4920+
c66cb070 4921+ case DEBUG_REGISTER:
4922+ class = C_REG;
4923+ break;
4924+ }
f33182aa 4925+
c66cb070 4926+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
4927+ return FALSE;
f33182aa 4928+
c66cb070 4929+ if (class == C_REG && (info->flags & COFF_FL_AVR) != 0)
f33182aa 4930+ {
c66cb070 4931+ struct coff_private_symdata *priv = (struct coff_private_symdata *)
4932+ csymp->symbol.udata.p;
4933+ val = coff_fixup_avr_register (val, priv->size * 8);
f33182aa 4934+ }
4935+
c66cb070 4936+ csymp->symbol.name = name;
4937+ csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */
f33182aa 4938+
c66cb070 4939+ /* Match the debugging symbol against the input symtab symbols. If
4940+ we found one, use the section information from it. Otherwise, we
4941+ are lost here and just use the absolute section that was
4942+ predeclared by coff_bfd_make_debug_symbol(). C_REG and C_AUTO
4943+ symbols (which we do not attempt to lookup in the symtab symbols
4944+ at all) go into the ABS section anyway. */
4945+ if (class != C_REG && class != C_AUTO)
4946+ {
4947+ symp = coff_find_symbol (info, name, FALSE, global);
4948+ if (symp)
4949+ {
4950+ csymp->symbol.section = symp->section;
4951+ vmadiff = symp->section->vma;
4952+ }
4953+ }
f33182aa 4954+
c66cb070 4955+ /* Symbols are relative to section vma. */
4956+ csymp->symbol.value = val - vmadiff;
4957+ csymp->native->u.syment.n_sclass = class;
4958+ coff_record_symbol (info, csymp);
f33182aa 4959+
c66cb070 4960+ return TRUE;
4961+}
f33182aa 4962+
c66cb070 4963+/* Start outputting a function. */
f33182aa 4964+
c66cb070 4965+static bfd_boolean
4966+coff_start_function (p, name, globalp)
4967+ PTR p;
4968+ const char *name;
4969+ bfd_boolean globalp;
4970+{
4971+ struct coff_write_handle *info = (struct coff_write_handle *) p;
4972+ struct coff_type_stack *tst, *savedts;
f33182aa 4973+
c66cb070 4974+#if COFF_DEBUG
4975+ printf ("coff_start_function(%s, %d)\n",
4976+ name, globalp);
f33182aa 4977+#endif
4978+
c66cb070 4979+ savedts = info->tstack;
4980+ info->tstack = NULL;
f33182aa 4981+
c66cb070 4982+ coff_push_type (TS_FUNC);
f33182aa 4983+
c66cb070 4984+ if (info->funname != NULL)
4985+ {
4986+ fprintf (stderr,
4987+ _("coff_start_function() called twice, pending %s, new %s\n"),
4988+ info->funname, name);
4989+ return FALSE;
4990+ }
4991+ info->funname = name;
4992+ info->funglobal = globalp;
4993+ info->flags |= COFF_FL_START_FCN;
4994+ tst->u.ts_func.savedts = savedts;
f33182aa 4995+
c66cb070 4996+ return TRUE;
4997+}
f33182aa 4998+
c66cb070 4999+/* Output a function parameter. */
f33182aa 5000+
c66cb070 5001+static bfd_boolean
5002+coff_function_parameter (p, name, kind, val)
5003+ PTR p;
5004+ const char *name;
5005+ enum debug_parm_kind kind;
5006+ bfd_vma val;
5007+{
5008+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5009+ coff_symbol_type *csymp;
5010+ unsigned char class;
f33182aa 5011+
c66cb070 5012+#if COFF_DEBUG
5013+ printf ("coff_function_parameter(%s, %d, %d)\n",
5014+ name, (int)kind, (int)val);
5015+#endif
f33182aa 5016+
c66cb070 5017+ switch (kind)
5018+ {
5019+ default:
5020+ abort ();
f33182aa 5021+
c66cb070 5022+ case DEBUG_PARM_STACK:
5023+ class = C_ARG;
5024+ break;
f33182aa 5025+
c66cb070 5026+ case DEBUG_PARM_REG:
5027+ class = C_REGPARM;
5028+ break;
f33182aa 5029+
c66cb070 5030+ case DEBUG_PARM_REFERENCE:
5031+ case DEBUG_PARM_REF_REG:
5032+ fprintf (stderr, _("Reference parameters not available in COFF\n"));
5033+ return TRUE;
5034+ }
f33182aa 5035+
c66cb070 5036+ if (!coff_make_typed_symbol (info, &csymp, TS_FUNC))
5037+ return FALSE;
f33182aa 5038+
c66cb070 5039+ if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0)
f33182aa 5040+ {
c66cb070 5041+ struct coff_private_symdata *priv = (struct coff_private_symdata *)
5042+ csymp->symbol.udata.p;
5043+ val = coff_fixup_avr_register (val, priv->size * 8);
5044+ }
f33182aa 5045+
c66cb070 5046+ csymp->symbol.name = name;
5047+ csymp->symbol.value = val;
5048+ csymp->symbol.flags |= BSF_LOCAL;
5049+ csymp->native->u.syment.n_sclass = class;
f33182aa 5050+
c66cb070 5051+ /* Since function parameters precede the actual function definition,
5052+ defer their output until the function has been created. */
5053+ info->fargs = (coff_symbol_type **)
5054+ xrealloc (info->fargs, ++info->nfargs * sizeof (coff_symbol_type *));
5055+ info->fargs[info->nfargs - 1] = csymp;
5056+
5057+ return TRUE;
5058+}
5059+
5060+/* Start a block. */
5061+
5062+static bfd_boolean
5063+coff_start_block (p, addr)
5064+ PTR p;
5065+ bfd_vma addr;
5066+{
5067+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5068+ struct coff_type_stack *tst, *otst;
5069+ struct coff_fix_stack *fixp, *ofp;
5070+ asymbol *symp;
5071+ coff_symbol_type *csymp;
5072+ unsigned int i;
5073+ bfd_boolean is_start_fcn;
5074+
5075+#if COFF_DEBUG
5076+ printf ("coff_start_block(%#x)\n", (int)addr);
5077+#endif
5078+
5079+ is_start_fcn = info->flags & COFF_FL_START_FCN;
5080+
5081+ if (is_start_fcn)
5082+ {
5083+ /* This is the starting block of a function. We are going to
5084+ write three symbols here, one for the function itself, one
5085+ ".bf" symbol to indicate the begin of the function, and
5086+ finally one ".bb" for the first block inside the function. */
5087+ info->flags &= ~COFF_FL_START_FCN;
5088+
5089+ /* Our function definition should be the only type stack element
5090+ by now. */
5091+ assert (info->tstack != NULL);
5092+ tst = info->tstack;
5093+ if (tst->tsk != TS_FUNC || tst->next != NULL)
5094+ {
5095+ fprintf (stderr,
5096+ _("coff_start_block() not within function definition\n"));
5097+ return FALSE;
5098+ }
5099+
5100+ /* Restore saved type stack, and push our now complete function
5101+ definition on top. */
5102+ info->tstack = tst->u.ts_func.savedts;
5103+ tst->next = info->tstack;
5104+ info->tstack = tst;
5105+
5106+ if (info->currentfile == NULL)
5107+ {
5108+ fprintf (stderr,
5109+ _("Warning: ignoring function %s() outside any compilation unit\n"),
5110+ info->funname);
5111+ for (tst = info->tstack, otst = NULL; tst != NULL;)
5112+ {
5113+ otst = tst;
5114+ tst = otst->next;
5115+ if (otst->tsk == TS_ENUM &&
5116+ otst->u.ts_enum.tagismalloced)
5117+ free (otst->u.ts_enum.tag.malloctag);
5118+ else if (otst->tsk == TS_STRUCT &&
5119+ otst->u.ts_struct.tagismalloced)
5120+ free (otst->u.ts_struct.tag.malloctag);
5121+ free (otst);
5122+ }
5123+ info->tstack = NULL;
5124+ info->funname = NULL;
5125+
5126+ return TRUE;
5127+ }
5128+
5129+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE))
5130+ return FALSE;
5131+
5132+ csymp->symbol.name = info->funname;
5133+ csymp->symbol.flags = BSF_FUNCTION |
5134+ (info->funglobal? BSF_GLOBAL: BSF_LOCAL);
5135+ symp = coff_find_symbol (info, info->funname, TRUE, info->funglobal);
5136+ if (symp == NULL)
5137+ {
5138+ fprintf (stderr,
5139+ _("function %s not found in symbol table, defaulting to \"text\" section\n"),
5140+ info->funname);
5141+ csymp->symbol.section = info->funcsection = info->textsect;
5142+ }
5143+ else
5144+ csymp->symbol.section = info->funcsection = symp->section;
5145+
5146+ /* Symbol addresses are relative to section vma. */
5147+ csymp->symbol.value = addr - info->funcsection->vma;
5148+ csymp->native->u.syment.n_sclass = info->funglobal? C_EXT: C_STAT;
5149+ /* Create two initial line number entries. The first one holds
5150+ the function symbol, the second one is the trailing record
5151+ that is required by coffgen.c::coff_write_native_symbol() to
5152+ have a line number of zero. */
5153+ csymp->lineno = (alent *) xmalloc (2 * sizeof (alent));
5154+ memset (csymp->lineno, 0, 2 * sizeof (alent));
5155+ info->nlnos = 2;
5156+ info->totlnos++;
5157+ csymp->lineno[0].u.sym = (asymbol *)csymp;
5158+ coff_record_symbol (info, csymp);
5159+ info->funcindex = info->nsyms - 1; /* remember for later */
5160+ /* Record our endndx field for later fixing. */
5161+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack));
5162+ fixp->native = csymp->native + 1; /* points to first AUX */
5163+ fixp->next = NULL;
5164+ if (info->fixes == NULL)
5165+ info->fixes = fixp;
5166+ else
5167+ {
5168+ for (ofp = info->fixes; ofp->next != NULL;)
5169+ ofp = ofp->next;
5170+ ofp->next = fixp;
5171+ }
5172+
5173+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5174+ if (csymp == NULL)
5175+ return FALSE;
5176+
5177+ csymp->symbol.name = ".bf";
5178+ csymp->native->u.syment.n_sclass = C_FCN;
5179+ csymp->native->u.syment.n_numaux = 1;
5180+ csymp->symbol.value = addr - info->funcsection->vma;
5181+ csymp->symbol.section = info->funcsection;
5182+ csymp->symbol.udata.p = NULL;
5183+ coff_record_symbol (info, csymp);
42dd3303 5184+ }
f33182aa 5185+
c66cb070 5186+ if (info->funname == NULL)
5187+ return TRUE;
f33182aa 5188+
c66cb070 5189+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5190+ if (csymp == NULL)
5191+ return FALSE;
f33182aa 5192+
c66cb070 5193+ csymp->symbol.name = ".bb";
5194+ csymp->native->u.syment.n_sclass = C_BLOCK;
5195+ csymp->native->u.syment.n_numaux = 1;
5196+ csymp->symbol.value = addr - info->funcsection->vma;
5197+ csymp->symbol.section = info->funcsection;
5198+ csymp->symbol.udata.p = NULL;
5199+ coff_record_symbol (info, csymp);
f33182aa 5200+
c66cb070 5201+ info->flags |= COFF_FL_FIX_BB;
f33182aa 5202+
c66cb070 5203+ /* Output any pending function parameters, if any. */
5204+ if (is_start_fcn && info->nfargs)
5205+ {
5206+ for (i = 0; i < info->nfargs; i++)
5207+ coff_record_symbol (info, info->fargs[i]);
f33182aa 5208+
c66cb070 5209+ free (info->fargs);
5210+ info->fargs = NULL;
5211+ info->nfargs = 0;
5212+ }
f33182aa 5213+
c66cb070 5214+ return TRUE;
5215+}
f33182aa 5216+
c66cb070 5217+/* End a block. */
f33182aa 5218+
c66cb070 5219+static bfd_boolean
5220+coff_end_block (p, addr)
5221+ PTR p;
5222+ bfd_vma addr;
5223+{
5224+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5225+ coff_symbol_type *csymp;
5226+ union internal_auxent *aux;
f33182aa 5227+
c66cb070 5228+#if COFF_DEBUG
5229+ printf ("coff_end_block(%#x)\n", (int)addr);
5230+#endif
f33182aa 5231+
c66cb070 5232+ if (info->funname == NULL)
5233+ return TRUE;
f33182aa 5234+
c66cb070 5235+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5236+ if (csymp == NULL)
5237+ return FALSE;
f33182aa 5238+
c66cb070 5239+ csymp->symbol.name = ".eb";
5240+ csymp->symbol.value = addr - info->funcsection->vma;
5241+ csymp->native->u.syment.n_sclass = C_BLOCK;
5242+ csymp->native->u.syment.n_numaux = 1;
5243+ csymp->symbol.udata.p = NULL;
5244+ csymp->symbol.section = info->funcsection;
5245+ aux = &((csymp->native + 1)->u.auxent);
5246+ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno;
5247+ coff_record_symbol (info, csymp);
f33182aa 5248+
c66cb070 5249+ info->endaddr = addr;
f33182aa 5250+
c66cb070 5251+ return TRUE;
5252+}
f33182aa 5253+
c66cb070 5254+/* End a function. */
f33182aa 5255+
c66cb070 5256+static bfd_boolean
5257+coff_end_function (p)
5258+ PTR p;
5259+{
5260+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5261+ coff_symbol_type *csymp;
5262+ union internal_auxent *aux;
42dd3303 5263+
c66cb070 5264+#if COFF_DEBUG
5265+ printf ("coff_end_function()\n");
f33182aa 5266+#endif
c66cb070 5267+
5268+ if (info->funname == NULL)
5269+ return TRUE;
5270+
5271+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0);
5272+ if (csymp == NULL)
5273+ return FALSE;
5274+
5275+ csymp->symbol.name = ".ef";
5276+ csymp->symbol.value = info->endaddr - info->funcsection->vma;
5277+ csymp->native->u.syment.n_sclass = C_FCN;
5278+ csymp->native->u.syment.n_numaux = 1;
5279+ csymp->symbol.udata.p = NULL;
5280+ csymp->symbol.section = info->funcsection;
5281+ aux = &((csymp->native + 1)->u.auxent);
5282+ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno;
5283+
5284+ coff_record_symbol (info, csymp);
5285+
5286+ csymp = (coff_symbol_type *) info->syms[info->funcindex];
5287+ aux = &((csymp->native + 1)->u.auxent);
5288+ aux->x_sym.x_misc.x_fsize = info->endaddr - csymp->symbol.value;
5289+
5290+ info->flags |= COFF_FL_FIX_ENDNDX;
5291+ info->funname = NULL;
5292+
5293+ return TRUE;
5294+}
5295+
5296+/* Output a line number. */
5297+
5298+static bfd_boolean
5299+coff_lineno (p, file, lineno, addr)
5300+ PTR p;
5301+ const char *file ATTRIBUTE_UNUSED;
5302+ unsigned long lineno;
5303+ bfd_vma addr;
5304+{
5305+ struct coff_write_handle *info = (struct coff_write_handle *) p;
5306+ coff_symbol_type *csymp;
5307+ union internal_auxent *aux;
5308+ long i;
5309+
5310+#if COFF_DEBUG
5311+ printf ("coff_lineno(%s, %ld, %d)\n",
5312+ file, lineno, (int)addr);
42dd3303 5313+#endif
f33182aa 5314+
c66cb070 5315+ /* COFF can inherently only handle line numbers inside of functions.
5316+ If we are not inside a function, punt. */
5317+ if (info->funname == NULL)
5318+ return TRUE;
5319+
5320+ if (info->nlnos == 2)
5321+ {
5322+ /* This is the first line number of this function. Fix the line
5323+ number for the .bf symbol immediately following the start of
5324+ function. We also have to remember the starting line number
5325+ of our function since all line number entries are relative to
5326+ it in COFF. Since regular line numbers must always be
5327+ non-zero, we artificially force the function to start one
5328+ line earlier. */
5329+ csymp = (coff_symbol_type *) info->syms[info->funcindex + 1];
5330+ aux = &((csymp->native + 1)->u.auxent);
5331+ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno;
5332+ info->funlno = lineno - 1;
5333+ }
5334+
5335+ if (info->flags & COFF_FL_FIX_BB)
5336+ {
5337+ /* This is the first line number after one (or more) .bb
5338+ symbols. Fix them. In order to cope with multiple blocks
5339+ starting at the same line number, we walk back the list of
5340+ symbols until we find a C_BLOCK one that had already been
5341+ fixed, or until we find a C_FCN symbol (presumably, the start
5342+ of our current function). */
5343+ info->flags &= ~COFF_FL_FIX_BB;
5344+
5345+ for (i = info->nsyms - 1; i >= 0; i--)
5346+ {
5347+ csymp = (coff_symbol_type *) info->syms[i];
5348+ if (csymp->native->u.syment.n_sclass == C_FCN)
5349+ break;
5350+ if (csymp->native->u.syment.n_sclass == C_BLOCK)
f33182aa 5351+ {
c66cb070 5352+ aux = &((csymp->native + 1)->u.auxent);
5353+ if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0)
5354+ /* already set up properly */
5355+ break;
5356+ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno;
f33182aa 5357+ }
c66cb070 5358+ }
5359+ }
42dd3303 5360+
c66cb070 5361+ csymp = (coff_symbol_type *) info->syms[info->funcindex];
5362+ csymp->lineno = (alent *) xrealloc (csymp->lineno,
5363+ ++info->nlnos * sizeof (alent));
5364+ memset (csymp->lineno + info->nlnos - 1, 0, sizeof (alent));
5365+ if (lineno > info->funlno)
5366+ csymp->lineno[info->nlnos - 2].line_number = lineno - info->funlno;
5367+ else
5368+ /* Line number unreasonable. Can e. g. happen for a line number
5369+ from an include file, which we cannot process in COFF. Just
5370+ set it to the first line, to avoid generating a large unsigned
5371+ short (~ 65000) line number. */
5372+ csymp->lineno[info->nlnos - 2].line_number = 1;
5373+ csymp->lineno[info->nlnos - 2].u.offset = addr;
5374+
5375+ info->lastlno = lineno;
5376+ info->totlnos++;
5377+
5378+ return TRUE;
5379+}
3ccd393f 5380diff -ruwN include/coff/avr.h include/coff/avr.h
5381--- include/coff/avr.h 1970-01-01 05:30:00.000000000 +0530
5382+++ include/coff/avr.h 2010-03-11 12:13:23.381749600 +0530
4cd5ba0f
ER
5383@@ -0,0 +1,110 @@
5384+/* coff information for Atmel AVR.
5385+
5386+ Copyright 2001 Free Software Foundation, Inc.
5387+
5388+ This program is free software; you can redistribute it and/or modify
5389+ it under the terms of the GNU General Public License as published by
5390+ the Free Software Foundation; either version 2 of the License, or
5391+ (at your option) any later version.
5392+
5393+ This program is distributed in the hope that it will be useful,
5394+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5395+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5396+ GNU General Public License for more details.
5397+
5398+ You should have received a copy of the GNU General Public License
5399+ along with this program; if not, write to the Free Software
5400+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
5401+
5402+/* This file was hacked from i860.h */
5403+
5404+#define L_LNNO_SIZE 2
5405+#include "coff/external.h"
5406+
5407+/* Bits for f_flags:
5408+ F_RELFLG relocation info stripped from file
5409+ F_EXEC file is executable (no unresolved external references)
5410+ F_LNNO line numbers stripped from file
5411+ F_LSYMS local symbols stripped from file */
5412+
5413+#define F_RELFLG (0x0001)
5414+#define F_EXEC (0x0002)
5415+#define F_LNNO (0x0004)
5416+#define F_LSYMS (0x0008)
5417+/* Upper nibble of flags always needs to be set. This used to be
5418+ * undocumented, recent information from Atmel says that bit 7 used to
5419+ * differentiate between an old vendor-specific deviation of the
5420+ * format and the current format. */
5421+#define F_JUNK (0x00f0)
5422+#define F_UNUSED (0xff00)
5423+
5424+#define AVRMAGIC 0xa12
5425+
5426+#undef AOUTSZ
5427+#ifdef AVR_EXT_COFF
5428+
5429+/* AVR "extended" COFF format. This uses the optional header ("a.out"
5430+ header) to inform the consumer about some additional features that
5431+ are supported. */
5432+#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */
5433+#define AOUTSZ 28 /* size of optional header in "extended" COFF */
5434+
5435+/* Flags in the optional header; they are stored in the vstamp field. */
5436+#define F_FULLPATHS 0x0001 /* long filenames supported */
5437+#define F_STRUCTINFO 0x0002 /* structure information contained */
5438+#define F_PTRINFO 0x0004 /* inter-segment pointers supported */
5439+
5440+#else /* old AVR COFF */
5441+
5442+#define AOUTSZ 0 /* no a.out for AVR */
5443+#endif
5444+
5445+/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */
5446+/*
5447+ * The following magic number causes AVR Studio 4.x to recognize
5448+ * avr-gcc/GNU binutils produced AVR extended COFF files. By now,
5449+ * the only special treatment for them is that the contents of .data
5450+ * will be appended after .text in the simulator flash.
5451+ *
5452+ * 0x9cc has been chosen since it resembles "gcc". ;-)
5453+ */
5454+#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */
5455+
5456+/* By matching not only the magic number, but also the size of the
5457+ optional a.out header, we can differentiate between both
5458+ formats. */
5459+#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ)
5460+
5461+/* AVR COFF has several anomalities in the way the handle the derived
5462+ type information, and AUX entries, mainly because they apparently
5463+ didn't bother to learn how COFF is supposed to work before they
5464+ started. We fix many of them at the export/import boundary, so all
5465+ the internal generic COFF handling will work mostly as designed. */
5466+
5467+/* NB: these functions are only defined in bfd/coff-avr.c, but also
5468+ used in coff-ext-avr.c, so the latter can only be configured if the
5469+ former is also present. This is certainly always the case
5470+ anyway. */
5471+extern void avr_coff_adjust_sym_in_post
5472+ PARAMS((bfd *, PTR, PTR));
5473+
5474+extern void avr_coff_adjust_sym_out_post
5475+ PARAMS((bfd *, PTR, PTR));
5476+
5477+#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \
5478+ avr_coff_adjust_sym_in_post (ABFD, EXT, INT)
5479+
5480+#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \
5481+ avr_coff_adjust_sym_out_post (ABFD, INT, EXT)
5482+
5483+/********************** RELOCATION DIRECTIVES **********************/
5484+
5485+struct external_reloc
5486+{
5487+ char r_vaddr[4];
5488+ char r_symndx[4];
5489+ char r_type[2];
5490+};
5491+
5492+#define RELOC struct external_reloc
5493+#define RELSZ 10
3ccd393f 5494diff -ruwN include/coff/internal.h include/coff/internal.h
5495--- include/coff/internal.h 2009-09-02 12:51:39.000000000 +0530
5496+++ include/coff/internal.h 2010-03-11 12:13:23.381749600 +0530
5497@@ -646,6 +646,8 @@
4cd5ba0f
ER
5498
5499 };
5500
5501+#define NAUXENTS 10 /* number of pre-allocated aux entries */
5502+
5503 /********************** RELOCATION DIRECTIVES **********************/
5504
5505 struct internal_reloc
This page took 1.466472 seconds and 4 git commands to generate.