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