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