From 148819d89b158be812fb30720ebc20c0d93758e3 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Fri, 16 Dec 2011 22:39:21 +0000 Subject: Upgrade to binutils 2.20.1. Completely reorganize the patches for this port. Patches for new devices are now synchronized with the Atmel AVR tools. The main difference is the naming scheme, as FreeBSD patches start with "patch-", while the Atmel AVR Tools patches end up in ".patch". --- devel/avr-binutils/Makefile | 3 +- devel/avr-binutils/distinfo | 4 +- .../files/patch-300-binutils-2.20.1-avr-size | 521 ++ .../files/patch-301-binutils-2.20.1-avr-coff | 5505 ++++++++++++++++++++ .../files/patch-302-binutils-2.20.1-new-sections | 38 + .../files/patch-303-binutils-2.20.1-as-dwarf | 29 + ...304-binutils-2.20.1-dwarf2-AVRStudio-workaround | 28 + .../patch-305-binutils-2.20.1-assembler-options | 12 + .../files/patch-400-binutils-2.20.1-xmega | 679 +++ .../files/patch-401-binutils-2.20.1-new-devices | 229 + .../files/patch-402-binutils-2.20.1-avrtiny10 | 218 + .../patch-403-binutils-2.20.1-xmega128a1u-64a1u | 42 + .../patch-404-binutils-2.20.1-atxmega16x1-32x1 | 30 + .../files/patch-405-binutils-2.20.1-atxmega128b1 | 36 + .../files/patch-406-binutils-2.20.1-atxmega256a3bu | 34 + .../files/patch-407-binutils-2.20.1-at90pwm161 | 73 + .../patch-408-binutils-2.20.1-atmega16hvb-32hvb | 52 + .../patch-409-binutils-2.20.1-atmega32_5_50_90_pa | 88 + .../files/patch-410-binutils-2.20.1-attiny1634 | 36 + .../files/patch-411-binutils-2.20.1-atmega48pa | 39 + .../files/patch-500-binutils-2.20.1-bug13789 | 377 ++ devel/avr-binutils/files/patch-aa | 50 - devel/avr-binutils/files/patch-as-dwarf | 10 - devel/avr-binutils/files/patch-as-dwarf-avrstudio | 27 - devel/avr-binutils/files/patch-avr-size | 513 -- devel/avr-binutils/files/patch-coff-avr | 5505 -------------------- devel/avr-binutils/files/patch-newdevices | 135 - devel/avr-binutils/files/patch-newsections | 38 - devel/avr-binutils/files/patch-xmega | 663 --- devel/avr-binutils/pkg-descr | 11 +- 30 files changed, 8071 insertions(+), 6954 deletions(-) create mode 100644 devel/avr-binutils/files/patch-300-binutils-2.20.1-avr-size create mode 100644 devel/avr-binutils/files/patch-301-binutils-2.20.1-avr-coff create mode 100644 devel/avr-binutils/files/patch-302-binutils-2.20.1-new-sections create mode 100644 devel/avr-binutils/files/patch-303-binutils-2.20.1-as-dwarf create mode 100644 devel/avr-binutils/files/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround create mode 100644 devel/avr-binutils/files/patch-305-binutils-2.20.1-assembler-options create mode 100644 devel/avr-binutils/files/patch-400-binutils-2.20.1-xmega create mode 100644 devel/avr-binutils/files/patch-401-binutils-2.20.1-new-devices create mode 100644 devel/avr-binutils/files/patch-402-binutils-2.20.1-avrtiny10 create mode 100644 devel/avr-binutils/files/patch-403-binutils-2.20.1-xmega128a1u-64a1u create mode 100644 devel/avr-binutils/files/patch-404-binutils-2.20.1-atxmega16x1-32x1 create mode 100644 devel/avr-binutils/files/patch-405-binutils-2.20.1-atxmega128b1 create mode 100644 devel/avr-binutils/files/patch-406-binutils-2.20.1-atxmega256a3bu create mode 100644 devel/avr-binutils/files/patch-407-binutils-2.20.1-at90pwm161 create mode 100644 devel/avr-binutils/files/patch-408-binutils-2.20.1-atmega16hvb-32hvb create mode 100644 devel/avr-binutils/files/patch-409-binutils-2.20.1-atmega32_5_50_90_pa create mode 100644 devel/avr-binutils/files/patch-410-binutils-2.20.1-attiny1634 create mode 100644 devel/avr-binutils/files/patch-411-binutils-2.20.1-atmega48pa create mode 100644 devel/avr-binutils/files/patch-500-binutils-2.20.1-bug13789 delete mode 100644 devel/avr-binutils/files/patch-aa delete mode 100644 devel/avr-binutils/files/patch-as-dwarf delete mode 100644 devel/avr-binutils/files/patch-as-dwarf-avrstudio delete mode 100644 devel/avr-binutils/files/patch-avr-size delete mode 100644 devel/avr-binutils/files/patch-coff-avr delete mode 100644 devel/avr-binutils/files/patch-newdevices delete mode 100644 devel/avr-binutils/files/patch-newsections delete mode 100644 devel/avr-binutils/files/patch-xmega (limited to 'devel/avr-binutils') diff --git a/devel/avr-binutils/Makefile b/devel/avr-binutils/Makefile index f70babd8a354..a2cae57fc7f4 100644 --- a/devel/avr-binutils/Makefile +++ b/devel/avr-binutils/Makefile @@ -6,8 +6,7 @@ # PORTNAME= binutils -PORTVERSION= 2.20 -PORTREVISION= 2 +PORTVERSION= 2.20.1 CATEGORIES= devel MASTER_SITES= ${MASTER_SITE_SOURCEWARE} MASTER_SITE_SUBDIR= binutils/releases diff --git a/devel/avr-binutils/distinfo b/devel/avr-binutils/distinfo index 65685cda9595..c72193d8513a 100644 --- a/devel/avr-binutils/distinfo +++ b/devel/avr-binutils/distinfo @@ -1,2 +1,2 @@ -SHA256 (binutils-2.20.tar.bz2) = e1df09f0aa3b50154ef93bfefe86d65d01c22cfb44d73299ad95e772133a75b0 -SIZE (binutils-2.20.tar.bz2) = 17506655 +SHA256 (binutils-2.20.1.tar.bz2) = 228b84722d87e88e7fdd36869e590e649ab523a0800a7d53df906498afe6f6f8 +SIZE (binutils-2.20.1.tar.bz2) = 17501436 diff --git a/devel/avr-binutils/files/patch-300-binutils-2.20.1-avr-size b/devel/avr-binutils/files/patch-300-binutils-2.20.1-avr-size new file mode 100644 index 000000000000..e9065e9ec556 --- /dev/null +++ b/devel/avr-binutils/files/patch-300-binutils-2.20.1-avr-size @@ -0,0 +1,521 @@ +AVR specific only +=========================================================== +--- binutils/size.c 2007-08-06 13:56:14.000000000 -0600 ++++ binutils/size.c 2007-09-13 09:13:10.281250000 -0600 +@@ -36,10 +36,31 @@ + #include "getopt.h" + #include "bucomm.h" + +-#ifndef BSD_DEFAULT +-#define BSD_DEFAULT 1 ++typedef enum ++{ ++ format_sysv = 0, ++ format_bsd = 1, ++ format_avr = 2, ++} format_type_t; ++ ++ ++/* Set the default format. */ ++#define FORMAT_DEFAULT_SYSV 0 ++#define FORMAT_DEFAULT_BSD 1 ++#define FORMAT_DEFAULT_AVR 0 ++ ++#if FORMAT_DEFAULT_SYSV ++ #define FORMAT_DEFAULT format_sysv ++ #define FORMAT_NAME "sysv" ++#elif FORMAT_DEFAULT_BSD ++ #define FORMAT_DEFAULT format_bsd ++ #define FORMAT_NAME "berkeley" ++#elif FORMAT_DEFAULT_AVR ++ #define FORMAT_DEFAULT format_avr ++ #define FORMAT_NAME "avr" + #endif + ++ + /* Program options. */ + + static enum +@@ -48,9 +69,8 @@ static enum + } + radix = decimal; + +-/* 0 means use AT&T-style output. */ +-static int berkeley_format = BSD_DEFAULT; + ++format_type_t format = FORMAT_DEFAULT; + static int show_version = 0; + static int show_help = 0; + static int show_totals = 0; +@@ -64,6 +84,246 @@ static bfd_size_type total_textsize; + /* Program exit status. */ + static int return_code = 0; + ++ ++/* AVR Size specific stuff */ ++ ++#define AVR64 64UL ++#define AVR128 128UL ++#define AVR256 256UL ++#define AVR512 512UL ++#define AVR1K 1024UL ++#define AVR2K 2048UL ++#define AVR4K 4096UL ++#define AVR8K 8192UL ++#define AVR16K 16384UL ++#define AVR20K 20480UL ++#define AVR24K 24576UL ++#define AVR32K 32768UL ++#define AVR36K 36864UL ++#define AVR40K 40960UL ++#define AVR64K 65536UL ++#define AVR68K 69632UL ++#define AVR128K 131072UL ++#define AVR136K 139264UL ++#define AVR200K 204800UL ++#define AVR256K 262144UL ++#define AVR264K 270336UL ++ ++typedef struct ++{ ++ char *name; ++ long flash; ++ long ram; ++ long eeprom; ++} avr_device_t; ++ ++avr_device_t avr[] = ++{ ++ {"atxmega256a3", AVR264K, AVR16K, AVR4K}, ++ {"atxmega256a3b", AVR264K, AVR16K, AVR4K}, ++ {"atxmega256d3", AVR264K, AVR16K, AVR4K}, ++ ++ {"atmega2560", AVR256K, AVR8K, AVR4K}, ++ {"atmega2561", AVR256K, AVR8K, AVR4K}, ++ ++ {"atxmega192a3", AVR200K, AVR16K, AVR2K}, ++ {"atxmega192d3", AVR200K, AVR16K, AVR2K}, ++ ++ {"atxmega128a1", AVR136K, AVR8K, AVR2K}, ++ {"atxmega128a1u", AVR136K, AVR8K, AVR2K}, ++ {"atxmega128a3", AVR136K, AVR8K, AVR2K}, ++ {"atxmega128d3", AVR136K, AVR8K, AVR2K}, ++ ++ {"at43usb320", AVR128K, 608UL, 0UL}, ++ {"at90can128", AVR128K, AVR4K, AVR4K}, ++ {"at90usb1286", AVR128K, AVR8K, AVR4K}, ++ {"at90usb1287", AVR128K, AVR8K, AVR4K}, ++ {"atmega128", AVR128K, AVR4K, AVR4K}, ++ {"atmega1280", AVR128K, AVR8K, AVR4K}, ++ {"atmega1281", AVR128K, AVR8K, AVR4K}, ++ {"atmega1284p", AVR128K, AVR16K, AVR4K}, ++ {"atmega128rfa1", AVR128K, AVR16K, AVR4K}, ++ {"atmega103", AVR128K, 4000UL, AVR4K}, ++ ++ {"atxmega64a1", AVR68K, AVR4K, AVR2K}, ++ {"atxmega64a1u", AVR68K, AVR4K, AVR2K}, ++ {"atxmega64a3", AVR68K, AVR4K, AVR2K}, ++ {"atxmega64d3", AVR68K, AVR4K, AVR2K}, ++ ++ {"at90can64", AVR64K, AVR4K, AVR2K}, ++ {"at90scr100", AVR64K, AVR4K, AVR2K}, ++ {"at90usb646", AVR64K, AVR4K, AVR2K}, ++ {"at90usb647", AVR64K, AVR4K, AVR2K}, ++ {"atmega64", AVR64K, AVR4K, AVR2K}, ++ {"atmega640", AVR64K, AVR8K, AVR4K}, ++ {"atmega644", AVR64K, AVR4K, AVR2K}, ++ {"atmega644a", AVR64K, AVR4K, AVR2K}, ++ {"atmega644p", AVR64K, AVR4K, AVR2K}, ++ {"atmega644pa", AVR64K, AVR4K, AVR2K}, ++ {"atmega645", AVR64K, AVR4K, AVR2K}, ++ {"atmega645a", AVR64K, AVR4K, AVR2K}, ++ {"atmega645p", AVR64K, AVR4K, AVR2K}, ++ {"atmega6450", AVR64K, AVR4K, AVR2K}, ++ {"atmega6450a", AVR64K, AVR4K, AVR2K}, ++ {"atmega6450p", AVR64K, AVR4K, AVR2K}, ++ {"atmega649", AVR64K, AVR4K, AVR2K}, ++ {"atmega649a", AVR64K, AVR4K, AVR2K}, ++ {"atmega649p", AVR64K, AVR4K, AVR2K}, ++ {"atmega6490", AVR64K, AVR4K, AVR2K}, ++ {"atmega6490a", AVR64K, AVR4K, AVR2K}, ++ {"atmega6490p", AVR64K, AVR4K, AVR2K}, ++ {"atmega64c1", AVR64K, AVR4K, AVR2K}, ++ {"atmega64hve", AVR64K, AVR4K, AVR1K}, ++ {"atmega64m1", AVR64K, AVR4K, AVR2K}, ++ {"m3000", AVR64K, AVR4K, 0UL}, ++ ++ {"atmega406", AVR40K, AVR2K, AVR512}, ++ ++ {"atxmega32a4", AVR36K, AVR4K, AVR1K}, ++ {"atxmega32d4", AVR36K, AVR4K, AVR1K}, ++ ++ {"at90can32", AVR32K, AVR2K, AVR1K}, ++ {"at94k", AVR32K, AVR4K, 0UL}, ++ {"atmega32", AVR32K, AVR2K, AVR1K}, ++ {"atmega323", AVR32K, AVR2K, AVR1K}, ++ {"atmega324a", AVR32K, AVR2K, AVR1K}, ++ {"atmega324p", AVR32K, AVR2K, AVR1K}, ++ {"atmega324pa", AVR32K, AVR2K, AVR1K}, ++ {"atmega325", AVR32K, AVR2K, AVR1K}, ++ {"atmega325a", AVR32K, AVR2K, AVR1K}, ++ {"atmega325p", AVR32K, AVR2K, AVR1K}, ++ {"atmega3250", AVR32K, AVR2K, AVR1K}, ++ {"atmega3250a", AVR32K, AVR2K, AVR1K}, ++ {"atmega3250p", AVR32K, AVR2K, AVR1K}, ++ {"atmega328", AVR32K, AVR2K, AVR1K}, ++ {"atmega328p", AVR32K, AVR2K, AVR1K}, ++ {"atmega329", AVR32K, AVR2K, AVR1K}, ++ {"atmega329a", AVR32K, AVR2K, AVR1K}, ++ {"atmega329p", AVR32K, AVR2K, AVR1K}, ++ {"atmega329pa", AVR32K, AVR2K, AVR1K}, ++ {"atmega3290", AVR32K, AVR2K, AVR1K}, ++ {"atmega3290a", AVR32K, AVR2K, AVR1K}, ++ {"atmega3290p", AVR32K, AVR2K, AVR1K}, ++ {"atmega32hvb", AVR32K, AVR2K, AVR1K}, ++ {"atmega32c1", AVR32K, AVR2K, AVR1K}, ++ {"atmega32hvb", AVR32K, AVR2K, AVR1K}, ++ {"atmega32m1", AVR32K, AVR2K, AVR1K}, ++ {"atmega32u2", AVR32K, AVR1K, AVR1K}, ++ {"atmega32u4", AVR32K, 2560UL, AVR1K}, ++ {"atmega32u6", AVR32K, 2560UL, AVR1K}, ++ ++ {"at43usb355", AVR24K, 1120UL, 0UL}, ++ ++ {"atxmega16a4", AVR20K, AVR2K, AVR1K}, ++ {"atxmega16d4", AVR20K, AVR2K, AVR1K}, ++ ++ {"at76c711", AVR16K, AVR2K, 0UL}, ++ {"at90pwm216", AVR16K, AVR1K, AVR512}, ++ {"at90pwm316", AVR16K, AVR1K, AVR512}, ++ {"at90usb162", AVR16K, AVR512, AVR512}, ++ {"atmega16", AVR16K, AVR1K, AVR512}, ++ {"atmega16a", AVR16K, AVR1K, AVR512}, ++ {"atmega161", AVR16K, AVR1K, AVR512}, ++ {"atmega162", AVR16K, AVR1K, AVR512}, ++ {"atmega163", AVR16K, AVR1K, AVR512}, ++ {"atmega164", AVR16K, AVR1K, AVR512}, ++ {"atmega164a", AVR16K, AVR1K, AVR512}, ++ {"atmega164p", AVR16K, AVR1K, AVR512}, ++ {"atmega165a", AVR16K, AVR1K, AVR512}, ++ {"atmega165", AVR16K, AVR1K, AVR512}, ++ {"atmega165p", AVR16K, AVR1K, AVR512}, ++ {"atmega168", AVR16K, AVR1K, AVR512}, ++ {"atmega168a", AVR16K, AVR1K, AVR512}, ++ {"atmega168p", AVR16K, AVR1K, AVR512}, ++ {"atmega169", AVR16K, AVR1K, AVR512}, ++ {"atmega169a", AVR16K, AVR1K, AVR512}, ++ {"atmega169p", AVR16K, AVR1K, AVR512}, ++ {"atmega169pa", AVR16K, AVR1K, AVR512}, ++ {"atmega16hva", AVR16K, 768UL, AVR256}, ++ {"atmega16hva2", AVR16K, AVR1K, AVR256}, ++ {"atmega16hvb", AVR16K, AVR1K, AVR512}, ++ {"atmega16m1", AVR16K, AVR1K, AVR512}, ++ {"atmega16u2", AVR16K, AVR512, AVR512}, ++ {"atmega16u4", AVR16K, 1280UL, AVR512}, ++ {"attiny167", AVR16K, AVR512, AVR512}, ++ ++ {"at90c8534", AVR8K, 352UL, AVR512}, ++ {"at90pwm1", AVR8K, AVR512, AVR512}, ++ {"at90pwm2", AVR8K, AVR512, AVR512}, ++ {"at90pwm2b", AVR8K, AVR512, AVR512}, ++ {"at90pwm3", AVR8K, AVR512, AVR512}, ++ {"at90pwm3b", AVR8K, AVR512, AVR512}, ++ {"at90pwm81", AVR8K, AVR256, AVR512}, ++ {"at90s8515", AVR8K, AVR512, AVR512}, ++ {"at90s8535", AVR8K, AVR512, AVR512}, ++ {"at90usb82", AVR8K, AVR512, AVR512}, ++ {"ata6289", AVR8K, AVR512, 320UL}, ++ {"atmega8", AVR8K, AVR1K, AVR512}, ++ {"atmega8515", AVR8K, AVR512, AVR512}, ++ {"atmega8535", AVR8K, AVR512, AVR512}, ++ {"atmega88", AVR8K, AVR1K, AVR512}, ++ {"atmega88a", AVR8K, AVR1K, AVR512}, ++ {"atmega88p", AVR8K, AVR1K, AVR512}, ++ {"atmega88pa", AVR8K, AVR1K, AVR512}, ++ {"atmega8hva", AVR8K, 768UL, AVR256}, ++ {"atmega8u2", AVR8K, AVR512, AVR512}, ++ {"attiny84", AVR8K, AVR512, AVR512}, ++ {"attiny84a", AVR8K, AVR512, AVR512}, ++ {"attiny85", AVR8K, AVR512, AVR512}, ++ {"attiny861", AVR8K, AVR512, AVR512}, ++ {"attiny861a", AVR8K, AVR512, AVR512}, ++ {"attiny87", AVR8K, AVR512, AVR512}, ++ {"attiny88", AVR8K, AVR512, AVR64}, ++ ++ {"at90s4414", AVR4K, 352UL, AVR256}, ++ {"at90s4433", AVR4K, AVR128, AVR256}, ++ {"at90s4434", AVR4K, 352UL, AVR256}, ++ {"atmega48", AVR4K, AVR512, AVR256}, ++ {"atmega48a", AVR4K, AVR512, AVR256}, ++ {"atmega48p", AVR4K, AVR512, AVR256}, ++ {"attiny4313", AVR4K, AVR256, AVR256}, ++ {"attiny43u", AVR4K, AVR256, AVR64}, ++ {"attiny44", AVR4K, AVR256, AVR256}, ++ {"attiny44a", AVR4K, AVR256, AVR256}, ++ {"attiny45", AVR4K, AVR256, AVR256}, ++ {"attiny461", AVR4K, AVR256, AVR256}, ++ {"attiny461a", AVR4K, AVR256, AVR256}, ++ {"attiny48", AVR4K, AVR256, AVR64}, ++ ++ {"at86rf401", AVR2K, 224UL, AVR128}, ++ {"at90s2313", AVR2K, AVR128, AVR128}, ++ {"at90s2323", AVR2K, AVR128, AVR128}, ++ {"at90s2333", AVR2K, 224UL, AVR128}, ++ {"at90s2343", AVR2K, AVR128, AVR128}, ++ {"attiny20", AVR2K, AVR128, 0UL}, ++ {"attiny22", AVR2K, 224UL, AVR128}, ++ {"attiny2313", AVR2K, AVR128, AVR128}, ++ {"attiny2313a", AVR2K, AVR128, AVR128}, ++ {"attiny24", AVR2K, AVR128, AVR128}, ++ {"attiny24a", AVR2K, AVR128, AVR128}, ++ {"attiny25", AVR2K, AVR128, AVR128}, ++ {"attiny26", AVR2K, AVR128, AVR128}, ++ {"attiny261", AVR2K, AVR128, AVR128}, ++ {"attiny261a", AVR2K, AVR128, AVR128}, ++ {"attiny28", AVR2K, 0UL, 0UL}, ++ {"attiny40", AVR2K, AVR256, 0UL}, ++ ++ {"at90s1200", AVR1K, 0UL, AVR64}, ++ {"attiny9", AVR1K, 32UL, 0UL}, ++ {"attiny10", AVR1K, 32UL, 0UL}, ++ {"attiny11", AVR1K, 0UL, AVR64}, ++ {"attiny12", AVR1K, 0UL, AVR64}, ++ {"attiny13", AVR1K, AVR64, AVR64}, ++ {"attiny13a", AVR1K, AVR64, AVR64}, ++ {"attiny15", AVR1K, 0UL, AVR64}, ++ ++ {"attiny4", AVR512, 32UL, 0UL}, ++ {"attiny5", AVR512, 32UL, 0UL}, ++}; ++ ++static char *avrmcu = NULL; ++ ++ + static char *target = NULL; + + /* Forward declarations. */ +@@ -79,7 +337,8 @@ usage (FILE *stream, int status) + fprintf (stream, _(" Displays the sizes of sections inside binary files\n")); + fprintf (stream, _(" If no input file(s) are specified, a.out is assumed\n")); + fprintf (stream, _(" The options are:\n\ +- -A|-B --format={sysv|berkeley} Select output style (default is %s)\n\ ++ -A|-B|-C --format={sysv|berkeley|avr} Select output style (default is %s)\n\ ++ --mcu= MCU name for AVR format only\n\ + -o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex\n\ + -t --totals Display the total sizes (Berkeley only)\n\ + --common Display total size for *COM* syms\n\ +@@ -88,11 +337,7 @@ usage (FILE *stream, int status) + -h --help Display this information\n\ + -v --version Display the program's version\n\ + \n"), +-#if BSD_DEFAULT +- "berkeley" +-#else +- "sysv" +-#endif ++FORMAT_NAME + ); + list_supported_targets (program_name, stream); + if (REPORT_BUGS_TO[0] && status == 0) +@@ -103,6 +359,7 @@ usage (FILE *stream, int status) + #define OPTION_FORMAT (200) + #define OPTION_RADIX (OPTION_FORMAT + 1) + #define OPTION_TARGET (OPTION_RADIX + 1) ++#define OPTION_MCU (OPTION_TARGET + 1) + + static struct option long_options[] = + { +@@ -110,6 +368,7 @@ static struct option long_options[] = + {"format", required_argument, 0, OPTION_FORMAT}, + {"radix", required_argument, 0, OPTION_RADIX}, + {"target", required_argument, 0, OPTION_TARGET}, ++ {"mcu", required_argument, 0, 203}, + {"totals", no_argument, &show_totals, 1}, + {"version", no_argument, &show_version, 1}, + {"help", no_argument, &show_help, 1}, +@@ -141,7 +399,7 @@ main (int argc, char **argv) + bfd_init (); + set_default_bfd_target (); + +- while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options, ++ while ((c = getopt_long (argc, argv, "ABCHhVvdfotx", long_options, + (int *) 0)) != EOF) + switch (c) + { +@@ -150,11 +409,15 @@ main (int argc, char **argv) + { + case 'B': + case 'b': +- berkeley_format = 1; ++ format = format_bsd; + break; + case 'S': + case 's': +- berkeley_format = 0; ++ format = format_sysv; ++ break; ++ case 'A': ++ case 'a': ++ format = format_avr; + break; + default: + non_fatal (_("invalid argument to --format: %s"), optarg); +@@ -162,6 +424,10 @@ main (int argc, char **argv) + } + break; + ++ case OPTION_MCU: ++ avrmcu = optarg; ++ break; ++ + case OPTION_TARGET: + target = optarg; + break; +@@ -190,11 +457,14 @@ main (int argc, char **argv) + break; + + case 'A': +- berkeley_format = 0; ++ format = format_sysv; + break; + case 'B': +- berkeley_format = 1; ++ format = format_bsd; + break; ++ case 'C': ++ format = format_avr; ++ break; + case 'v': + case 'V': + show_version = 1; +@@ -240,7 +509,7 @@ main (int argc, char **argv) + for (; optind < argc;) + display_file (argv[optind++]); + +- if (show_totals && berkeley_format) ++ if (show_totals && format == format_bsd) + { + bfd_size_type total = total_textsize + total_datasize + total_bsssize; + +@@ -599,13 +869,117 @@ print_sysv_format (bfd *file) + printf ("\n\n"); + } + ++ ++static avr_device_t * ++avr_find_device (void) ++{ ++ unsigned int i; ++ if (avrmcu != NULL) ++ { ++ for (i = 0; i < sizeof(avr) / sizeof(avr[0]); i++) ++ { ++ if (strcmp(avr[i].name, avrmcu) == 0) ++ { ++ /* Match found */ ++ return (&avr[i]); ++ } ++ } ++ } ++ return (NULL); ++} ++ ++ ++ ++static void ++print_avr_format (bfd *file) ++{ ++ char *avr_name = "Unknown"; ++ int flashmax = 0; ++ int rammax = 0; ++ int eeprommax = 0; ++ asection *section; ++ bfd_size_type datasize = 0; ++ bfd_size_type textsize = 0; ++ bfd_size_type bsssize = 0; ++ bfd_size_type bootloadersize = 0; ++ bfd_size_type noinitsize = 0; ++ bfd_size_type eepromsize = 0; ++ ++ avr_device_t *avrdevice = avr_find_device(); ++ if (avrdevice != NULL) ++ { ++ avr_name = avrdevice->name; ++ flashmax = avrdevice->flash; ++ rammax = avrdevice->ram; ++ eeprommax = avrdevice->eeprom; ++ } ++ ++ if ((section = bfd_get_section_by_name (file, ".data")) != NULL) ++ datasize = bfd_section_size (file, section); ++ if ((section = bfd_get_section_by_name (file, ".text")) != NULL) ++ textsize = bfd_section_size (file, section); ++ if ((section = bfd_get_section_by_name (file, ".bss")) != NULL) ++ bsssize = bfd_section_size (file, section); ++ if ((section = bfd_get_section_by_name (file, ".bootloader")) != NULL) ++ bootloadersize = bfd_section_size (file, section); ++ if ((section = bfd_get_section_by_name (file, ".noinit")) != NULL) ++ noinitsize = bfd_section_size (file, section); ++ if ((section = bfd_get_section_by_name (file, ".eeprom")) != NULL) ++ eepromsize = bfd_section_size (file, section); ++ ++ bfd_size_type text = textsize + datasize + bootloadersize; ++ bfd_size_type data = datasize + bsssize + noinitsize; ++ bfd_size_type eeprom = eepromsize; ++ ++ printf ("AVR Memory Usage\n" ++ "----------------\n" ++ "Device: %s\n\n", avr_name); ++ ++ /* Text size */ ++ printf ("Program:%8ld bytes", text); ++ if (flashmax > 0) ++ { ++ printf (" (%2.1f%% Full)", ((float)text / flashmax) * 100); ++ } ++ printf ("\n(.text + .data + .bootloader)\n\n"); ++ ++ /* Data size */ ++ printf ("Data: %8ld bytes", data); ++ if (rammax > 0) ++ { ++ printf (" (%2.1f%% Full)", ((float)data / rammax) * 100); ++ } ++ printf ("\n(.data + .bss + .noinit)\n\n"); ++ ++ /* EEPROM size */ ++ if (eeprom > 0) ++ { ++ printf ("EEPROM: %8ld bytes", eeprom); ++ if (eeprommax > 0) ++ { ++ printf (" (%2.1f%% Full)", ((float)eeprom / eeprommax) * 100); ++ } ++ printf ("\n(.eeprom)\n\n"); ++ } ++} ++ ++ + static void + print_sizes (bfd *file) + { + if (show_common) + calculate_common_size (file); +- if (berkeley_format) +- print_berkeley_format (file); +- else +- print_sysv_format (file); ++ switch (format) ++ { ++ case format_sysv: ++ print_sysv_format (file); ++ break; ++ case format_bsd: ++ print_berkeley_format (file); ++ break; ++ case format_avr: ++ default: ++ print_avr_format (file); ++ break; ++ } + } diff --git a/devel/avr-binutils/files/patch-301-binutils-2.20.1-avr-coff b/devel/avr-binutils/files/patch-301-binutils-2.20.1-avr-coff new file mode 100644 index 000000000000..c21327f43c73 --- /dev/null +++ b/devel/avr-binutils/files/patch-301-binutils-2.20.1-avr-coff @@ -0,0 +1,5505 @@ +diff -ruwN bfd/Makefile.am bfd/Makefile.am +--- bfd/Makefile.am 2009-10-16 17:17:44.000000000 +0530 ++++ bfd/Makefile.am 2010-03-11 12:13:23.069283600 +0530 +@@ -228,6 +228,8 @@ + coff-apollo.lo \ + coff-arm.lo \ + coff-aux.lo \ ++ coff-avr.lo \ ++ coff-ext-avr.lo \ + coff-go32.lo \ + coff-h8300.lo \ + coff-h8500.lo \ +@@ -411,6 +413,8 @@ + coff-apollo.c \ + coff-arm.c \ + coff-aux.c \ ++ coff-avr.c \ ++ coff-ext-avr.c \ + coff-go32.c \ + coff-h8300.c \ + coff-h8500.c \ +diff -ruwN bfd/Makefile.in bfd/Makefile.in +--- bfd/Makefile.in 2009-10-16 17:17:48.000000000 +0530 ++++ bfd/Makefile.in 2010-03-11 12:13:23.084906900 +0530 +@@ -524,6 +524,8 @@ + coff-apollo.lo \ + coff-arm.lo \ + coff-aux.lo \ ++ coff-avr.lo \ ++ coff-ext-avr.lo \ + coff-go32.lo \ + coff-h8300.lo \ + coff-h8500.lo \ +@@ -707,6 +709,8 @@ + coff-apollo.c \ + coff-arm.c \ + coff-aux.c \ ++ coff-avr.c \ ++ coff-ext-avr.c \ + coff-go32.c \ + coff-h8300.c \ + coff-h8500.c \ +diff -ruwN bfd/coff-avr.c bfd/coff-avr.c +--- bfd/coff-avr.c 1970-01-01 05:30:00.000000000 +0530 ++++ bfd/coff-avr.c 2010-03-11 12:13:23.100530200 +0530 +@@ -0,0 +1,613 @@ ++/* BFD back-end for Atmel AVR COFF files. ++ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 ++ Free Software Foundation, Inc. ++ Created mostly by substituting "avr" for "i860" in coff-i860.c ++ ++This file is part of BFD, the Binary File Descriptor library. ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#include "bfd.h" ++#include "sysdep.h" ++#include "libbfd.h" ++ ++#include "coff/avr.h" ++ ++#include "coff/internal.h" ++ ++#include "libcoff.h" ++ ++static bfd_reloc_status_type coff_avr_reloc ++ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); ++static reloc_howto_type *coff_avr_rtype_to_howto ++ PARAMS ((bfd *, asection *, struct internal_reloc *, ++ struct coff_link_hash_entry *, struct internal_syment *, ++ bfd_vma *)); ++static const bfd_target * coff_avr_object_p PARAMS ((bfd *)); ++ ++#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) ++/* The page size is a guess based on ELF. */ ++ ++#define COFF_PAGE_SIZE 0x1000 ++ ++/* For some reason when using avr COFF the value stored in the .text ++ section for a reference to a common symbol is the value itself plus ++ any desired offset. Ian Taylor, Cygnus Support. */ ++ ++/* If we are producing relocateable output, we need to do some ++ adjustments to the object file that are not done by the ++ bfd_perform_relocation function. This function is called by every ++ reloc type to make any required adjustments. */ ++ ++static bfd_reloc_status_type ++coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, ++ error_message) ++ bfd *abfd; ++ arelent *reloc_entry; ++ asymbol *symbol; ++ PTR data; ++ asection *input_section ATTRIBUTE_UNUSED; ++ bfd *output_bfd; ++ char **error_message ATTRIBUTE_UNUSED; ++{ ++ symvalue diff; ++ ++ if (output_bfd == (bfd *) NULL) ++ return bfd_reloc_continue; ++ ++ if (bfd_is_com_section (symbol->section)) ++ { ++ /* We are relocating a common symbol. The current value in the ++ object file is ORIG + OFFSET, where ORIG is the value of the ++ common symbol as seen by the object file when it was compiled ++ (this may be zero if the symbol was undefined) and OFFSET is ++ the offset into the common symbol (normally zero, but may be ++ non-zero when referring to a field in a common structure). ++ ORIG is the negative of reloc_entry->addend, which is set by ++ the CALC_ADDEND macro below. We want to replace the value in ++ the object file with NEW + OFFSET, where NEW is the value of ++ the common symbol which we are going to put in the final ++ object file. NEW is symbol->value. */ ++ diff = symbol->value + reloc_entry->addend; ++ } ++ else ++ { ++ /* For some reason bfd_perform_relocation always effectively ++ ignores the addend for a COFF target when producing ++ relocateable output. This seems to be always wrong for 860 ++ COFF, so we handle the addend here instead. */ ++ diff = reloc_entry->addend; ++ } ++ ++#define DOIT(x) \ ++ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) ++ ++ if (diff != 0) ++ { ++ reloc_howto_type *howto = reloc_entry->howto; ++ unsigned char *addr = (unsigned char *) data + reloc_entry->address; ++ ++ switch (howto->size) ++ { ++ case 0: ++ { ++ char x = bfd_get_8 (abfd, addr); ++ DOIT (x); ++ bfd_put_8 (abfd, x, addr); ++ } ++ break; ++ ++ case 1: ++ { ++ short x = bfd_get_16 (abfd, addr); ++ DOIT (x); ++ bfd_put_16 (abfd, (bfd_vma) x, addr); ++ } ++ break; ++ ++ case 2: ++ { ++ long x = bfd_get_32 (abfd, addr); ++ DOIT (x); ++ bfd_put_32 (abfd, (bfd_vma) x, addr); ++ } ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ /* Now let bfd_perform_relocation finish everything up. */ ++ return bfd_reloc_continue; ++} ++ ++#ifndef PCRELOFFSET ++#define PCRELOFFSET FALSE ++#endif ++ ++static reloc_howto_type howto_table[] = ++{ ++ EMPTY_HOWTO (0), ++ EMPTY_HOWTO (1), ++ EMPTY_HOWTO (2), ++ EMPTY_HOWTO (3), ++ EMPTY_HOWTO (4), ++ EMPTY_HOWTO (5), ++ HOWTO (R_DIR32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "dir32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ /* {7}, */ ++ HOWTO (R_IMAGEBASE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "rva32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ EMPTY_HOWTO (010), ++ EMPTY_HOWTO (011), ++ EMPTY_HOWTO (012), ++ EMPTY_HOWTO (013), ++ EMPTY_HOWTO (014), ++ EMPTY_HOWTO (015), ++ EMPTY_HOWTO (016), ++ HOWTO (R_RELBYTE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "8", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_RELWORD, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "16", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_RELLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRBYTE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "DISP8", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRWORD, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "DISP16", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_avr_reloc, /* special_function */ ++ "DISP32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ PCRELOFFSET) /* pcrel_offset */ ++}; ++ ++/* Turn a howto into a reloc nunmber */ ++ ++#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } ++#define BADMAG(x) AVRBADMAG(x) ++#define AVR 1 /* Customize coffcode.h */ ++ ++#define RTYPE2HOWTO(cache_ptr, dst) \ ++ (cache_ptr)->howto = howto_table + (dst)->r_type; ++ ++/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared ++ library. On some other COFF targets STYP_BSS is normally ++ STYP_NOLOAD. */ ++#define BSS_NOLOAD_IS_SHARED_LIBRARY ++ ++/* Compute the addend of a reloc. If the reloc is to a common symbol, ++ the object file contains the value of the common symbol. By the ++ time this is called, the linker may be using a different symbol ++ from a different object file with a different value. Therefore, we ++ hack wildly to locate the original symbol from this file so that we ++ can make the correct adjustment. This macro sets coffsym to the ++ symbol from the original file, and uses it to set the addend value ++ correctly. If this is not a common symbol, the usual addend ++ calculation is done, except that an additional tweak is needed for ++ PC relative relocs. ++ FIXME: This macro refers to symbols and asect; these are from the ++ calling function, not the macro arguments. */ ++ ++#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ ++ { \ ++ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ ++ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ ++ coffsym = (obj_symbols (abfd) \ ++ + (cache_ptr->sym_ptr_ptr - symbols)); \ ++ else if (ptr) \ ++ coffsym = coff_symbol_from (abfd, ptr); \ ++ if (coffsym != (coff_symbol_type *) NULL \ ++ && coffsym->native->u.syment.n_scnum == 0) \ ++ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ ++ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ ++ && ptr->section != (asection *) NULL) \ ++ cache_ptr->addend = - (ptr->section->vma + ptr->value); \ ++ else \ ++ cache_ptr->addend = 0; \ ++ if (ptr && howto_table[reloc.r_type].pc_relative) \ ++ cache_ptr->addend += asect->vma; \ ++ } ++ ++/* We use the special COFF backend linker. */ ++#define coff_relocate_section _bfd_coff_generic_relocate_section ++ ++static reloc_howto_type * ++coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) ++ bfd *abfd ATTRIBUTE_UNUSED; ++ asection *sec; ++ struct internal_reloc *rel; ++ struct coff_link_hash_entry *h; ++ struct internal_syment *sym; ++ bfd_vma *addendp; ++{ ++ ++ reloc_howto_type *howto; ++ ++ howto = howto_table + rel->r_type; ++ ++ if (howto->pc_relative) ++ *addendp += sec->vma; ++ ++ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) ++ { ++ /* This is a common symbol. The section contents include the ++ size (sym->n_value) as an addend. The relocate_section ++ function will be adding in the final value of the symbol. We ++ need to subtract out the current size in order to get the ++ correct result. */ ++ ++ BFD_ASSERT (h != NULL); ++ ++ /* I think we *do* want to bypass this. If we don't, I have seen some data ++ parameters get the wrong relcation address. If I link two versions ++ with and without this section bypassed and then do a binary comparison, ++ the addresses which are different can be looked up in the map. The ++ case in which this section has been bypassed has addresses which correspond ++ to values I can find in the map. */ ++ *addendp -= sym->n_value; ++ } ++ ++ /* If the output symbol is common (in which case this must be a ++ relocateable link), we need to add in the final size of the ++ common symbol. */ ++ if (h != NULL && h->root.type == bfd_link_hash_common) ++ *addendp += h->root.u.c.size; ++ ++ return howto; ++} ++ ++#define coff_rtype_to_howto coff_avr_rtype_to_howto ++ ++#ifndef bfd_pe_print_pdata ++#define bfd_pe_print_pdata NULL ++#endif ++ ++#include "coffcode.h" ++ ++static const bfd_target * ++coff_avr_object_p(a) ++ bfd *a; ++{ ++ return coff_object_p (a); ++} ++ ++/* Handle all the abominations of AVR COFF: ++ ++ Generic COFF always uses the D1 slot to indicate the "most ++ important" derived type, and the D2...Dn slots for decreasing ++ importance. E. g., a function symbol will always have its DT_FCN ++ element in D1, an array its DT_ARY (its first DT_ARY in a ++ multi-dimensional array). In contrast, AVR COFF expects this most ++ important derived type specifier in the upmost Dn slot that is ++ allocated at all (i. e. that is != 0). ++ ++ Generic COFF says that "Any symbol that satisfies more than one ++ condition [... for AUX entries] should have a union format in its ++ auxiliary entry." AVR COFF uses sepearate AUX entries for multiple ++ derived types, and in some cases (like the ISFCN one), even puts ++ the most important one into the last allocated AUX entry. We ++ join/split them here at the border as well. Note that when ++ generating AUX entries (where we need to split them), the n_numaux ++ field must already have been set up properly (e. g. in ++ binutils/wrcoff.c) since the entry renumbering and pointerization ++ would not work otherwise. Thus, we only split the information into ++ multiple records if n_numaux > 1. For similar reasons, we keep ++ n_numaux > 1 on input to keep the appropriate AUX entries ++ allocated, so a symbol can be reconstructed if it is being passed ++ through one of the GNU tools. ++ ++ Note that this adjustment is called after the symbol itself has ++ been swapped in, but before the AUX entries are swapped in. This ++ is the only hook available that could swap (or merge) AUX entries ++ at all, so we have to operate on the external AUX entries still. */ ++ ++void ++avr_coff_adjust_sym_in_post (abfd, ext, in) ++ bfd *abfd; ++ PTR ext; ++ PTR in; ++{ ++ struct internal_syment *dst = (struct internal_syment *)in; ++ unsigned short dt, bt, ndt; ++ dt = dst->n_type & ~N_BTMASK; ++ bt = BTYPE (dst->n_type); ++ ++ /* Some AVR COFF producers seem to violate the COFF specs, and ++ produce symbols for tag names that have the C_FOO filled in ++ properly, but T_NULL as the base type value. Patch up here, ++ since some of our generic COFF tools (in particular ++ binutils/rdcoff.c) rely on the correct data. */ ++ if (bt == T_NULL) ++ switch (dst->n_sclass) ++ { ++ case C_STRTAG: ++ bt = T_STRUCT; ++ break; ++ ++ case C_UNTAG: ++ bt = T_UNION; ++ break; ++ ++ case C_ENTAG: ++ bt = T_ENUM; ++ break; ++ } ++ ++ /* Swap the derived type slots. */ ++ if (dt != 0) ++ { ++ ndt = 0; ++ while (dt != 0) ++ { ++ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); ++ dt >>= N_TSHIFT; ++ } ++ dst->n_type = (ndt << N_BTSHFT) | bt; ++ } ++ else ++ dst->n_type = bt; ++ ++ /* If the derived type is function, and there is more than one AUX ++ entry, swap the first and the last AUX entry, so the most ++ interesting one will become the first. ++ ++ If the fundamental type is a tagged type (struct/union/enum), try ++ to find the AUX entry describing the tagged type (the one that ++ has x_sym.x_tagndx filled in), and merge the tag index into the ++ first AUX entry. Depending on the actual input file, there might ++ be further DT_PTR entries which we just ignore, since we could ++ not handle that information anyway. */ ++ if (dst->n_numaux > 1 && dst->n_sclass != C_FILE) ++ { ++ AUXENT caux, *auxp1, *auxp2; ++ size_t symesz; ++ unsigned int i; ++ ++ symesz = bfd_coff_symesz (abfd); ++ i = dst->n_numaux; ++ ++ auxp1 = (AUXENT *)((char *)ext + symesz); ++ auxp2 = (AUXENT *)((char *)ext + i * symesz); ++ ++ if (ISFCN (dst->n_type) ++ || (ISPTR(dst->n_type) ++ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))) ++ { ++ caux = *auxp2; ++ *auxp2 = *auxp1; ++ *auxp1 = caux; ++ } ++ else ++ caux = *auxp1; ++ ++ if ((ISFCN (dst->n_type) || ISARY (dst->n_type)) ++ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)) ++ { ++ while (i > 1) ++ { ++ auxp2 = (AUXENT *)((char *)ext + i * symesz); ++ ++ if (auxp2->x_sym.x_tagndx[0] != 0 || auxp2->x_sym.x_tagndx[1] != 0 ++ || auxp2->x_sym.x_tagndx[2] != 0 || auxp2->x_sym.x_tagndx[3] != 0) ++ { ++ memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx, ++ 4 * sizeof (char)); ++ break; ++ } ++ i--; ++ } ++ if (i > 1) ++ *auxp1 = caux; ++ } ++ } ++} ++ ++/* When exporting an AVR COFF file, just undo all that has been done ++ above. Again, we are called after the symbol itself has been ++ swapped out, but before the AUX entries are being written. ++ Unfortunately, we are only given a pointer to the symbol itself, so ++ we have to derive the pointer to the respective aux entries from ++ that address, which is a bit clumsy. */ ++void ++avr_coff_adjust_sym_out_post (abfd, in, ext) ++ bfd *abfd; ++ PTR in; ++ PTR ext; ++{ ++ struct internal_syment *src = (struct internal_syment *)(in); ++ struct external_syment *dst = (struct external_syment *)(ext); ++ unsigned short dt, bt, ndt; ++ ++ dt = src->n_type & ~N_BTMASK; ++ bt = BTYPE (src->n_type); ++ ++ if (dt != 0) ++ { ++ ndt = 0; ++ while (dt != 0) ++ { ++ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); ++ dt >>= N_TSHIFT; ++ } ++ H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type); ++ } ++ ++ if (src->n_numaux > 1 && src->n_sclass != C_FILE) ++ { ++ combined_entry_type *srce, *dste; ++ char *hackp; ++ unsigned int i; ++ ++ /* Recover the original combinend_entry_type *. */ ++ hackp = (char *)in; ++ hackp -= offsetof(combined_entry_type, u.syment); ++ srce = (combined_entry_type *)hackp; ++ srce++; ++ ++ /* We simply duplicate the first AUX entry as many times as ++ needed. Since COFF itself normally uses just a single AUX ++ entry for all the information, this will work -- each COFF ++ consumer will then just pick the fields it is particularly ++ interested in. This would not work for the AVR COFF specific ++ DT_PTR AUX entries, but we don't support them anyway. */ ++ for (i = 1; i < src->n_numaux; i++) ++ { ++ dste = srce + i; ++ *dste = *srce; ++ } ++ } ++} ++ ++const bfd_target ++#ifdef TARGET_SYM ++ TARGET_SYM = ++#else ++ avrcoff_vec = ++#endif ++{ ++#ifdef TARGET_NAME ++ TARGET_NAME, ++#else ++ "coff-avr", /* name */ ++#endif ++ bfd_target_coff_flavour, ++ BFD_ENDIAN_LITTLE, /* data byte order is little */ ++ BFD_ENDIAN_LITTLE, /* header byte order is little */ ++ ++ (HAS_RELOC | EXEC_P | /* object flags */ ++ HAS_LINENO | HAS_DEBUG | ++ HAS_SYMS | HAS_LOCALS | WP_TEXT), ++ ++ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ ++ 0, /* leading char */ ++ '/', /* ar_pad_char */ ++ 15, /* ar_max_namelen */ ++ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ ++ ++/* Note that we allow an object file to be treated as a core file as well. */ ++ {_bfd_dummy_target, coff_avr_object_p, /* bfd_check_format */ ++ bfd_generic_archive_p, coff_avr_object_p}, ++ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ ++ bfd_false}, ++ {bfd_false, coff_write_object_contents, /* bfd_write_contents */ ++ _bfd_write_archive_contents, bfd_false}, ++ ++ BFD_JUMP_TABLE_GENERIC (coff), ++ BFD_JUMP_TABLE_COPY (coff), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), ++ BFD_JUMP_TABLE_SYMBOLS (coff), ++ BFD_JUMP_TABLE_RELOCS (coff), ++ BFD_JUMP_TABLE_WRITE (coff), ++ BFD_JUMP_TABLE_LINK (coff), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ COFF_SWAP_TABLE ++}; +diff -ruwN bfd/coff-ext-avr.c bfd/coff-ext-avr.c +--- bfd/coff-ext-avr.c 1970-01-01 05:30:00.000000000 +0530 ++++ bfd/coff-ext-avr.c 2010-03-11 12:13:23.131776800 +0530 +@@ -0,0 +1,428 @@ ++/* BFD back-end for Atmel AVR "extended" COFF files. ++ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 ++ Free Software Foundation, Inc. ++ This is mostly the same as avr-coff, except of the presence of the ++ COFF optional header. ++ ++This file is part of BFD, the Binary File Descriptor library. ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#include "bfd.h" ++#include "sysdep.h" ++#include "libbfd.h" ++ ++#define AVR_EXT_COFF 1 ++#include "coff/avr.h" ++ ++#include "coff/internal.h" ++ ++#include "libcoff.h" ++ ++static bfd_reloc_status_type coff_ext_avr_reloc ++ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); ++static reloc_howto_type *coff_ext_avr_rtype_to_howto ++ PARAMS ((bfd *, asection *, struct internal_reloc *, ++ struct coff_link_hash_entry *, struct internal_syment *, ++ bfd_vma *)); ++static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *)); ++ ++#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) ++/* The page size is a guess based on ELF. */ ++ ++#define COFF_PAGE_SIZE 0x1000 ++ ++/* For some reason when using avr COFF the value stored in the .text ++ section for a reference to a common symbol is the value itself plus ++ any desired offset. Ian Taylor, Cygnus Support. */ ++ ++/* If we are producing relocateable output, we need to do some ++ adjustments to the object file that are not done by the ++ bfd_perform_relocation function. This function is called by every ++ reloc type to make any required adjustments. */ ++ ++static bfd_reloc_status_type ++coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, ++ error_message) ++ bfd *abfd; ++ arelent *reloc_entry; ++ asymbol *symbol; ++ PTR data; ++ asection *input_section ATTRIBUTE_UNUSED; ++ bfd *output_bfd; ++ char **error_message ATTRIBUTE_UNUSED; ++{ ++ symvalue diff; ++ ++ if (output_bfd == (bfd *) NULL) ++ return bfd_reloc_continue; ++ ++ if (bfd_is_com_section (symbol->section)) ++ { ++ /* We are relocating a common symbol. The current value in the ++ object file is ORIG + OFFSET, where ORIG is the value of the ++ common symbol as seen by the object file when it was compiled ++ (this may be zero if the symbol was undefined) and OFFSET is ++ the offset into the common symbol (normally zero, but may be ++ non-zero when referring to a field in a common structure). ++ ORIG is the negative of reloc_entry->addend, which is set by ++ the CALC_ADDEND macro below. We want to replace the value in ++ the object file with NEW + OFFSET, where NEW is the value of ++ the common symbol which we are going to put in the final ++ object file. NEW is symbol->value. */ ++ diff = symbol->value + reloc_entry->addend; ++ } ++ else ++ { ++ /* For some reason bfd_perform_relocation always effectively ++ ignores the addend for a COFF target when producing ++ relocateable output. This seems to be always wrong for 860 ++ COFF, so we handle the addend here instead. */ ++ diff = reloc_entry->addend; ++ } ++ ++#define DOIT(x) \ ++ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) ++ ++ if (diff != 0) ++ { ++ reloc_howto_type *howto = reloc_entry->howto; ++ unsigned char *addr = (unsigned char *) data + reloc_entry->address; ++ ++ switch (howto->size) ++ { ++ case 0: ++ { ++ char x = bfd_get_8 (abfd, addr); ++ DOIT (x); ++ bfd_put_8 (abfd, x, addr); ++ } ++ break; ++ ++ case 1: ++ { ++ short x = bfd_get_16 (abfd, addr); ++ DOIT (x); ++ bfd_put_16 (abfd, (bfd_vma) x, addr); ++ } ++ break; ++ ++ case 2: ++ { ++ long x = bfd_get_32 (abfd, addr); ++ DOIT (x); ++ bfd_put_32 (abfd, (bfd_vma) x, addr); ++ } ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ /* Now let bfd_perform_relocation finish everything up. */ ++ return bfd_reloc_continue; ++} ++ ++#ifndef PCRELOFFSET ++#define PCRELOFFSET FALSE ++#endif ++ ++static reloc_howto_type howto_table[] = ++{ ++ EMPTY_HOWTO (0), ++ EMPTY_HOWTO (1), ++ EMPTY_HOWTO (2), ++ EMPTY_HOWTO (3), ++ EMPTY_HOWTO (4), ++ EMPTY_HOWTO (5), ++ HOWTO (R_DIR32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "dir32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ /* {7}, */ ++ HOWTO (R_IMAGEBASE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "rva32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ EMPTY_HOWTO (010), ++ EMPTY_HOWTO (011), ++ EMPTY_HOWTO (012), ++ EMPTY_HOWTO (013), ++ EMPTY_HOWTO (014), ++ EMPTY_HOWTO (015), ++ EMPTY_HOWTO (016), ++ HOWTO (R_RELBYTE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "8", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_RELWORD, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "16", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_RELLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRBYTE, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "DISP8", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRWORD, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "DISP16", /* name */ ++ TRUE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ PCRELOFFSET), /* pcrel_offset */ ++ HOWTO (R_PCRLONG, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed, /* complain_on_overflow */ ++ coff_ext_avr_reloc, /* special_function */ ++ "DISP32", /* name */ ++ TRUE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ PCRELOFFSET) /* pcrel_offset */ ++}; ++ ++/* Turn a howto into a reloc nunmber */ ++ ++#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } ++#define BADMAG(x) AVRBADMAG(x) ++#define AVR 1 /* Customize coffcode.h */ ++ ++#define RTYPE2HOWTO(cache_ptr, dst) \ ++ (cache_ptr)->howto = howto_table + (dst)->r_type; ++ ++/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared ++ library. On some other COFF targets STYP_BSS is normally ++ STYP_NOLOAD. */ ++#define BSS_NOLOAD_IS_SHARED_LIBRARY ++ ++/* Compute the addend of a reloc. If the reloc is to a common symbol, ++ the object file contains the value of the common symbol. By the ++ time this is called, the linker may be using a different symbol ++ from a different object file with a different value. Therefore, we ++ hack wildly to locate the original symbol from this file so that we ++ can make the correct adjustment. This macro sets coffsym to the ++ symbol from the original file, and uses it to set the addend value ++ correctly. If this is not a common symbol, the usual addend ++ calculation is done, except that an additional tweak is needed for ++ PC relative relocs. ++ FIXME: This macro refers to symbols and asect; these are from the ++ calling function, not the macro arguments. */ ++ ++#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ ++ { \ ++ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ ++ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ ++ coffsym = (obj_symbols (abfd) \ ++ + (cache_ptr->sym_ptr_ptr - symbols)); \ ++ else if (ptr) \ ++ coffsym = coff_symbol_from (abfd, ptr); \ ++ if (coffsym != (coff_symbol_type *) NULL \ ++ && coffsym->native->u.syment.n_scnum == 0) \ ++ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ ++ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ ++ && ptr->section != (asection *) NULL) \ ++ cache_ptr->addend = - (ptr->section->vma + ptr->value); \ ++ else \ ++ cache_ptr->addend = 0; \ ++ if (ptr && howto_table[reloc.r_type].pc_relative) \ ++ cache_ptr->addend += asect->vma; \ ++ } ++ ++/* We use the special COFF backend linker. */ ++#define coff_relocate_section _bfd_coff_generic_relocate_section ++ ++static reloc_howto_type * ++coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) ++ bfd *abfd ATTRIBUTE_UNUSED; ++ asection *sec; ++ struct internal_reloc *rel; ++ struct coff_link_hash_entry *h; ++ struct internal_syment *sym; ++ bfd_vma *addendp; ++{ ++ ++ reloc_howto_type *howto; ++ ++ howto = howto_table + rel->r_type; ++ ++ if (howto->pc_relative) ++ *addendp += sec->vma; ++ ++ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) ++ { ++ /* This is a common symbol. The section contents include the ++ size (sym->n_value) as an addend. The relocate_section ++ function will be adding in the final value of the symbol. We ++ need to subtract out the current size in order to get the ++ correct result. */ ++ ++ BFD_ASSERT (h != NULL); ++ ++ /* I think we *do* want to bypass this. If we don't, I have seen some data ++ parameters get the wrong relcation address. If I link two versions ++ with and without this section bypassed and then do a binary comparison, ++ the addresses which are different can be looked up in the map. The ++ case in which this section has been bypassed has addresses which correspond ++ to values I can find in the map. */ ++ *addendp -= sym->n_value; ++ } ++ ++ /* If the output symbol is common (in which case this must be a ++ relocateable link), we need to add in the final size of the ++ common symbol. */ ++ if (h != NULL && h->root.type == bfd_link_hash_common) ++ *addendp += h->root.u.c.size; ++ ++ return howto; ++} ++ ++#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto ++ ++#ifndef bfd_pe_print_pdata ++#define bfd_pe_print_pdata NULL ++#endif ++ ++#include "coffcode.h" ++ ++static const bfd_target * ++coff_ext_avr_object_p(a) ++ bfd *a; ++{ ++ return coff_object_p (a); ++} ++ ++const bfd_target ++#ifdef TARGET_SYM ++ TARGET_SYM = ++#else ++ avrextcoff_vec = ++#endif ++{ ++#ifdef TARGET_NAME ++ TARGET_NAME, ++#else ++ "coff-ext-avr", /* name */ ++#endif ++ bfd_target_coff_flavour, ++ BFD_ENDIAN_LITTLE, /* data byte order is little */ ++ BFD_ENDIAN_LITTLE, /* header byte order is little */ ++ ++ (HAS_RELOC | EXEC_P | /* object flags */ ++ HAS_LINENO | HAS_DEBUG | ++ HAS_SYMS | HAS_LOCALS | WP_TEXT), ++ ++ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ ++ 0, /* leading char */ ++ '/', /* ar_pad_char */ ++ 15, /* ar_max_namelen */ ++ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ ++ ++/* Note that we allow an object file to be treated as a core file as well. */ ++ {_bfd_dummy_target, coff_ext_avr_object_p, /* bfd_check_format */ ++ bfd_generic_archive_p, coff_ext_avr_object_p}, ++ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ ++ bfd_false}, ++ {bfd_false, coff_write_object_contents, /* bfd_write_contents */ ++ _bfd_write_archive_contents, bfd_false}, ++ ++ BFD_JUMP_TABLE_GENERIC (coff), ++ BFD_JUMP_TABLE_COPY (coff), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), ++ BFD_JUMP_TABLE_SYMBOLS (coff), ++ BFD_JUMP_TABLE_RELOCS (coff), ++ BFD_JUMP_TABLE_WRITE (coff), ++ BFD_JUMP_TABLE_LINK (coff), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ COFF_SWAP_TABLE ++}; +diff -ruwN bfd/coffcode.h bfd/coffcode.h +--- bfd/coffcode.h 2009-09-10 17:17:12.000000000 +0530 ++++ bfd/coffcode.h 2010-03-11 12:13:23.147400100 +0530 +@@ -1,3 +1,4 @@ ++ + /* Support for the generic parts of most COFF variants, for BFD. + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +@@ -1910,6 +1911,17 @@ + coff->relocbase = 0; + coff->local_toc_sym_map = 0; + ++ /* These members communicate important constants about the symbol ++ table to GDB's symbol-reading code. These `constants' ++ unfortunately vary among coff implementations... */ ++ coff->local_n_btmask = N_BTMASK; ++ coff->local_n_btshft = N_BTSHFT; ++ coff->local_n_tmask = N_TMASK; ++ coff->local_n_tshift = N_TSHIFT; ++ coff->local_symesz = bfd_coff_symesz (abfd); ++ coff->local_auxesz = bfd_coff_auxesz (abfd); ++ coff->local_linesz = bfd_coff_linesz (abfd); ++ + /* make_abs_section(abfd);*/ + + return TRUE; +@@ -1934,17 +1946,6 @@ + + coff->sym_filepos = internal_f->f_symptr; + +- /* These members communicate important constants about the symbol +- table to GDB's symbol-reading code. These `constants' +- unfortunately vary among coff implementations... */ +- coff->local_n_btmask = N_BTMASK; +- coff->local_n_btshft = N_BTSHFT; +- coff->local_n_tmask = N_TMASK; +- coff->local_n_tshift = N_TSHIFT; +- coff->local_symesz = bfd_coff_symesz (abfd); +- coff->local_auxesz = bfd_coff_auxesz (abfd); +- coff->local_linesz = bfd_coff_linesz (abfd); +- + coff->timestamp = internal_f->f_timdat; + + obj_raw_syment_count (abfd) = +@@ -2076,6 +2077,11 @@ + } + break; + #endif ++#ifdef AVRMAGIC ++ case AVRMAGIC: ++ arch = bfd_arch_avr; ++ break; ++#endif + #ifdef MC68MAGIC + case MC68MAGIC: + case M68MAGIC: +@@ -2871,6 +2877,13 @@ + return TRUE; + #endif + ++#ifdef AVRMAGIC ++ case bfd_arch_avr: ++ *magicp = AVRMAGIC; ++ return TRUE; ++ break; ++#endif ++ + #ifdef PPCMAGIC + case bfd_arch_powerpc: + *magicp = PPCMAGIC; +@@ -3698,6 +3711,11 @@ + section.s_page = 0; + #endif + ++#ifdef AVR ++ /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively ++ ignores s_vaddr. */ ++ section.s_paddr = current->vma; ++#endif + #ifdef COFF_WITH_PE + section.s_paddr = 0; + #endif +@@ -4042,6 +4060,17 @@ + internal_a.magic = ZMAGIC; + #endif + ++#ifdef AVR ++ /* a.out is a dummy for non-extended COFF */ ++ internal_a.magic = AVRAOUTMAGIC; ++ /* Upper nibble of f_flags must be set for historical reasons. ++ The upper byte remains blank on coff-avr, so undo the F_AR32WR ++ setting performed above. */ ++ internal_f.f_flags |= F_JUNK; ++ internal_f.f_flags &= ~F_UNUSED; ++#define __A_MAGIC_SET__ ++#endif /* AVR */ ++ + #if defined(PPC_PE) + #define __A_MAGIC_SET__ + internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; +@@ -4109,8 +4138,16 @@ + #endif + } + ++#ifdef AVR_EXT_COFF ++ /* Note that we do not set F_PTRINFO because the GNU toolchain ++ doesn't provide any information about the target of a pointer, ++ so we cannot derive which section our pointer target would be ++ in. */ ++ internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO; ++#else + /* FIXME: Does anybody ever set this to another value? */ + internal_a.vstamp = 0; ++#endif + + /* Now should write relocs, strings, syms. */ + obj_sym_filepos (abfd) = sym_base; +@@ -4668,6 +4705,10 @@ + /* In PE, 0x69 (105) denotes a weak external symbol. */ + case C_NT_WEAK: + #endif ++#ifdef AVR ++ /* Some AVR COFF compilers handle EXTDEF like EXT. */ ++ case C_EXTDEF: /* external definition */ ++#endif + switch (coff_classify_symbol (abfd, &src->u.syment)) + { + case COFF_SYMBOL_GLOBAL: +@@ -4891,7 +4932,9 @@ + && src->u.syment.n_scnum == 0) + break; + /* Fall through. */ ++#if !defined(AVR) + case C_EXTDEF: /* External definition. */ ++#endif + case C_ULABEL: /* Undefined label. */ + case C_USTATIC: /* Undefined static. */ + #ifndef COFF_WITH_PE +diff -ruwN bfd/coffgen.c bfd/coffgen.c +--- bfd/coffgen.c 2009-09-10 17:17:12.000000000 +0530 ++++ bfd/coffgen.c 2010-03-11 12:13:23.163023400 +0530 +@@ -699,6 +699,20 @@ + if (last_file != NULL) + last_file->n_value = native_index; + last_file = &(s->u.syment); ++ if (bfd_get_arch (bfd_ptr) == bfd_arch_avr ++ && bfd_coff_long_filenames (bfd_ptr) ++ && s->u.syment.n_numaux > 0) ++ { ++ /* AVR COFF records long filenames in successive aux ++ records. Adjust the number of aux records ++ required here, so the renumbering will account ++ for them. */ ++ unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr); ++ unsigned int namelen = strlen (coff_symbol_ptr->symbol.name); ++ unsigned int n = (namelen + filnmlen - 1) / filnmlen; ++ ++ s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n; ++ } + } + else + /* Modify the symbol values according to their section and +@@ -827,6 +841,20 @@ + { + if (name_length <= filnmlen) + strncpy (auxent->x_file.x_fname, name, filnmlen); ++ else if (bfd_get_arch (abfd) == bfd_arch_avr) ++ { ++ /* AVR COFF records long filenames in successive aux records. */ ++ int i = 1; ++ while (name_length > filnmlen && i < NAUXENTS) ++ { ++ strncpy (auxent->x_file.x_fname, name, filnmlen); ++ name += filnmlen; ++ name_length -= filnmlen; ++ i++; ++ auxent = &(native + i)->u.auxent; ++ } ++ strncpy (auxent->x_file.x_fname, name, filnmlen); ++ } + else + { + auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; +@@ -1272,6 +1300,10 @@ + if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) + return FALSE; + } ++ if (bfd_get_arch (abfd) == bfd_arch_avr) ++ /* AVR COFF handles long file names in aux records. */ ++ maxlen = name_length; ++ else + maxlen = bfd_coff_filnmlen (abfd); + } + else +@@ -1710,14 +1742,27 @@ + { + /* Ordinary short filename, put into memory anyway. The + Microsoft PE tools sometimes store a filename in +- multiple AUX entries. */ ++ multiple AUX entries. ++ AVR COFF does it that way, too. */ + if (internal_ptr->u.syment.n_numaux > 1 +- && coff_data (abfd)->pe) +- internal_ptr->u.syment._n._n_n._n_offset = +- ((bfd_hostptr_t) +- copy_name (abfd, +- (internal_ptr + 1)->u.auxent.x_file.x_fname, +- internal_ptr->u.syment.n_numaux * symesz)); ++ && (coff_data (abfd)->pe ++ || (bfd_get_arch (abfd) == bfd_arch_avr))) ++ { ++ char *b; ++ unsigned int i; ++ ++ /* We allocate enough storage to fit the contents of ++ this many aux records, and simply append a \0. ++ This ensures the string will always be ++ terminated, even in the case where it just fit ++ into the aux records. */ ++ b = (char *) bfd_alloc (abfd, ++ internal_ptr->u.syment.n_numaux * FILNMLEN + 1); ++ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) b; ++ b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0'; ++ for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN) ++ memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN); ++ } + else + internal_ptr->u.syment._n._n_n._n_offset = + ((bfd_hostptr_t) +@@ -1823,9 +1868,9 @@ + + if (new_symbol == NULL) + return NULL; +- /* @@ The 10 is a guess at a plausible maximum number of aux entries ++ /* @@ The NAUXENTS is a guess at a plausible maximum number of aux entries + (but shouldn't be a constant). */ +- amt = sizeof (combined_entry_type) * 10; ++ amt = sizeof (combined_entry_type) * (NAUXENTS + 1); + new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt); + if (!new_symbol->native) + return NULL; +diff -ruwN bfd/coffswap.h bfd/coffswap.h +--- bfd/coffswap.h 2009-09-07 13:45:15.000000000 +0530 ++++ bfd/coffswap.h 2010-03-11 12:13:23.178646700 +0530 +@@ -383,7 +383,11 @@ + void * ext1, + int type, + int in_class, +- int indx, ++ int indx ++#if defined(AVR) && __GNUC__ ++ __attribute__((unused)) ++#endif ++ , + int numaux, + void * in1) + { +@@ -409,9 +413,13 @@ + #else + if (numaux > 1) + { ++#if defined(AVR) ++ memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT)); ++#else + if (indx == 0) + memcpy (in->x_file.x_fname, ext->x_file.x_fname, + numaux * sizeof (AUXENT)); ++#endif + } + else + memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); +diff -ruwN bfd/config.bfd bfd/config.bfd +--- bfd/config.bfd 2009-08-06 23:08:00.000000000 +0530 ++++ bfd/config.bfd 2010-03-11 12:13:23.178646700 +0530 +@@ -339,6 +339,7 @@ + + avr-*-*) + targ_defvec=bfd_elf32_avr_vec ++ targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec" + ;; + + bfin-*-*) +diff -ruwN bfd/configure bfd/configure +--- bfd/configure 2009-10-16 17:17:47.000000000 +0530 ++++ bfd/configure 2010-03-11 12:13:23.209893300 +0530 +@@ -14782,6 +14782,8 @@ + armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; + armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; + armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; ++ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; ++ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; + b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; + b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; + bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; +diff -ruwN bfd/configure.in bfd/configure.in +--- bfd/configure.in 2009-10-16 17:17:44.000000000 +0530 ++++ bfd/configure.in 2010-03-11 12:13:23.209893300 +0530 +@@ -670,6 +670,8 @@ + armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; + armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; + armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; ++ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; ++ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; + b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; + b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; + bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; +diff -ruwN bfd/targets.c bfd/targets.c +--- bfd/targets.c 2009-09-10 17:17:13.000000000 +0530 ++++ bfd/targets.c 2010-03-11 12:13:23.225516600 +0530 +@@ -564,6 +564,8 @@ + extern const bfd_target armpe_little_vec; + extern const bfd_target armpei_big_vec; + extern const bfd_target armpei_little_vec; ++extern const bfd_target avrcoff_vec; ++extern const bfd_target avrextcoff_vec; + extern const bfd_target b_out_vec_big_host; + extern const bfd_target b_out_vec_little_host; + extern const bfd_target bfd_pei_ia64_vec; +@@ -890,6 +892,8 @@ + &armpe_little_vec, + &armpei_big_vec, + &armpei_little_vec, ++ &avrcoff_vec, ++ &avrextcoff_vec, + &b_out_vec_big_host, + &b_out_vec_little_host, + #ifdef BFD64 +diff -ruwN binutils/Makefile.am binutils/Makefile.am +--- binutils/Makefile.am 2009-09-09 13:43:23.000000000 +0530 ++++ binutils/Makefile.am 2010-03-11 12:13:23.241139900 +0530 +@@ -101,7 +101,7 @@ + resbin.c rescoff.c resrc.c resres.c \ + size.c srconv.c stabs.c strings.c sysdump.c \ + unwind-ia64.c version.c \ +- windres.c winduni.c wrstabs.c \ ++ windres.c winduni.c wrcoff.c wrstabs.c \ + windmc.c mclex.c + + GENERATED_CFILES = \ +@@ -109,7 +109,7 @@ + defparse.c deflex.c nlmheader.c rcparse.c mcparse.c + + DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c +-WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c ++WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c + + # Code shared by all the binutils. + BULIBS = bucomm.c version.c filemode.c +diff -ruwN binutils/Makefile.in binutils/Makefile.in +--- binutils/Makefile.in 2009-09-09 13:43:23.000000000 +0530 ++++ binutils/Makefile.in 2010-03-11 12:13:23.241139900 +0530 +@@ -126,7 +126,7 @@ + nm_new_OBJECTS = $(am_nm_new_OBJECTS) + nm_new_LDADD = $(LDADD) + am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \ +- ieee.$(OBJEXT) rdcoff.$(OBJEXT) ++ ieee.$(OBJEXT) rdcoff.$(OBJEXT) wrcoff.$(OBJEXT) + am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT) + am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \ + rename.$(OBJEXT) $(am__objects_3) $(am__objects_1) +@@ -439,7 +439,7 @@ + resbin.c rescoff.c resrc.c resres.c \ + size.c srconv.c stabs.c strings.c sysdump.c \ + unwind-ia64.c version.c \ +- windres.c winduni.c wrstabs.c \ ++ windres.c winduni.c wrcoff.c wrstabs.c \ + windmc.c mclex.c + + GENERATED_CFILES = \ +@@ -447,7 +447,7 @@ + defparse.c deflex.c nlmheader.c rcparse.c mcparse.c + + DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c +-WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c ++WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c + + # Code shared by all the binutils. + BULIBS = bucomm.c version.c filemode.c +diff -ruwN binutils/bucomm.c binutils/bucomm.c +--- binutils/bucomm.c 2009-09-14 17:13:26.000000000 +0530 ++++ binutils/bucomm.c 2010-03-11 12:13:23.256763200 +0530 +@@ -550,6 +550,32 @@ + return ret; + } + ++/* Return the basename of "file", i. e. everything minus whatever ++ directory part has been provided. Stolen from bfd/archive.c. ++ Should we also handle the VMS case (as in bfd/archive.c)? */ ++const char * ++bu_basename (file) ++ const char *file; ++{ ++ const char *filename = strrchr (file, '/'); ++ ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM ++ { ++ /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ ++ char *bslash = strrchr (file, '\\'); ++ if (filename == NULL || (bslash != NULL && bslash > filename)) ++ filename = bslash; ++ if (filename == NULL && file[0] != '\0' && file[1] == ':') ++ filename = file + 1; ++ } ++#endif ++ if (filename != (char *) NULL) ++ filename++; ++ else ++ filename = file; ++ return filename; ++} ++ + /* Returns the size of the named file. If the file does not + exist, or if it is not a real file, then a suitable non-fatal + error message is printed and zero is returned. */ +diff -ruwN binutils/bucomm.h binutils/bucomm.h +--- binutils/bucomm.h 2009-09-02 12:52:31.000000000 +0530 ++++ binutils/bucomm.h 2010-03-11 12:13:23.272386500 +0530 +@@ -58,6 +58,8 @@ + + off_t get_file_size (const char *); + ++const char *bu_basename PARAMS ((const char *)); ++ + extern char *program_name; + + /* filemode.c */ +diff -ruwN binutils/budbg.h binutils/budbg.h +--- binutils/budbg.h 2009-09-02 12:52:31.000000000 +0530 ++++ binutils/budbg.h 2010-03-11 12:13:23.272386500 +0530 +@@ -52,8 +52,11 @@ + + extern bfd_boolean write_ieee_debugging_info (bfd *, void *); + +-/* Routine used to read COFF debugging information. */ ++/* Routine used to read and write COFF debugging information. */ + + extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *); + ++extern bfd_boolean write_coff_debugging_info ++ (bfd *abfd, void *, long *symcountp, asymbol ***); ++ + #endif +diff -ruwN binutils/debug.c binutils/debug.c +--- binutils/debug.c 2009-09-14 17:13:26.000000000 +0530 ++++ binutils/debug.c 2010-03-11 12:13:23.288009800 +0530 +@@ -31,6 +31,7 @@ + #include + #include "bfd.h" + #include "libiberty.h" ++#include "bucomm.h" + #include "debug.h" + + /* Global information we keep for debugging. A pointer to this +@@ -552,6 +553,19 @@ + struct debug_type_s *t; + }; + ++/* Simple list, used for pathname translations. */ ++struct xlat_list ++{ ++ /* Next string on list. */ ++ struct xlat_list *next; ++ /* Old part to match against. */ ++ const char *old; ++ size_t olen; ++ /* New part to replace. */ ++ const char *newstr; ++ size_t nlen; ++}; ++ + /* Local functions. */ + + static void debug_error (const char *); +@@ -588,6 +602,11 @@ + (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); + static bfd_boolean debug_class_type_samep + (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); ++static const char *debug_xlat_pathname (const char *); ++ ++/* List of pathname translations. */ ++static struct xlat_list *xlat, *xltail; ++static bfd_boolean xlat_basename; + + /* Issue an error message. */ + +@@ -680,6 +699,8 @@ + + if (name == NULL) + name = ""; ++ else ++ name = debug_xlat_pathname (name); + + nfile = (struct debug_file *) xmalloc (sizeof *nfile); + memset (nfile, 0, sizeof *nfile); +@@ -720,6 +741,8 @@ + + if (name == NULL) + name = ""; ++ else ++ name = debug_xlat_pathname (name); + + if (info->current_unit == NULL) + { +@@ -3370,3 +3393,69 @@ + + return TRUE; + } ++ ++/* Register a pathname translation. */ ++void ++debug_register_pathname_xlat (oname, nname) ++ const char *oname; ++ const char *nname; ++{ ++ struct xlat_list *xlp; ++ ++ /* Special case: if oname is given as NULL, this means the ++ --basename option has been given to objcopy. */ ++ if (oname == NULL) ++ { ++ xlat_basename = TRUE; ++ return; ++ } ++ ++ xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list)); ++ xlp->next = NULL; ++ if (xlat == NULL) ++ xlat = xltail = xlp; ++ else ++ { ++ xltail->next = xlp; ++ xltail = xlp; ++ } ++ xlp->old = oname; ++ xlp->newstr = nname; ++ xlp->olen = strlen (oname); ++ xlp->nlen = strlen (nname); ++} ++ ++/* Try to translate a pathname. */ ++static const char * ++debug_xlat_pathname (oname) ++ const char *oname; ++{ ++ struct xlat_list *xlp; ++ char *cp; ++ size_t olen; ++ ++ if (xlat_basename) ++ return bu_basename (oname); ++ ++ olen = strlen (oname); ++ for (xlp = xlat; xlp; xlp = xlp->next) ++ { ++ if (xlp->olen > olen) ++ /* This cannot be our turn. */ ++ continue; ++ /* Since we have pre-computed all our length values to avoid ++ repetitively computing them, just use memcmp() since it's ++ faster than strcmp(). */ ++ if (memcmp (xlp->old, oname, xlp->olen) == 0) ++ { ++ cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1); ++ memcpy (cp, xlp->newstr, xlp->nlen); ++ memcpy (cp + xlp->nlen, oname + xlp->olen, ++ olen - xlp->olen + 1); ++ return cp; ++ } ++ } ++ ++ /* Not found, pass the original name on. */ ++ return oname; ++} +diff -ruwN binutils/debug.h binutils/debug.h +--- binutils/debug.h 2009-09-14 17:13:26.000000000 +0530 ++++ binutils/debug.h 2010-03-11 12:13:23.288009800 +0530 +@@ -440,6 +440,12 @@ + + extern bfd_boolean debug_start_source (void *, const char *); + ++/* Register a pathname translation for source (and include) filenames. ++ This is used by the --change-pathname option of objcopy. */ ++ ++extern void debug_register_pathname_xlat ++ PARAMS ((const char *, const char *)); ++ + /* Record a function definition. This implicitly starts a function + block. The debug_type argument is the type of the return value. + The bfd_boolean indicates whether the function is globally visible. +diff -ruwN binutils/doc/objcopy.1 binutils/doc/objcopy.1 +--- binutils/doc/objcopy.1 2009-10-16 17:22:19.000000000 +0530 ++++ binutils/doc/objcopy.1 2010-03-11 12:13:23.303633100 +0530 +@@ -202,6 +202,8 @@ + [\fB\-\-readonly\-text\fR] + [\fB\-\-pure\fR] + [\fB\-\-impure\fR] ++ [\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR] ++ [\fB\-\-basename\fR] + [\fB\-\-file\-alignment=\fR\fInum\fR] + [\fB\-\-heap=\fR\fIsize\fR] + [\fB\-\-image\-base=\fR\fIaddress\fR] +@@ -885,6 +887,23 @@ + It can also be a useful way of reducing the size of a \fB\-\-just\-symbols\fR + linker input file. + .RE ++.IP "\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR" 4 ++.IX Item "--change-pathname old=new" ++When converting debugging information using \fB\-\-debugging\fR, for ++every pathname that starts with \fIold\fR, replace the matching part ++by \fInew\fR. This is intented to map pathnames between different ++debugging tools, or when parts of the object file(s) had their ++pathnames recorded in a different build environment. Note that only ++leading directory name components might be changed that way, since the ++trailing filename could be recorded elsewhere as well (depending on the ++debugging format of the input file). ++.IP "\fB\-\-basename\fR" ++.IX Item "--basename" ++When converting debugging information using \fB\-\-debugging\fR, for ++every pathname, strip all leading directory information. This option ++takes precedence over any \fB\-\-change\-pathname\fR option. For some ++debugging formats that cannot handle long filenames, this options is ++implied (notably, some COFF debugging formats). + .IP "\fB\-V\fR" 4 + .IX Item "-V" + .PD 0 +diff -ruwN binutils/objcopy.c binutils/objcopy.c +--- binutils/objcopy.c 2009-09-14 17:13:26.000000000 +0530 ++++ binutils/objcopy.c 2010-03-11 12:13:23.319256400 +0530 +@@ -32,6 +32,7 @@ + #include "elf-bfd.h" + #include + #include "libbfd.h" ++#include "debug.h" + #include "coff/internal.h" + #include "libcoff.h" + +@@ -297,6 +298,8 @@ + OPTION_IMPURE, + OPTION_EXTRACT_SYMBOL, + OPTION_REVERSE_BYTES, ++ OPTION_CHANGE_PATHNAME, ++ OPTION_BASENAME, + OPTION_FILE_ALIGNMENT, + OPTION_HEAP, + OPTION_IMAGE_BASE, +@@ -346,10 +349,12 @@ + {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, + {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, + {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, ++ {"basename", no_argument, 0, OPTION_BASENAME}, + {"binary-architecture", required_argument, 0, 'B'}, + {"byte", required_argument, 0, 'b'}, + {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, + {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, ++ {"change-pathname", required_argument, 0, OPTION_CHANGE_PATHNAME}, + {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, + {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, + {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, +@@ -543,6 +548,8 @@ + --prefix-alloc-sections \n\ + Add to start of every allocatable\n\ + section name\n\ ++ --change-pathname = Change debug pathnames from to \n\ ++ --basename Strip directory part from debug pathnames\n\ + --file-alignment Set PE file alignment to \n\ + --heap [,] Set PE reserve/commit heap to /\n\ + \n\ +@@ -999,6 +1006,8 @@ + asymbol **from = isyms, **to = osyms; + long src_count = 0, dst_count = 0; + int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; ++ bfd_boolean need_for_debugging = convert_debugging ++ && bfd_get_arch (abfd) == bfd_arch_avr; + + for (; src_count < symcount; src_count++) + { +@@ -1099,7 +1108,8 @@ + || bfd_is_com_section (bfd_get_section (sym))) + keep = strip_symbols != STRIP_UNNEEDED; + else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ +- keep = (strip_symbols != STRIP_DEBUG ++ keep = need_for_debugging ++ || (strip_symbols != STRIP_DEBUG + && strip_symbols != STRIP_UNNEEDED + && ! convert_debugging); + else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) +@@ -2817,6 +2827,10 @@ + return write_ieee_debugging_info (obfd, dhandle); + + if (bfd_get_flavour (obfd) == bfd_target_coff_flavour ++ && bfd_get_arch (obfd) == bfd_arch_avr) ++ return write_coff_debugging_info (obfd, dhandle, symcountp, symppp); ++ ++ if (bfd_get_flavour (obfd) == bfd_target_coff_flavour + || bfd_get_flavour (obfd) == bfd_target_elf_flavour) + { + bfd_byte *syms, *strings; +@@ -3641,6 +3655,30 @@ + prefix_alloc_sections_string = optarg; + break; + ++ case OPTION_CHANGE_PATHNAME: ++ { ++ const char *s; ++ int len; ++ char *name; ++ ++ s = strchr (optarg, '='); ++ if (s == NULL) ++ fatal (_("bad format for %s"), "--change-pathname"); ++ ++ len = s - optarg; ++ name = (char *) xmalloc (len + 1); ++ strncpy (name, optarg, len); ++ name[len] = '\0'; ++ ++ debug_register_pathname_xlat (name, s + 1); ++ } ++ break; ++ ++ case OPTION_BASENAME: ++ /* very special case of pathname translation */ ++ debug_register_pathname_xlat (NULL, NULL); ++ break; ++ + case OPTION_READONLY_TEXT: + bfd_flags_to_set |= WP_TEXT; + bfd_flags_to_clear &= ~WP_TEXT; +diff -ruwN binutils/rdcoff.c binutils/rdcoff.c +--- binutils/rdcoff.c 2009-09-02 12:52:32.000000000 +0530 ++++ binutils/rdcoff.c 2010-03-11 12:13:23.334879700 +0530 +@@ -82,6 +82,9 @@ + struct coff_slots *slots; + /* Basic types. */ + debug_type basic[T_MAX + 1]; ++ /* Some general information, kept here for convenience. */ ++ size_t intsize; /* sizeof (int) */ ++ size_t doublesize; /* sizeof (double) */ + }; + + static debug_type *coff_get_slot (struct coff_types *, int); +@@ -101,6 +104,7 @@ + (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *, + void *, debug_type, bfd_boolean); + static bfd_boolean external_coff_symbol_p (int sym_class); ++static bfd_vma coff_convert_register (bfd *, bfd_vma); + + /* Return the slot for a type. */ + +@@ -271,8 +275,7 @@ + break; + + case T_INT: +- /* FIXME: Perhaps the size should depend upon the architecture. */ +- ret = debug_make_int_type (dhandle, 4, FALSE); ++ ret = debug_make_int_type (dhandle, types->intsize, FALSE); + name = "int"; + break; + +@@ -287,7 +290,7 @@ + break; + + case T_DOUBLE: +- ret = debug_make_float_type (dhandle, 8); ++ ret = debug_make_float_type (dhandle, types->doublesize); + name = "double"; + break; + +@@ -307,7 +310,7 @@ + break; + + case T_UINT: +- ret = debug_make_int_type (dhandle, 4, TRUE); ++ ret = debug_make_int_type (dhandle, types->intsize, TRUE); + name = "unsigned int"; + break; + +@@ -565,6 +568,8 @@ + + case C_WEAKEXT: + case C_EXT: ++ /* AVR COFF abuses C_EXTDEF */ ++ case C_EXTDEF: + if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, + DEBUG_GLOBAL, bfd_asymbol_value (sym))) + return FALSE; +@@ -580,9 +585,9 @@ + break; + + case C_REG: +- /* FIXME: We may need to convert the register number. */ + if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, +- DEBUG_REGISTER, bfd_asymbol_value (sym))) ++ DEBUG_REGISTER, ++ coff_convert_register (abfd, bfd_asymbol_value (sym)))) + return FALSE; + break; + +@@ -596,9 +601,9 @@ + break; + + case C_REGPARM: +- /* FIXME: We may need to convert the register number. */ + if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, +- DEBUG_PARM_REG, bfd_asymbol_value (sym))) ++ DEBUG_PARM_REG, ++ coff_convert_register (abfd, bfd_asymbol_value (sym)))) + return FALSE; + break; + +@@ -648,6 +653,28 @@ + return FALSE; + } + ++static bfd_vma ++coff_convert_register (abfd, val) ++ bfd *abfd; ++ bfd_vma val; ++{ ++ ++ switch (bfd_get_arch (abfd)) ++ { ++ case bfd_arch_avr: ++ /* AVR COFF wants to describe up to four registers by the four ++ bytes of the 32-bit value. Unused bytes are filled with ++ 0xff. In theory, this would allow for non-contiguous ++ register usage to hold a single value, but hopefully, no ++ compiler is going to use that feature. We could not handle ++ it anyway. */ ++ return val & 0xff; ++ ++ default: ++ return val; ++ } ++} ++ + /* This is the main routine. It looks through all the symbols and + handles them. */ + +@@ -674,6 +701,17 @@ + types.slots = NULL; + for (i = 0; i <= T_MAX; i++) + types.basic[i] = DEBUG_TYPE_NULL; ++ switch (bfd_get_arch (abfd)) ++ { ++ case bfd_arch_avr: ++ types.intsize = 2; ++ types.doublesize = 4; ++ break; ++ ++ default: ++ types.intsize = 4; ++ types.doublesize = 8; ++ } + + next_c_file = -1; + fnname = NULL; +@@ -734,7 +772,6 @@ + switch (syment.n_sclass) + { + case C_EFCN: +- case C_EXTDEF: + case C_ULABEL: + case C_USTATIC: + case C_LINE: +@@ -757,6 +794,8 @@ + /* Fall through. */ + case C_WEAKEXT: + case C_EXT: ++ /* AVR COFF abuses C_EXTDEF for C_EXT */ ++ case C_EXTDEF: + if (ISFCN (syment.n_type)) + { + fnname = name; +diff -ruwN binutils/wrcoff.c binutils/wrcoff.c +--- binutils/wrcoff.c 1970-01-01 05:30:00.000000000 +0530 ++++ binutils/wrcoff.c 2010-03-11 12:13:23.366126300 +0530 +@@ -0,0 +1,3410 @@ ++/* wrcoff.c -- Generate (AVR) COFF debugging information ++ Copyright 2003 Free Software Foundation, Inc. ++ ++ Written by Joerg Wunsch. ++ ++ This file is part of GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ 02111-1307, USA. */ ++ ++/* This file contains code which writes out COFF debugging ++ information. By now, this has only been tested on the AVR ++ platform, though any attempt has been made to keep the conversion ++ applicable to possible other COFF debugging consumers as well. */ ++ ++#include ++#include ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "coff/internal.h" ++#include "bucomm.h" ++#include "libiberty.h" ++#include "safe-ctype.h" ++#include "debug.h" ++#include "budbg.h" ++ ++/* Enabling COFF_DEBUG will trace the internal callback functions and ++ their parameters as debug_write() calls them. */ ++//#define COFF_DEBUG 1 ++ ++#include "libcoff.h" ++ ++#define N_TMASK (coff_data (info->abfd)->local_n_tmask) ++#define N_BTSHFT (coff_data (info->abfd)->local_n_btshft) ++#define N_BTMASK (coff_data (info->abfd)->local_n_btmask) ++#define N_TSHIFT (coff_data (info->abfd)->local_n_tshift) ++ ++/* Structure of local symbols per compilation unit. */ ++struct coff_compilation_unit ++{ ++ const char *fname; ++ asymbol **syms; ++ long nsyms, totsyms; ++}; ++ ++enum ts_kind ++{ ++ TS_EMPTY, ++ TS_VOID, ++ TS_INT, ++ TS_FLOAT, ++ TS_COMPLEX, ++ TS_ENUM, ++ TS_POINTER, ++ TS_FUNC, ++ TS_ARRAY, ++ TS_STRUCT, ++ TS_NONE = -1 ++}; ++ ++/* Structure defining the pre-defined types. */ ++struct coff_predef_type ++{ ++ enum ts_kind kind; ++ unsigned int size; /* in bytes */ ++ bfd_boolean isunsigned; ++ int slot; ++}; ++ ++struct coff_type_stack; ++struct coff_hash_entry; ++ ++struct coff_struct_fields ++{ ++ const char *name; ++ bfd_vma bitpos; ++ bfd_vma bitsize; ++ enum debug_visibility visibility; ++ struct coff_type_stack *types; ++}; ++ ++/* Our type stack. */ ++struct coff_type_stack ++{ ++ struct coff_type_stack *next; ++ enum ts_kind tsk; ++ union ++ { ++ /* TS_INT */ ++ struct ++ { ++ unsigned int size; ++ bfd_boolean isunsigned; ++ } ++ ts_int; ++ ++ /* TS_FLOAT */ ++ struct ++ { ++ unsigned int size; ++ } ++ ts_float; ++ ++ /* TS_ENUM */ ++ struct ++ { ++ union ++ { ++ const char *fixtag; ++ char *malloctag; ++ } ++ tag; ++ bfd_boolean tagismalloced; ++ const char **names; ++ bfd_signed_vma *vals; ++ struct coff_enum_hash_entry *ehash; ++ } ++ ts_enum; ++ ++ /* TS_FUNC */ ++ struct ++ { ++ struct coff_type_stack *savedts; ++ } ++ ts_func; ++ ++ /* TS_ARRAY */ ++ struct ++ { ++ bfd_signed_vma low; ++ bfd_signed_vma high; ++ } ++ ts_array; ++ ++ /* TS_STRUCT */ ++ struct ++ { ++ union ++ { ++ const char *fixtag; ++ char *malloctag; ++ } ++ tag; ++ bfd_boolean tagismalloced; ++ unsigned int id; ++ bfd_boolean isstruct; ++ unsigned int size; ++ long nfields; ++ struct coff_struct_fields *fields; ++ struct coff_type_stack *savedts; ++ struct coff_struct_hash_entry *shash; ++ } ++ ts_struct; ++ } ++ u; ++}; ++ ++struct coff_name_type_hash_table ++{ ++ struct bfd_hash_table root; ++}; ++ ++struct coff_name_type_hash_entry ++{ ++ struct bfd_hash_entry root; ++ /* Information for this name. */ ++ struct coff_type_stack *types; ++ bfd_boolean emitted; ++}; ++ ++struct coff_struct_hash_table ++{ ++ struct bfd_hash_table root; ++}; ++ ++struct coff_struct_hash_entry ++{ ++ struct bfd_hash_entry root; ++ /* Information for this name. */ ++ struct coff_type_stack *types; ++ bfd_boolean emitted; ++ combined_entry_type *native; ++ /* list of symbol indices that need fixing */ ++ long *fixidxs; ++ unsigned nfixidxs; ++}; ++ ++struct coff_enum_hash_table ++{ ++ struct bfd_hash_table root; ++}; ++ ++struct coff_enum_hash_entry ++{ ++ struct bfd_hash_entry root; ++ /* Information for this name. */ ++ struct coff_type_stack *types; ++ bfd_boolean emitted; ++ combined_entry_type *native; ++ /* list of symbol indices that need fixing */ ++ long *fixidxs; ++ unsigned nfixidxs; ++}; ++ ++/* COFF private symbol data. Used as a cookie to pass data around ++ between various processing stages. The generic COFF handling code ++ doesn't use any private data. */ ++struct coff_private_symdata ++{ ++ unsigned int size; /* size of symbol, used in AVR register ++ translation */ ++ struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */ ++ struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */ ++}; ++ ++/* Stack of tags that need endndx fixing. */ ++struct coff_fix_stack ++{ ++ struct coff_fix_stack *next; ++ combined_entry_type *native; ++}; ++ ++/* This is the handle passed through debug_write. */ ++ ++struct coff_write_handle ++{ ++ /* The BFD. */ ++ bfd *abfd; ++ /* Pointers to .text and .data sections, can be used as defaults if ++ no other information is available. */ ++ asection *textsect; ++ asection *datasect; ++ /* Some special flags. */ ++ unsigned long flags; ++ /* Flags describing architecture options. */ ++#define COFF_FL_AVR 0x0001 /* COFF is for AVR platform. */ ++#define COFF_FL_EXT_AVR 0x0002 /* AVR "extended" COFF */ ++ /* Flags describing internal status information. */ ++#define COFF_FL_FIX_ENDNDX 0x10000 /* apply endndx fix at next symbol */ ++#define COFF_FL_START_FCN 0x20000 /* begin of function pending */ ++#define COFF_FL_FIX_BB 0x40000 /* fix last ".bb" symbol */ ++ /* List of our compilation units, from input symbol table. */ ++ struct coff_compilation_unit *units; ++ long nunits; ++ struct coff_compilation_unit *currentfile; ++ /* Global symbols from input symbol table. */ ++ asymbol **globals; ++ long nglobals; ++ /* Section syms for named sections. */ ++ coff_symbol_type **secsyms; ++ long nsecsyms; ++ /* Our COFF symbols. */ ++ asymbol **syms; ++ long nsyms; ++ /* Total line number count. */ ++ unsigned long totlnos; ++ /* Size of standard objects on this arch. */ ++ unsigned int pointersize; ++ unsigned int enumsize; ++ /* Pending information when starting a function. We have to defer ++ almost everything, some actions can be taken when seeing the ++ starting block of that function, some will even have to wait ++ until we see the end of the function. */ ++ const char *funname; /* name of function */ ++ bfd_boolean funglobal; /* global/local function? */ ++ unsigned int lastlno; /* last line number seen so far */ ++ long funcindex; /* index of ".func" symbol in syms */ ++ unsigned int nlnos; /* line numbers recorded for this function*/ ++ bfd_vma endaddr; /* last .eb address we have seen so far */ ++ unsigned int funlno; /* first line number in function */ ++ coff_symbol_type **fargs; /* function arguments */ ++ unsigned int nfargs; ++ asection *funcsection; /* section the current function is using */ ++ /* Type information */ ++ struct coff_type_stack *tstack; ++ struct coff_name_type_hash_table types; ++ struct coff_struct_hash_table structs; ++ struct coff_enum_hash_table enums; ++ unsigned nenums; /* counter for anonymous enum tags */ ++ /* Stack of pending endndx fixes, see coff_record_symbol(). */ ++ struct coff_fix_stack *fixes; ++}; ++ ++/* Predefined types, default to usual 32-bit architectures. ++ Arch-dependant different byte sizes will be tuned upon entering ++ write_coff_debugging_info(). The table is looked up from front to ++ end, so we put `more popular' types that might have the same size ++ as other types first (e. g. "int" precedes "long" and "short"). */ ++static struct coff_predef_type coff_predef_types[] = ++{ ++ { TS_INT, 4, FALSE, 4 }, /* signed int */ ++ { TS_INT, 1, FALSE, 2 }, /* signed char */ ++ { TS_INT, 2, FALSE, 3 }, /* signed short */ ++ { TS_INT, 4, FALSE, 5 }, /* long int */ ++ { TS_FLOAT, 8, FALSE, 7 }, /* double */ ++ { TS_FLOAT, 4, FALSE, 6 }, /* float */ ++ { TS_INT, 4, TRUE, 14 }, /* unsigned int */ ++ { TS_INT, 1, TRUE, 12 }, /* unsigned char */ ++ { TS_INT, 2, TRUE, 13 }, /* unsigned short */ ++ { TS_INT, 4, TRUE, 15 }, /* unsigned long */ ++}; ++ ++static bfd_boolean coff_copy_symbols ++ PARAMS ((struct coff_write_handle *, long, asymbol **)); ++static asymbol *coff_find_symbol ++ PARAMS ((struct coff_write_handle *, const char *, bfd_boolean, bfd_boolean)); ++static void coff_record_symbol ++ PARAMS ((struct coff_write_handle *, coff_symbol_type *)); ++static symvalue coff_fixup_avr_register PARAMS ((symvalue, int)); ++static struct bfd_hash_entry *coff_name_type_newfunc ++ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); ++static bfd_boolean coff_free_type_info ++ PARAMS ((struct coff_name_type_hash_entry *, PTR)); ++static struct bfd_hash_entry *coff_struct_newfunc ++ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); ++static bfd_boolean coff_free_struct_info ++ PARAMS ((struct coff_struct_hash_entry *, PTR)); ++static struct bfd_hash_entry *coff_enum_newfunc ++ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); ++static bfd_boolean coff_free_enum_info ++ PARAMS ((struct coff_enum_hash_entry *, PTR)); ++static unsigned int coff_get_fundamental_type ++ PARAMS ((struct coff_write_handle *, struct coff_type_stack *)); ++static bfd_boolean coff_make_typed_symbol ++ PARAMS ((struct coff_write_handle *, coff_symbol_type **, enum ts_kind)); ++static bfd_boolean coff_emit_struct ++ PARAMS ((struct coff_write_handle *, struct coff_type_stack *, ++ struct coff_struct_hash_entry *)); ++static bfd_boolean coff_emit_enum ++ PARAMS ((struct coff_write_handle *, struct coff_type_stack *, ++ struct coff_enum_hash_entry *)); ++static bfd_boolean coff_emit_ndebug_sym ++ PARAMS ((struct coff_write_handle *, asymbol *, bfd_boolean)); ++ ++static bfd_boolean coff_start_compilation_unit PARAMS ((PTR, const char *)); ++static bfd_boolean coff_start_source PARAMS ((PTR, const char *)); ++static bfd_boolean coff_empty_type PARAMS ((PTR)); ++static bfd_boolean coff_void_type PARAMS ((PTR)); ++static bfd_boolean coff_int_type PARAMS ((PTR, unsigned int, bfd_boolean)); ++static bfd_boolean coff_float_type PARAMS ((PTR, unsigned int)); ++static bfd_boolean coff_complex_type PARAMS ((PTR, unsigned int)); ++static bfd_boolean coff_bool_type PARAMS ((PTR, unsigned int)); ++static bfd_boolean coff_enum_type ++ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); ++static bfd_boolean coff_pointer_type PARAMS ((PTR)); ++static bfd_boolean coff_function_type PARAMS ((PTR, int, bfd_boolean)); ++static bfd_boolean coff_reference_type PARAMS ((PTR)); ++static bfd_boolean coff_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); ++static bfd_boolean coff_array_type ++ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean)); ++static bfd_boolean coff_set_type PARAMS ((PTR, bfd_boolean)); ++static bfd_boolean coff_offset_type PARAMS ((PTR)); ++static bfd_boolean coff_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean)); ++static bfd_boolean coff_const_type PARAMS ((PTR)); ++static bfd_boolean coff_volatile_type PARAMS ((PTR)); ++static bfd_boolean coff_start_struct_type ++ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int)); ++static bfd_boolean coff_struct_field ++ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); ++static bfd_boolean coff_end_struct_type PARAMS ((PTR)); ++static bfd_boolean coff_start_class_type ++ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, ++ bfd_boolean)); ++static bfd_boolean coff_class_static_member ++ PARAMS ((PTR, const char *, const char *, enum debug_visibility)); ++static bfd_boolean coff_class_baseclass ++ PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility)); ++static bfd_boolean coff_class_start_method PARAMS ((PTR, const char *)); ++static bfd_boolean coff_class_method_variant ++ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, ++ bfd_vma, bfd_boolean)); ++static bfd_boolean coff_class_static_method_variant ++ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean)); ++static bfd_boolean coff_class_end_method PARAMS ((PTR)); ++static bfd_boolean coff_end_class_type PARAMS ((PTR)); ++static bfd_boolean coff_typedef_type PARAMS ((PTR, const char *)); ++static bfd_boolean coff_tag_type ++ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); ++static bfd_boolean coff_typdef PARAMS ((PTR, const char *)); ++static bfd_boolean coff_tag PARAMS ((PTR, const char *)); ++static bfd_boolean coff_int_constant PARAMS ((PTR, const char *, bfd_vma)); ++static bfd_boolean coff_float_constant PARAMS ((PTR, const char *, double)); ++static bfd_boolean coff_typed_constant PARAMS ((PTR, const char *, bfd_vma)); ++static bfd_boolean coff_variable ++ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); ++static bfd_boolean coff_start_function PARAMS ((PTR, const char *, bfd_boolean)); ++static bfd_boolean coff_function_parameter ++ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); ++static bfd_boolean coff_start_block PARAMS ((PTR, bfd_vma)); ++static bfd_boolean coff_end_block PARAMS ((PTR, bfd_vma)); ++static bfd_boolean coff_end_function PARAMS ((PTR)); ++static bfd_boolean coff_lineno ++ PARAMS ((PTR, const char *, unsigned long, bfd_vma)); ++ ++static const struct debug_write_fns coff_fns = ++{ ++ coff_start_compilation_unit, ++ coff_start_source, ++ coff_empty_type, ++ coff_void_type, ++ coff_int_type, ++ coff_float_type, ++ coff_complex_type, ++ coff_bool_type, ++ coff_enum_type, ++ coff_pointer_type, ++ coff_function_type, ++ coff_reference_type, ++ coff_range_type, ++ coff_array_type, ++ coff_set_type, ++ coff_offset_type, ++ coff_method_type, ++ coff_const_type, ++ coff_volatile_type, ++ coff_start_struct_type, ++ coff_struct_field, ++ coff_end_struct_type, ++ coff_start_class_type, ++ coff_class_static_member, ++ coff_class_baseclass, ++ coff_class_start_method, ++ coff_class_method_variant, ++ coff_class_static_method_variant, ++ coff_class_end_method, ++ coff_end_class_type, ++ coff_typedef_type, ++ coff_tag_type, ++ coff_typdef, ++ coff_tag, ++ coff_int_constant, ++ coff_float_constant, ++ coff_typed_constant, ++ coff_variable, ++ coff_start_function, ++ coff_function_parameter, ++ coff_start_block, ++ coff_end_block, ++ coff_end_function, ++ coff_lineno ++}; ++ ++/* ++ * Copy our input (non-debugging) symbols. Local symbols will be ++ * maintained in one bucket per each compilation unit, global (and ++ * weak) symbols will be kept in a simple array. ++ */ ++static bfd_boolean ++coff_copy_symbols (info, count, sympp) ++ struct coff_write_handle *info; ++ long count; ++ asymbol **sympp; ++{ ++ asymbol *osym; ++ long i; ++ struct coff_compilation_unit *up; ++ ++ up = NULL; ++ ++ for (i = 0; i < count; i++) ++ { ++ osym = sympp[i]; ++ ++ /* Try to figure out the .text and .data sections from our input ++ symbols as we walk them. Unfortunately, this ought to be the ++ /input/ section pointers, so their ->output_section is ++ non-NULL. That's why we can't simply walk through all the ++ sections of our abfd since this is describing the output ++ only. */ ++ if (info->textsect == NULL && osym->section->flags & SEC_CODE) ++ /* Assume this to be our .text section. */ ++ info->textsect = osym->section; ++ else if (info->datasect == NULL && osym->section->flags & SEC_DATA) ++ /* Assume this to be our .data section. */ ++ info->datasect = osym->section; ++ ++ if (osym->flags & BSF_FILE) ++ { ++ /* New file name. */ ++ long l; ++ ++ up = NULL; ++ ++ /* Well, maybe an old one actually? If so, append it there. ++ This can happen for files that contribute to multiple ++ (input) sections that were concatenated by the linker ++ (like crt1.S). */ ++ for (l = 0; l < info->nunits; l++) ++ { ++ if (strcmp (info->units[l].fname, osym->name) == 0) ++ { ++ up = info->units + l; ++ break; ++ } ++ } ++ ++ if (up == NULL) ++ { ++ info->units = (struct coff_compilation_unit *) ++ xrealloc (info->units, ++ ++info->nunits * sizeof(struct coff_compilation_unit)); ++ up = info->units + (info->nunits - 1); ++ up->fname = osym->name; ++ up->syms = NULL; ++ up->nsyms = up->totsyms = 0; ++ } ++ } ++ else if (osym->flags & (BSF_GLOBAL | BSF_WEAK)) ++ { ++ /* Global (or weak) symbols are recorded outside compilation ++ units. */ ++ info->globals = (asymbol **) ++ xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *)); ++ info->globals[info->nglobals - 1] = osym; ++ continue; ++ } ++ else if (!bfd_is_const_section(osym->section)) ++ { ++ if (osym->flags & BSF_SECTION_SYM) ++ { ++ coff_symbol_type *csymp; ++ /* Just record them by now, they'll be fixed up later. */ ++ ++ if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0) ++ { ++ /* Very first symbol, fake a compilation unit name ++ for it. Historical precedence seems to dictate ++ this, but AVR COFF does not use that. */ ++ csymp = (coff_symbol_type *) ++ coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (""); ++ csymp->symbol.value = 0; ++ csymp->symbol.udata.p = NULL; ++ csymp->native->u.syment.n_sclass = C_FILE; ++ /* force filename into aux entry */ ++ csymp->native->u.syment.n_numaux = 1; ++ coff_record_symbol (info, csymp); ++ } ++ ++ /* convert to COFF native section symbol */ ++ csymp = (coff_symbol_type *) ++ coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (osym->section->name); ++ csymp->symbol.value = osym->section->output_section->vma; ++ csymp->symbol.flags = BSF_DEBUGGING | BSF_SECTION_SYM; ++ csymp->symbol.section = osym->section; ++ csymp->symbol.udata.p = NULL; ++ csymp->native->fix_scnlen = 1; ++ csymp->native->u.syment.n_sclass = C_STAT; ++ csymp->native->u.syment.n_type = T_NULL; ++ csymp->native->u.syment.n_numaux = 1; ++ ++ coff_record_symbol (info, csymp); ++ ++ info->secsyms = (coff_symbol_type **) ++ xrealloc (info->secsyms, ++ ++info->nsecsyms * sizeof(coff_symbol_type *)); ++ info->secsyms[info->nsecsyms - 1] = csymp; ++ } ++ else ++ { ++ /* Local symbol in a named section, will be recorded ++ within the respective compilation unit. */ ++ if (up == NULL) ++ { ++ fprintf (stderr, ++ _("Discarding local symbol outside any compilation unit")); ++ if (osym->name) ++ fprintf (stderr, ": %s", osym->name); ++ putc ('\n', stderr); ++ } ++ else ++ { ++ up->syms = (asymbol **) ++ xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *)); ++ up->syms[up->nsyms - 1] = osym; ++ up->totsyms = up->nsyms; ++ continue; ++ } ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Find a name in the symbol table. If found, the respective entry in ++ the symbol vector is zeroed, so after processing all debugging ++ symbols, only non-debugging symbols will remain. */ ++static asymbol * ++coff_find_symbol (info, name, isfunction, global) ++ struct coff_write_handle *info; ++ const char *name; ++ bfd_boolean isfunction; ++ bfd_boolean global; ++{ ++ asymbol *symp; ++ long i; ++ size_t namelen; ++ ++ if (global) ++ { ++ for (i = 0; i < info->nglobals; i++) ++ { ++ symp = info->globals[i]; ++ if (symp == NULL) ++ continue; ++ if (strcmp (name, symp->name) == 0 ++ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) ++ { ++ info->globals[i] = NULL; ++ return symp; ++ } ++ } ++ return NULL; ++ } ++ ++ if (info->currentfile == NULL) ++ return NULL; ++ ++ /* For local symbols, the match optionally stops at a dot in the ++ symtab symbol's name; this is used by gcc to indicate ++ function-scope static symbols (e. g. symbol "foo" will become ++ "foo.1" in function scope). */ ++ namelen = strlen (name); ++ for (i = 0; i < info->currentfile->nsyms; i++) ++ { ++ symp = info->currentfile->syms[i]; ++ if (symp == NULL) ++ continue; ++ if (strncmp (name, symp->name, namelen) == 0 ++ && (symp->name[namelen] == '\0' || symp->name[namelen] == '.') ++ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) ++ { ++ info->currentfile->syms[i] = NULL; ++ info->currentfile->totsyms--; ++ return symp; ++ } ++ } ++ return NULL; ++} ++ ++static void ++coff_record_symbol (info, csymp) ++ struct coff_write_handle *info; ++ coff_symbol_type *csymp; ++{ ++ struct coff_private_symdata *priv; ++ ++ info->syms = (asymbol **) xrealloc (info->syms, ++ ++info->nsyms * sizeof (asymbol *)); ++ info->syms[info->nsyms - 1] = (asymbol *)csymp; ++ ++ if ((priv = csymp->symbol.udata.p) != NULL) ++ { ++ if (priv->shash != NULL) ++ { ++ struct coff_struct_hash_entry *shash = priv->shash; ++ shash->fixidxs = (long *) ++ xrealloc (shash->fixidxs, ++shash->nfixidxs * sizeof (long)); ++ shash->fixidxs[shash->nfixidxs - 1] = info->nsyms - 1; ++ } ++ if (priv->ehash != NULL) ++ { ++ struct coff_enum_hash_entry *ehash = priv->ehash; ++ ehash->fixidxs = (long *) ++ xrealloc (ehash->fixidxs, ++ehash->nfixidxs * sizeof (long)); ++ ehash->fixidxs[ehash->nfixidxs - 1] = info->nsyms - 1; ++ } ++ free (priv); ++ csymp->symbol.udata.p = NULL; ++ } ++ ++ /* If there are any pending endndx fixes, pop the last element from ++ that stack, and record the current symbol for fixing. We need to ++ do this here since we need to record our current csymp->native ++ (where that csymp is completely unrelated to whatever symbol was ++ previously generated that requested the fixup). The stack of ++ pending fixes is required since several endndx fixes could be ++ nested, e. g. the start of a function has a pending fix that ++ needs to point to the first symbol after the function, but there ++ could be an anonymous struct definition inside that function's ++ local variables where the endndx needs to point after the last ++ symbol of this struct. Also, structs and unions could be nested. ++ ++ Each call to coff_record_symbol() can fix at most one endndx ++ (even if more are pending in the stack), but that's OK. ++ ++ Note that bfd/coffgen.c converts that csymp->native into a ++ symtable slot number after coff_renumber_symbols() has been ++ run. */ ++ if (info->flags & COFF_FL_FIX_ENDNDX) ++ { ++ struct coff_fix_stack *fsp, *ofsp; ++ union internal_auxent *aux; ++ ++ assert (info->fixes != NULL); ++ ++ fsp = info->fixes; ++ ofsp = NULL; ++ while (fsp->next != NULL) ++ { ++ ofsp = fsp; ++ fsp = fsp->next; ++ } ++ if (ofsp == NULL) ++ info->fixes = NULL; ++ else ++ ofsp->next = NULL; ++ ++ aux = &(fsp->native->u.auxent); ++ fsp->native->fix_end = 1; ++ aux->x_sym.x_fcnary.x_fcn.x_endndx.p = csymp->native; ++ free (fsp); ++ ++ info->flags &= ~COFF_FL_FIX_ENDNDX; ++ } ++} ++ ++/* Fixup AVR COFF register handling: they don't only mention the ++ starting register number, but all registers, each within one byte ++ of the value. Unused register positions are filled up with ++ 0xff. */ ++static symvalue ++coff_fixup_avr_register (val, size) ++ symvalue val; ++ int size; ++{ ++ union ++ { ++ unsigned char c[4]; ++ symvalue v; ++ } u; ++ ++ u.c[1] = u.c[2] = u.c[3] = 0xff; ++ u.c[0] = val; ++ if (size > 8) ++ u.c[1] = val + 1; ++ if (size > 16) ++ { ++ u.c[2] = val + 2; ++ u.c[3] = val + 3; ++ } ++ ++ return u.v; ++} ++ ++/* Initialize an entry in the hash tables. */ ++ ++static struct bfd_hash_entry * ++coff_name_type_newfunc (entry, table, string) ++ struct bfd_hash_entry *entry; ++ struct bfd_hash_table *table; ++ const char *string; ++{ ++ struct coff_name_type_hash_entry *ret = ++ (struct coff_name_type_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == NULL) ++ ret = ((struct coff_name_type_hash_entry *) ++ bfd_hash_allocate (table, sizeof *ret)); ++ if (ret == NULL) ++ return NULL; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = ((struct coff_name_type_hash_entry *) ++ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); ++ if (ret) ++ { ++ /* Set local fields. */ ++ ret->types = NULL; ++ ret->emitted = FALSE; ++ } ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++static struct bfd_hash_entry * ++coff_struct_newfunc (entry, table, string) ++ struct bfd_hash_entry *entry; ++ struct bfd_hash_table *table; ++ const char *string; ++{ ++ struct coff_struct_hash_entry *ret = ++ (struct coff_struct_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == NULL) ++ ret = ((struct coff_struct_hash_entry *) ++ bfd_hash_allocate (table, sizeof *ret)); ++ if (ret == NULL) ++ return NULL; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = ((struct coff_struct_hash_entry *) ++ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); ++ if (ret) ++ { ++ /* Set local fields. */ ++ ret->types = NULL; ++ ret->emitted = FALSE; ++ ret->fixidxs = NULL; ++ ret->nfixidxs = 0; ++ ret->native = NULL; ++ } ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++static struct bfd_hash_entry * ++coff_enum_newfunc (entry, table, string) ++ struct bfd_hash_entry *entry; ++ struct bfd_hash_table *table; ++ const char *string; ++{ ++ struct coff_enum_hash_entry *ret = ++ (struct coff_enum_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == NULL) ++ ret = ((struct coff_enum_hash_entry *) ++ bfd_hash_allocate (table, sizeof *ret)); ++ if (ret == NULL) ++ return NULL; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = ((struct coff_enum_hash_entry *) ++ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); ++ if (ret) ++ { ++ /* Set local fields. */ ++ ret->types = NULL; ++ ret->emitted = FALSE; ++ ret->fixidxs = NULL; ++ ret->nfixidxs = 0; ++ ret->native = NULL; ++ } ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++/* Look up an entry in the hash tables. */ ++ ++#define coff_name_type_hash_lookup(table, string, create, copy) \ ++ ((struct coff_name_type_hash_entry *) \ ++ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) ++ ++/* Traverse the hash table. */ ++ ++#define coff_name_type_hash_traverse(table, func, info) \ ++ (bfd_hash_traverse \ ++ (&(table)->root, \ ++ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ ++ (info))) ++ ++#define coff_struct_hash_lookup(table, string, create, copy) \ ++ ((struct coff_struct_hash_entry *) \ ++ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) ++ ++/* Traverse the hash table. */ ++ ++#define coff_struct_hash_traverse(table, func, info) \ ++ (bfd_hash_traverse \ ++ (&(table)->root, \ ++ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ ++ (info))) ++ ++#define coff_enum_hash_lookup(table, string, create, copy) \ ++ ((struct coff_enum_hash_entry *) \ ++ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) ++ ++/* Traverse the hash table. */ ++ ++#define coff_enum_hash_traverse(table, func, info) \ ++ (bfd_hash_traverse \ ++ (&(table)->root, \ ++ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ ++ (info))) ++ ++#define coff_push_type(kind) \ ++ tst = (struct coff_type_stack *) xmalloc (sizeof (struct coff_type_stack)); \ ++ memset (tst, 0, sizeof (*tst)); \ ++ tst->next = info->tstack; \ ++ tst->tsk = kind; \ ++ info->tstack = tst ++ ++#define coff_pop_type() \ ++ tst = info->tstack; \ ++ if (tst == NULL) { \ ++ fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \ ++ return FALSE; \ ++ } \ ++ info->tstack = tst->next; \ ++ tst->next = NULL ++ ++#define coff_complain_unsupp(s) \ ++ fprintf (stderr, _("%s type not supported in %s\n"), \ ++ s, info->abfd->xvec->name); \ ++ return FALSE ++ ++/* These function is called via the hash traverse routine when freeing ++ a hash table (at the end of a translation unit). */ ++static bfd_boolean ++coff_free_type_info (h, p) ++ struct coff_name_type_hash_entry *h; ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ struct coff_type_stack *tst, *otst; ++ ++ for (tst = h->types; tst != NULL;) ++ { ++ otst = tst; ++ tst = tst->next; ++ free (otst); ++ } ++ return TRUE; ++} ++ ++static bfd_boolean ++coff_free_struct_info (h, p) ++ struct coff_struct_hash_entry *h; ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ struct coff_type_stack *tst, *otst, *xtst, *xotst; ++ struct coff_struct_fields *fp; ++ long i; ++ ++ for (tst = h->types; tst != NULL;) ++ { ++ otst = tst; ++ if (tst->u.ts_struct.tagismalloced) ++ free (tst->u.ts_struct.tag.malloctag); ++ for (i = 0, fp = tst->u.ts_struct.fields; ++ i < tst->u.ts_struct.nfields; ++ i++, fp++) ++ { ++ xtst = fp->types; ++ while (xtst != NULL) ++ { ++ xotst = xtst->next; ++ free (xtst); ++ xtst = xotst; ++ } ++ } ++ free (tst->u.ts_struct.fields); ++ tst = tst->next; ++ free (otst); ++ } ++ return TRUE; ++} ++ ++static bfd_boolean ++coff_free_enum_info (h, p) ++ struct coff_enum_hash_entry *h; ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ struct coff_type_stack *tst, *otst; ++ ++ for (tst = h->types; tst != NULL;) ++ { ++ otst = tst; ++ if (tst->u.ts_enum.tagismalloced) ++ free (tst->u.ts_enum.tag.malloctag); ++ tst = tst->next; ++ free (otst); ++ } ++ return TRUE; ++} ++ ++static unsigned int ++coff_get_fundamental_type (info, tst) ++ struct coff_write_handle *info ATTRIBUTE_UNUSED; ++ struct coff_type_stack *tst; ++{ ++ size_t i; ++ ++ /* See if one of our predefined types will fit. */ ++ if (tst->tsk == TS_INT) ++ { ++ for (i = 0; ++ i < sizeof coff_predef_types / sizeof (struct coff_predef_type); ++ i++) ++ { ++ if (coff_predef_types[i].kind == TS_INT ++ && coff_predef_types[i].size == tst->u.ts_int.size ++ && coff_predef_types[i].isunsigned == tst->u.ts_int.isunsigned) ++ return coff_predef_types[i].slot; ++ } ++ fprintf (stderr, ++ _("%ssigned %d-bit integer type not available in COFF\n"), ++ tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8); ++ } ++ else ++ { ++ for (i = 0; ++ i < sizeof coff_predef_types / sizeof (struct coff_predef_type); ++ i++) ++ { ++ if (coff_predef_types[i].kind == TS_FLOAT ++ && coff_predef_types[i].size == tst->u.ts_float.size) ++ return coff_predef_types[i].slot; ++ } ++ fprintf (stderr, _("%d-bit float type not available in COFF\n"), ++ tst->u.ts_float.size * 8); ++ } ++ ++ return T_NULL; ++} ++ ++static bfd_boolean ++coff_make_typed_symbol (info, csympp, stopat) ++ struct coff_write_handle *info; ++ coff_symbol_type **csympp; ++ enum ts_kind stopat; ++{ ++ struct coff_type_stack *tst; ++ union internal_auxent *aux; ++ struct coff_struct_hash_entry *shash; ++ struct coff_enum_hash_entry *ehash; ++ struct coff_private_symdata *priv; ++ unsigned int type, numaux, arydim, size, i, nele, nderived; ++ const char *name; ++ bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) ++ == COFF_FL_AVR; ++ ++ /* Synthesize a new internal COFF symbol. */ ++ *csympp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (*csympp == NULL) ++ return FALSE; ++ ++ priv = (struct coff_private_symdata *) xmalloc (sizeof *priv); ++ memset (priv, 0, sizeof *priv); ++ ++ type = arydim = size = nderived = 0; ++ ++ aux = &(((*csympp)->native + 1)->u.auxent); ++ ++ /* Now, walk the type stack, and see how we could convert the info ++ we've got to what COFF understands. */ ++ for (;;) ++ { ++ if (info->tstack == NULL) ++ break; ++ ++ /* If we have been advised to not pop the entire stack, stop ++ here. */ ++ if (info->tstack->tsk == stopat && info->tstack->next == NULL) ++ break; ++ ++ coff_pop_type (); ++ ++ switch (tst->tsk) ++ { ++ case TS_NONE: ++ /* cannot happen */ ++ break; ++ ++ case TS_EMPTY: ++ if (info->tstack != NULL && info->tstack->tsk != stopat) ++ fprintf (stderr, _("empty type not last on type stack\n")); ++ /* type |= T_NULL; */ ++ break; ++ ++ case TS_VOID: ++ if (info->tstack != NULL && info->tstack->tsk != stopat) ++ fprintf (stderr, _("void type not last on type stack\n")); ++ type |= T_VOID; ++ break; ++ ++ case TS_INT: ++ if (info->tstack != NULL && info->tstack->tsk != stopat) ++ fprintf (stderr, _("int type not last on type stack\n")); ++ type |= coff_get_fundamental_type (info, tst); ++ if (size == 0) ++ size = tst->u.ts_int.size; ++ break; ++ ++ case TS_FLOAT: ++ if (info->tstack != NULL && info->tstack->tsk != stopat) ++ fprintf (stderr, _("float type not last on type stack\n")); ++ type |= coff_get_fundamental_type (info, tst); ++ if (size == 0) ++ size = tst->u.ts_float.size; ++ break; ++ ++ case TS_POINTER: ++ nderived++; ++ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT); ++ size = info->pointersize; ++ break; ++ ++ case TS_FUNC: ++ nderived++; ++ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT); ++ /* AUX entry for DT_FCN will be filled in elsewhere. */ ++ break; ++ ++ case TS_ARRAY: ++ /* We need to limit arydim so the assignment below won't ++ overwrite random locations. */ ++ if (arydim >= DIMNUM) ++ { ++ fprintf (stderr, ++ _("More than %d array dimensions, result is invalid.\n"), ++ DIMNUM); ++ arydim = DIMNUM - 1; ++ } ++ nderived++; ++ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_ARY << N_BTSHFT); ++ aux->x_sym.x_fcnary.x_ary.x_dimen[arydim++] = ++ tst->u.ts_array.high - tst->u.ts_array.low + 1; ++ ++ break; ++ ++ case TS_COMPLEX: ++ coff_complain_unsupp (_("complex")); ++ ++ case TS_ENUM: ++ type |= T_ENUM; ++ if (size == 0) ++ size = info->enumsize; ++ ++ if (tst->u.ts_enum.ehash != NULL) ++ { ++ /* enum tag will be fixed later. */ ++ priv->ehash = tst->u.ts_enum.ehash; ++ break; ++ } ++ if (tst->u.ts_enum.tagismalloced) ++ name = tst->u.ts_enum.tag.malloctag; ++ else ++ name = tst->u.ts_enum.tag.fixtag; ++ ehash = coff_enum_hash_lookup (&info->enums, name, ++ TRUE, tst->u.ts_enum.tagismalloced); ++ if (ehash == NULL) ++ return FALSE; ++ if (!ehash->emitted) ++ { ++ if (ehash->types == NULL) ++ { ++ ehash->types = (struct coff_type_stack *) ++ xmalloc (sizeof (struct coff_type_stack)); ++ memcpy (ehash->types, tst, sizeof (struct coff_type_stack)); ++ } ++ ehash->emitted = TRUE; ++ coff_emit_enum (info, tst, ehash); ++ if (ehash->nfixidxs != 0) ++ { ++ coff_symbol_type *symp; ++ unsigned i; ++ ++ for (i = 0; i < ehash->nfixidxs; i++) ++ { ++ combined_entry_type *np; ++ ++ symp = (coff_symbol_type *) info->syms[ehash->fixidxs[i]]; ++ symp->native->u.syment.n_type &= ~N_BTMASK; ++ symp->native->u.syment.n_type |= T_ENUM; ++ ++ if (oldavrcoff) ++ continue; ++ ++ np = symp->native + 1; ++ np->fix_tag = 1; ++ np->u.auxent.x_sym.x_tagndx.p = ehash->native; ++ if (np->u.auxent.x_sym.x_misc.x_fsize == 0) ++ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; ++ } ++ ++ free (ehash->fixidxs); ++ ehash->nfixidxs = 0; ++ } ++ } ++ if (!oldavrcoff) ++ { ++ ((*csympp)->native + 1)->fix_tag = 1; ++ aux->x_sym.x_tagndx.p = ehash->native; ++ if (aux->x_sym.x_misc.x_fsize == 0) ++ aux->x_sym.x_misc.x_lnsz.x_size = size; ++ } ++ break; ++ ++ case TS_STRUCT: ++ if (tst->u.ts_struct.isstruct) ++ type |= T_STRUCT; ++ else ++ type |= T_UNION; ++ if (size == 0) ++ size = tst->u.ts_struct.size; ++ ++ if (tst->u.ts_struct.shash != NULL) ++ { ++ /* struct tag will be fixed later. */ ++ priv->shash = tst->u.ts_struct.shash; ++ break; ++ } ++ if (tst->u.ts_struct.tagismalloced) ++ name = tst->u.ts_struct.tag.malloctag; ++ else ++ name = tst->u.ts_struct.tag.fixtag; ++ shash = coff_struct_hash_lookup (&info->structs, name, ++ TRUE, tst->u.ts_struct.tagismalloced); ++ if (shash == NULL) ++ return FALSE; ++ if (!shash->emitted) ++ { ++ if (shash->types == NULL) ++ { ++ shash->types = (struct coff_type_stack *) ++ xmalloc (sizeof (struct coff_type_stack)); ++ memcpy (shash->types, tst, sizeof (struct coff_type_stack)); ++ } ++ shash->emitted = TRUE; ++ coff_emit_struct (info, tst, shash); ++ if (shash->nfixidxs != 0) ++ { ++ coff_symbol_type *symp; ++ unsigned i; ++ ++ for (i = 0; i < shash->nfixidxs; i++) ++ { ++ combined_entry_type *np; ++ ++ symp = (coff_symbol_type *) info->syms[shash->fixidxs[i]]; ++ symp->native->u.syment.n_type &= ~N_BTMASK; ++ if (tst->u.ts_struct.isstruct) ++ symp->native->u.syment.n_type |= T_STRUCT; ++ else ++ symp->native->u.syment.n_type |= T_UNION; ++ ++ if (oldavrcoff) ++ continue; ++ ++ np = symp->native + 1; ++ np->fix_tag = 1; ++ np->u.auxent.x_sym.x_tagndx.p = shash->native; ++ if (np->u.auxent.x_sym.x_misc.x_fsize == 0) ++ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; ++ } ++ ++ free (shash->fixidxs); ++ shash->nfixidxs = 0; ++ } ++ } ++ if (!oldavrcoff) ++ { ++ ((*csympp)->native + 1)->fix_tag = 1; ++ aux->x_sym.x_tagndx.p = shash->native; ++ if (aux->x_sym.x_misc.x_fsize == 0) ++ aux->x_sym.x_misc.x_lnsz.x_size = size; ++ } ++ break; ++ } ++ free (tst); ++ } ++ ++ if (nderived > 6) ++ fprintf (stderr, ++ _("More than 6 derived type specifiers, result is invalid.\n")); ++ ++ /* Our type computation so far used the reverse order for derived ++ type specifiers. Fix this here if there was more than one ++ derived type specifier. */ ++ if (nderived > 1) ++ { ++ unsigned int nty, bty; ++ bty = type & N_BTMASK; ++ type = type >> N_BTSHFT; ++ nty = 0; ++ while (nderived-- > 0) ++ { ++ nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT)); ++ type >>= N_TSHIFT; ++ } ++ type = (nty << N_BTSHFT) | bty; ++ } ++ ++ if (ISARY (type)) ++ { ++ /* Compute size of entire array. */ ++ for (i = 0, nele = 1; i < arydim; i++) ++ nele *= aux->x_sym.x_fcnary.x_ary.x_dimen[i]; ++ aux->x_sym.x_misc.x_lnsz.x_size = size * nele; ++ } ++ ++ numaux = 0; ++ if (ISARY (type) || ISFCN (type)) ++ numaux++; ++ if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION ++ || BTYPE (type) == T_ENUM) ++ && !oldavrcoff) ++ numaux++; ++ /* Only AVR COFF uses multiple AUX entries. */ ++ if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0) ++ numaux = 1; ++ ++ priv->size = size; ++ (*csympp)->symbol.udata.p = priv; ++ (*csympp)->native->u.syment.n_type = type; ++ (*csympp)->native->u.syment.n_numaux = numaux; ++ ++ /* If the fundamental type comes out as T_NULL, this means we don't ++ have any type information. Just don't emit any aux entries in ++ that case, and drop any derived type information as well. */ ++ if (BTYPE (type) == T_NULL) ++ { ++ printf ("coff_make_typed_symbol() -> T_NULL\n"); ++ //(*csympp)->native->u.syment.n_type = T_NULL; ++ (*csympp)->native->u.syment.n_numaux = 0; ++ } ++ ++ return TRUE; ++} ++ ++static bfd_boolean coff_emit_struct (info, tst, shash) ++ struct coff_write_handle *info; ++ struct coff_type_stack *tst; ++ struct coff_struct_hash_entry *shash; ++{ ++ coff_symbol_type *csymp, *scsymp, *ecsymp; ++ union internal_auxent *aux; ++ struct coff_fix_stack *fixp, *ofp; ++ bfd_boolean isstruct = tst->u.ts_struct.isstruct; ++ bfd_boolean isbitfield = FALSE; ++ struct coff_type_stack *savedtst; ++ struct coff_struct_fields *fp; ++ unsigned short sclass; ++ long i; ++ ++ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == ++ COFF_FL_AVR) ++ /* old AVR COFF doesn't support struct debugging */ ++ return TRUE; ++ ++ /* Synthesize a new internal COFF symbol for the struct/union. */ ++ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (scsymp == NULL) ++ return FALSE; ++ ++ if (tst->u.ts_struct.tagismalloced) ++ scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag); ++ else ++ scsymp->symbol.name = tst->u.ts_struct.tag.fixtag; ++ scsymp->symbol.flags = BSF_NOT_AT_END; ++ scsymp->symbol.section = bfd_und_section_ptr; ++ scsymp->native->u.syment.n_sclass = isstruct? C_STRTAG: C_UNTAG; ++ scsymp->native->u.syment.n_type = isstruct? T_STRUCT: T_UNION; ++ scsymp->native->u.syment.n_numaux = 1; ++ scsymp->symbol.udata.p = NULL; ++ scsymp->symbol.value = 0; ++ ++ shash->native = scsymp->native; ++ ++ /* Synthesize a new internal COFF symbol for the end of struct/union. */ ++ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (ecsymp == NULL) ++ return FALSE; ++ ++ ecsymp->symbol.name = ".eos"; ++ ecsymp->symbol.flags = BSF_NOT_AT_END; ++ /* We need to use the com section here since bfd/coffgen.c ++ translates this into an N_UNDEF one without clobbering the ++ value. */ ++ ecsymp->symbol.section = bfd_com_section_ptr; ++ ecsymp->native->u.syment.n_sclass = C_EOS; ++ ecsymp->symbol.udata.p = NULL; ++ ecsymp->symbol.value = tst->u.ts_struct.size; ++ ecsymp->native->u.syment.n_numaux = 1; ++ (ecsymp->native + 1)->fix_tag = 1; ++ aux = &((ecsymp->native + 1)->u.auxent); ++ aux->x_sym.x_tagndx.p = scsymp->native; ++ aux->x_sym.x_misc.x_lnsz.x_size = tst->u.ts_struct.size; ++ ++ coff_record_symbol (info, scsymp); ++ ++ savedtst = info->tstack; ++ ++ if (isstruct) ++ { ++ /* First, make a quick walk along all the fields, and figure out ++ * whether we've got a genuine struct or a bitfield struct. */ ++ for (i = 0, fp = tst->u.ts_struct.fields; ++ i < tst->u.ts_struct.nfields; ++ i++, fp++) ++ if (fp->bitsize % 8 != 0) ++ { ++ isbitfield = TRUE; ++ break; ++ } ++ } ++ ++ sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU; ++ ++ for (i = 0, fp = tst->u.ts_struct.fields; ++ i < tst->u.ts_struct.nfields; ++ i++, fp++) ++ { ++ if (strlen (fp->name) == 0) ++ { ++ /* empty name could happen inside bitfield */ ++ fp->types = NULL; ++ continue; ++ } ++ ++ info->tstack = fp->types; ++ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (fp->name); ++ csymp->symbol.flags = BSF_NOT_AT_END; ++ csymp->symbol.section = bfd_com_section_ptr; ++ csymp->native->u.syment.n_sclass = sclass; ++ csymp->symbol.value = isbitfield? fp->bitpos: fp->bitpos / 8; ++ if (isbitfield) ++ { ++ csymp->native->u.syment.n_numaux = 1; ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_sym.x_misc.x_lnsz.x_size = fp->bitsize; ++ } ++ ++ coff_record_symbol (info, csymp); ++ ++ fp->types = NULL; ++ } ++ ++ info->tstack = savedtst; ++ ++ /* Record our endndx field for later fixing. */ ++ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); ++ fixp->native = scsymp->native + 1; /* points to first AUX */ ++ fixp->next = NULL; ++ if (info->fixes == NULL) ++ info->fixes = fixp; ++ else ++ { ++ for (ofp = info->fixes; ofp->next != NULL;) ++ ofp = ofp->next; ++ ofp->next = fixp; ++ } ++ ++ coff_record_symbol (info, ecsymp); ++ info->flags |= COFF_FL_FIX_ENDNDX; ++ ++ return TRUE; ++} ++ ++static bfd_boolean coff_emit_enum (info, tst, ehash) ++ struct coff_write_handle *info; ++ struct coff_type_stack *tst; ++ struct coff_enum_hash_entry *ehash; ++{ ++ coff_symbol_type *csymp, *scsymp, *ecsymp; ++ union internal_auxent *aux; ++ struct coff_fix_stack *fixp, *ofp; ++ int i; ++ ++ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == ++ COFF_FL_AVR) ++ /* old AVR COFF doesn't support enum debugging */ ++ return TRUE; ++ ++ /* Synthesize a new internal COFF symbol for the enum. */ ++ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (scsymp == NULL) ++ return FALSE; ++ ++ if (tst->u.ts_enum.tagismalloced) ++ scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag); ++ else ++ scsymp->symbol.name = tst->u.ts_enum.tag.fixtag; ++ scsymp->symbol.flags = BSF_NOT_AT_END; ++ scsymp->symbol.section = bfd_und_section_ptr; ++ scsymp->native->u.syment.n_sclass = C_ENTAG; ++ scsymp->native->u.syment.n_type = T_ENUM; ++ scsymp->native->u.syment.n_numaux = 1; ++ scsymp->symbol.udata.p = NULL; ++ scsymp->symbol.value = 0; ++ ++ ehash->native = scsymp->native; ++ ++ /* Synthesize a new internal COFF symbol for the end of struct/union. */ ++ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (ecsymp == NULL) ++ return FALSE; ++ ++ ecsymp->symbol.name = ".eos"; ++ ecsymp->symbol.flags = BSF_NOT_AT_END; ++ /* We need to use the com section here since bfd/coffgen.c ++ translates this into an N_UNDEF one without clobbering the ++ value. */ ++ ecsymp->symbol.section = bfd_com_section_ptr; ++ ecsymp->native->u.syment.n_sclass = C_EOS; ++ ecsymp->symbol.udata.p = NULL; ++ ecsymp->symbol.value = info->enumsize; ++ ecsymp->native->u.syment.n_numaux = 1; ++ (ecsymp->native + 1)->fix_tag = 1; ++ aux = &((ecsymp->native + 1)->u.auxent); ++ aux->x_sym.x_tagndx.p = scsymp->native; ++ aux->x_sym.x_misc.x_lnsz.x_size = info->enumsize; ++ ++ coff_record_symbol (info, scsymp); ++ ++ for (i = 0;; i++) ++ { ++ const char *name = tst->u.ts_enum.names[i]; ++ if (name == NULL) ++ break; ++ ++ /* Synthesize a new internal COFF symbol for the enum. */ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (name); ++ csymp->symbol.flags = BSF_NOT_AT_END; ++ csymp->symbol.section = bfd_com_section_ptr; ++ csymp->native->u.syment.n_sclass = C_MOE; ++ csymp->symbol.udata.p = NULL; ++ csymp->symbol.value = tst->u.ts_enum.vals[i]; ++ ++ coff_record_symbol (info, csymp); ++ } ++ ++ /* Record our endndx field for later fixing. */ ++ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); ++ fixp->native = scsymp->native + 1; /* points to first AUX */ ++ fixp->next = NULL; ++ if (info->fixes == NULL) ++ info->fixes = fixp; ++ else ++ { ++ for (ofp = info->fixes; ofp->next != NULL;) ++ ofp = ofp->next; ++ ofp->next = fixp; ++ } ++ ++ coff_record_symbol (info, ecsymp); ++ info->flags |= COFF_FL_FIX_ENDNDX; ++ ++ return TRUE; ++} ++ ++/* Emit a non-debugging symbol that came from the input symbol table, ++ and has not been claimed by one of the debugging symbols. */ ++static bfd_boolean ++coff_emit_ndebug_sym (info, osymp, localp) ++ struct coff_write_handle *info; ++ asymbol *osymp; ++ bfd_boolean localp; ++{ ++ coff_symbol_type *csymp; ++ ++ /* Create new COFF symbol. */ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (osymp->name); ++ csymp->symbol.value = osymp->value; ++ csymp->symbol.flags = localp? BSF_LOCAL: BSF_GLOBAL; ++ csymp->symbol.section = osymp->section; ++ csymp->symbol.udata.p = NULL; ++ csymp->native->u.syment.n_sclass = localp? C_STAT: C_EXT; ++ csymp->native->u.syment.n_type = T_NULL; ++ ++ coff_record_symbol (info, csymp); ++ ++ return TRUE; ++} ++ ++/* The general routine to write out COFF debugging information. This ++ synthesizes and accumulates the COFF symbols. Actual symbol table ++ output is performed later on by the BFD functions. ABFD is the BFD ++ and DHANDLE is the handle for the debugging information. symcountp ++ and symppp point to the incoming (parsed) symbol list on entry, and ++ will be updated to point to the new symbol table's values upon ++ exit. */ ++ ++bfd_boolean ++write_coff_debugging_info (abfd, dhandle, symcountp, symppp) ++ bfd *abfd; ++ PTR dhandle; ++ long *symcountp; ++ asymbol ***symppp; ++{ ++ struct coff_write_handle info; ++ long i, l; ++ asymbol *symp; ++ struct coff_compilation_unit *up; ++ coff_symbol_type *csymp; ++ ++ memset ((void *)&info, 0, sizeof info); ++ ++ info.abfd = abfd; ++ ++ info.pointersize = info.enumsize = 4; ++ ++ switch (bfd_get_arch (abfd)) ++ { ++ case bfd_arch_avr: ++ info.flags |= COFF_FL_AVR; ++ if (strcmp (abfd->xvec->name, "coff-ext-avr") == 0) ++ info.flags |= COFF_FL_EXT_AVR; ++ /* Fix the builtin type sizes. */ ++ coff_predef_types[0].size = 2; /* sizeof(int) == 2 */ ++ coff_predef_types[4].size = 4; /* sizeof(double) == 4 */ ++ coff_predef_types[6].size = 2; /* sizeof(unsigned int) == 2 */ ++ info.pointersize = info.enumsize = 2; ++ break; ++ ++ default: ++ ; ++ } ++ ++ coff_copy_symbols(&info, *symcountp, *symppp); ++ ++ if (info.textsect == NULL) ++ { ++ fprintf (stderr, _("Warning: no \"text\" section found in output file\n")); ++ info.textsect = bfd_abs_section_ptr; ++ } ++ if (info.datasect == NULL) ++ { ++ fprintf (stderr, _("Warning: no \"data\" section found in output file\n")); ++ info.datasect = bfd_abs_section_ptr; ++ } ++ ++ if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc, ++ sizeof(struct coff_name_type_hash_entry))) ++ return FALSE; ++ ++ if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc, ++ sizeof(struct coff_struct_hash_entry))) ++ return FALSE; ++ ++ if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc, ++ sizeof(struct coff_enum_hash_entry))) ++ return FALSE; ++ ++ if (! debug_write (dhandle, &coff_fns, (PTR) &info)) ++ return FALSE; ++ ++ /* If there is an old compilation unit that has got any local ++ non-debugging symbols left over, send them out now. */ ++ if (info.currentfile != NULL && info.currentfile->totsyms != 0) ++ for (i = 0; i < info.currentfile->nsyms; i++) ++ { ++ up = info.currentfile; ++ ++ if (up->syms[i] != NULL) ++ { ++ coff_emit_ndebug_sym (&info, up->syms[i], TRUE); ++ up->syms[i] = NULL; ++ up->totsyms--; ++ } ++ } ++ ++ /* See whether there are any non-debugging symbols left from the ++ input symbol table. First look at all local symbols which must ++ be from entire compilation units we didn't see yet in the ++ debugging information, because anything else has already been ++ handled at the end of each compilation unit (like in the loop ++ immediately above). Any compilation unit that has already been ++ processed that way is supposed to have its "totsyms" counted down ++ to 0 now, so we can skip them. ++ ++ Finally, put out all remaining global non-debugging symbols. */ ++ for (l = 0; l < info.nunits; l++) ++ { ++ const char *bn; ++ ++ up = info.units + l; ++ if (up->totsyms == 0) ++ continue; ++ ++ /* Create COFF symbol for this compilation unit. */ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info.abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ bn = bu_basename (up->fname); ++ ++ if (bfd_coff_long_filenames (info.abfd)) ++ csymp->symbol.name = up->fname; ++ else ++ csymp->symbol.name = bn; ++ ++ csymp->symbol.value = 0; ++ csymp->symbol.udata.p = NULL; ++ csymp->native->u.syment.n_sclass = C_FILE; ++ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ ++ coff_record_symbol (&info, csymp); ++ ++ for (i = 0; i < up->nsyms; i++) ++ { ++ symp = up->syms[i]; ++ if (symp == NULL) ++ continue; ++ ++ coff_emit_ndebug_sym (&info, symp, TRUE); ++ } ++ } ++ ++ for (i = 0; i < info.nglobals; i++) ++ { ++ symp = info.globals[i]; ++ if (symp == NULL) ++ continue; ++ ++ coff_emit_ndebug_sym (&info, symp, FALSE); ++ } ++ ++ /* Fixup the AUX entries for the section symbols we have emitted ++ earlier (so they are guaranteed to be at the beginning of the ++ symbol table). In particular, the line number count (which we ++ only have for the text section) is known right now. */ ++ for (i = 0; i < info.nsecsyms; i++) ++ { ++ union internal_auxent *aux; ++ ++ csymp = info.secsyms[i]; ++ ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_scn.x_scnlen = csymp->symbol.section->output_section->rawsize; ++ aux->x_scn.x_nreloc = csymp->symbol.section->reloc_count; ++ if (csymp->symbol.section == info.textsect) ++ aux->x_scn.x_nlinno = info.totlnos; ++ } ++ free (info.secsyms); ++ ++ coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL); ++ bfd_hash_table_free (&info.types.root); ++ ++ coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL); ++ bfd_hash_table_free (&info.structs.root); ++ ++ coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL); ++ bfd_hash_table_free (&info.enums.root); ++ ++ /* FIXME: free all the other stuff remembered in "info". */ ++ ++ free (*symppp); ++ ++ *symcountp = info.nsyms; ++ *symppp = (asymbol **)info.syms; ++ ++ return TRUE; ++} ++ ++/* Start writing out information for a compilation unit. */ ++ ++static bfd_boolean ++coff_start_compilation_unit (p, filename) ++ PTR p; ++ const char *filename; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ long i; ++ const char *bn; ++ bfd_boolean found; ++ coff_symbol_type *csymp; ++ ++#if COFF_DEBUG ++ printf ("coff_start_compilation_unit(%s)\n", filename); ++#endif ++ ++ /* If there is an old compilation unit that has got any local ++ non-debugging symbols left over, send them out now. */ ++ if (info->currentfile != NULL && info->currentfile->totsyms != 0) ++ for (i = 0; i < info->currentfile->nsyms; i++) ++ { ++ struct coff_compilation_unit *up = info->currentfile; ++ ++ if (up->syms[i] != NULL) ++ { ++ coff_emit_ndebug_sym (info, up->syms[i], TRUE); ++ up->syms[i] = NULL; ++ up->totsyms--; ++ } ++ } ++ ++ /* symtab (and thus COFF debugging) symbols can only transfer the ++ basename of the file, so strip the dirname */ ++ bn = bu_basename (filename); ++ ++ for (i = 0, found = FALSE; i < info->nunits; i++) ++ { ++ if (strcmp (info->units[i].fname, bn) == 0) ++ { ++ info->currentfile = info->units + i; ++ found = TRUE; ++ break; ++ } ++ } ++ if (!found) ++ { ++ fprintf(stderr, ++ _("Warning: file %s not found in symbol table, ignoring\n"), ++ filename); ++ info->currentfile = NULL; ++ return TRUE; ++ } ++ ++ /* Synthesize a new internal COFF symbol. */ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ /* Note that coff_fix_symbol_name() [coffgen.c] will fix this for ++ us: the symbol name will be replaced by ".file", and the filename ++ will be moved to the aux entries. We use the long name obtained ++ from the debugging information (that includes the full path) if ++ our COFF format supports long filenames, otherwise we only use ++ the basename of the file. */ ++ if (bfd_coff_long_filenames (info->abfd)) ++ csymp->symbol.name = filename; ++ else ++ csymp->symbol.name = bn; ++ csymp->symbol.value = 0; ++ csymp->symbol.udata.p = NULL; ++ csymp->native->u.syment.n_sclass = C_FILE; ++ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ ++ coff_record_symbol (info, csymp); ++ ++ return TRUE; ++} ++ ++/* Start writing out information for a particular source file. */ ++ ++static bfd_boolean ++coff_start_source (p, filename) ++ PTR p ATTRIBUTE_UNUSED; ++ const char *filename ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_start_source(%s)\n", filename); ++#endif ++ ++ /* COFF cannot handle include filenames. */ ++ ++ return TRUE; ++} ++ ++/* Push an empty type. This shouldn't normally happen. */ ++ ++static bfd_boolean ++coff_empty_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_empty_type()\n"); ++#endif ++ ++ coff_push_type (TS_EMPTY); ++ ++ return TRUE; ++} ++ ++/* Push a void type. */ ++ ++static bfd_boolean ++coff_void_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_void_type()\n"); ++#endif ++ ++ coff_push_type (TS_VOID); ++ ++ return TRUE; ++} ++ ++/* Push an integer type. */ ++ ++static bfd_boolean ++coff_int_type (p, size, unsignedp) ++ PTR p; ++ unsigned int size; ++ bfd_boolean unsignedp; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_int_type(%d, %d)\n", size, unsignedp); ++#endif ++ ++ coff_push_type (TS_INT); ++ tst->u.ts_int.size = size; ++ tst->u.ts_int.isunsigned = unsignedp; ++ ++ return TRUE; ++} ++ ++/* Push a floating point type. */ ++ ++static bfd_boolean ++coff_float_type (p, size) ++ PTR p; ++ unsigned int size; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_float_type(%d)\n", size); ++#endif ++ ++ coff_push_type (TS_FLOAT); ++ tst->u.ts_float.size = size; ++ ++ return TRUE; ++} ++ ++/* Push a complex type. */ ++ ++static bfd_boolean ++coff_complex_type (p, size) ++ PTR p; ++ unsigned int size ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_complex_type(%d)\n", size); ++#endif ++ ++ coff_push_type (TS_COMPLEX); ++ ++ return TRUE; ++} ++ ++/* Push a bfd_boolean type. */ ++ ++static bfd_boolean ++coff_bool_type (p, size) ++ PTR p; ++ unsigned int size; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_bool_type(%d)\n", size); ++#endif ++ ++ coff_push_type (TS_INT); ++ tst->u.ts_int.size = size; ++ tst->u.ts_int.isunsigned = TRUE; ++ ++ return TRUE; ++} ++ ++/* Push an enum type. */ ++ ++static bfd_boolean ++coff_enum_type (p, tag, names, vals) ++ PTR p; ++ const char *tag; ++ const char **names; ++ bfd_signed_vma *vals; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ char buf[20]; ++ ++#if COFF_DEBUG ++ int idx; ++ printf ("coff_enum_type(%s [", tag); ++ for (idx = 0; names[idx] != NULL; idx++) ++ printf ("%s -> %d, ", names[idx], (int)vals[idx]); ++ printf ("])\n"); ++#endif ++ ++ coff_push_type (TS_ENUM); ++ ++ if (tag == NULL) ++ { ++ sprintf(buf, ".%dfake", info->nenums++); ++ tst->u.ts_enum.tag.malloctag = xstrdup (buf); ++ tst->u.ts_enum.tagismalloced = TRUE; ++ } ++ else ++ tst->u.ts_enum.tag.fixtag = tag; ++ tst->u.ts_enum.names = names; ++ tst->u.ts_enum.vals = vals; ++ ++ return TRUE; ++} ++ ++/* Push a pointer type. */ ++ ++static bfd_boolean ++coff_pointer_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_pointer_type()\n"); ++#endif ++ ++ coff_push_type (TS_POINTER); ++ ++ return TRUE; ++} ++ ++/* Push a function type. */ ++ ++static bfd_boolean ++coff_function_type (p, argcount, varargs) ++ PTR p; ++ int argcount; ++ bfd_boolean varargs ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_function_type(%d, %d)\n", argcount, varargs); ++#endif ++ ++ coff_push_type (TS_FUNC); ++ ++ /* FIXME should properly discard function arguments */ ++ if (argcount > -1) ++ { ++ fprintf (stderr, ++ _("coff_function_type() called with positive argcount\n")); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Push a reference type. */ ++ ++static bfd_boolean ++coff_reference_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_reference_type()\n"); ++#endif ++ ++ coff_complain_unsupp (_("reference")); ++ ++ return TRUE; ++} ++ ++/* Push a range type. */ ++ ++static bfd_boolean ++coff_range_type (p, low, high) ++ PTR p; ++ bfd_signed_vma low ATTRIBUTE_UNUSED; ++ bfd_signed_vma high ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_range_type([%d..%d)\n", (int)low, (int)high); ++#endif ++ ++ coff_complain_unsupp (_("range")); ++ ++ return TRUE; ++} ++ ++/* Push an array type. */ ++ ++static bfd_boolean ++coff_array_type (p, low, high, stringp) ++ PTR p; ++ bfd_signed_vma low; ++ bfd_signed_vma high; ++ bfd_boolean stringp; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst; ++ ++#if COFF_DEBUG ++ printf ("coff_array_type([%d..%d], %d)\n", ++ (int)low, (int)high, stringp); ++#endif ++ ++ /* Pop the range type, but ignore it. COFF doesn't use it. */ ++ coff_pop_type (); ++ ++ /* FIXME What to do here? */ ++ if (stringp) ++ { ++ fprintf(stderr, _("coff_array_type(): stringp == TRUE\n")); ++ return FALSE; ++ } ++ ++ coff_push_type (TS_ARRAY); ++ tst->u.ts_array.low = low; ++ tst->u.ts_array.high = high; ++ ++ return TRUE; ++} ++ ++/* Push a set type. */ ++ ++static bfd_boolean ++coff_set_type (p, bitstringp) ++ PTR p; ++ bfd_boolean bitstringp ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_set_type(%d)\n", bitstringp); ++#endif ++ ++ coff_complain_unsupp (_("set")); ++ ++ return TRUE; ++} ++ ++/* Push an offset type. */ ++ ++static bfd_boolean ++coff_offset_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_offset_type()\n"); ++#endif ++ ++ coff_complain_unsupp (_("offset")); ++ ++ return TRUE; ++} ++ ++/* Push a method type. */ ++ ++static bfd_boolean ++coff_method_type (p, domainp, argcount, varargs) ++ PTR p; ++ bfd_boolean domainp ATTRIBUTE_UNUSED; ++ int argcount ATTRIBUTE_UNUSED; ++ bfd_boolean varargs ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_method_type(%d, %d, %d)\n", ++ domainp, argcount, varargs); ++#endif ++ ++ coff_complain_unsupp (_("method")); ++ ++ return TRUE; ++} ++ ++/* Push a const version of a type. */ ++ ++static bfd_boolean ++coff_const_type (p) ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_const_type()\n"); ++#endif ++ ++ /* const modifier is ignored by COFF */ ++ ++ return TRUE; ++} ++ ++/* Push a volatile version of a type. */ ++ ++static bfd_boolean ++coff_volatile_type (p) ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_volatile_type()\n"); ++#endif ++ ++ /* volatile modifier is ignored by COFF */ ++ ++ return TRUE; ++} ++ ++/* Start outputting a struct. */ ++ ++static bfd_boolean ++coff_start_struct_type (p, tag, id, structp, size) ++ PTR p; ++ const char *tag; ++ unsigned int id; ++ bfd_boolean structp; ++ unsigned int size; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *savedts; ++ struct coff_struct_hash_entry *shash; ++ char buf[20]; ++ const char *name; ++ ++#if COFF_DEBUG ++ printf ("coff_start_struct_type(%s, %d, %d, %d)\n", ++ tag, id, structp, size); ++#endif ++ ++ savedts = info->tstack; ++ info->tstack = NULL; ++ ++ coff_push_type (TS_STRUCT); ++ ++ if (tag == NULL) ++ { ++ sprintf(buf, ".%dfake", id); ++ name = tst->u.ts_struct.tag.malloctag = xstrdup (buf); ++ tst->u.ts_struct.tagismalloced = TRUE; ++ } ++ else ++ name = tst->u.ts_struct.tag.fixtag = tag; ++ tst->u.ts_struct.id = id; ++ tst->u.ts_struct.isstruct = structp; ++ tst->u.ts_struct.size = size; ++ tst->u.ts_struct.savedts = savedts; ++ ++ shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE); ++ if (shash != NULL && shash->types != NULL) ++ { ++#if COFF_DEBUG ++ printf ("new %s definition for %s\n", ++ tst->u.ts_struct.isstruct? "struct": "union", name); ++#endif ++ coff_free_struct_info (shash, NULL); ++ shash->types = NULL; ++ shash->emitted = FALSE; ++ } ++ else ++ (void)coff_struct_hash_lookup (&info->structs, name, ++ TRUE, tst->u.ts_struct.tagismalloced); ++ ++ return TRUE; ++} ++ ++/* Add a field to a struct. */ ++ ++static bfd_boolean ++coff_struct_field (p, name, bitpos, bitsize, visibility) ++ PTR p; ++ const char *name; ++ bfd_vma bitpos; ++ bfd_vma bitsize; ++ enum debug_visibility visibility; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *otst; ++ struct coff_struct_fields *fp; ++ struct coff_struct_hash_entry *shash; ++ struct coff_enum_hash_entry *ehash; ++ const char *tag; ++ ++#if COFF_DEBUG ++ printf ("coff_struct_field(%s, %d, %d, %d)\n", ++ name, (int)bitpos, (int)bitsize, (int)visibility); ++#endif ++ ++ /* Find the last element on the type stack. */ ++ assert (info->tstack != NULL); ++ for (tst = info->tstack, otst = NULL; tst->next != NULL;) ++ { ++ otst = tst; ++ tst = tst->next; ++ } ++ if (otst != NULL) ++ otst->next = NULL; ++ ++ if (tst->tsk != TS_STRUCT) ++ { ++ fprintf (stderr, "coff_struct_field() not within structure definition\n"); ++ return FALSE; ++ } ++ tst->u.ts_struct.fields = (struct coff_struct_fields *) ++ xrealloc (tst->u.ts_struct.fields, ++ ++tst->u.ts_struct.nfields * sizeof (struct coff_struct_fields)); ++ fp = tst->u.ts_struct.fields + (tst->u.ts_struct.nfields - 1); ++ fp->name = name; ++ fp->bitpos = bitpos; ++ fp->bitsize = bitsize; ++ fp->visibility = visibility; ++ otst = fp->types = info->tstack; ++ while (otst->next != NULL) ++ otst = otst->next; ++ if (otst->tsk == TS_STRUCT && otst->u.ts_struct.shash == NULL) ++ { ++ if (otst->u.ts_struct.tagismalloced) ++ tag = otst->u.ts_struct.tag.malloctag; ++ else ++ tag = otst->u.ts_struct.tag.fixtag; ++ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); ++ assert (shash != NULL); ++ if (!shash->emitted) ++ { ++ if (shash->types == NULL) ++ { ++ shash->types = (struct coff_type_stack *) ++ xmalloc (sizeof (struct coff_type_stack)); ++ memcpy (shash->types, otst, sizeof (struct coff_type_stack)); ++ } ++ shash->emitted = TRUE; ++ coff_emit_struct (info, otst, shash); ++ } ++ } ++ else if (otst->tsk == TS_ENUM) ++ { ++ if (otst->u.ts_enum.tagismalloced) ++ tag = otst->u.ts_enum.tag.malloctag; ++ else ++ tag = otst->u.ts_enum.tag.fixtag; ++ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); ++ assert (ehash != NULL); ++ if (!ehash->emitted) ++ { ++ if (ehash->types == NULL) ++ { ++ ehash->types = (struct coff_type_stack *) ++ xmalloc (sizeof (struct coff_type_stack)); ++ memcpy (ehash->types, otst, sizeof (struct coff_type_stack)); ++ } ++ ehash->emitted = TRUE; ++ coff_emit_enum (info, otst, ehash); ++ } ++ } ++ ++ info->tstack = tst; ++ ++ return TRUE; ++} ++ ++/* Finish up a struct. */ ++ ++static bfd_boolean ++coff_end_struct_type (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *savedts; ++ ++#if COFF_DEBUG ++ printf ("coff_end_struct_type()\n"); ++#endif ++ ++ /* Our struct definition should be the only type stack element by ++ now. */ ++ assert (info->tstack != NULL); ++ tst = info->tstack; ++ if (tst->tsk != TS_STRUCT || tst->next != NULL) ++ { ++ fprintf (stderr, "coff_struct_field() not within structure definition\n"); ++ return FALSE; ++ } ++ ++ /* Restore saved type stack, and push our now complete struct ++ definition on top. */ ++ savedts = tst->u.ts_struct.savedts; ++ tst->u.ts_struct.savedts = info->tstack; ++ info->tstack = savedts; ++ tst->next = info->tstack; ++ info->tstack = tst; ++ ++ return TRUE; ++} ++ ++/* Start outputting a class. */ ++ ++static bfd_boolean ++coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr) ++ PTR p; ++ const char *tag ATTRIBUTE_UNUSED; ++ unsigned int id ATTRIBUTE_UNUSED; ++ bfd_boolean structp ATTRIBUTE_UNUSED; ++ unsigned int size ATTRIBUTE_UNUSED; ++ bfd_boolean vptr ATTRIBUTE_UNUSED; ++ bfd_boolean ownvptr ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n", ++ tag, id, structp, size, vptr, ownvptr); ++#endif ++ ++ coff_complain_unsupp (_("class")); ++ ++ return TRUE; ++} ++ ++/* Add a static member to the class on the type stack. */ ++ ++static bfd_boolean ++coff_class_static_member (p, name, physname, visibility) ++ PTR p ATTRIBUTE_UNUSED; ++ const char *name ATTRIBUTE_UNUSED; ++ const char *physname ATTRIBUTE_UNUSED; ++ enum debug_visibility visibility ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_static_member(%s, %s, %d)\n", ++ name, physname, (int)visibility); ++#endif ++ ++ return TRUE; ++} ++ ++/* Add a base class to the class on the type stack. */ ++ ++static bfd_boolean ++coff_class_baseclass (p, bitpos, virtual, visibility) ++ PTR p ATTRIBUTE_UNUSED; ++ bfd_vma bitpos ATTRIBUTE_UNUSED; ++ bfd_boolean virtual ATTRIBUTE_UNUSED; ++ enum debug_visibility visibility ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_baseclass(%d, %d, %d)\n", ++ (int)bitpos, virtual, (int)visibility); ++#endif ++ ++ return TRUE; ++} ++ ++/* Start adding a method to the class on the type stack. */ ++ ++static bfd_boolean ++coff_class_start_method (p, name) ++ PTR p ATTRIBUTE_UNUSED; ++ const char *name ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_start_method(%s)\n", name); ++#endif ++ ++ return TRUE; ++} ++ ++/* Add a variant to the current method. */ ++ ++static bfd_boolean ++coff_class_method_variant (p, physname, visibility, constp, volatilep, ++ voffset, contextp) ++ PTR p ATTRIBUTE_UNUSED; ++ const char *physname ATTRIBUTE_UNUSED; ++ enum debug_visibility visibility ATTRIBUTE_UNUSED; ++ bfd_boolean constp ATTRIBUTE_UNUSED; ++ bfd_boolean volatilep ATTRIBUTE_UNUSED; ++ bfd_vma voffset ATTRIBUTE_UNUSED; ++ bfd_boolean contextp ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n", ++ physname, (int)visibility, constp, volatilep, ++ (int)voffset, contextp); ++#endif ++ ++ return TRUE; ++} ++ ++/* Add a static variant to the current method. */ ++ ++static bfd_boolean ++coff_class_static_method_variant (p, physname, visibility, constp, volatilep) ++ PTR p ATTRIBUTE_UNUSED; ++ const char *physname ATTRIBUTE_UNUSED; ++ enum debug_visibility visibility ATTRIBUTE_UNUSED; ++ bfd_boolean constp ATTRIBUTE_UNUSED; ++ bfd_boolean volatilep ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n", ++ physname, (int)visibility, constp, volatilep); ++#endif ++ ++ return TRUE; ++} ++ ++/* Finish up a method. */ ++ ++static bfd_boolean ++coff_class_end_method (p) ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_class_end_method()\n"); ++#endif ++ ++ return TRUE; ++} ++ ++/* Finish up a class. */ ++ ++static bfd_boolean ++coff_end_class_type (p) ++ PTR p ATTRIBUTE_UNUSED; ++{ ++ ++#if COFF_DEBUG ++ printf ("coff_end_class_type()\n"); ++#endif ++ ++ return TRUE; ++} ++ ++/* Push a typedef which was previously defined. */ ++ ++static bfd_boolean ++coff_typedef_type (p, name) ++ PTR p; ++ const char *name; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_name_type_hash_entry *nthash; ++ struct coff_type_stack *tst, *newchain, *newst, *temp; ++ ++#if COFF_DEBUG ++ printf ("coff_typedef_type(%s)\n", name); ++#endif ++ ++ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); ++ ++ /* nthash should never be NULL, since that would imply that the ++ generic debugging code has asked for a typedef which it has not ++ yet defined. */ ++ assert (nthash != NULL); ++ ++ /* Just push the entire type stack snapshot we've got on top of the ++ existing typestack. See coff_typdef() below for how this ++ works. We need to copy over each element however, since anybody ++ popping elements off the typestack is supposed to free() each of ++ them. */ ++ ++ for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;) ++ { ++ temp = newst; ++ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); ++ if (newchain == NULL) ++ newchain = newst; ++ memcpy (newst, tst, sizeof (*newst)); ++ if (temp != NULL) ++ temp->next = newst; ++ ++ tst = tst->next; ++ } ++ newst->next = info->tstack; ++ info->tstack = newchain; ++ ++ return TRUE; ++} ++ ++/* Push a struct, union or class tag. */ ++ ++static bfd_boolean ++coff_tag_type (p, name, id, kind) ++ PTR p; ++ const char *name; ++ unsigned int id ATTRIBUTE_UNUSED; ++ enum debug_type_kind kind; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *newchain, *newst, *temp; ++ struct coff_struct_hash_entry *shash; ++ struct coff_enum_hash_entry *ehash; ++ char buf[20]; ++ bfd_boolean needcopy = FALSE; ++ bfd_boolean isstruct = TRUE; ++ ++#if COFF_DEBUG ++ printf ("coff_tag_type(%s, %d, %d)\n", ++ name, id, kind); ++#endif ++ ++ if (name == NULL) ++ { ++ sprintf(buf, ".%dfake", id); ++ needcopy = TRUE; ++ } ++ ++ switch (kind) ++ { ++ case DEBUG_KIND_UNION: ++ case DEBUG_KIND_UNION_CLASS: ++ isstruct = FALSE; ++ /* FALLTHROUGH */ ++ case DEBUG_KIND_STRUCT: ++ case DEBUG_KIND_CLASS: ++ shash = coff_struct_hash_lookup (&info->structs, ++ name == NULL? buf: name, TRUE, needcopy); ++ assert (shash != NULL); ++ tst = shash->types; ++ if (tst == NULL) ++ { ++ /* This is a reference to a tag that has not yet been ++ defined (i. e., a forward reference). Synthesize a ++ ts_struct entry by now, and mark it for later fixup. */ ++ tst = (struct coff_type_stack *) xmalloc (sizeof *tst); ++ memset (tst, 0, sizeof *tst); ++ tst->tsk = TS_STRUCT; ++ tst->u.ts_struct.isstruct = isstruct; ++ tst->u.ts_struct.shash = shash; ++ } ++ docopystack: ++ /* Just push the entire type stack snapshot we've got on top of the ++ existing typestack. See coff_typdef() below for how this ++ works. We need to copy over each element however, since anybody ++ popping elements off the typestack is supposed to free() each of ++ them. */ ++ for (temp = newst = newchain = NULL; tst != NULL;) ++ { ++ temp = newst; ++ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); ++ if (newchain == NULL) ++ newchain = newst; ++ memcpy (newst, tst, sizeof (*newst)); ++ if (temp != NULL) ++ temp->next = newst; ++ ++ tst = tst->next; ++ } ++ if (newst) ++ { ++ newst->next = info->tstack; ++ info->tstack = newchain; ++ } ++ break; ++ ++ case DEBUG_KIND_ENUM: ++ ehash = coff_enum_hash_lookup (&info->enums, ++ name == NULL? buf: name, TRUE, needcopy); ++ assert (ehash != NULL); ++ tst = ehash->types; ++ if (tst == NULL) ++ { ++ /* This is a reference to a tag that has not yet been ++ defined (i. e., a forward reference). Synthesize a ++ ts_enum entry by now, and mark it for later fixup. */ ++ tst = (struct coff_type_stack *) xmalloc (sizeof *tst); ++ memset (tst, 0, sizeof *tst); ++ tst->tsk = TS_ENUM; ++ tst->u.ts_enum.ehash = ehash; ++ } ++ goto docopystack; ++ ++ default: ++ fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"), ++ (int)kind); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/* Define a typedef. */ ++ ++static bfd_boolean ++coff_typdef (p, name) ++ PTR p; ++ const char *name; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_name_type_hash_entry *nthash; ++ ++#if COFF_DEBUG ++ printf ("coff_typdef(%s)\n", name); ++#endif ++ ++ /* COFF cannot really handle typedefs. While there is the option to ++ mark a symbol using the storage class C_TPDEF (so the COFF reader ++ will know that name), there is no way to place a reference to ++ that typedef into the just 16 bits COFF reserves for all of its ++ type information. Thus, any use of the typedef must always fully ++ dereference the typedef again. We do this by "snapshotting" the ++ current type stack under the name of our typedef, and later on, ++ when BFD debugging tells us to make use of the typedef (in ++ coff_typedef_type()), we just look it up, and push all we've got ++ completely onto the type stack again. */ ++ ++ if (info->tstack == NULL) ++ { ++ fprintf (stderr, _("coff_typdef() on an empty type stack\n")); ++ return FALSE; ++ } ++ ++ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); ++ if (nthash != NULL) ++ { ++#if COFF_DEBUG ++ printf ("new typedef for %s\n", name); ++#endif ++ coff_free_type_info (nthash, NULL); ++ } ++ else ++ nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE); ++ if (nthash == NULL) ++ return FALSE; ++ nthash->types = info->tstack; ++ ++ /* If the typestack is "sufficiently complex", emit a C_TPDEF symbol ++ for it. We assume it to be sufficiently complex if there are ++ either at least two derived types, or one derived type where the ++ base type is not a simple scalar one. */ ++ if (!nthash->emitted ++ && info->tstack->next != NULL ++ && (info->tstack->next->next != NULL || info->tstack->next->tsk >= TS_ENUM)) ++ { ++ struct coff_type_stack *newchain, *otst, *tst, *ntst; ++ coff_symbol_type *csymp; ++ ++ nthash->emitted = TRUE; ++ ++ for (tst = info->tstack, newchain = otst = NULL; ++ tst != NULL; ++ tst = tst->next) ++ { ++ ntst = (struct coff_type_stack *) ++ xmalloc (sizeof (struct coff_type_stack)); ++ memcpy (ntst, tst, sizeof (struct coff_type_stack)); ++ if (otst == NULL) ++ newchain = ntst; ++ else ++ otst->next = ntst; ++ otst = ntst; ++ } ++ info->tstack = newchain; ++ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) ++ return FALSE; ++ ++ csymp->symbol.name = xstrdup (name); ++ csymp->symbol.flags = BSF_NOT_AT_END; ++ csymp->symbol.section = bfd_com_section_ptr; ++ csymp->native->u.syment.n_sclass = C_TPDEF; ++ csymp->symbol.value = 0; ++ ++ coff_record_symbol (info, csymp); ++ } ++ info->tstack = NULL; ++ ++ return TRUE; ++} ++ ++/* Define a tag. */ ++ ++static bfd_boolean ++coff_tag (p, tag) ++ PTR p; ++ const char *tag; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst = NULL; ++ struct coff_struct_hash_entry *shash; ++ struct coff_enum_hash_entry *ehash; ++ ++ ++#if COFF_DEBUG ++ printf ("coff_tag(%s)\n", tag); ++#endif ++ ++ if (info->tstack == NULL) ++ { ++ fprintf (stderr, _("coff_tag() called on an empty typestack\n")); ++ return FALSE; ++ } ++ ++ switch (info->tstack->tsk) ++ { ++ case TS_STRUCT: ++ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); ++ assert (shash != NULL); ++ shash->types = info->tstack; ++ info->tstack = NULL; ++ break; ++ ++ case TS_ENUM: ++ ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE); ++ if (ehash != NULL && ehash->types != NULL) ++ { ++#if COFF_DEBUG ++ printf ("new enum definition for %s\n", tag); ++#endif ++ coff_free_enum_info (ehash, NULL); ++ } ++ else ++ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); ++ if (ehash == NULL) ++ return FALSE; ++ ehash->types = info->tstack; ++ info->tstack = NULL; ++ break; ++ ++ default: ++ fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* Define an integer constant. */ ++ ++static bfd_boolean ++coff_int_constant (p, name, val) ++ PTR p; ++ const char *name ATTRIBUTE_UNUSED; ++ bfd_vma val ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_int_constant(%s, %d)\n", name, (int)val); ++#endif ++ ++ coff_complain_unsupp (_("int constant")); ++ ++ return TRUE; ++} ++ ++/* Define a floating point constant. */ ++ ++static bfd_boolean ++coff_float_constant (p, name, val) ++ PTR p; ++ const char *name ATTRIBUTE_UNUSED; ++ double val ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_float_constant(%s, %g)\n", name, val); ++#endif ++ ++ coff_complain_unsupp (_("float constant")); ++ ++ return TRUE; ++} ++ ++/* Define a typed constant. */ ++ ++static bfd_boolean ++coff_typed_constant (p, name, val) ++ PTR p; ++ const char *name ATTRIBUTE_UNUSED; ++ bfd_vma val ATTRIBUTE_UNUSED; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ ++#if COFF_DEBUG ++ printf ("coff_typed_constant(%s, %d)\n", name, (int)val); ++#endif ++ ++ coff_complain_unsupp (_("typed constant")); ++ ++ return TRUE; ++} ++ ++/* Record a variable. */ ++ ++static bfd_boolean ++coff_variable (p, name, kind, val) ++ PTR p; ++ const char *name; ++ enum debug_var_kind kind; ++ bfd_vma val; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ unsigned char class; ++ asymbol *symp = NULL; ++ coff_symbol_type *csymp; ++ bfd_boolean global = FALSE; ++ flagword flags = BSF_LOCAL; ++ bfd_vma vmadiff = 0; ++ ++#if COFF_DEBUG ++ printf ("coff_variable(%s, %d, %d)\n", ++ name, (int)kind, (int)val); ++#endif ++ ++ switch (kind) ++ { ++ default: ++ abort (); ++ ++ case DEBUG_GLOBAL: ++ flags = BSF_GLOBAL; ++ global = TRUE; ++ /* AVR COFF historically used C_EXTDEF for global variables, and ++ C_EXT for global functions. Since some AVR COFF consumers ++ apparently depend on this, we mimic this behaviour as ++ well. */ ++ class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT; ++ break; ++ ++ case DEBUG_STATIC: ++ case DEBUG_LOCAL_STATIC: ++ class = C_STAT; ++ break; ++ ++ case DEBUG_LOCAL: ++ class = C_AUTO; ++ break; ++ ++ case DEBUG_REGISTER: ++ class = C_REG; ++ break; ++ } ++ ++ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) ++ return FALSE; ++ ++ if (class == C_REG && (info->flags & COFF_FL_AVR) != 0) ++ { ++ struct coff_private_symdata *priv = (struct coff_private_symdata *) ++ csymp->symbol.udata.p; ++ val = coff_fixup_avr_register (val, priv->size * 8); ++ } ++ ++ csymp->symbol.name = name; ++ csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */ ++ ++ /* Match the debugging symbol against the input symtab symbols. If ++ we found one, use the section information from it. Otherwise, we ++ are lost here and just use the absolute section that was ++ predeclared by coff_bfd_make_debug_symbol(). C_REG and C_AUTO ++ symbols (which we do not attempt to lookup in the symtab symbols ++ at all) go into the ABS section anyway. */ ++ if (class != C_REG && class != C_AUTO) ++ { ++ symp = coff_find_symbol (info, name, FALSE, global); ++ if (symp) ++ { ++ csymp->symbol.section = symp->section; ++ vmadiff = symp->section->vma; ++ } ++ } ++ ++ /* Symbols are relative to section vma. */ ++ csymp->symbol.value = val - vmadiff; ++ csymp->native->u.syment.n_sclass = class; ++ coff_record_symbol (info, csymp); ++ ++ return TRUE; ++} ++ ++/* Start outputting a function. */ ++ ++static bfd_boolean ++coff_start_function (p, name, globalp) ++ PTR p; ++ const char *name; ++ bfd_boolean globalp; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *savedts; ++ ++#if COFF_DEBUG ++ printf ("coff_start_function(%s, %d)\n", ++ name, globalp); ++#endif ++ ++ savedts = info->tstack; ++ info->tstack = NULL; ++ ++ coff_push_type (TS_FUNC); ++ ++ if (info->funname != NULL) ++ { ++ fprintf (stderr, ++ _("coff_start_function() called twice, pending %s, new %s\n"), ++ info->funname, name); ++ return FALSE; ++ } ++ info->funname = name; ++ info->funglobal = globalp; ++ info->flags |= COFF_FL_START_FCN; ++ tst->u.ts_func.savedts = savedts; ++ ++ return TRUE; ++} ++ ++/* Output a function parameter. */ ++ ++static bfd_boolean ++coff_function_parameter (p, name, kind, val) ++ PTR p; ++ const char *name; ++ enum debug_parm_kind kind; ++ bfd_vma val; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ coff_symbol_type *csymp; ++ unsigned char class; ++ ++#if COFF_DEBUG ++ printf ("coff_function_parameter(%s, %d, %d)\n", ++ name, (int)kind, (int)val); ++#endif ++ ++ switch (kind) ++ { ++ default: ++ abort (); ++ ++ case DEBUG_PARM_STACK: ++ class = C_ARG; ++ break; ++ ++ case DEBUG_PARM_REG: ++ class = C_REGPARM; ++ break; ++ ++ case DEBUG_PARM_REFERENCE: ++ case DEBUG_PARM_REF_REG: ++ fprintf (stderr, _("Reference parameters not available in COFF\n")); ++ return TRUE; ++ } ++ ++ if (!coff_make_typed_symbol (info, &csymp, TS_FUNC)) ++ return FALSE; ++ ++ if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0) ++ { ++ struct coff_private_symdata *priv = (struct coff_private_symdata *) ++ csymp->symbol.udata.p; ++ val = coff_fixup_avr_register (val, priv->size * 8); ++ } ++ ++ csymp->symbol.name = name; ++ csymp->symbol.value = val; ++ csymp->symbol.flags |= BSF_LOCAL; ++ csymp->native->u.syment.n_sclass = class; ++ ++ /* Since function parameters precede the actual function definition, ++ defer their output until the function has been created. */ ++ info->fargs = (coff_symbol_type **) ++ xrealloc (info->fargs, ++info->nfargs * sizeof (coff_symbol_type *)); ++ info->fargs[info->nfargs - 1] = csymp; ++ ++ return TRUE; ++} ++ ++/* Start a block. */ ++ ++static bfd_boolean ++coff_start_block (p, addr) ++ PTR p; ++ bfd_vma addr; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ struct coff_type_stack *tst, *otst; ++ struct coff_fix_stack *fixp, *ofp; ++ asymbol *symp; ++ coff_symbol_type *csymp; ++ unsigned int i; ++ bfd_boolean is_start_fcn; ++ ++#if COFF_DEBUG ++ printf ("coff_start_block(%#x)\n", (int)addr); ++#endif ++ ++ is_start_fcn = info->flags & COFF_FL_START_FCN; ++ ++ if (is_start_fcn) ++ { ++ /* This is the starting block of a function. We are going to ++ write three symbols here, one for the function itself, one ++ ".bf" symbol to indicate the begin of the function, and ++ finally one ".bb" for the first block inside the function. */ ++ info->flags &= ~COFF_FL_START_FCN; ++ ++ /* Our function definition should be the only type stack element ++ by now. */ ++ assert (info->tstack != NULL); ++ tst = info->tstack; ++ if (tst->tsk != TS_FUNC || tst->next != NULL) ++ { ++ fprintf (stderr, ++ _("coff_start_block() not within function definition\n")); ++ return FALSE; ++ } ++ ++ /* Restore saved type stack, and push our now complete function ++ definition on top. */ ++ info->tstack = tst->u.ts_func.savedts; ++ tst->next = info->tstack; ++ info->tstack = tst; ++ ++ if (info->currentfile == NULL) ++ { ++ fprintf (stderr, ++ _("Warning: ignoring function %s() outside any compilation unit\n"), ++ info->funname); ++ for (tst = info->tstack, otst = NULL; tst != NULL;) ++ { ++ otst = tst; ++ tst = otst->next; ++ if (otst->tsk == TS_ENUM && ++ otst->u.ts_enum.tagismalloced) ++ free (otst->u.ts_enum.tag.malloctag); ++ else if (otst->tsk == TS_STRUCT && ++ otst->u.ts_struct.tagismalloced) ++ free (otst->u.ts_struct.tag.malloctag); ++ free (otst); ++ } ++ info->tstack = NULL; ++ info->funname = NULL; ++ ++ return TRUE; ++ } ++ ++ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) ++ return FALSE; ++ ++ csymp->symbol.name = info->funname; ++ csymp->symbol.flags = BSF_FUNCTION | ++ (info->funglobal? BSF_GLOBAL: BSF_LOCAL); ++ symp = coff_find_symbol (info, info->funname, TRUE, info->funglobal); ++ if (symp == NULL) ++ { ++ fprintf (stderr, ++ _("function %s not found in symbol table, defaulting to \"text\" section\n"), ++ info->funname); ++ csymp->symbol.section = info->funcsection = info->textsect; ++ } ++ else ++ csymp->symbol.section = info->funcsection = symp->section; ++ ++ /* Symbol addresses are relative to section vma. */ ++ csymp->symbol.value = addr - info->funcsection->vma; ++ csymp->native->u.syment.n_sclass = info->funglobal? C_EXT: C_STAT; ++ /* Create two initial line number entries. The first one holds ++ the function symbol, the second one is the trailing record ++ that is required by coffgen.c::coff_write_native_symbol() to ++ have a line number of zero. */ ++ csymp->lineno = (alent *) xmalloc (2 * sizeof (alent)); ++ memset (csymp->lineno, 0, 2 * sizeof (alent)); ++ info->nlnos = 2; ++ info->totlnos++; ++ csymp->lineno[0].u.sym = (asymbol *)csymp; ++ coff_record_symbol (info, csymp); ++ info->funcindex = info->nsyms - 1; /* remember for later */ ++ /* Record our endndx field for later fixing. */ ++ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); ++ fixp->native = csymp->native + 1; /* points to first AUX */ ++ fixp->next = NULL; ++ if (info->fixes == NULL) ++ info->fixes = fixp; ++ else ++ { ++ for (ofp = info->fixes; ofp->next != NULL;) ++ ofp = ofp->next; ++ ofp->next = fixp; ++ } ++ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = ".bf"; ++ csymp->native->u.syment.n_sclass = C_FCN; ++ csymp->native->u.syment.n_numaux = 1; ++ csymp->symbol.value = addr - info->funcsection->vma; ++ csymp->symbol.section = info->funcsection; ++ csymp->symbol.udata.p = NULL; ++ coff_record_symbol (info, csymp); ++ } ++ ++ if (info->funname == NULL) ++ return TRUE; ++ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = ".bb"; ++ csymp->native->u.syment.n_sclass = C_BLOCK; ++ csymp->native->u.syment.n_numaux = 1; ++ csymp->symbol.value = addr - info->funcsection->vma; ++ csymp->symbol.section = info->funcsection; ++ csymp->symbol.udata.p = NULL; ++ coff_record_symbol (info, csymp); ++ ++ info->flags |= COFF_FL_FIX_BB; ++ ++ /* Output any pending function parameters, if any. */ ++ if (is_start_fcn && info->nfargs) ++ { ++ for (i = 0; i < info->nfargs; i++) ++ coff_record_symbol (info, info->fargs[i]); ++ ++ free (info->fargs); ++ info->fargs = NULL; ++ info->nfargs = 0; ++ } ++ ++ return TRUE; ++} ++ ++/* End a block. */ ++ ++static bfd_boolean ++coff_end_block (p, addr) ++ PTR p; ++ bfd_vma addr; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ coff_symbol_type *csymp; ++ union internal_auxent *aux; ++ ++#if COFF_DEBUG ++ printf ("coff_end_block(%#x)\n", (int)addr); ++#endif ++ ++ if (info->funname == NULL) ++ return TRUE; ++ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = ".eb"; ++ csymp->symbol.value = addr - info->funcsection->vma; ++ csymp->native->u.syment.n_sclass = C_BLOCK; ++ csymp->native->u.syment.n_numaux = 1; ++ csymp->symbol.udata.p = NULL; ++ csymp->symbol.section = info->funcsection; ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; ++ coff_record_symbol (info, csymp); ++ ++ info->endaddr = addr; ++ ++ return TRUE; ++} ++ ++/* End a function. */ ++ ++static bfd_boolean ++coff_end_function (p) ++ PTR p; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ coff_symbol_type *csymp; ++ union internal_auxent *aux; ++ ++#if COFF_DEBUG ++ printf ("coff_end_function()\n"); ++#endif ++ ++ if (info->funname == NULL) ++ return TRUE; ++ ++ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); ++ if (csymp == NULL) ++ return FALSE; ++ ++ csymp->symbol.name = ".ef"; ++ csymp->symbol.value = info->endaddr - info->funcsection->vma; ++ csymp->native->u.syment.n_sclass = C_FCN; ++ csymp->native->u.syment.n_numaux = 1; ++ csymp->symbol.udata.p = NULL; ++ csymp->symbol.section = info->funcsection; ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; ++ ++ coff_record_symbol (info, csymp); ++ ++ csymp = (coff_symbol_type *) info->syms[info->funcindex]; ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_sym.x_misc.x_fsize = info->endaddr - csymp->symbol.value; ++ ++ info->flags |= COFF_FL_FIX_ENDNDX; ++ info->funname = NULL; ++ ++ return TRUE; ++} ++ ++/* Output a line number. */ ++ ++static bfd_boolean ++coff_lineno (p, file, lineno, addr) ++ PTR p; ++ const char *file ATTRIBUTE_UNUSED; ++ unsigned long lineno; ++ bfd_vma addr; ++{ ++ struct coff_write_handle *info = (struct coff_write_handle *) p; ++ coff_symbol_type *csymp; ++ union internal_auxent *aux; ++ long i; ++ ++#if COFF_DEBUG ++ printf ("coff_lineno(%s, %ld, %d)\n", ++ file, lineno, (int)addr); ++#endif ++ ++ /* COFF can inherently only handle line numbers inside of functions. ++ If we are not inside a function, punt. */ ++ if (info->funname == NULL) ++ return TRUE; ++ ++ if (info->nlnos == 2) ++ { ++ /* This is the first line number of this function. Fix the line ++ number for the .bf symbol immediately following the start of ++ function. We also have to remember the starting line number ++ of our function since all line number entries are relative to ++ it in COFF. Since regular line numbers must always be ++ non-zero, we artificially force the function to start one ++ line earlier. */ ++ csymp = (coff_symbol_type *) info->syms[info->funcindex + 1]; ++ aux = &((csymp->native + 1)->u.auxent); ++ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; ++ info->funlno = lineno - 1; ++ } ++ ++ if (info->flags & COFF_FL_FIX_BB) ++ { ++ /* This is the first line number after one (or more) .bb ++ symbols. Fix them. In order to cope with multiple blocks ++ starting at the same line number, we walk back the list of ++ symbols until we find a C_BLOCK one that had already been ++ fixed, or until we find a C_FCN symbol (presumably, the start ++ of our current function). */ ++ info->flags &= ~COFF_FL_FIX_BB; ++ ++ for (i = info->nsyms - 1; i >= 0; i--) ++ { ++ csymp = (coff_symbol_type *) info->syms[i]; ++ if (csymp->native->u.syment.n_sclass == C_FCN) ++ break; ++ if (csymp->native->u.syment.n_sclass == C_BLOCK) ++ { ++ aux = &((csymp->native + 1)->u.auxent); ++ if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0) ++ /* already set up properly */ ++ break; ++ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; ++ } ++ } ++ } ++ ++ csymp = (coff_symbol_type *) info->syms[info->funcindex]; ++ csymp->lineno = (alent *) xrealloc (csymp->lineno, ++ ++info->nlnos * sizeof (alent)); ++ memset (csymp->lineno + info->nlnos - 1, 0, sizeof (alent)); ++ if (lineno > info->funlno) ++ csymp->lineno[info->nlnos - 2].line_number = lineno - info->funlno; ++ else ++ /* Line number unreasonable. Can e. g. happen for a line number ++ from an include file, which we cannot process in COFF. Just ++ set it to the first line, to avoid generating a large unsigned ++ short (~ 65000) line number. */ ++ csymp->lineno[info->nlnos - 2].line_number = 1; ++ csymp->lineno[info->nlnos - 2].u.offset = addr; ++ ++ info->lastlno = lineno; ++ info->totlnos++; ++ ++ return TRUE; ++} +diff -ruwN include/coff/avr.h include/coff/avr.h +--- include/coff/avr.h 1970-01-01 05:30:00.000000000 +0530 ++++ include/coff/avr.h 2010-03-11 12:13:23.381749600 +0530 +@@ -0,0 +1,110 @@ ++/* coff information for Atmel AVR. ++ ++ Copyright 2001 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++/* This file was hacked from i860.h */ ++ ++#define L_LNNO_SIZE 2 ++#include "coff/external.h" ++ ++/* Bits for f_flags: ++ F_RELFLG relocation info stripped from file ++ F_EXEC file is executable (no unresolved external references) ++ F_LNNO line numbers stripped from file ++ F_LSYMS local symbols stripped from file */ ++ ++#define F_RELFLG (0x0001) ++#define F_EXEC (0x0002) ++#define F_LNNO (0x0004) ++#define F_LSYMS (0x0008) ++/* Upper nibble of flags always needs to be set. This used to be ++ * undocumented, recent information from Atmel says that bit 7 used to ++ * differentiate between an old vendor-specific deviation of the ++ * format and the current format. */ ++#define F_JUNK (0x00f0) ++#define F_UNUSED (0xff00) ++ ++#define AVRMAGIC 0xa12 ++ ++#undef AOUTSZ ++#ifdef AVR_EXT_COFF ++ ++/* AVR "extended" COFF format. This uses the optional header ("a.out" ++ header) to inform the consumer about some additional features that ++ are supported. */ ++#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */ ++#define AOUTSZ 28 /* size of optional header in "extended" COFF */ ++ ++/* Flags in the optional header; they are stored in the vstamp field. */ ++#define F_FULLPATHS 0x0001 /* long filenames supported */ ++#define F_STRUCTINFO 0x0002 /* structure information contained */ ++#define F_PTRINFO 0x0004 /* inter-segment pointers supported */ ++ ++#else /* old AVR COFF */ ++ ++#define AOUTSZ 0 /* no a.out for AVR */ ++#endif ++ ++/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */ ++/* ++ * The following magic number causes AVR Studio 4.x to recognize ++ * avr-gcc/GNU binutils produced AVR extended COFF files. By now, ++ * the only special treatment for them is that the contents of .data ++ * will be appended after .text in the simulator flash. ++ * ++ * 0x9cc has been chosen since it resembles "gcc". ;-) ++ */ ++#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */ ++ ++/* By matching not only the magic number, but also the size of the ++ optional a.out header, we can differentiate between both ++ formats. */ ++#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ) ++ ++/* AVR COFF has several anomalities in the way the handle the derived ++ type information, and AUX entries, mainly because they apparently ++ didn't bother to learn how COFF is supposed to work before they ++ started. We fix many of them at the export/import boundary, so all ++ the internal generic COFF handling will work mostly as designed. */ ++ ++/* NB: these functions are only defined in bfd/coff-avr.c, but also ++ used in coff-ext-avr.c, so the latter can only be configured if the ++ former is also present. This is certainly always the case ++ anyway. */ ++extern void avr_coff_adjust_sym_in_post ++ PARAMS((bfd *, PTR, PTR)); ++ ++extern void avr_coff_adjust_sym_out_post ++ PARAMS((bfd *, PTR, PTR)); ++ ++#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \ ++ avr_coff_adjust_sym_in_post (ABFD, EXT, INT) ++ ++#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \ ++ avr_coff_adjust_sym_out_post (ABFD, INT, EXT) ++ ++/********************** RELOCATION DIRECTIVES **********************/ ++ ++struct external_reloc ++{ ++ char r_vaddr[4]; ++ char r_symndx[4]; ++ char r_type[2]; ++}; ++ ++#define RELOC struct external_reloc ++#define RELSZ 10 +diff -ruwN include/coff/internal.h include/coff/internal.h +--- include/coff/internal.h 2009-09-02 12:51:39.000000000 +0530 ++++ include/coff/internal.h 2010-03-11 12:13:23.381749600 +0530 +@@ -646,6 +646,8 @@ + + }; + ++#define NAUXENTS 10 /* number of pre-allocated aux entries */ ++ + /********************** RELOCATION DIRECTIVES **********************/ + + struct internal_reloc diff --git a/devel/avr-binutils/files/patch-302-binutils-2.20.1-new-sections b/devel/avr-binutils/files/patch-302-binutils-2.20.1-new-sections new file mode 100644 index 000000000000..c1dac97a4b70 --- /dev/null +++ b/devel/avr-binutils/files/patch-302-binutils-2.20.1-new-sections @@ -0,0 +1,38 @@ +diff -ruwN ld/scripttempl/avr.sc ld/scripttempl/avr.sc +--- ld/scripttempl/avr.sc 2009-10-09 18:42:35.000000000 +0530 ++++ ld/scripttempl/avr.sc 2010-03-11 12:26:00.563046000 +0530 +@@ -7,6 +7,9 @@ + text (rx) : ORIGIN = 0, LENGTH = $TEXT_LENGTH + data (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = $DATA_LENGTH + eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K ++ fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K ++ lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K ++ signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K + } + + SECTIONS +@@ -196,6 +199,24 @@ + ${RELOCATING+ __eeprom_end = . ; } + } ${RELOCATING+ > eeprom} + ++ .fuse ${RELOCATING-0}: ++ { ++ KEEP(*(.fuse)) ++ KEEP(*(.lfuse)) ++ KEEP(*(.hfuse)) ++ KEEP(*(.efuse)) ++ } ${RELOCATING+ > fuse} ++ ++ .lock ${RELOCATING-0}: ++ { ++ KEEP(*(.lock*)) ++ } ${RELOCATING+ > lock} ++ ++ .signature ${RELOCATING-0}: ++ { ++ KEEP(*(.signature*)) ++ } ${RELOCATING+ > signature} ++ + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } diff --git a/devel/avr-binutils/files/patch-303-binutils-2.20.1-as-dwarf b/devel/avr-binutils/files/patch-303-binutils-2.20.1-as-dwarf new file mode 100644 index 000000000000..6aade2d90bb2 --- /dev/null +++ b/devel/avr-binutils/files/patch-303-binutils-2.20.1-as-dwarf @@ -0,0 +1,29 @@ +diff -ruwN gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2010-03-11 14:56:16.484109300 +0530 ++++ gas/config/tc-avr.c 2010-03-11 14:58:59.248690500 +0530 +@@ -24,6 +24,7 @@ + #include "as.h" + #include "safe-ctype.h" + #include "subsegs.h" ++#include "dwarf2dbg.h" + + struct avr_opcodes_s + { +@@ -1368,6 +1369,7 @@ + + dwarf2_emit_insn (0); + ++ dwarf2_emit_insn (0); + /* We used to set input_line_pointer to the result of get_operands, + but that is wrong. Our caller assumes we don't change it. */ + { +diff -ruwN gas/config/tc-avr.h gas/config/tc-avr.h +--- gas/config/tc-avr.h 2010-03-11 14:56:16.484109300 +0530 ++++ gas/config/tc-avr.h 2010-03-11 14:58:59.264313900 +0530 +@@ -147,3 +147,6 @@ + + /* This target is buggy, and sets fix size too large. */ + #define TC_FX_SIZE_SLACK(FIX) 2 ++ ++/* keep DWARF2_ADDR_SIZE in consistency with C compiler produced information */ ++#define DWARF2_ADDR_SIZE(bfd) 4 diff --git a/devel/avr-binutils/files/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround b/devel/avr-binutils/files/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround new file mode 100644 index 000000000000..a75b26b27919 --- /dev/null +++ b/devel/avr-binutils/files/patch-304-binutils-2.20.1-dwarf2-AVRStudio-workaround @@ -0,0 +1,28 @@ +diff -ruwN gas/dwarf2dbg.c gas/dwarf2dbg.c +--- gas/dwarf2dbg.c 2010-03-11 15:06:25.773290700 +0530 ++++ gas/dwarf2dbg.c 2010-03-11 15:08:20.410311300 +0530 +@@ -112,8 +112,11 @@ + Note: If you want to change this, you'll have to update the + "standard_opcode_lengths" table that is emitted below in + out_debug_line(). */ ++#ifndef TC_AVR + #define DWARF2_LINE_OPCODE_BASE 13 +- ++#else ++#define DWARF2_LINE_OPCODE_BASE 10 ++#endif + #ifndef DWARF2_LINE_BASE + /* Minimum line offset in a special line info. opcode. This value + was chosen to give a reasonable range of values. */ +@@ -1439,9 +1442,11 @@ + out_byte (0); /* DW_LNS_set_basic_block */ + out_byte (0); /* DW_LNS_const_add_pc */ + out_byte (1); /* DW_LNS_fixed_advance_pc */ ++#ifndef TC_AVR + out_byte (0); /* DW_LNS_set_prologue_end */ + out_byte (0); /* DW_LNS_set_epilogue_begin */ + out_byte (1); /* DW_LNS_set_isa */ ++#endif + + out_file_list (); + diff --git a/devel/avr-binutils/files/patch-305-binutils-2.20.1-assembler-options b/devel/avr-binutils/files/patch-305-binutils-2.20.1-assembler-options new file mode 100644 index 000000000000..18ecaac49d2d --- /dev/null +++ b/devel/avr-binutils/files/patch-305-binutils-2.20.1-assembler-options @@ -0,0 +1,12 @@ +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-02-08 10:59:27.000000000 -0600 ++++ gas/config/tc-avr.c 2011-02-08 11:01:47.000000000 -0600 +@@ -378,7 +378,7 @@ void + md_show_usage (FILE *stream) + { + fprintf (stream, +- _("AVR options:\n" ++ _("AVR Assembler options:\n" + " -mmcu=[avr-name] select microcontroller variant\n" + " [avr-name] can be:\n" + " avr1 - classic AVR core without data RAM\n" diff --git a/devel/avr-binutils/files/patch-400-binutils-2.20.1-xmega b/devel/avr-binutils/files/patch-400-binutils-2.20.1-xmega new file mode 100644 index 000000000000..7f6e0840bcb8 --- /dev/null +++ b/devel/avr-binutils/files/patch-400-binutils-2.20.1-xmega @@ -0,0 +1,679 @@ +avrxmega1 +avrxmega2 +avrxmega3 +avrxmega4 +avrxmega5 +avrxmega6 +avrxmega7 +atxmega16a4 +atxmega16d4 +atxmega32d4 +atxmega32a4 +atxmega64a3 +atxmega64d3 +atxmega64a1 +atxmega128a3 +atxmega128d3 +atxmega192a3 +atxmega192d3 +atxmega256a3 +atxmega256a3b +atxmega256d3 +atxmega128a1 +======================================================= +diff -Naurp bfd/archures.c bfd/archures.c +--- bfd/archures.c 2009-09-10 06:47:11.000000000 -0500 ++++ bfd/archures.c 2011-06-07 11:44:52.000000000 -0500 +@@ -368,6 +368,13 @@ DESCRIPTION + .#define bfd_mach_avr5 5 + .#define bfd_mach_avr51 51 + .#define bfd_mach_avr6 6 ++.#define bfd_mach_avrxmega1 101 ++.#define bfd_mach_avrxmega2 102 ++.#define bfd_mach_avrxmega3 103 ++.#define bfd_mach_avrxmega4 104 ++.#define bfd_mach_avrxmega5 105 ++.#define bfd_mach_avrxmega6 106 ++.#define bfd_mach_avrxmega7 107 + . bfd_arch_bfin, {* ADI Blackfin *} + .#define bfd_mach_bfin 1 + . bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *} +diff -Naurp bfd/bfd-in2.h bfd/bfd-in2.h +--- bfd/bfd-in2.h 2010-02-03 07:28:24.000000000 -0600 ++++ bfd/bfd-in2.h 2011-06-07 11:44:52.000000000 -0500 +@@ -2042,6 +2042,13 @@ enum bfd_architecture + #define bfd_mach_avr5 5 + #define bfd_mach_avr51 51 + #define bfd_mach_avr6 6 ++#define bfd_mach_avrxmega1 101 ++#define bfd_mach_avrxmega2 102 ++#define bfd_mach_avrxmega3 103 ++#define bfd_mach_avrxmega4 104 ++#define bfd_mach_avrxmega5 105 ++#define bfd_mach_avrxmega6 106 ++#define bfd_mach_avrxmega7 107 + bfd_arch_bfin, /* ADI Blackfin */ + #define bfd_mach_bfin 1 + bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ +diff -Naurp bfd/cpu-avr.c bfd/cpu-avr.c +--- bfd/cpu-avr.c 2009-09-02 02:18:36.000000000 -0500 ++++ bfd/cpu-avr.c 2011-06-07 11:44:52.000000000 -0500 +@@ -133,7 +133,29 @@ static const bfd_arch_info_type arch_inf + N (22, bfd_mach_avr51, "avr:51", FALSE, & arch_info_struct[9]), + + /* 3-Byte PC. */ +- N (22, bfd_mach_avr6, "avr:6", FALSE, NULL) ++ N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]), ++ ++ /* Xmega 1 */ ++ N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[11]), ++ ++ /* Xmega 2 */ ++ N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[12]), ++ ++ /* Xmega 3 */ ++ N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[13]), ++ ++ /* Xmega 4 */ ++ N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[14]), ++ ++ /* Xmega 5 */ ++ N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[15]), ++ ++ /* Xmega 6 */ ++ N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]), ++ ++ /* Xmega 7 */ ++ N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL) ++ + }; + + const bfd_arch_info_type bfd_avr_arch = +diff -Naurp bfd/elf32-avr.c bfd/elf32-avr.c +--- bfd/elf32-avr.c 2009-09-02 02:18:36.000000000 -0500 ++++ bfd/elf32-avr.c 2011-06-07 11:44:52.000000000 -0500 +@@ -1328,6 +1328,34 @@ bfd_elf_avr_final_write_processing (bfd + case bfd_mach_avr6: + val = E_AVR_MACH_AVR6; + break; ++ ++ case bfd_mach_avrxmega1: ++ val = E_AVR_MACH_XMEGA1; ++ break; ++ ++ case bfd_mach_avrxmega2: ++ val = E_AVR_MACH_XMEGA2; ++ break; ++ ++ case bfd_mach_avrxmega3: ++ val = E_AVR_MACH_XMEGA3; ++ break; ++ ++ case bfd_mach_avrxmega4: ++ val = E_AVR_MACH_XMEGA4; ++ break; ++ ++ case bfd_mach_avrxmega5: ++ val = E_AVR_MACH_XMEGA5; ++ break; ++ ++ case bfd_mach_avrxmega6: ++ val = E_AVR_MACH_XMEGA6; ++ break; ++ ++ case bfd_mach_avrxmega7: ++ val = E_AVR_MACH_XMEGA7; ++ break; + } + + elf_elfheader (abfd)->e_machine = EM_AVR; +@@ -1390,6 +1418,34 @@ elf32_avr_object_p (bfd *abfd) + case E_AVR_MACH_AVR6: + e_set = bfd_mach_avr6; + break; ++ ++ case E_AVR_MACH_XMEGA1: ++ e_set = bfd_mach_avrxmega1; ++ break; ++ ++ case E_AVR_MACH_XMEGA2: ++ e_set = bfd_mach_avrxmega2; ++ break; ++ ++ case E_AVR_MACH_XMEGA3: ++ e_set = bfd_mach_avrxmega3; ++ break; ++ ++ case E_AVR_MACH_XMEGA4: ++ e_set = bfd_mach_avrxmega4; ++ break; ++ ++ case E_AVR_MACH_XMEGA5: ++ e_set = bfd_mach_avrxmega5; ++ break; ++ ++ case E_AVR_MACH_XMEGA6: ++ e_set = bfd_mach_avrxmega6; ++ break; ++ ++ case E_AVR_MACH_XMEGA7: ++ e_set = bfd_mach_avrxmega7; ++ break; + } + } + return bfd_default_set_arch_mach (abfd, bfd_arch_avr, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 11:47:11.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 11:44:52.000000000 -0500 +@@ -30,18 +30,19 @@ struct avr_opcodes_s + { + char * name; + char * constraints; ++ char *opcode; + int insn_size; /* In words. */ + int isa; + unsigned int bin_opcode; + }; + + #define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \ +-{#NAME, CONSTR, SIZE, ISA, BIN}, ++{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN}, + + struct avr_opcodes_s avr_opcodes[] = + { + #include "opcode/avr.h" +- {NULL, NULL, 0, 0, 0} ++ {NULL, NULL, NULL, 0, 0, 0} + }; + + const char comment_chars[] = ";"; +@@ -80,6 +81,13 @@ static struct mcu_type_s mcu_types[] = + {"avr5", AVR_ISA_AVR51, bfd_mach_avr5}, + {"avr51", AVR_ISA_AVR51, bfd_mach_avr51}, + {"avr6", AVR_ISA_AVR6, bfd_mach_avr6}, ++ {"avrxmega1", AVR_ISA_XMEGA, bfd_mach_avrxmega1}, ++ {"avrxmega2", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"avrxmega3", AVR_ISA_XMEGA, bfd_mach_avrxmega3}, ++ {"avrxmega4", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, ++ {"avrxmega5", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, ++ {"avrxmega6", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"avrxmega7", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, + {"at90s1200", AVR_ISA_1200, bfd_mach_avr1}, + {"attiny11", AVR_ISA_AVR1, bfd_mach_avr1}, + {"attiny12", AVR_ISA_AVR1, bfd_mach_avr1}, +@@ -216,6 +224,21 @@ static struct mcu_type_s mcu_types[] = + {"m3001b", AVR_ISA_AVR51, bfd_mach_avr51}, + {"atmega2560", AVR_ISA_AVR6, bfd_mach_avr6}, + {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6}, ++ {"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega16d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega32a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega32d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, ++ {"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, ++ {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, ++ {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, + {NULL, 0, 0} + }; + +@@ -393,6 +416,11 @@ md_show_usage (FILE *stream) + " avr5 - enhanced AVR core with up to 64K program memory\n" + " avr51 - enhanced AVR core with up to 128K program memory\n" + " avr6 - enhanced AVR core with up to 256K program memory\n" ++ " avrxmega3 - XMEGA, > 8K, <= 64K FLASH, > 64K RAM\n" ++ " avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM\n" ++ " avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n" ++ " avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n" ++ " avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n" + " or immediate microcontroller name.\n")); + fprintf (stream, + _(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n" +@@ -820,7 +848,12 @@ avr_operand (struct avr_opcodes_s *opcod + if (*str == '+') + { + ++str; +- op_mask |= 1; ++ char *s; ++ for (s = opcode->opcode; *s; ++s) ++ { ++ if (*s == '+') ++ op_mask |= (1 << (15 - (s - opcode->opcode))); ++ } + } + + /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+". */ +@@ -937,6 +970,16 @@ avr_operand (struct avr_opcodes_s *opcod + } + break; + ++ case 'E': ++ { ++ unsigned int x; ++ ++ x = avr_get_constant (str, 15); ++ str = input_line_pointer; ++ op_mask |= (x << 4); ++ } ++ break; ++ + case '?': + break; + +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2009-09-02 02:24:21.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 11:44:52.000000000 -0500 +@@ -80,6 +80,27 @@ atmega128rfa1, at90can128, at90usb1286, + Instruction set avr6 is for the enhanced AVR core with a 3-byte PC (MCU types: + atmega2560, atmega2561). + ++Instruction set avrxmega2 is for the XMEGA AVR core with 8K to 64K program ++memory space and less than 64K data space (MCU types: atxmega16a4, atxmega16d4, ++atxmega32d4). ++ ++Instruction set avrxmega3 is for the XMEGA AVR core with 8K to 64K program ++memory space and greater than 64K data space (MCU types: atxmega32a4). ++ ++Instruction set avrxmega4 is for the XMEGA AVR core with up to 64K program ++memory space and less than 64K data space (MCU types: atxmega64a3, atxmega64d3). ++ ++Instruction set avrxmega5 is for the XMEGA AVR core with up to 64K program ++memory space and greater than 64K data space (MCU types: atxmega64a1). ++ ++Instruction set avrxmega6 is for the XMEGA AVR core with up to 256K program ++memory space and less than 64K data space (MCU types: atxmega128a3, ++atxmega128d3, atxmega192a3, atxmega192d3, atxmega256a3, atxmega256a3b, ++atxmega192d3). ++ ++Instruction set avrxmega7 is for the XMEGA AVR core with up to 256K program ++memory space and greater than 64K data space (MCU types: atxmega128a1). ++ + @cindex @code{-mall-opcodes} command line option, AVR + @item -mall-opcodes + Accept all AVR opcodes, even if not supported by @code{-mmcu}. +diff -Naurp include/elf/avr.h include/elf/avr.h +--- include/elf/avr.h 2008-08-09 00:35:13.000000000 -0500 ++++ include/elf/avr.h 2011-06-07 11:44:52.000000000 -0500 +@@ -40,6 +40,13 @@ + #define E_AVR_MACH_AVR5 5 + #define E_AVR_MACH_AVR51 51 + #define E_AVR_MACH_AVR6 6 ++#define E_AVR_MACH_XMEGA1 101 ++#define E_AVR_MACH_XMEGA2 102 ++#define E_AVR_MACH_XMEGA3 103 ++#define E_AVR_MACH_XMEGA4 104 ++#define E_AVR_MACH_XMEGA5 105 ++#define E_AVR_MACH_XMEGA6 106 ++#define E_AVR_MACH_XMEGA7 107 + + /* Relocations. */ + START_RELOC_NUMBERS (elf_avr_reloc_type) +diff -Naurp include/opcode/avr.h include/opcode/avr.h +--- include/opcode/avr.h 2008-08-09 00:35:13.000000000 -0500 ++++ include/opcode/avr.h 2011-06-07 11:44:52.000000000 -0500 +@@ -30,6 +30,8 @@ + #define AVR_ISA_BRK 0x0400 /* device has BREAK (on-chip debug) */ + #define AVR_ISA_EIND 0x0800 /* device has >128K program memory (none yet) */ + #define AVR_ISA_MOVW 0x1000 /* device has MOVW */ ++#define AVR_ISA_SPMX 0x2000 /* device has SPM Z[+] */ ++#define AVR_ISA_DES 0x4000 /* device has DES */ + + #define AVR_ISA_TINY1 (AVR_ISA_1200 | AVR_ISA_LPM) + #define AVR_ISA_2xxx (AVR_ISA_TINY1 | AVR_ISA_SRAM) +@@ -48,6 +50,8 @@ + #define AVR_ISA_94K (AVR_ISA_M603 | AVR_ISA_MUL | AVR_ISA_MOVW | AVR_ISA_LPMX) + #define AVR_ISA_M323 (AVR_ISA_M161 | AVR_ISA_BRK) + #define AVR_ISA_M128 (AVR_ISA_M323 | AVR_ISA_ELPM | AVR_ISA_ELPMX) ++#define AVR_ISA_M256 (AVR_ISA_M128 | AVR_ISA_EIND) ++#define AVR_ISA_XMEGA (AVR_ISA_M256 | AVR_ISA_SPMX | AVR_ISA_DES) + + #define AVR_ISA_AVR1 AVR_ISA_TINY1 + #define AVR_ISA_AVR2 AVR_ISA_2xxx +@@ -108,6 +112,7 @@ + L - signed pc relative offset from -2048 to 2047 + h - absolute code address (call, jmp) + S - immediate value from 0 to 7 (S = s << 4) ++ E - immediate value from 0 to 15, shifted left by 4 (des) + ? - use this opcode entry if no parameters, else use next opcode entry + + Order is important - some binary opcodes have more than one name, +@@ -168,7 +173,8 @@ AVR_INSN (reti, "", "1001010100011000 + AVR_INSN (sleep,"", "1001010110001000", 1, AVR_ISA_1200, 0x9588) + AVR_INSN (break,"", "1001010110011000", 1, AVR_ISA_BRK, 0x9598) + AVR_INSN (wdr, "", "1001010110101000", 1, AVR_ISA_1200, 0x95a8) +-AVR_INSN (spm, "", "1001010111101000", 1, AVR_ISA_SPM, 0x95e8) ++AVR_INSN (spm, "?", "1001010111101000", 1, AVR_ISA_SPM, 0x95e8) ++AVR_INSN (spm, "z", "10010101111+1000", 1, AVR_ISA_SPMX, 0x95e8) + + AVR_INSN (adc, "r,r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00) + AVR_INSN (add, "r,r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00) +@@ -282,3 +288,6 @@ AVR_INSN (st, "e,r", "100!001rrrrree-+ + AVR_INSN (eicall, "", "1001010100011001", 1, AVR_ISA_EIND, 0x9519) + AVR_INSN (eijmp, "", "1001010000011001", 1, AVR_ISA_EIND, 0x9419) + ++/* DES instruction for encryption and decryption */ ++AVR_INSN (des, "E", "10010100EEEE1011", 1, AVR_ISA_DES, 0x940B) ++ +diff -Naurp ld/configure.tgt ld/configure.tgt +--- ld/configure.tgt 2009-08-06 12:38:03.000000000 -0500 ++++ ld/configure.tgt 2011-06-07 11:44:52.000000000 -0500 +@@ -110,7 +110,7 @@ xscale-*-coff) targ_emul=armcoff ;; + xscale-*-elf) targ_emul=armelf + ;; + avr-*-*) targ_emul=avr2 +- targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6" ++ targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7" + ;; + bfin-*-elf) targ_emul=elf32bfin; + targ_extra_emuls="elf32bfinfd" +diff -Naurp ld/emulparams/avrxmega1.sh ld/emulparams/avrxmega1.sh +--- ld/emulparams/avrxmega1.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega1.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:101 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega2.sh ld/emulparams/avrxmega2.sh +--- ld/emulparams/avrxmega2.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega2.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:102 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega3.sh ld/emulparams/avrxmega3.sh +--- ld/emulparams/avrxmega3.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega3.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:103 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega4.sh ld/emulparams/avrxmega4.sh +--- ld/emulparams/avrxmega4.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega4.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:104 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega5.sh ld/emulparams/avrxmega5.sh +--- ld/emulparams/avrxmega5.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega5.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:105 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega6.sh ld/emulparams/avrxmega6.sh +--- ld/emulparams/avrxmega6.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega6.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:106 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emulparams/avrxmega7.sh ld/emulparams/avrxmega7.sh +--- ld/emulparams/avrxmega7.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrxmega7.sh 2011-06-07 11:44:52.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:107 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=1024K ++DATA_ORIGIN=0x802000 ++DATA_LENGTH=0xffa0 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/emultempl/avrelf.em ld/emultempl/avrelf.em +--- ld/emultempl/avrelf.em 2009-09-02 02:25:35.000000000 -0500 ++++ ld/emultempl/avrelf.em 2011-06-07 11:44:52.000000000 -0500 +@@ -71,8 +71,10 @@ avr_elf_${EMULATION_NAME}_before_allocat + + gld${EMULATION_NAME}_before_allocation (); + +- /* We only need stubs for the avr6 family. */ +- if (strcmp ("${EMULATION_NAME}","avr6")) ++ /* We only need stubs for avr6, avrxmega6, and avrxmega7. */ ++ if (strcmp ("${EMULATION_NAME}","avr6") ++ && strcmp ("${EMULATION_NAME}","avrxmega6") ++ && strcmp ("${EMULATION_NAME}","avrxmega7") ) + avr_no_stubs = TRUE; + + avr_elf_set_global_bfd_parameters (); +diff -Naurp ld/Makefile.am ld/Makefile.am +--- ld/Makefile.am 2010-02-22 02:07:01.000000000 -0600 ++++ ld/Makefile.am 2011-06-07 11:44:52.000000000 -0500 +@@ -148,6 +148,13 @@ ALL_EMULATIONS = \ + eavr5.o \ + eavr51.o \ + eavr6.o \ ++ eavrxmega1.o \ ++ eavrxmega2.o \ ++ eavrxmega3.o \ ++ eavrxmega4.o \ ++ eavrxmega5.o \ ++ eavrxmega6.o \ ++ eavrxmega7.o \ + ecoff_i860.o \ + ecoff_sparc.o \ + eelf32_spu.o \ +@@ -727,6 +734,34 @@ eavr6.c: $(srcdir)/emulparams/avr6.sh $( + $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ + ${GEN_DEPENDS} + ${GENSCRIPTS} avr6 "$(tdir_avr2)" ++eavrxmega1.c: $(srcdir)/emulparams/avrxmega1.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega1 "$(tdir_avr2)" ++eavrxmega2.c: $(srcdir)/emulparams/avrxmega2.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega2 "$(tdir_avr2)" ++eavrxmega3.c: $(srcdir)/emulparams/avrxmega3.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega3 "$(tdir_avr2)" ++eavrxmega4.c: $(srcdir)/emulparams/avrxmega4.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega4 "$(tdir_avr2)" ++eavrxmega5.c: $(srcdir)/emulparams/avrxmega5.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega5 "$(tdir_avr2)" ++eavrxmega6.c: $(srcdir)/emulparams/avrxmega6.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega6 "$(tdir_avr2)" ++eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" + ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" +diff -Naurp ld/Makefile.in ld/Makefile.in +--- ld/Makefile.in 2010-03-03 08:06:21.000000000 -0600 ++++ ld/Makefile.in 2011-06-07 11:44:52.000000000 -0500 +@@ -434,6 +434,13 @@ ALL_EMULATIONS = \ + eavr5.o \ + eavr51.o \ + eavr6.o \ ++ eavrxmega1.o \ ++ eavrxmega2.o \ ++ eavrxmega3.o \ ++ eavrxmega4.o \ ++ eavrxmega5.o \ ++ eavrxmega6.o \ ++ eavrxmega7.o \ + ecoff_i860.o \ + ecoff_sparc.o \ + eelf32_spu.o \ +@@ -2069,6 +2076,34 @@ eavr6.c: $(srcdir)/emulparams/avr6.sh $( + $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ + ${GEN_DEPENDS} + ${GENSCRIPTS} avr6 "$(tdir_avr2)" ++eavrxmega1.c: $(srcdir)/emulparams/avrxmega1.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega1 "$(tdir_avr2)" ++eavrxmega2.c: $(srcdir)/emulparams/avrxmega2.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega2 "$(tdir_avr2)" ++eavrxmega3.c: $(srcdir)/emulparams/avrxmega3.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega3 "$(tdir_avr2)" ++eavrxmega4.c: $(srcdir)/emulparams/avrxmega4.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega4 "$(tdir_avr2)" ++eavrxmega5.c: $(srcdir)/emulparams/avrxmega5.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega5 "$(tdir_avr2)" ++eavrxmega6.c: $(srcdir)/emulparams/avrxmega6.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega6 "$(tdir_avr2)" ++eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" + ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" +diff -Naurp opcodes/avr-dis.c opcodes/avr-dis.c +--- opcodes/avr-dis.c 2008-11-06 06:03:24.000000000 -0600 ++++ opcodes/avr-dis.c 2011-06-07 11:44:52.000000000 -0500 +@@ -50,7 +50,7 @@ static const char * comment_start = "0x" + + static int + avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constraint, +- char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr) ++ char *opcode_str, char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr) + { + int ok = 1; + *sym = 0; +@@ -118,8 +118,18 @@ avr_operand (unsigned int insn, unsigned + + case 'z': + *buf++ = 'Z'; +- if (insn & 0x1) ++ ++ /* Check for post-increment. */ ++ char *s; ++ for (s = opcode_str; *s; ++s) ++ { ++ if (*s == '+') ++ { + *buf++ = '+'; ++ break; ++ } ++ } ++ + *buf = '\0'; + if (AVR_UNDEF_P (insn)) + sprintf (comment, _("undefined")); +@@ -227,6 +237,10 @@ avr_operand (unsigned int insn, unsigned + } + break; + ++ case 'E': ++ sprintf (buf, "%d", (insn >> 4) & 15); ++ break; ++ + case '?': + *buf = '\0'; + break; +@@ -331,7 +345,8 @@ print_insn_avr (bfd_vma addr, disassembl + + if (opcode->name) + { +- char *op = opcode->constraints; ++ char *constraints = opcode->constraints; ++ char *opcode_str = opcode->opcode; + + insn2 = 0; + ok = 1; +@@ -342,14 +357,14 @@ print_insn_avr (bfd_vma addr, disassembl + cmd_len = 4; + } + +- if (*op && *op != '?') ++ if (*constraints && *constraints != '?') + { +- int regs = REGISTER_P (*op); ++ int regs = REGISTER_P (*constraints); + +- ok = avr_operand (insn, insn2, addr, *op, op1, comment1, 0, &sym_op1, &sym_addr1); ++ ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1, comment1, 0, &sym_op1, &sym_addr1); + +- if (ok && *(++op) == ',') +- ok = avr_operand (insn, insn2, addr, *(++op), op2, ++ if (ok && *(++constraints) == ',') ++ ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str, op2, + *comment1 ? comment2 : comment1, regs, &sym_op2, &sym_addr2); + } + } diff --git a/devel/avr-binutils/files/patch-401-binutils-2.20.1-new-devices b/devel/avr-binutils/files/patch-401-binutils-2.20.1-new-devices new file mode 100644 index 000000000000..34f3a7bfb86d --- /dev/null +++ b/devel/avr-binutils/files/patch-401-binutils-2.20.1-new-devices @@ -0,0 +1,229 @@ +attiny461a +atmega48a +atmega88a +atmega88pa +atmega16a +atmega164a +atmega165a +atmega168a +atmega169a +atmega169pa +atmega324a +atmega324pa +atmega328 +atmega329pa +atmega644a +atmega645a +atmega645p +atmega649p +atmega649a +atmega6450a +atmega6450p +atmega6490a +atmega6490p +atmega64hve +atmega16hva2 +attiny84a +atmega325a +atmega3250a +atmega329a +atmega3290a +m3000 +Remove: m3000f, m3000s, m3001b, atmega16c1, atmega4hvd, atmega8hvd, atmega8m1, +atmega8c1, attiny327 +=========================================================== +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-01-12 14:20:58.000000000 -0600 ++++ gas/config/tc-avr.c 2011-01-12 14:24:17.000000000 -0600 +@@ -115,12 +115,14 @@ static struct mcu_type_s mcu_types[] = + {"attiny44", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny44a", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny84", AVR_ISA_AVR25, bfd_mach_avr25}, ++ {"attiny84a", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny25", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny45", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny85", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny261", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny261a", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny461", AVR_ISA_AVR25, bfd_mach_avr25}, ++ {"attiny461a", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny861", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny861a", AVR_ISA_AVR25, bfd_mach_avr25}, + {"attiny87", AVR_ISA_AVR25, bfd_mach_avr25}, +@@ -134,7 +136,6 @@ static struct mcu_type_s mcu_types[] = + {"atmega103", AVR_ISA_AVR31, bfd_mach_avr31}, + {"at43usb320", AVR_ISA_AVR31, bfd_mach_avr31}, + {"attiny167", AVR_ISA_AVR35, bfd_mach_avr35}, +- {"attiny327", AVR_ISA_AVR35, bfd_mach_avr35}, + {"at90usb82", AVR_ISA_AVR35, bfd_mach_avr35}, + {"at90usb162", AVR_ISA_AVR35, bfd_mach_avr35}, + {"atmega8u2", AVR_ISA_AVR35, bfd_mach_avr35}, +@@ -142,16 +143,15 @@ static struct mcu_type_s mcu_types[] = + {"atmega32u2", AVR_ISA_AVR35, bfd_mach_avr35}, + {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, + {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4}, ++ {"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega88", AVR_ISA_AVR4, bfd_mach_avr4}, ++ {"atmega88a", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega88p", AVR_ISA_AVR4, bfd_mach_avr4}, ++ {"atmega88pa", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega8515", AVR_ISA_M8, bfd_mach_avr4}, + {"atmega8535", AVR_ISA_M8, bfd_mach_avr4}, + {"atmega8hva", AVR_ISA_AVR4, bfd_mach_avr4}, +- {"atmega4hvd", AVR_ISA_AVR4, bfd_mach_avr4}, +- {"atmega8hvd", AVR_ISA_AVR4, bfd_mach_avr4}, +- {"atmega8c1", AVR_ISA_AVR4, bfd_mach_avr4}, +- {"atmega8m1", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm1", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm2", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm2b", AVR_ISA_AVR4, bfd_mach_avr4}, +@@ -159,40 +159,64 @@ static struct mcu_type_s mcu_types[] = + {"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega16", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega16a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega161", AVR_ISA_M161, bfd_mach_avr5}, + {"atmega162", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega163", AVR_ISA_M161, bfd_mach_avr5}, ++ {"atmega164a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega164p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega165", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega165a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega165p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega168", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega168a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega168p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega169", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega169a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega169p", AVR_ISA_AVR5, bfd_mach_avr5}, +- {"atmega16c1", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega169pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega32", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega323", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega324a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega324p", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega324pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega325", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega325a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega325p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3250", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega3250a",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3250p",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega328", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega328p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega329", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega329a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega329p", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega329pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3290", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega3290a",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega406", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega64", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega640", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega644", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega644a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega644p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega644pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega645", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega645a", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega645p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega649", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega649p", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega649a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega6450", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega6450a",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega6450p",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega6490", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega6490a",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega6490p",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega64hve",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5}, + {"at90can32" , AVR_ISA_AVR5, bfd_mach_avr5}, +@@ -211,6 +235,7 @@ static struct mcu_type_s mcu_types[] = + {"at90usb647", AVR_ISA_AVR5, bfd_mach_avr5}, + {"at90scr100", AVR_ISA_AVR5, bfd_mach_avr5}, + {"at94k", AVR_ISA_94K, bfd_mach_avr5}, ++ {"m3000", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega128", AVR_ISA_AVR51, bfd_mach_avr51}, + {"atmega1280", AVR_ISA_AVR51, bfd_mach_avr51}, + {"atmega1281", AVR_ISA_AVR51, bfd_mach_avr51}, +@@ -219,9 +244,6 @@ static struct mcu_type_s mcu_types[] = + {"at90can128", AVR_ISA_AVR51, bfd_mach_avr51}, + {"at90usb1286",AVR_ISA_AVR51, bfd_mach_avr51}, + {"at90usb1287",AVR_ISA_AVR51, bfd_mach_avr51}, +- {"m3000f", AVR_ISA_AVR51, bfd_mach_avr51}, +- {"m3000s", AVR_ISA_AVR51, bfd_mach_avr51}, +- {"m3001b", AVR_ISA_AVR51, bfd_mach_avr51}, + {"atmega2560", AVR_ISA_AVR6, bfd_mach_avr6}, + {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6}, + {"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-01-12 14:20:58.000000000 -0600 ++++ gas/doc/c-avr.texi 2011-01-12 14:22:42.000000000 -0600 +@@ -43,9 +43,10 @@ at90s8535). + + Instruction set avr25 is for the classic AVR core with up to 8K program memory + space plus the MOVW instruction (MCU types: attiny13, attiny13a, attiny2313, +-attiny2313a, attiny24, attiny24a, attiny4313, attiny44, attiny44a, attiny84, +-attiny25, attiny45, attiny85, attiny261, attiny261a, attiny461, attiny861, +-attiny861a, attiny87, attiny43u, attiny48, attiny88, at86rf401, ata6289). ++attiny2313a, attiny24, attiny24a, attiny4313, attiny43u, attiny44, attiny44a, ++attiny84, attiny84a, attiny25, attiny45, attiny85, attiny261, attiny261a, ++attiny461, attiny461a, attiny861, attiny861a, attiny87, attiny43u, attiny48, ++attiny88, at86rf401, ata6289). + + Instruction set avr3 is for the classic AVR core with up to 128K program + memory space (MCU types: at43usb355, at76c711). +@@ -54,28 +55,33 @@ Instruction set avr31 is for the classic + memory space (MCU types: atmega103, at43usb320). + + Instruction set avr35 is for classic AVR core plus MOVW, CALL, and JMP +-instructions (MCU types: attiny167, attiny327, at90usb82, at90usb162, atmega8u2, ++instructions (MCU types: attiny167, at90usb82, at90usb162, atmega8u2, + atmega16u2, atmega32u2). + + Instruction set avr4 is for the enhanced AVR core with up to 8K program +-memory space (MCU types: atmega48, atmega48p,atmega8, atmega88, atmega88p, +-atmega8515, atmega8535, atmega8hva, atmega4hvd, atmega8hvd, at90pwm1, +-at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, at90pwm81, atmega8m1, atmega8c1). ++memory space (MCU types: atmega48, atmega48a, atmega48p,atmega8, atmega88, ++atmega88a, atmega88p, atmega88pa, atmega8515, atmega8535, atmega8hva, ++at90pwm1,at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, ++at90pwm81). + + Instruction set avr5 is for the enhanced AVR core with up to 128K program +-memory space (MCU types: atmega16, atmega161, atmega162, atmega163, atmega164p, +-atmega165, atmega165p, atmega168, atmega168p, atmega169, atmega169p, atmega16c1, +-atmega32, atmega323, atmega324p, atmega325, atmega325p, atmega3250, atmega3250p, +-atmega328p, atmega329, atmega329p, atmega3290, atmega3290p, atmega406, atmega64, +-atmega640, atmega644, atmega644p, atmega644pa, atmega645, atmega6450, atmega649, +-atmega6490, atmega16hva, atmega16hvb, atmega32hvb, at90can32, at90can64, +-at90pwm216, at90pwm316, atmega32c1, atmega64c1, atmega16m1, atmega32m1, +-atmega64m1, atmega16u4, atmega32u4, atmega32u6, at90usb646, at90usb647, at94k, +-at90scr100). ++memory space (MCU types: atmega16, atmega16a, atmega161, atmega162, atmega163, ++atmega164a, atmega164p, atmega165, atmega165a, atmega165p, atmega168, ++atmega168a, atmega168p, atmega169, atmega169p, atmega169pa, ++atmega32, atmega323, atmega324a, atmega324p, atmega324pa, atmega325, atmega325a, ++atmega325p, atmega3250, atmega3250a, atmega3250p, atmega328, atmega328p, ++atmega329, atmega329a, atmega329p, atmega329pa, atmega3290, atmega3290a, ++atmega3290p, atmega406, atmega64, atmega640, atmega644, atmega644a, atmega644p, ++atmega644pa, atmega645, atmega645a, atmega645p, atmega6450, atmega6450a, ++atmega6450p, atmega649, atmega649a, atmega649p, atmega6490, atmega6490a, ++atmega6490p, atmega64hve, atmega16hva, atmega16hva2, atmega16hvb, atmega32hvb, ++at90can32, at90can64, at90pwm216, at90pwm316, atmega16u4, atmega32c1, ++atmega64c1, atmega64m1, atmega16m1, atmega32m1, atmega64m1, atmega16u4, ++atmega32u4, atmega32u6, at90usb646, at90usb647, at94k, at90scr100). + + Instruction set avr51 is for the enhanced AVR core with exactly 128K program + memory space (MCU types: atmega128, atmega1280, atmega1281, atmega1284p, +-atmega128rfa1, at90can128, at90usb1286, at90usb1287, m3000f, m3000s, m3001b). ++atmega128rfa1, at90can128, at90usb1286, at90usb1287, m3000). + + Instruction set avr6 is for the enhanced AVR core with a 3-byte PC (MCU types: + atmega2560, atmega2561). diff --git a/devel/avr-binutils/files/patch-402-binutils-2.20.1-avrtiny10 b/devel/avr-binutils/files/patch-402-binutils-2.20.1-avrtiny10 new file mode 100644 index 000000000000..d51aeb5c0131 --- /dev/null +++ b/devel/avr-binutils/files/patch-402-binutils-2.20.1-avrtiny10 @@ -0,0 +1,218 @@ +diff -Naurp bfd/archures.c bfd/archures.c +--- bfd/archures.c 2011-06-07 11:55:03.000000000 -0500 ++++ bfd/archures.c 2011-06-07 11:56:48.000000000 -0500 +@@ -375,6 +375,7 @@ DESCRIPTION + .#define bfd_mach_avrxmega5 105 + .#define bfd_mach_avrxmega6 106 + .#define bfd_mach_avrxmega7 107 ++.#define bfd_mach_avrtiny10 201 + . bfd_arch_bfin, {* ADI Blackfin *} + .#define bfd_mach_bfin 1 + . bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *} +diff -Naurp bfd/bfd-in2.h bfd/bfd-in2.h +--- bfd/bfd-in2.h 2011-06-07 11:55:03.000000000 -0500 ++++ bfd/bfd-in2.h 2011-06-07 11:56:48.000000000 -0500 +@@ -2049,6 +2049,7 @@ enum bfd_architecture + #define bfd_mach_avrxmega5 105 + #define bfd_mach_avrxmega6 106 + #define bfd_mach_avrxmega7 107 ++#define bfd_mach_avrtiny10 201 + bfd_arch_bfin, /* ADI Blackfin */ + #define bfd_mach_bfin 1 + bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ +diff -Naurp bfd/cpu-avr.c bfd/cpu-avr.c +--- bfd/cpu-avr.c 2011-06-07 11:55:03.000000000 -0500 ++++ bfd/cpu-avr.c 2011-06-07 11:56:48.000000000 -0500 +@@ -154,7 +154,10 @@ static const bfd_arch_info_type arch_inf + N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]), + + /* Xmega 7 */ +- N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL) ++ N (24, bfd_mach_avrxmega7, "avr:107", FALSE, & arch_info_struct[17]), ++ ++ /* attiny 10 */ ++ N (16, bfd_mach_avrtiny10, "avr:201", FALSE, NULL) + + }; + +diff -Naurp bfd/elf32-avr.c bfd/elf32-avr.c +--- bfd/elf32-avr.c 2011-06-07 11:55:03.000000000 -0500 ++++ bfd/elf32-avr.c 2011-06-07 11:56:48.000000000 -0500 +@@ -1356,6 +1356,10 @@ bfd_elf_avr_final_write_processing (bfd + case bfd_mach_avrxmega7: + val = E_AVR_MACH_XMEGA7; + break; ++ ++ case bfd_mach_avrtiny10: ++ val = E_AVR_MACH_AVRTINY10; ++ break; + } + + elf_elfheader (abfd)->e_machine = EM_AVR; +@@ -1446,6 +1450,10 @@ elf32_avr_object_p (bfd *abfd) + case E_AVR_MACH_XMEGA7: + e_set = bfd_mach_avrxmega7; + break; ++ ++ case E_AVR_MACH_AVRTINY10: ++ e_set = bfd_mach_avrtiny10; ++ break; + } + } + return bfd_default_set_arch_mach (abfd, bfd_arch_avr, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 11:56:25.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 11:56:48.000000000 -0500 +@@ -88,6 +88,7 @@ static struct mcu_type_s mcu_types[] = + {"avrxmega5", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, + {"avrxmega6", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"avrxmega7", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, ++ {"avrtiny10", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, + {"at90s1200", AVR_ISA_1200, bfd_mach_avr1}, + {"attiny11", AVR_ISA_AVR1, bfd_mach_avr1}, + {"attiny12", AVR_ISA_AVR1, bfd_mach_avr1}, +@@ -261,6 +262,12 @@ static struct mcu_type_s mcu_types[] = + {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, ++ {"attiny4", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, ++ {"attiny5", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, ++ {"attiny9", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, ++ {"attiny10", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, ++ {"attiny20", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, ++ {"attiny40", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, + {NULL, 0, 0} + }; + +@@ -443,6 +450,7 @@ md_show_usage (FILE *stream) + " avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n" + " avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n" + " avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n" ++ " avrtiny10 - tiny devices with 16 gp registers\n" + " or immediate microcontroller name.\n")); + fprintf (stream, + _(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n" +@@ -790,6 +798,17 @@ avr_operand (struct avr_opcodes_s *opcod + op_mask = avr_get_constant (str, 31); + str = input_line_pointer; + } ++ if (strcmp(avr_mcu->name, "avrtiny10") == 0 ++ || strcmp(avr_mcu->name, "attiny10") == 0 ++ || strcmp(avr_mcu->name, "attiny4") == 0 ++ || strcmp(avr_mcu->name, "attiny5") == 0 ++ || strcmp(avr_mcu->name, "attiny9") == 0 ++ || strcmp(avr_mcu->name, "attiny20") == 0 ++ || strcmp(avr_mcu->name, "attiny40") == 0) ++ { ++ if(op_mask < 16) ++ as_bad (_("register number above 15 required")); ++ } + + if (op_mask <= 31) + { +diff -Naurp include/elf/avr.h include/elf/avr.h +--- include/elf/avr.h 2011-06-07 11:55:03.000000000 -0500 ++++ include/elf/avr.h 2011-06-07 11:56:48.000000000 -0500 +@@ -47,6 +47,7 @@ + #define E_AVR_MACH_XMEGA5 105 + #define E_AVR_MACH_XMEGA6 106 + #define E_AVR_MACH_XMEGA7 107 ++#define E_AVR_MACH_AVRTINY10 201 + + /* Relocations. */ + START_RELOC_NUMBERS (elf_avr_reloc_type) +diff -Naurp include/opcode/avr.h include/opcode/avr.h +--- include/opcode/avr.h 2011-06-07 11:55:03.000000000 -0500 ++++ include/opcode/avr.h 2011-06-07 11:56:48.000000000 -0500 +@@ -69,7 +69,7 @@ + AVR_ISA_ELPM | AVR_ISA_ELPMX | AVR_ISA_SPM | \ + AVR_ISA_SPM | AVR_ISA_BRK | AVR_ISA_EIND | \ + AVR_ISA_MOVW) +- ++#define AVR_ISA_AVRTINY10 (AVR_ISA_1200 | AVR_ISA_BRK | AVR_ISA_SRAM) + #define REGISTER_P(x) ((x) == 'r' \ + || (x) == 'd' \ + || (x) == 'w' \ +@@ -159,8 +159,8 @@ AVR_INSN (sez, "", "1001010000011000 + AVR_INSN (bclr, "S", "100101001SSS1000", 1, AVR_ISA_1200, 0x9488) + AVR_INSN (bset, "S", "100101000SSS1000", 1, AVR_ISA_1200, 0x9408) + +-AVR_INSN (icall,"", "1001010100001001", 1, AVR_ISA_2xxx, 0x9509) +-AVR_INSN (ijmp, "", "1001010000001001", 1, AVR_ISA_2xxx, 0x9409) ++AVR_INSN (icall,"", "1001010100001001", 1, AVR_ISA_SRAM, 0x9509) ++AVR_INSN (ijmp, "", "1001010000001001", 1, AVR_ISA_SRAM, 0x9409) + + AVR_INSN (lpm, "?", "1001010111001000", 1, AVR_ISA_TINY1,0x95c8) + AVR_INSN (lpm, "r,z", "1001000ddddd010+", 1, AVR_ISA_LPMX, 0x9004) +@@ -260,8 +260,8 @@ AVR_INSN (dec, "r", "1001010rrrrr1010 + AVR_INSN (inc, "r", "1001010rrrrr0011", 1, AVR_ISA_1200, 0x9403) + AVR_INSN (lsr, "r", "1001010rrrrr0110", 1, AVR_ISA_1200, 0x9406) + AVR_INSN (neg, "r", "1001010rrrrr0001", 1, AVR_ISA_1200, 0x9401) +-AVR_INSN (pop, "r", "1001000rrrrr1111", 1, AVR_ISA_2xxx, 0x900f) +-AVR_INSN (push, "r", "1001001rrrrr1111", 1, AVR_ISA_2xxx, 0x920f) ++AVR_INSN (pop, "r", "1001000rrrrr1111", 1, AVR_ISA_SRAM, 0x900f) ++AVR_INSN (push, "r", "1001001rrrrr1111", 1, AVR_ISA_SRAM, 0x920f) + AVR_INSN (ror, "r", "1001010rrrrr0111", 1, AVR_ISA_1200, 0x9407) + AVR_INSN (swap, "r", "1001010rrrrr0010", 1, AVR_ISA_1200, 0x9402) + +@@ -273,8 +273,8 @@ AVR_INSN (fmul, "a,a", "000000110ddd1rrr + AVR_INSN (fmuls,"a,a", "000000111ddd0rrr", 1, AVR_ISA_MUL, 0x0380) + AVR_INSN (fmulsu,"a,a","000000111ddd1rrr", 1, AVR_ISA_MUL, 0x0388) + +-AVR_INSN (sts, "i,r", "1001001ddddd0000", 2, AVR_ISA_2xxx, 0x9200) +-AVR_INSN (lds, "r,i", "1001000ddddd0000", 2, AVR_ISA_2xxx, 0x9000) ++AVR_INSN (sts, "i,r", "1001001ddddd0000", 2, AVR_ISA_SRAM, 0x9200) ++AVR_INSN (lds, "r,i", "1001000ddddd0000", 2, AVR_ISA_SRAM, 0x9000) + + /* Special case for b+0, `e' must be next entry after `b', + b={Y=1,Z=0}, ee={X=11,Y=10,Z=00}, !=1 if -e or e+ or X. */ +diff -Naurp ld/configure.tgt ld/configure.tgt +--- ld/configure.tgt 2011-06-07 11:55:03.000000000 -0500 ++++ ld/configure.tgt 2011-06-07 11:56:48.000000000 -0500 +@@ -110,7 +110,7 @@ xscale-*-coff) targ_emul=armcoff ;; + xscale-*-elf) targ_emul=armelf + ;; + avr-*-*) targ_emul=avr2 +- targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7" ++ targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny10" + ;; + bfin-*-elf) targ_emul=elf32bfin; + targ_extra_emuls="elf32bfinfd" +diff -Naurp ld/emulparams/avrtiny10.sh ld/emulparams/avrtiny10.sh +--- ld/emulparams/avrtiny10.sh 1969-12-31 18:00:00.000000000 -0600 ++++ ld/emulparams/avrtiny10.sh 2011-06-07 11:56:48.000000000 -0500 +@@ -0,0 +1,12 @@ ++ARCH=avr:201 ++MACHINE= ++SCRIPT_NAME=avr ++OUTPUT_FORMAT="elf32-avr" ++MAXPAGESIZE=1 ++EMBEDDED=yes ++TEMPLATE_NAME=elf32 ++ ++TEXT_LENGTH=4K ++DATA_ORIGIN=0x800040 ++DATA_LENGTH=0x140 ++EXTRA_EM_FILE=avrelf +diff -Naurp ld/Makefile.am ld/Makefile.am +--- ld/Makefile.am 2011-06-07 11:55:03.000000000 -0500 ++++ ld/Makefile.am 2011-06-07 11:56:48.000000000 -0500 +@@ -155,6 +155,7 @@ ALL_EMULATIONS = \ + eavrxmega5.o \ + eavrxmega6.o \ + eavrxmega7.o \ ++ eavrtiny10.o \ + ecoff_i860.o \ + ecoff_sparc.o \ + eelf32_spu.o \ +@@ -762,6 +763,10 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxm + $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ + ${GEN_DEPENDS} + ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" ++eavrtiny10.c: $(srcdir)/emulparams/avrtiny10.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrtiny10 "$(tdir_avr2)" + ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" diff --git a/devel/avr-binutils/files/patch-403-binutils-2.20.1-xmega128a1u-64a1u b/devel/avr-binutils/files/patch-403-binutils-2.20.1-xmega128a1u-64a1u new file mode 100644 index 000000000000..03c651b78e72 --- /dev/null +++ b/devel/avr-binutils/files/patch-403-binutils-2.20.1-xmega128a1u-64a1u @@ -0,0 +1,42 @@ +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:00:46.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:01:05.000000000 -0500 +@@ -254,6 +254,7 @@ static struct mcu_type_s mcu_types[] = + {"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, + {"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, + {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, ++ {"atxmega64a1u",AVR_ISA_XMEGA, bfd_mach_avrxmega5}, + {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, +@@ -262,6 +263,7 @@ static struct mcu_type_s mcu_types[] = + {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, ++ {"atxmega128a1u",AVR_ISA_XMEGA, bfd_mach_avrxmega7}, + {"attiny4", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, + {"attiny5", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, + {"attiny9", AVR_ISA_AVRTINY10, bfd_mach_avrtiny10}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 11:56:25.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:01:05.000000000 -0500 +@@ -97,7 +97,8 @@ Instruction set avrxmega4 is for the XME + memory space and less than 64K data space (MCU types: atxmega64a3, atxmega64d3). + + Instruction set avrxmega5 is for the XMEGA AVR core with up to 64K program +-memory space and greater than 64K data space (MCU types: atxmega64a1). ++memory space and greater than 64K data space (MCU types: atxmega64a1, ++atxmega64a1u). + + Instruction set avrxmega6 is for the XMEGA AVR core with up to 256K program + memory space and less than 64K data space (MCU types: atxmega128a3, +@@ -105,7 +106,8 @@ atxmega128d3, atxmega192a3, atxmega192d3 + atxmega192d3). + + Instruction set avrxmega7 is for the XMEGA AVR core with up to 256K program +-memory space and greater than 64K data space (MCU types: atxmega128a1). ++memory space and greater than 64K data space (MCU types: atxmega128a1, ++atxmega128a1u). + + @cindex @code{-mall-opcodes} command line option, AVR + @item -mall-opcodes diff --git a/devel/avr-binutils/files/patch-404-binutils-2.20.1-atxmega16x1-32x1 b/devel/avr-binutils/files/patch-404-binutils-2.20.1-atxmega16x1-32x1 new file mode 100644 index 000000000000..97f8e1c8cdb5 --- /dev/null +++ b/devel/avr-binutils/files/patch-404-binutils-2.20.1-atxmega16x1-32x1 @@ -0,0 +1,30 @@ +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:03:38.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:03:51.000000000 -0500 +@@ -249,8 +249,10 @@ static struct mcu_type_s mcu_types[] = + {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6}, + {"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, + {"atxmega16d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega16x1", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, + {"atxmega32a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, + {"atxmega32d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, ++ {"atxmega32x1", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, + {"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, + {"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, + {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 12:03:38.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:03:51.000000000 -0500 +@@ -88,10 +88,10 @@ atmega2560, atmega2561). + + Instruction set avrxmega2 is for the XMEGA AVR core with 8K to 64K program + memory space and less than 64K data space (MCU types: atxmega16a4, atxmega16d4, +-atxmega32d4). ++atxmega16x1, atxmega32a4, atxmega32d4, atxmega32x1). + + Instruction set avrxmega3 is for the XMEGA AVR core with 8K to 64K program +-memory space and greater than 64K data space (MCU types: atxmega32a4). ++memory space and greater than 64K data space (MCU types: none). + + Instruction set avrxmega4 is for the XMEGA AVR core with up to 64K program + memory space and less than 64K data space (MCU types: atxmega64a3, atxmega64d3). diff --git a/devel/avr-binutils/files/patch-405-binutils-2.20.1-atxmega128b1 b/devel/avr-binutils/files/patch-405-binutils-2.20.1-atxmega128b1 new file mode 100644 index 000000000000..2dd65d2fbabc --- /dev/null +++ b/devel/avr-binutils/files/patch-405-binutils-2.20.1-atxmega128b1 @@ -0,0 +1,36 @@ +diff -Naurp binutils/size.c binutils/size.c +--- binutils/size.c 2011-06-07 11:47:11.000000000 -0500 ++++ binutils/size.c 2011-06-07 12:23:39.000000000 -0500 +@@ -132,6 +132,7 @@ avr_device_t avr[] = + {"atxmega128a1", AVR136K, AVR8K, AVR2K}, + {"atxmega128a1u", AVR136K, AVR8K, AVR2K}, + {"atxmega128a3", AVR136K, AVR8K, AVR2K}, ++ {"atxmega128b1", AVR136K, AVR8K, AVR2K}, + {"atxmega128d3", AVR136K, AVR8K, AVR2K}, + + {"at43usb320", AVR128K, 608UL, 0UL}, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:05:36.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:23:39.000000000 -0500 +@@ -258,6 +258,7 @@ static struct mcu_type_s mcu_types[] = + {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, + {"atxmega64a1u",AVR_ISA_XMEGA, bfd_mach_avrxmega5}, + {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega128b1", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 12:05:36.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:23:39.000000000 -0500 +@@ -102,8 +102,8 @@ atxmega64a1u). + + Instruction set avrxmega6 is for the XMEGA AVR core with up to 256K program + memory space and less than 64K data space (MCU types: atxmega128a3, +-atxmega128d3, atxmega192a3, atxmega192d3, atxmega256a3, atxmega256a3b, +-atxmega192d3). ++atxmega128d3, atxmega192a3, atxmega128b1, atxmega192d3, atxmega256a3, ++atxmega256a3b, atxmega192d3). + + Instruction set avrxmega7 is for the XMEGA AVR core with up to 256K program + memory space and greater than 64K data space (MCU types: atxmega128a1, diff --git a/devel/avr-binutils/files/patch-406-binutils-2.20.1-atxmega256a3bu b/devel/avr-binutils/files/patch-406-binutils-2.20.1-atxmega256a3bu new file mode 100644 index 000000000000..fe44be90af09 --- /dev/null +++ b/devel/avr-binutils/files/patch-406-binutils-2.20.1-atxmega256a3bu @@ -0,0 +1,34 @@ +diff -Naurp binutils/size.c binutils/size.c +--- binutils/size.c 2011-06-07 12:31:12.000000000 -0500 ++++ binutils/size.c 2011-06-07 12:31:23.000000000 -0500 +@@ -121,6 +121,7 @@ avr_device_t avr[] = + { + {"atxmega256a3", AVR264K, AVR16K, AVR4K}, + {"atxmega256a3b", AVR264K, AVR16K, AVR4K}, ++ {"atxmega256a3bu",AVR264K, AVR16K, AVR4K}, + {"atxmega256d3", AVR264K, AVR16K, AVR4K}, + + {"atmega2560", AVR256K, AVR8K, AVR4K}, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:31:12.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:31:23.000000000 -0500 +@@ -264,6 +264,7 @@ static struct mcu_type_s mcu_types[] = + {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6}, ++ {"atxmega256a3bu",AVR_ISA_XMEGA,bfd_mach_avrxmega6}, + {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, + {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, + {"atxmega128a1u",AVR_ISA_XMEGA, bfd_mach_avrxmega7}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 12:31:12.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:31:23.000000000 -0500 +@@ -103,7 +103,7 @@ atxmega64a1u). + Instruction set avrxmega6 is for the XMEGA AVR core with up to 256K program + memory space and less than 64K data space (MCU types: atxmega128a3, + atxmega128d3, atxmega192a3, atxmega128b1, atxmega192d3, atxmega256a3, +-atxmega256a3b, atxmega192d3). ++atxmega256a3b, atxmega256a3bu, atxmega192d3). + + Instruction set avrxmega7 is for the XMEGA AVR core with up to 256K program + memory space and greater than 64K data space (MCU types: atxmega128a1, diff --git a/devel/avr-binutils/files/patch-407-binutils-2.20.1-at90pwm161 b/devel/avr-binutils/files/patch-407-binutils-2.20.1-at90pwm161 new file mode 100644 index 000000000000..43f2e66ea67a --- /dev/null +++ b/devel/avr-binutils/files/patch-407-binutils-2.20.1-at90pwm161 @@ -0,0 +1,73 @@ +diff -rupw binutils/size.c binutils/size.c +--- binutils/size.c 2011-01-10 13:22:40.000000000 -0600 ++++ binutils/size.c 2011-01-05 19:15:32.000000000 -0600 +@@ -220,6 +220,7 @@ avr_device_t avr[] = + {"atxmega16d4", AVR20K, AVR2K, AVR1K}, + + {"at76c711", AVR16K, AVR2K, 0UL}, ++ {"at90pwm161", AVR16K, AVR1K, AVR512}, + {"at90pwm216", AVR16K, AVR1K, AVR512}, + {"at90pwm316", AVR16K, AVR1K, AVR512}, + {"at90usb162", AVR16K, AVR512, AVR512}, +diff -rupw gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-01-10 13:22:40.000000000 -0600 ++++ gas/config/tc-avr.c 2011-01-05 19:09:23.000000000 -0600 +@@ -159,6 +159,7 @@ static struct mcu_type_s mcu_types[] = + {"at90pwm3", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4}, + {"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4}, ++ {"at90pwm161", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega161", AVR_ISA_M161, bfd_mach_avr5}, +diff -rupw gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-01-10 13:22:40.000000000 -0600 ++++ gas/doc/c-avr.texi 2011-01-05 19:10:26.000000000 -0600 +@@ -65,8 +65,8 @@ at90pwm1,at90pwm2, at90pwm2b, at90pwm3, + at90pwm81). + + Instruction set avr5 is for the enhanced AVR core with up to 128K program +-memory space (MCU types: atmega16, atmega16a, atmega161, atmega162, atmega163, +-atmega164a, atmega164p, atmega165, atmega165a, atmega165p, atmega168, ++memory space (MCU types: at90pwm161, atmega16, atmega16a, atmega161, atmega162, ++atmega163, atmega164a, atmega164p, atmega165, atmega165a, atmega165p, atmega168, + atmega168a, atmega168p, atmega169, atmega169p, atmega169pa, + atmega32, atmega323, atmega324a, atmega324p, atmega324pa, atmega325, atmega325a, + atmega325p, atmega3250, atmega3250a, atmega3250p, atmega328, atmega328p, +diff -rupw ld/Makefile.in ld/Makefile.in +--- ld/Makefile.in 2011-01-10 13:22:05.000000000 -0600 ++++ ld/Makefile.in 2011-01-06 11:18:12.000000000 -0600 +@@ -441,6 +441,7 @@ ALL_EMULATIONS = \ + eavrxmega5.o \ + eavrxmega6.o \ + eavrxmega7.o \ ++ eavrtiny10.o \ + ecoff_i860.o \ + ecoff_sparc.o \ + eelf32_spu.o \ +@@ -952,6 +953,14 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny10.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecoff_i860.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecoff_sparc.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@ +@@ -2104,6 +2113,10 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxm + $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ + ${GEN_DEPENDS} + ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" ++eavrtiny10.c: $(srcdir)/emulparams/avrtiny10.sh \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ ${GEN_DEPENDS} ++ ${GENSCRIPTS} avrtiny10 "$(tdir_avr2)" + ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} + ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" diff --git a/devel/avr-binutils/files/patch-408-binutils-2.20.1-atmega16hvb-32hvb b/devel/avr-binutils/files/patch-408-binutils-2.20.1-atmega16hvb-32hvb new file mode 100644 index 000000000000..eeccf6a8532b --- /dev/null +++ b/devel/avr-binutils/files/patch-408-binutils-2.20.1-atmega16hvb-32hvb @@ -0,0 +1,52 @@ +diff -Naur binutils/size.c binutils/size.c +--- binutils/size.c 2011-01-19 13:46:48.000000000 -0600 ++++ binutils/size.c 2011-01-19 13:50:05.000000000 -0600 +@@ -207,8 +207,8 @@ + {"atmega3290a", AVR32K, AVR2K, AVR1K}, + {"atmega3290p", AVR32K, AVR2K, AVR1K}, + {"atmega32hvb", AVR32K, AVR2K, AVR1K}, ++ {"atmega32hvbrevb",AVR32K, AVR2K, AVR1K}, + {"atmega32c1", AVR32K, AVR2K, AVR1K}, +- {"atmega32hvb", AVR32K, AVR2K, AVR1K}, + {"atmega32m1", AVR32K, AVR2K, AVR1K}, + {"atmega32u2", AVR32K, AVR1K, AVR1K}, + {"atmega32u4", AVR32K, 2560UL, AVR1K}, +@@ -244,7 +244,8 @@ + {"atmega169pa", AVR16K, AVR1K, AVR512}, + {"atmega16hva", AVR16K, 768UL, AVR256}, + {"atmega16hva2", AVR16K, AVR1K, AVR256}, +- {"atmega16hvb", AVR16K, AVR1K, AVR512}, ++ {"atmega16hvb", AVR16K, AVR1K, AVR512}, ++ {"atmega16hvbrevb",AVR16K, AVR1K, AVR512}, + {"atmega16m1", AVR16K, AVR1K, AVR512}, + {"atmega16u2", AVR16K, AVR512, AVR512}, + {"atmega16u4", AVR16K, 1280UL, AVR512}, +diff -Naur gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-01-19 13:46:48.000000000 -0600 ++++ gas/config/tc-avr.c 2011-01-19 13:51:06.000000000 -0600 +@@ -220,7 +220,9 @@ + {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega16hvbrevb",AVR_ISA_AVR5,bfd_mach_avr5}, + {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega32hvbrevb",AVR_ISA_AVR5,bfd_mach_avr5}, + {"at90can32" , AVR_ISA_AVR5, bfd_mach_avr5}, + {"at90can64" , AVR_ISA_AVR5, bfd_mach_avr5}, + {"at90pwm216", AVR_ISA_AVR5, bfd_mach_avr5}, +diff -Naur gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-01-19 13:46:48.000000000 -0600 ++++ gas/doc/c-avr.texi 2011-01-19 13:52:30.000000000 -0600 +@@ -75,9 +75,9 @@ + atmega644pa, atmega645, atmega645a, atmega645p, atmega6450, atmega6450a, + atmega6450p, atmega649, atmega649a, atmega649p, atmega6490, atmega6490a, + atmega6490p, atmega64hve, atmega16hva, atmega16hva2, atmega16hvb, atmega32hvb, +-at90can32, at90can64, at90pwm216, at90pwm316, atmega16u4, atmega32c1, +-atmega64c1, atmega64m1, atmega16m1, atmega32m1, atmega64m1, atmega16u4, +-atmega32u4, atmega32u6, at90usb646, at90usb647, at94k, at90scr100). ++atmega16hvbrevb, atmega32hvbrevb, at90can32, at90can64, at90pwm216, at90pwm316, ++atmega16u4, atmega32c1, atmega64c1, atmega64m1, atmega16m1, atmega32m1, atmega64m1, ++atmega16u4, atmega32u4, atmega32u6, at90usb646, at90usb647, at94k, at90scr100). + + Instruction set avr51 is for the enhanced AVR core with exactly 128K program + memory space (MCU types: atmega128, atmega1280, atmega1281, atmega1284p, diff --git a/devel/avr-binutils/files/patch-409-binutils-2.20.1-atmega32_5_50_90_pa b/devel/avr-binutils/files/patch-409-binutils-2.20.1-atmega32_5_50_90_pa new file mode 100644 index 000000000000..bf390e35be86 --- /dev/null +++ b/devel/avr-binutils/files/patch-409-binutils-2.20.1-atmega32_5_50_90_pa @@ -0,0 +1,88 @@ +diff -Naurp binutils/size.c binutils/size.c +--- binutils/size.c 2011-02-17 11:55:20.000000000 -0600 ++++ binutils/size.c 2011-02-16 15:37:59.000000000 -0600 +@@ -194,9 +194,11 @@ avr_device_t avr[] = + {"atmega325", AVR32K, AVR2K, AVR1K}, + {"atmega325a", AVR32K, AVR2K, AVR1K}, + {"atmega325p", AVR32K, AVR2K, AVR1K}, ++ {"atmega325pa", AVR32K, AVR2K, AVR1K}, + {"atmega3250", AVR32K, AVR2K, AVR1K}, + {"atmega3250a", AVR32K, AVR2K, AVR1K}, + {"atmega3250p", AVR32K, AVR2K, AVR1K}, ++ {"atmega3250pa", AVR32K, AVR2K, AVR1K}, + {"atmega328", AVR32K, AVR2K, AVR1K}, + {"atmega328p", AVR32K, AVR2K, AVR1K}, + {"atmega329", AVR32K, AVR2K, AVR1K}, +@@ -206,6 +208,7 @@ avr_device_t avr[] = + {"atmega3290", AVR32K, AVR2K, AVR1K}, + {"atmega3290a", AVR32K, AVR2K, AVR1K}, + {"atmega3290p", AVR32K, AVR2K, AVR1K}, ++ {"atmega3290pa", AVR32K, AVR2K, AVR1K}, + {"atmega32hvb", AVR32K, AVR2K, AVR1K}, + {"atmega32hvbrevb",AVR32K, AVR2K, AVR1K}, + {"atmega32c1", AVR32K, AVR2K, AVR1K}, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-02-17 11:55:20.000000000 -0600 ++++ gas/config/tc-avr.c 2011-02-16 15:22:24.000000000 -0600 +@@ -185,9 +185,11 @@ static struct mcu_type_s mcu_types[] = + {"atmega325", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega325a", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega325p", AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega325pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3250", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3250a",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3250p",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega3250pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega328", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega328p", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega329", AVR_ISA_AVR5, bfd_mach_avr5}, +@@ -197,6 +199,7 @@ static struct mcu_type_s mcu_types[] = + {"atmega3290", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3290a",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5}, ++ {"atmega3290pa",AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega406", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega64", AVR_ISA_AVR5, bfd_mach_avr5}, + {"atmega640", AVR_ISA_AVR5, bfd_mach_avr5}, +diff -Naurp gas/doc/as.info gas/doc/as.info +--- gas/doc/as.info 2010-03-01 07:49:55.000000000 -0600 ++++ gas/doc/as.info 2011-02-17 11:59:53.000000000 -0600 +@@ -7097,14 +7097,15 @@ File: as.info, Node: AVR Options, Next + program memory space (MCU types: atmega16, atmega161, atmega162, + atmega163, atmega164p, atmega165, atmega165p, atmega168, + atmega168p, atmega169, atmega169p, atmega16c1, atmega32, +- atmega323, atmega324p, atmega325, atmega325p, atmega3250, +- atmega3250p, atmega328p, atmega329, atmega329p, atmega3290, +- atmega3290p, atmega406, atmega64, atmega640, atmega644, +- atmega644p, atmega644pa, atmega645, atmega6450, atmega649, +- atmega6490, atmega16hva, atmega16hvb, atmega32hvb, at90can32, +- at90can64, at90pwm216, at90pwm316, atmega32c1, atmega64c1, +- atmega16m1, atmega32m1, atmega64m1, atmega16u4, atmega32u4, +- atmega32u6, at90usb646, at90usb647, at94k, at90scr100). ++ atmega323, atmega324p, atmega325, atmega325p, atmega325pa, ++ atmega3250, atmega3250p, atmega3250pa, atmega328p, atmega329, ++ atmega329p, atmega3290, atmega3290p, atmega3290pa, atmega406, ++ atmega64, atmega640, atmega644, atmega644p, atmega644pa, atmega645, ++ atmega6450, atmega649, atmega6490, atmega16hva, atmega16hvb, ++ atmega32hvb, at90can32, at90can64, at90pwm216, at90pwm316, ++ atmega32c1, atmega64c1, atmega16m1, atmega32m1, atmega64m1, ++ atmega16u4, atmega32u4, atmega32u6, at90usb646, at90usb647, ++ at94k, at90scr100). + + Instruction set avr51 is for the enhanced AVR core with exactly + 128K program memory space (MCU types: atmega128, atmega1280, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-02-17 11:55:20.000000000 -0600 ++++ gas/doc/c-avr.texi 2011-02-16 15:42:20.000000000 -0600 +@@ -69,9 +69,9 @@ memory space (MCU types: at90pwm161, atm + atmega163, atmega164a, atmega164p, atmega165, atmega165a, atmega165p, atmega168, + atmega168a, atmega168p, atmega169, atmega169p, atmega169pa, + atmega32, atmega323, atmega324a, atmega324p, atmega324pa, atmega325, atmega325a, +-atmega325p, atmega3250, atmega3250a, atmega3250p, atmega328, atmega328p, ++atmega325p, atmega325pa, atmega3250, atmega3250a, atmega3250p, atmega3250pa, atmega328, atmega328p, + atmega329, atmega329a, atmega329p, atmega329pa, atmega3290, atmega3290a, +-atmega3290p, atmega406, atmega64, atmega640, atmega644, atmega644a, atmega644p, ++atmega3290p, atmega3290pa, atmega406, atmega64, atmega640, atmega644, atmega644a, atmega644p, + atmega644pa, atmega645, atmega645a, atmega645p, atmega6450, atmega6450a, + atmega6450p, atmega649, atmega649a, atmega649p, atmega6490, atmega6490a, + atmega6490p, atmega64hve, atmega16hva, atmega16hva2, atmega16hvb, atmega32hvb, diff --git a/devel/avr-binutils/files/patch-410-binutils-2.20.1-attiny1634 b/devel/avr-binutils/files/patch-410-binutils-2.20.1-attiny1634 new file mode 100644 index 000000000000..e41a2f6193e7 --- /dev/null +++ b/devel/avr-binutils/files/patch-410-binutils-2.20.1-attiny1634 @@ -0,0 +1,36 @@ +diff -Naurp binutils/size.c binutils/size.c +--- binutils/size.c 2011-06-07 12:36:56.000000000 -0500 ++++ binutils/size.c 2011-06-07 12:37:08.000000000 -0500 +@@ -250,6 +250,7 @@ avr_device_t avr[] = + {"atmega16hvb", AVR16K, AVR1K, AVR512}, + {"atmega16hvbrevb",AVR16K, AVR1K, AVR512}, + {"atmega16m1", AVR16K, AVR1K, AVR512}, ++ {"attiny1634", AVR16K, AVR1K, AVR256}, + {"atmega16u2", AVR16K, AVR512, AVR512}, + {"atmega16u4", AVR16K, 1280UL, AVR512}, + {"attiny167", AVR16K, AVR512, AVR512}, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:36:56.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:37:08.000000000 -0500 +@@ -142,6 +142,7 @@ static struct mcu_type_s mcu_types[] = + {"atmega8u2", AVR_ISA_AVR35, bfd_mach_avr35}, + {"atmega16u2", AVR_ISA_AVR35, bfd_mach_avr35}, + {"atmega32u2", AVR_ISA_AVR35, bfd_mach_avr35}, ++ {"attiny1634", AVR_ISA_AVR35, bfd_mach_avr35}, + {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, + {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 12:36:56.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:37:08.000000000 -0500 +@@ -55,8 +55,8 @@ Instruction set avr31 is for the classic + memory space (MCU types: atmega103, at43usb320). + + Instruction set avr35 is for classic AVR core plus MOVW, CALL, and JMP +-instructions (MCU types: attiny167, at90usb82, at90usb162, atmega8u2, +-atmega16u2, atmega32u2). ++instructions (MCU types: attiny167, attiny1634, at90usb82, at90usb162, ++atmega8u2, atmega16u2, atmega32u2). + + Instruction set avr4 is for the enhanced AVR core with up to 8K program + memory space (MCU types: atmega48, atmega48a, atmega48p,atmega8, atmega88, diff --git a/devel/avr-binutils/files/patch-411-binutils-2.20.1-atmega48pa b/devel/avr-binutils/files/patch-411-binutils-2.20.1-atmega48pa new file mode 100644 index 000000000000..9dd0e85f3967 --- /dev/null +++ b/devel/avr-binutils/files/patch-411-binutils-2.20.1-atmega48pa @@ -0,0 +1,39 @@ +diff -Naurp binutils/size.c binutils/size.c +--- binutils/size.c 2011-06-07 12:38:50.000000000 -0500 ++++ binutils/size.c 2011-06-07 12:39:18.000000000 -0500 +@@ -288,6 +288,7 @@ avr_device_t avr[] = + {"at90s4434", AVR4K, 352UL, AVR256}, + {"atmega48", AVR4K, AVR512, AVR256}, + {"atmega48a", AVR4K, AVR512, AVR256}, ++ {"atmega48pa", AVR4K, AVR512, AVR256}, + {"atmega48p", AVR4K, AVR512, AVR256}, + {"attiny4313", AVR4K, AVR256, AVR256}, + {"attiny43u", AVR4K, AVR256, AVR64}, +diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c +--- gas/config/tc-avr.c 2011-06-07 12:38:50.000000000 -0500 ++++ gas/config/tc-avr.c 2011-06-07 12:39:18.000000000 -0500 +@@ -146,6 +146,7 @@ static struct mcu_type_s mcu_types[] = + {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, + {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4}, ++ {"atmega48pa", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega88", AVR_ISA_AVR4, bfd_mach_avr4}, + {"atmega88a", AVR_ISA_AVR4, bfd_mach_avr4}, +diff -Naurp gas/doc/c-avr.texi gas/doc/c-avr.texi +--- gas/doc/c-avr.texi 2011-06-07 12:38:50.000000000 -0500 ++++ gas/doc/c-avr.texi 2011-06-07 12:39:18.000000000 -0500 +@@ -59,10 +59,9 @@ instructions (MCU types: attiny167, atti + atmega8u2, atmega16u2, atmega32u2). + + Instruction set avr4 is for the enhanced AVR core with up to 8K program +-memory space (MCU types: atmega48, atmega48a, atmega48p,atmega8, atmega88, +-atmega88a, atmega88p, atmega88pa, atmega8515, atmega8535, atmega8hva, +-at90pwm1,at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, +-at90pwm81). ++memory space (MCU types: atmega48, atmega48a, atmega48pa, atmega48p,atmega8, ++atmega88, atmega88a, atmega88p, atmega88pa, atmega8515, atmega8535, atmega8hva, ++at90pwm1,at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, at90pwm81). + + Instruction set avr5 is for the enhanced AVR core with up to 128K program + memory space (MCU types: at90pwm161, atmega16, atmega16a, atmega161, atmega162, diff --git a/devel/avr-binutils/files/patch-500-binutils-2.20.1-bug13789 b/devel/avr-binutils/files/patch-500-binutils-2.20.1-bug13789 new file mode 100644 index 000000000000..6bd1e412a10c --- /dev/null +++ b/devel/avr-binutils/files/patch-500-binutils-2.20.1-bug13789 @@ -0,0 +1,377 @@ +diff -rupN bfd/archures.c bfd/archures.c +--- bfd/archures.c 2011-05-11 20:06:37.000000000 -0500 ++++ bfd/archures.c 2011-05-10 13:35:37.000000000 -0500 +@@ -368,6 +368,7 @@ DESCRIPTION + .#define bfd_mach_avr5 5 + .#define bfd_mach_avr51 51 + .#define bfd_mach_avr6 6 ++.#define bfd_mach_avrtiny10 100 + .#define bfd_mach_avrxmega1 101 + .#define bfd_mach_avrxmega2 102 + .#define bfd_mach_avrxmega3 103 +@@ -375,7 +376,6 @@ DESCRIPTION + .#define bfd_mach_avrxmega5 105 + .#define bfd_mach_avrxmega6 106 + .#define bfd_mach_avrxmega7 107 +-.#define bfd_mach_avrtiny10 201 + . bfd_arch_bfin, {* ADI Blackfin *} + .#define bfd_mach_bfin 1 + . bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *} +diff -rupN bfd/bfd-in2.h bfd/bfd-in2.h +--- bfd/bfd-in2.h 2011-05-11 20:06:39.000000000 -0500 ++++ bfd/bfd-in2.h 2011-05-10 13:35:37.000000000 -0500 +@@ -2042,6 +2042,7 @@ enum bfd_architecture + #define bfd_mach_avr5 5 + #define bfd_mach_avr51 51 + #define bfd_mach_avr6 6 ++#define bfd_mach_avrtiny10 100 + #define bfd_mach_avrxmega1 101 + #define bfd_mach_avrxmega2 102 + #define bfd_mach_avrxmega3 103 +@@ -2049,7 +2050,6 @@ enum bfd_architecture + #define bfd_mach_avrxmega5 105 + #define bfd_mach_avrxmega6 106 + #define bfd_mach_avrxmega7 107 +-#define bfd_mach_avrtiny10 201 + bfd_arch_bfin, /* ADI Blackfin */ + #define bfd_mach_bfin 1 + bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ +diff -rupN bfd/cpu-avr.c bfd/cpu-avr.c +--- bfd/cpu-avr.c 2011-05-11 20:06:41.000000000 -0500 ++++ bfd/cpu-avr.c 2011-05-10 13:35:37.000000000 -0500 +@@ -135,29 +135,29 @@ static const bfd_arch_info_type arch_inf + /* 3-Byte PC. */ + N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]), + ++ /* attiny 10 */ ++ N (16, bfd_mach_avrtiny10, "avr:100", FALSE, & arch_info_struct[11]), ++ + /* Xmega 1 */ +- N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[11]), ++ N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[12]), + + /* Xmega 2 */ +- N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[12]), ++ N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[13]), + + /* Xmega 3 */ +- N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[13]), ++ N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[14]), + + /* Xmega 4 */ +- N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[14]), ++ N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[15]), + + /* Xmega 5 */ +- N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[15]), ++ N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[16]), + + /* Xmega 6 */ +- N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]), ++ N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[17]), + + /* Xmega 7 */ +- N (24, bfd_mach_avrxmega7, "avr:107", FALSE, & arch_info_struct[17]), +- +- /* attiny 10 */ +- N (16, bfd_mach_avrtiny10, "avr:201", FALSE, NULL) ++ N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL) + + }; + +diff -rupN include/elf/avr.h include/elf/avr.h +--- include/elf/avr.h 2011-05-11 20:06:42.000000000 -0500 ++++ include/elf/avr.h 2011-05-10 13:35:37.000000000 -0500 +@@ -40,6 +40,7 @@ + #define E_AVR_MACH_AVR5 5 + #define E_AVR_MACH_AVR51 51 + #define E_AVR_MACH_AVR6 6 ++#define E_AVR_MACH_AVRTINY10 100 + #define E_AVR_MACH_XMEGA1 101 + #define E_AVR_MACH_XMEGA2 102 + #define E_AVR_MACH_XMEGA3 103 +@@ -47,7 +48,6 @@ + #define E_AVR_MACH_XMEGA5 105 + #define E_AVR_MACH_XMEGA6 106 + #define E_AVR_MACH_XMEGA7 107 +-#define E_AVR_MACH_AVRTINY10 201 + + /* Relocations. */ + START_RELOC_NUMBERS (elf_avr_reloc_type) +diff -rupN ld/emulparams/avrtiny10.sh ld/emulparams/avrtiny10.sh +--- ld/emulparams/avrtiny10.sh 2011-05-11 20:06:44.000000000 -0500 ++++ ld/emulparams/avrtiny10.sh 2011-05-10 13:39:44.000000000 -0500 +@@ -1,12 +1,13 @@ +-ARCH=avr:201 ++ARCH=avr:100 + MACHINE= +-SCRIPT_NAME=avr ++SCRIPT_NAME=avrtiny10 + OUTPUT_FORMAT="elf32-avr" + MAXPAGESIZE=1 + EMBEDDED=yes + TEMPLATE_NAME=elf32 + ++TEXT_ORIGIN=0x0 + TEXT_LENGTH=4K +-DATA_ORIGIN=0x800040 +-DATA_LENGTH=0x140 ++DATA_ORIGIN=0x0800040 ++DATA_LENGTH=0x1F + EXTRA_EM_FILE=avrelf +diff -rupN ld/Makefile.am ld/Makefile.am +--- ld/Makefile.am 2011-05-11 20:06:47.000000000 -0500 ++++ ld/Makefile.am 2011-05-10 13:35:37.000000000 -0500 +@@ -764,7 +764,7 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxm + ${GEN_DEPENDS} + ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" + eavrtiny10.c: $(srcdir)/emulparams/avrtiny10.sh \ +- $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ ++ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avrtiny10.sc \ + ${GEN_DEPENDS} + ${GENSCRIPTS} avrtiny10 "$(tdir_avr2)" + ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ +diff -rupN ld/scripttempl/avrtiny10.sc ld/scripttempl/avrtiny10.sc +--- ld/scripttempl/avrtiny10.sc 1969-12-31 18:00:00.000000000 -0600 ++++ ld/scripttempl/avrtiny10.sc 2011-05-10 13:35:37.000000000 -0500 +@@ -0,0 +1,240 @@ ++cat < text} ++ ++ .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))} ++ { ++ ${RELOCATING+ PROVIDE (__data_start = .) ; } ++ *(.data) ++ *(.data*) ++ *(.rodata) /* We need to include .rodata here if gcc is used */ ++ *(.rodata*) /* with -fdata-sections. */ ++ *(.gnu.linkonce.d*) ++ ${RELOCATING+. = ALIGN(2);} ++ ${RELOCATING+ _edata = . ; } ++ ${RELOCATING+ PROVIDE (__data_end = .) ; } ++ } ${RELOCATING+ > data} ++ ++ .bss ${RELOCATING-0} :${RELOCATING+ AT (ADDR (.bss))} ++ { ++ ${RELOCATING+ PROVIDE (__bss_start = .) ; } ++ *(.bss) ++ *(.bss*) ++ *(COMMON) ++ ${RELOCATING+ PROVIDE (__bss_end = .) ; } ++ } ${RELOCATING+ > data} ++ ++ ${RELOCATING+ __data_load_start = LOADADDR(.data); } ++ ${RELOCATING+ __data_load_end = __data_load_start + SIZEOF(.data); } ++ ++ /* Global data not cleared after reset. */ ++ .noinit ${RELOCATING-0}: ++ { ++ ${RELOCATING+ PROVIDE (__noinit_start = .) ; } ++ *(.noinit*) ++ ${RELOCATING+ PROVIDE (__noinit_end = .) ; } ++ ${RELOCATING+ _end = . ; } ++ ${RELOCATING+ PROVIDE (__heap_start = .) ; } ++ } ${RELOCATING+ > data} ++ ++ .lock ${RELOCATING-0}: ++ { ++ KEEP(*(.lock*)) ++ } ${RELOCATING+ > lock} ++ ++ .signature ${RELOCATING-0}: ++ { ++ KEEP(*(.signature*)) ++ } ${RELOCATING+ > signature} ++ ++ /* Stabs debugging sections. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ .stab.excl 0 : { *(.stab.excl) } ++ .stab.exclstr 0 : { *(.stab.exclstr) } ++ .stab.index 0 : { *(.stab.index) } ++ .stab.indexstr 0 : { *(.stab.indexstr) } ++ .comment 0 : { *(.comment) } ++ ++ /* DWARF debug sections. ++ Symbols in the DWARF debugging sections are relative to the beginning ++ of the section so we begin them at 0. */ ++ ++ /* DWARF 1 */ ++ .debug 0 : { *(.debug) } ++ .line 0 : { *(.line) } ++ ++ /* GNU DWARF 1 extensions */ ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ ++ /* DWARF 1.1 and DWARF 2 */ ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ ++ /* DWARF 2 */ ++ .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } ++ .debug_abbrev 0 : { *(.debug_abbrev) } ++ .debug_line 0 : { *(.debug_line) } ++ .debug_frame 0 : { *(.debug_frame) } ++ .debug_str 0 : { *(.debug_str) } ++ .debug_loc 0 : { *(.debug_loc) } ++ .debug_macinfo 0 : { *(.debug_macinfo) } ++} ++EOF ++ diff --git a/devel/avr-binutils/files/patch-aa b/devel/avr-binutils/files/patch-aa deleted file mode 100644 index 154b211ebfd2..000000000000 --- a/devel/avr-binutils/files/patch-aa +++ /dev/null @@ -1,50 +0,0 @@ ---- etc/Makefile.in~ 2009-07-31 00:44:48.000000000 +0200 -+++ etc/Makefile.in 2010-03-03 17:13:29.000000000 +0100 -@@ -64,7 +64,8 @@ - HTMLFILES = standards.html configure.html - - all: info --install: install-info -+#install: install-info -+install: - - uninstall: - ---- libiberty/Makefile.in~ 2009-08-23 21:03:58.000000000 +0200 -+++ libiberty/Makefile.in 2010-03-03 17:14:00.000000000 +0100 -@@ -321,7 +321,8 @@ - @MAINT@ echo stamp > stamp-functions - - INSTALL_DEST = @INSTALL_DEST@ --install: install_to_$(INSTALL_DEST) install-subdir -+#install: install_to_$(INSTALL_DEST) install-subdir -+install: - - # This is tricky. Even though CC in the Makefile contains - # multilib-specific flags, it's overridden by FLAGS_TO_PASS from the ---- bfd/Makefile.in~ 2009-10-16 13:47:48.000000000 +0200 -+++ bfd/Makefile.in 2010-03-03 17:19:17.000000000 +0100 -@@ -1673,8 +1673,9 @@ - for dir in "$(DESTDIR)$(bfdlibdir)" "$(DESTDIR)$(bfdincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done --install: $(BUILT_SOURCES) -- $(MAKE) $(AM_MAKEFLAGS) install-recursive -+#install: $(BUILT_SOURCES) -+# $(MAKE) $(AM_MAKEFLAGS) install-recursive -+install: - install-exec: install-exec-recursive - install-data: install-data-recursive - uninstall: uninstall-recursive ---- opcodes/Makefile.in~ 2009-09-07 14:08:03.000000000 +0200 -+++ opcodes/Makefile.in 2010-03-03 17:19:43.000000000 +0100 -@@ -1051,7 +1051,8 @@ - for dir in "$(DESTDIR)$(bfdlibdir)" "$(DESTDIR)$(bfdincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done --install: install-recursive -+#install: install-recursive -+install: - install-exec: install-exec-recursive - install-data: install-data-recursive - uninstall: uninstall-recursive diff --git a/devel/avr-binutils/files/patch-as-dwarf b/devel/avr-binutils/files/patch-as-dwarf deleted file mode 100644 index d081eb3a9982..000000000000 --- a/devel/avr-binutils/files/patch-as-dwarf +++ /dev/null @@ -1,10 +0,0 @@ -diff -ru binutils-2.19.1.orig/gas/config/tc-avr.h binutils-2.19.1/gas/config/tc-avr.h ---- gas/config/tc-avr.h Tue Jul 3 14:01:04 2007 -+++ gas/config/tc-avr.h Thu Apr 16 20:46:54 2009 -@@ -147,3 +147,6 @@ - - /* This target is buggy, and sets fix size too large. */ - #define TC_FX_SIZE_SLACK(FIX) 2 -+ -+/* keep DWARF2_ADDR_SIZE in consistency with C compiler produced information */ -+#define DWARF2_ADDR_SIZE(bfd) 4 diff --git a/devel/avr-binutils/files/patch-as-dwarf-avrstudio b/devel/avr-binutils/files/patch-as-dwarf-avrstudio deleted file mode 100644 index 8f403621ac32..000000000000 --- a/devel/avr-binutils/files/patch-as-dwarf-avrstudio +++ /dev/null @@ -1,27 +0,0 @@ ---- gas/dwarf2dbg.c.orig 2009-09-14 13:43:26.000000000 +0200 -+++ gas/dwarf2dbg.c 2010-03-04 11:13:52.000000000 +0100 -@@ -112,8 +112,11 @@ - Note: If you want to change this, you'll have to update the - "standard_opcode_lengths" table that is emitted below in - out_debug_line(). */ -+#ifndef TC_AVR - #define DWARF2_LINE_OPCODE_BASE 13 -- -+#else -+#define DWARF2_LINE_OPCODE_BASE 10 -+#endif - #ifndef DWARF2_LINE_BASE - /* Minimum line offset in a special line info. opcode. This value - was chosen to give a reasonable range of values. */ -@@ -1439,9 +1442,11 @@ - out_byte (0); /* DW_LNS_set_basic_block */ - out_byte (0); /* DW_LNS_const_add_pc */ - out_byte (1); /* DW_LNS_fixed_advance_pc */ -+#ifndef TC_AVR - out_byte (0); /* DW_LNS_set_prologue_end */ - out_byte (0); /* DW_LNS_set_epilogue_begin */ - out_byte (1); /* DW_LNS_set_isa */ -+#endif - - out_file_list (); - diff --git a/devel/avr-binutils/files/patch-avr-size b/devel/avr-binutils/files/patch-avr-size deleted file mode 100644 index bfa60301c597..000000000000 --- a/devel/avr-binutils/files/patch-avr-size +++ /dev/null @@ -1,513 +0,0 @@ -AVR specific only -=========================================================== ---- binutils/size.c 2007-08-06 13:56:14.000000000 -0600 -+++ binutils/size.c 2007-09-13 09:13:10.281250000 -0600 -@@ -36,10 +36,31 @@ - #include "getopt.h" - #include "bucomm.h" - --#ifndef BSD_DEFAULT --#define BSD_DEFAULT 1 -+typedef enum -+{ -+ format_sysv = 0, -+ format_bsd = 1, -+ format_avr = 2, -+} format_type_t; -+ -+ -+/* Set the default format. */ -+#define FORMAT_DEFAULT_SYSV 0 -+#define FORMAT_DEFAULT_BSD 1 -+#define FORMAT_DEFAULT_AVR 0 -+ -+#if FORMAT_DEFAULT_SYSV -+ #define FORMAT_DEFAULT format_sysv -+ #define FORMAT_NAME "sysv" -+#elif FORMAT_DEFAULT_BSD -+ #define FORMAT_DEFAULT format_bsd -+ #define FORMAT_NAME "berkeley" -+#elif FORMAT_DEFAULT_AVR -+ #define FORMAT_DEFAULT format_avr -+ #define FORMAT_NAME "avr" - #endif - -+ - /* Program options. */ - - static enum -@@ -48,9 +69,8 @@ static enum - } - radix = decimal; - --/* 0 means use AT&T-style output. */ --static int berkeley_format = BSD_DEFAULT; - -+format_type_t format = FORMAT_DEFAULT; - static int show_version = 0; - static int show_help = 0; - static int show_totals = 0; -@@ -64,6 +84,238 @@ static bfd_size_type total_textsize; - /* Program exit status. */ - static int return_code = 0; - -+ -+/* AVR Size specific stuff */ -+ -+#define AVR64 64UL -+#define AVR128 128UL -+#define AVR256 256UL -+#define AVR512 512UL -+#define AVR1K 1024UL -+#define AVR2K 2048UL -+#define AVR4K 4096UL -+#define AVR8K 8192UL -+#define AVR16K 16384UL -+#define AVR20K 20480UL -+#define AVR24K 24576UL -+#define AVR32K 32768UL -+#define AVR36K 36864UL -+#define AVR40K 40960UL -+#define AVR64K 65536UL -+#define AVR68K 69632UL -+#define AVR128K 131072UL -+#define AVR136K 139264UL -+#define AVR200K 204800UL -+#define AVR256K 262144UL -+#define AVR264K 270336UL -+ -+typedef struct -+{ -+ char *name; -+ long flash; -+ long ram; -+ long eeprom; -+} avr_device_t; -+ -+avr_device_t avr[] = -+{ -+ {"atxmega256a3", AVR264K, AVR16K, AVR4K}, -+ {"atxmega256a3b", AVR264K, AVR16K, AVR4K}, -+ {"atxmega256d3", AVR264K, AVR16K, AVR4K}, -+ -+ {"atmega2560", AVR256K, AVR8K, AVR4K}, -+ {"atmega2561", AVR256K, AVR8K, AVR4K}, -+ -+ {"atxmega192a3", AVR200K, AVR16K, AVR2K}, -+ {"atxmega192d3", AVR200K, AVR16K, AVR2K}, -+ -+ {"atxmega128a1", AVR136K, AVR8K, AVR2K}, -+ {"atxmega128a3", AVR136K, AVR8K, AVR2K}, -+ {"atxmega128d3", AVR136K, AVR8K, AVR2K}, -+ -+ {"at43usb320", AVR128K, 608UL, 0UL}, -+ {"at90can128", AVR128K, AVR4K, AVR4K}, -+ {"at90usb1286", AVR128K, AVR8K, AVR4K}, -+ {"at90usb1287", AVR128K, AVR8K, AVR4K}, -+ {"atmega128", AVR128K, AVR4K, AVR4K}, -+ {"atmega1280", AVR128K, AVR8K, AVR4K}, -+ {"atmega1281", AVR128K, AVR8K, AVR4K}, -+ {"atmega1284p", AVR128K, AVR16K, AVR4K}, -+ {"atmega128rfa1", AVR128K, AVR16K, AVR4K}, -+ {"atmega103", AVR128K, 4000UL, AVR4K}, -+ -+ {"atxmega64a1", AVR68K, AVR4K, AVR2K}, -+ {"atxmega64a3", AVR68K, AVR4K, AVR2K}, -+ {"atxmega64d3", AVR68K, AVR4K, AVR2K}, -+ -+ {"at90can64", AVR64K, AVR4K, AVR2K}, -+ {"at90scr100", AVR64K, AVR4K, AVR2K}, -+ {"at90usb646", AVR64K, AVR4K, AVR2K}, -+ {"at90usb647", AVR64K, AVR4K, AVR2K}, -+ {"atmega64", AVR64K, AVR4K, AVR2K}, -+ {"atmega640", AVR64K, AVR8K, AVR4K}, -+ {"atmega644", AVR64K, AVR4K, AVR2K}, -+ {"atmega644a", AVR64K, AVR4K, AVR2K}, -+ {"atmega644p", AVR64K, AVR4K, AVR2K}, -+ {"atmega644pa", AVR64K, AVR4K, AVR2K}, -+ {"atmega645", AVR64K, AVR4K, AVR2K}, -+ {"atmega645a", AVR64K, AVR4K, AVR2K}, -+ {"atmega645p", AVR64K, AVR4K, AVR2K}, -+ {"atmega6450", AVR64K, AVR4K, AVR2K}, -+ {"atmega6450a", AVR64K, AVR4K, AVR2K}, -+ {"atmega6450p", AVR64K, AVR4K, AVR2K}, -+ {"atmega649", AVR64K, AVR4K, AVR2K}, -+ {"atmega649a", AVR64K, AVR4K, AVR2K}, -+ {"atmega649p", AVR64K, AVR4K, AVR2K}, -+ {"atmega6490", AVR64K, AVR4K, AVR2K}, -+ {"atmega6490a", AVR64K, AVR4K, AVR2K}, -+ {"atmega6490p", AVR64K, AVR4K, AVR2K}, -+ {"atmega64c1", AVR64K, AVR4K, AVR2K}, -+ {"atmega64hve", AVR64K, AVR4K, AVR1K}, -+ {"atmega64m1", AVR64K, AVR4K, AVR2K}, -+ -+ {"atmega406", AVR40K, AVR2K, AVR512}, -+ -+ {"atxmega32a4", AVR36K, AVR4K, AVR1K}, -+ {"atxmega32d4", AVR36K, AVR4K, AVR1K}, -+ -+ {"at90can32", AVR32K, AVR2K, AVR1K}, -+ {"at94k", AVR32K, AVR4K, 0UL}, -+ {"atmega32", AVR32K, AVR2K, AVR1K}, -+ {"atmega323", AVR32K, AVR2K, AVR1K}, -+ {"atmega324a", AVR32K, AVR2K, AVR1K}, -+ {"atmega324p", AVR32K, AVR2K, AVR1K}, -+ {"atmega324pa", AVR32K, AVR2K, AVR1K}, -+ {"atmega325", AVR32K, AVR2K, AVR1K}, -+ {"atmega325p", AVR32K, AVR2K, AVR1K}, -+ {"atmega3250", AVR32K, AVR2K, AVR1K}, -+ {"atmega3250p", AVR32K, AVR2K, AVR1K}, -+ {"atmega328", AVR32K, AVR2K, AVR1K}, -+ {"atmega328p", AVR32K, AVR2K, AVR1K}, -+ {"atmega329", AVR32K, AVR2K, AVR1K}, -+ {"atmega329p", AVR32K, AVR2K, AVR1K}, -+ {"atmega329pa", AVR32K, AVR2K, AVR1K}, -+ {"atmega3290", AVR32K, AVR2K, AVR1K}, -+ {"atmega3290p", AVR32K, AVR2K, AVR1K}, -+ {"atmega32hvb", AVR32K, AVR2K, AVR1K}, -+ {"atmega32c1", AVR32K, AVR2K, AVR1K}, -+ {"atmega32hvb", AVR32K, AVR2K, AVR1K}, -+ {"atmega32m1", AVR32K, AVR2K, AVR1K}, -+ {"atmega32u2", AVR32K, AVR1K, AVR1K}, -+ {"atmega32u4", AVR32K, 2560UL, AVR1K}, -+ {"atmega32u6", AVR32K, 2560UL, AVR1K}, -+ -+ {"at43usb355", AVR24K, 1120UL, 0UL}, -+ -+ {"atxmega16a4", AVR20K, AVR2K, AVR1K}, -+ {"atxmega16d4", AVR20K, AVR2K, AVR1K}, -+ -+ {"at76c711", AVR16K, AVR2K, 0UL}, -+ {"at90pwm216", AVR16K, AVR1K, AVR512}, -+ {"at90pwm316", AVR16K, AVR1K, AVR512}, -+ {"at90usb162", AVR16K, AVR512, AVR512}, -+ {"atmega16", AVR16K, AVR1K, AVR512}, -+ {"atmega16a", AVR16K, AVR1K, AVR512}, -+ {"atmega161", AVR16K, AVR1K, AVR512}, -+ {"atmega162", AVR16K, AVR1K, AVR512}, -+ {"atmega163", AVR16K, AVR1K, AVR512}, -+ {"atmega164", AVR16K, AVR1K, AVR512}, -+ {"atmega164a", AVR16K, AVR1K, AVR512}, -+ {"atmega164p", AVR16K, AVR1K, AVR512}, -+ {"atmega165a", AVR16K, AVR1K, AVR512}, -+ {"atmega165", AVR16K, AVR1K, AVR512}, -+ {"atmega165p", AVR16K, AVR1K, AVR512}, -+ {"atmega168", AVR16K, AVR1K, AVR512}, -+ {"atmega168a", AVR16K, AVR1K, AVR512}, -+ {"atmega168p", AVR16K, AVR1K, AVR512}, -+ {"atmega169", AVR16K, AVR1K, AVR512}, -+ {"atmega169a", AVR16K, AVR1K, AVR512}, -+ {"atmega169p", AVR16K, AVR1K, AVR512}, -+ {"atmega169pa", AVR16K, AVR1K, AVR512}, -+ {"atmega16hva", AVR16K, 768UL, AVR256}, -+ {"atmega16hva2", AVR16K, AVR1K, AVR256}, -+ {"atmega16hvb", AVR16K, AVR1K, AVR512}, -+ {"atmega16m1", AVR16K, AVR1K, AVR512}, -+ {"atmega16u2", AVR16K, AVR512, AVR512}, -+ {"atmega16u4", AVR16K, 1280UL, AVR512}, -+ {"attiny167", AVR16K, AVR512, AVR512}, -+ -+ {"at90c8534", AVR8K, 352UL, AVR512}, -+ {"at90pwm1", AVR8K, AVR512, AVR512}, -+ {"at90pwm2", AVR8K, AVR512, AVR512}, -+ {"at90pwm2b", AVR8K, AVR512, AVR512}, -+ {"at90pwm3", AVR8K, AVR512, AVR512}, -+ {"at90pwm3b", AVR8K, AVR512, AVR512}, -+ {"at90pwm81", AVR8K, AVR256, AVR512}, -+ {"at90s8515", AVR8K, AVR512, AVR512}, -+ {"at90s8535", AVR8K, AVR512, AVR512}, -+ {"at90usb82", AVR8K, AVR512, AVR512}, -+ {"ata6289", AVR8K, AVR512, 320UL}, -+ {"atmega8", AVR8K, AVR1K, AVR512}, -+ {"atmega8515", AVR8K, AVR512, AVR512}, -+ {"atmega8535", AVR8K, AVR512, AVR512}, -+ {"atmega88", AVR8K, AVR1K, AVR512}, -+ {"atmega88a", AVR8K, AVR1K, AVR512}, -+ {"atmega88p", AVR8K, AVR1K, AVR512}, -+ {"atmega88pa", AVR8K, AVR1K, AVR512}, -+ {"atmega8hva", AVR8K, 768UL, AVR256}, -+ {"atmega8u2", AVR8K, AVR512, AVR512}, -+ {"attiny84", AVR8K, AVR512, AVR512}, -+ {"attiny85", AVR8K, AVR512, AVR512}, -+ {"attiny861", AVR8K, AVR512, AVR512}, -+ {"attiny861a", AVR8K, AVR512, AVR512}, -+ {"attiny87", AVR8K, AVR512, AVR512}, -+ {"attiny88", AVR8K, AVR512, AVR64}, -+ -+ {"at90s4414", AVR4K, 352UL, AVR256}, -+ {"at90s4433", AVR4K, AVR128, AVR256}, -+ {"at90s4434", AVR4K, 352UL, AVR256}, -+ {"atmega48", AVR4K, AVR512, AVR256}, -+ {"atmega48a", AVR4K, AVR512, AVR256}, -+ {"atmega48p", AVR4K, AVR512, AVR256}, -+ {"attiny4313", AVR4K, AVR256, AVR256}, -+ {"attiny43u", AVR4K, AVR256, AVR64}, -+ {"attiny44", AVR4K, AVR256, AVR256}, -+ {"attiny44a", AVR4K, AVR256, AVR256}, -+ {"attiny45", AVR4K, AVR256, AVR256}, -+ {"attiny461", AVR4K, AVR256, AVR256}, -+ {"attiny461a", AVR4K, AVR256, AVR256}, -+ {"attiny48", AVR4K, AVR256, AVR64}, -+ -+ {"at86rf401", AVR2K, 224UL, AVR128}, -+ {"at90s2313", AVR2K, AVR128, AVR128}, -+ {"at90s2323", AVR2K, AVR128, AVR128}, -+ {"at90s2333", AVR2K, 224UL, AVR128}, -+ {"at90s2343", AVR2K, AVR128, AVR128}, -+ {"attiny20", AVR2K, AVR128, 0UL}, -+ {"attiny22", AVR2K, 224UL, AVR128}, -+ {"attiny2313", AVR2K, AVR128, AVR128}, -+ {"attiny2313a", AVR2K, AVR128, AVR128}, -+ {"attiny24", AVR2K, AVR128, AVR128}, -+ {"attiny24a", AVR2K, AVR128, AVR128}, -+ {"attiny25", AVR2K, AVR128, AVR128}, -+ {"attiny26", AVR2K, AVR128, AVR128}, -+ {"attiny261", AVR2K, AVR128, AVR128}, -+ {"attiny261a", AVR2K, AVR128, AVR128}, -+ {"attiny28", AVR2K, 0UL, 0UL}, -+ {"attiny40", AVR2K, AVR256, 0UL}, -+ -+ {"at90s1200", AVR1K, 0UL, AVR64}, -+ {"attiny9", AVR1K, 32UL, 0UL}, -+ {"attiny10", AVR1K, 32UL, 0UL}, -+ {"attiny11", AVR1K, 0UL, AVR64}, -+ {"attiny12", AVR1K, 0UL, AVR64}, -+ {"attiny13", AVR1K, AVR64, AVR64}, -+ {"attiny13a", AVR1K, AVR64, AVR64}, -+ {"attiny15", AVR1K, 0UL, AVR64}, -+ -+ {"attiny4", AVR512, 32UL, 0UL}, -+ {"attiny5", AVR512, 32UL, 0UL}, -+}; -+ -+static char *avrmcu = NULL; -+ -+ - static char *target = NULL; - - /* Forward declarations. */ -@@ -79,7 +329,8 @@ usage (FILE *stream, int status) - fprintf (stream, _(" Displays the sizes of sections inside binary files\n")); - fprintf (stream, _(" If no input file(s) are specified, a.out is assumed\n")); - fprintf (stream, _(" The options are:\n\ -- -A|-B --format={sysv|berkeley} Select output style (default is %s)\n\ -+ -A|-B|-C --format={sysv|berkeley|avr} Select output style (default is %s)\n\ -+ --mcu= MCU name for AVR format only\n\ - -o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex\n\ - -t --totals Display the total sizes (Berkeley only)\n\ - --common Display total size for *COM* syms\n\ -@@ -88,11 +329,7 @@ usage (FILE *stream, int status) - -h --help Display this information\n\ - -v --version Display the program's version\n\ - \n"), --#if BSD_DEFAULT -- "berkeley" --#else -- "sysv" --#endif -+FORMAT_NAME - ); - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && status == 0) -@@ -103,6 +351,7 @@ usage (FILE *stream, int status) - #define OPTION_FORMAT (200) - #define OPTION_RADIX (OPTION_FORMAT + 1) - #define OPTION_TARGET (OPTION_RADIX + 1) -+#define OPTION_MCU (OPTION_TARGET + 1) - - static struct option long_options[] = - { -@@ -110,6 +360,7 @@ static struct option long_options[] = - {"format", required_argument, 0, OPTION_FORMAT}, - {"radix", required_argument, 0, OPTION_RADIX}, - {"target", required_argument, 0, OPTION_TARGET}, -+ {"mcu", required_argument, 0, 203}, - {"totals", no_argument, &show_totals, 1}, - {"version", no_argument, &show_version, 1}, - {"help", no_argument, &show_help, 1}, -@@ -141,7 +391,7 @@ main (int argc, char **argv) - bfd_init (); - set_default_bfd_target (); - -- while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options, -+ while ((c = getopt_long (argc, argv, "ABCHhVvdfotx", long_options, - (int *) 0)) != EOF) - switch (c) - { -@@ -150,11 +401,15 @@ main (int argc, char **argv) - { - case 'B': - case 'b': -- berkeley_format = 1; -+ format = format_bsd; - break; - case 'S': - case 's': -- berkeley_format = 0; -+ format = format_sysv; -+ break; -+ case 'A': -+ case 'a': -+ format = format_avr; - break; - default: - non_fatal (_("invalid argument to --format: %s"), optarg); -@@ -162,6 +416,10 @@ main (int argc, char **argv) - } - break; - -+ case OPTION_MCU: -+ avrmcu = optarg; -+ break; -+ - case OPTION_TARGET: - target = optarg; - break; -@@ -190,11 +449,14 @@ main (int argc, char **argv) - break; - - case 'A': -- berkeley_format = 0; -+ format = format_sysv; - break; - case 'B': -- berkeley_format = 1; -+ format = format_bsd; - break; -+ case 'C': -+ format = format_avr; -+ break; - case 'v': - case 'V': - show_version = 1; -@@ -240,7 +501,7 @@ main (int argc, char **argv) - for (; optind < argc;) - display_file (argv[optind++]); - -- if (show_totals && berkeley_format) -+ if (show_totals && format == format_bsd) - { - bfd_size_type total = total_textsize + total_datasize + total_bsssize; - -@@ -599,13 +861,117 @@ print_sysv_format (bfd *file) - printf ("\n\n"); - } - -+ -+static avr_device_t * -+avr_find_device (void) -+{ -+ unsigned int i; -+ if (avrmcu != NULL) -+ { -+ for (i = 0; i < sizeof(avr) / sizeof(avr[0]); i++) -+ { -+ if (strcmp(avr[i].name, avrmcu) == 0) -+ { -+ /* Match found */ -+ return (&avr[i]); -+ } -+ } -+ } -+ return (NULL); -+} -+ -+ -+ -+static void -+print_avr_format (bfd *file) -+{ -+ char *avr_name = "Unknown"; -+ int flashmax = 0; -+ int rammax = 0; -+ int eeprommax = 0; -+ asection *section; -+ bfd_size_type datasize = 0; -+ bfd_size_type textsize = 0; -+ bfd_size_type bsssize = 0; -+ bfd_size_type bootloadersize = 0; -+ bfd_size_type noinitsize = 0; -+ bfd_size_type eepromsize = 0; -+ -+ avr_device_t *avrdevice = avr_find_device(); -+ if (avrdevice != NULL) -+ { -+ avr_name = avrdevice->name; -+ flashmax = avrdevice->flash; -+ rammax = avrdevice->ram; -+ eeprommax = avrdevice->eeprom; -+ } -+ -+ if ((section = bfd_get_section_by_name (file, ".data")) != NULL) -+ datasize = bfd_section_size (file, section); -+ if ((section = bfd_get_section_by_name (file, ".text")) != NULL) -+ textsize = bfd_section_size (file, section); -+ if ((section = bfd_get_section_by_name (file, ".bss")) != NULL) -+ bsssize = bfd_section_size (file, section); -+ if ((section = bfd_get_section_by_name (file, ".bootloader")) != NULL) -+ bootloadersize = bfd_section_size (file, section); -+ if ((section = bfd_get_section_by_name (file, ".noinit")) != NULL) -+ noinitsize = bfd_section_size (file, section); -+ if ((section = bfd_get_section_by_name (file, ".eeprom")) != NULL) -+ eepromsize = bfd_section_size (file, section); -+ -+ bfd_size_type text = textsize + datasize + bootloadersize; -+ bfd_size_type data = datasize + bsssize + noinitsize; -+ bfd_size_type eeprom = eepromsize; -+ -+ printf ("AVR Memory Usage\n" -+ "----------------\n" -+ "Device: %s\n\n", avr_name); -+ -+ /* Text size */ -+ printf ("Program:%8ld bytes", text); -+ if (flashmax > 0) -+ { -+ printf (" (%2.1f%% Full)", ((float)text / flashmax) * 100); -+ } -+ printf ("\n(.text + .data + .bootloader)\n\n"); -+ -+ /* Data size */ -+ printf ("Data: %8ld bytes", data); -+ if (rammax > 0) -+ { -+ printf (" (%2.1f%% Full)", ((float)data / rammax) * 100); -+ } -+ printf ("\n(.data + .bss + .noinit)\n\n"); -+ -+ /* EEPROM size */ -+ if (eeprom > 0) -+ { -+ printf ("EEPROM: %8ld bytes", eeprom); -+ if (eeprommax > 0) -+ { -+ printf (" (%2.1f%% Full)", ((float)eeprom / eeprommax) * 100); -+ } -+ printf ("\n(.eeprom)\n\n"); -+ } -+} -+ -+ - static void - print_sizes (bfd *file) - { - if (show_common) - calculate_common_size (file); -- if (berkeley_format) -- print_berkeley_format (file); -- else -- print_sysv_format (file); -+ switch (format) -+ { -+ case format_sysv: -+ print_sysv_format (file); -+ break; -+ case format_bsd: -+ print_berkeley_format (file); -+ break; -+ case format_avr: -+ default: -+ print_avr_format (file); -+ break; -+ } - } diff --git a/devel/avr-binutils/files/patch-coff-avr b/devel/avr-binutils/files/patch-coff-avr deleted file mode 100644 index c8c97f20b35d..000000000000 --- a/devel/avr-binutils/files/patch-coff-avr +++ /dev/null @@ -1,5505 +0,0 @@ -diff -Nruw bfd/Makefile.am bfd/Makefile.am ---- bfd/Makefile.am 2009-10-16 17:17:44.000000000 +0530 -+++ bfd/Makefile.am 2010-02-11 10:59:11.320193800 +0530 -@@ -228,6 +228,8 @@ - coff-apollo.lo \ - coff-arm.lo \ - coff-aux.lo \ -+ coff-avr.lo \ -+ coff-ext-avr.lo \ - coff-go32.lo \ - coff-h8300.lo \ - coff-h8500.lo \ -@@ -411,6 +413,8 @@ - coff-apollo.c \ - coff-arm.c \ - coff-aux.c \ -+ coff-avr.c \ -+ coff-ext-avr.c \ - coff-go32.c \ - coff-h8300.c \ - coff-h8500.c \ -diff -Nruw bfd/Makefile.in bfd/Makefile.in ---- bfd/Makefile.in 2009-10-16 17:17:48.000000000 +0530 -+++ bfd/Makefile.in 2010-02-11 11:13:52.698455300 +0530 -@@ -524,6 +524,8 @@ - coff-apollo.lo \ - coff-arm.lo \ - coff-aux.lo \ -+ coff-avr.lo \ -+ coff-ext-avr.lo \ - coff-go32.lo \ - coff-h8300.lo \ - coff-h8500.lo \ -@@ -707,6 +709,8 @@ - coff-apollo.c \ - coff-arm.c \ - coff-aux.c \ -+ coff-avr.c \ -+ coff-ext-avr.c \ - coff-go32.c \ - coff-h8300.c \ - coff-h8500.c \ -diff -Nruw bfd/coff-avr.c bfd/coff-avr.c ---- bfd/coff-avr.c 1970-01-01 05:30:00.000000000 +0530 -+++ bfd/coff-avr.c 2010-02-10 17:35:58.222099600 +0530 -@@ -0,0 +1,613 @@ -+/* BFD back-end for Atmel AVR COFF files. -+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 -+ Free Software Foundation, Inc. -+ Created mostly by substituting "avr" for "i860" in coff-i860.c -+ -+This file is part of BFD, the Binary File Descriptor library. -+ -+This program is free software; you can redistribute it and/or modify -+it under the terms of the GNU General Public License as published by -+the Free Software Foundation; either version 2 of the License, or -+(at your option) any later version. -+ -+This program is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+You should have received a copy of the GNU General Public License -+along with this program; if not, write to the Free Software -+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#include "bfd.h" -+#include "sysdep.h" -+#include "libbfd.h" -+ -+#include "coff/avr.h" -+ -+#include "coff/internal.h" -+ -+#include "libcoff.h" -+ -+static bfd_reloc_status_type coff_avr_reloc -+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -+static reloc_howto_type *coff_avr_rtype_to_howto -+ PARAMS ((bfd *, asection *, struct internal_reloc *, -+ struct coff_link_hash_entry *, struct internal_syment *, -+ bfd_vma *)); -+static const bfd_target * coff_avr_object_p PARAMS ((bfd *)); -+ -+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -+/* The page size is a guess based on ELF. */ -+ -+#define COFF_PAGE_SIZE 0x1000 -+ -+/* For some reason when using avr COFF the value stored in the .text -+ section for a reference to a common symbol is the value itself plus -+ any desired offset. Ian Taylor, Cygnus Support. */ -+ -+/* If we are producing relocateable output, we need to do some -+ adjustments to the object file that are not done by the -+ bfd_perform_relocation function. This function is called by every -+ reloc type to make any required adjustments. */ -+ -+static bfd_reloc_status_type -+coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, -+ error_message) -+ bfd *abfd; -+ arelent *reloc_entry; -+ asymbol *symbol; -+ PTR data; -+ asection *input_section ATTRIBUTE_UNUSED; -+ bfd *output_bfd; -+ char **error_message ATTRIBUTE_UNUSED; -+{ -+ symvalue diff; -+ -+ if (output_bfd == (bfd *) NULL) -+ return bfd_reloc_continue; -+ -+ if (bfd_is_com_section (symbol->section)) -+ { -+ /* We are relocating a common symbol. The current value in the -+ object file is ORIG + OFFSET, where ORIG is the value of the -+ common symbol as seen by the object file when it was compiled -+ (this may be zero if the symbol was undefined) and OFFSET is -+ the offset into the common symbol (normally zero, but may be -+ non-zero when referring to a field in a common structure). -+ ORIG is the negative of reloc_entry->addend, which is set by -+ the CALC_ADDEND macro below. We want to replace the value in -+ the object file with NEW + OFFSET, where NEW is the value of -+ the common symbol which we are going to put in the final -+ object file. NEW is symbol->value. */ -+ diff = symbol->value + reloc_entry->addend; -+ } -+ else -+ { -+ /* For some reason bfd_perform_relocation always effectively -+ ignores the addend for a COFF target when producing -+ relocateable output. This seems to be always wrong for 860 -+ COFF, so we handle the addend here instead. */ -+ diff = reloc_entry->addend; -+ } -+ -+#define DOIT(x) \ -+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) -+ -+ if (diff != 0) -+ { -+ reloc_howto_type *howto = reloc_entry->howto; -+ unsigned char *addr = (unsigned char *) data + reloc_entry->address; -+ -+ switch (howto->size) -+ { -+ case 0: -+ { -+ char x = bfd_get_8 (abfd, addr); -+ DOIT (x); -+ bfd_put_8 (abfd, x, addr); -+ } -+ break; -+ -+ case 1: -+ { -+ short x = bfd_get_16 (abfd, addr); -+ DOIT (x); -+ bfd_put_16 (abfd, (bfd_vma) x, addr); -+ } -+ break; -+ -+ case 2: -+ { -+ long x = bfd_get_32 (abfd, addr); -+ DOIT (x); -+ bfd_put_32 (abfd, (bfd_vma) x, addr); -+ } -+ break; -+ -+ default: -+ abort (); -+ } -+ } -+ -+ /* Now let bfd_perform_relocation finish everything up. */ -+ return bfd_reloc_continue; -+} -+ -+#ifndef PCRELOFFSET -+#define PCRELOFFSET FALSE -+#endif -+ -+static reloc_howto_type howto_table[] = -+{ -+ EMPTY_HOWTO (0), -+ EMPTY_HOWTO (1), -+ EMPTY_HOWTO (2), -+ EMPTY_HOWTO (3), -+ EMPTY_HOWTO (4), -+ EMPTY_HOWTO (5), -+ HOWTO (R_DIR32, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "dir32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ TRUE), /* pcrel_offset */ -+ /* {7}, */ -+ HOWTO (R_IMAGEBASE, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "rva32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ EMPTY_HOWTO (010), -+ EMPTY_HOWTO (011), -+ EMPTY_HOWTO (012), -+ EMPTY_HOWTO (013), -+ EMPTY_HOWTO (014), -+ EMPTY_HOWTO (015), -+ EMPTY_HOWTO (016), -+ HOWTO (R_RELBYTE, /* type */ -+ 0, /* rightshift */ -+ 0, /* size (0 = byte, 1 = short, 2 = long) */ -+ 8, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "8", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x000000ff, /* src_mask */ -+ 0x000000ff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_RELWORD, /* type */ -+ 0, /* rightshift */ -+ 1, /* size (0 = byte, 1 = short, 2 = long) */ -+ 16, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "16", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x0000ffff, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_RELLONG, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRBYTE, /* type */ -+ 0, /* rightshift */ -+ 0, /* size (0 = byte, 1 = short, 2 = long) */ -+ 8, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "DISP8", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x000000ff, /* src_mask */ -+ 0x000000ff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRWORD, /* type */ -+ 0, /* rightshift */ -+ 1, /* size (0 = byte, 1 = short, 2 = long) */ -+ 16, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "DISP16", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x0000ffff, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRLONG, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_avr_reloc, /* special_function */ -+ "DISP32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ PCRELOFFSET) /* pcrel_offset */ -+}; -+ -+/* Turn a howto into a reloc nunmber */ -+ -+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -+#define BADMAG(x) AVRBADMAG(x) -+#define AVR 1 /* Customize coffcode.h */ -+ -+#define RTYPE2HOWTO(cache_ptr, dst) \ -+ (cache_ptr)->howto = howto_table + (dst)->r_type; -+ -+/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared -+ library. On some other COFF targets STYP_BSS is normally -+ STYP_NOLOAD. */ -+#define BSS_NOLOAD_IS_SHARED_LIBRARY -+ -+/* Compute the addend of a reloc. If the reloc is to a common symbol, -+ the object file contains the value of the common symbol. By the -+ time this is called, the linker may be using a different symbol -+ from a different object file with a different value. Therefore, we -+ hack wildly to locate the original symbol from this file so that we -+ can make the correct adjustment. This macro sets coffsym to the -+ symbol from the original file, and uses it to set the addend value -+ correctly. If this is not a common symbol, the usual addend -+ calculation is done, except that an additional tweak is needed for -+ PC relative relocs. -+ FIXME: This macro refers to symbols and asect; these are from the -+ calling function, not the macro arguments. */ -+ -+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ -+ { \ -+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ -+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ -+ coffsym = (obj_symbols (abfd) \ -+ + (cache_ptr->sym_ptr_ptr - symbols)); \ -+ else if (ptr) \ -+ coffsym = coff_symbol_from (abfd, ptr); \ -+ if (coffsym != (coff_symbol_type *) NULL \ -+ && coffsym->native->u.syment.n_scnum == 0) \ -+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ -+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ -+ && ptr->section != (asection *) NULL) \ -+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \ -+ else \ -+ cache_ptr->addend = 0; \ -+ if (ptr && howto_table[reloc.r_type].pc_relative) \ -+ cache_ptr->addend += asect->vma; \ -+ } -+ -+/* We use the special COFF backend linker. */ -+#define coff_relocate_section _bfd_coff_generic_relocate_section -+ -+static reloc_howto_type * -+coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) -+ bfd *abfd ATTRIBUTE_UNUSED; -+ asection *sec; -+ struct internal_reloc *rel; -+ struct coff_link_hash_entry *h; -+ struct internal_syment *sym; -+ bfd_vma *addendp; -+{ -+ -+ reloc_howto_type *howto; -+ -+ howto = howto_table + rel->r_type; -+ -+ if (howto->pc_relative) -+ *addendp += sec->vma; -+ -+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) -+ { -+ /* This is a common symbol. The section contents include the -+ size (sym->n_value) as an addend. The relocate_section -+ function will be adding in the final value of the symbol. We -+ need to subtract out the current size in order to get the -+ correct result. */ -+ -+ BFD_ASSERT (h != NULL); -+ -+ /* I think we *do* want to bypass this. If we don't, I have seen some data -+ parameters get the wrong relcation address. If I link two versions -+ with and without this section bypassed and then do a binary comparison, -+ the addresses which are different can be looked up in the map. The -+ case in which this section has been bypassed has addresses which correspond -+ to values I can find in the map. */ -+ *addendp -= sym->n_value; -+ } -+ -+ /* If the output symbol is common (in which case this must be a -+ relocateable link), we need to add in the final size of the -+ common symbol. */ -+ if (h != NULL && h->root.type == bfd_link_hash_common) -+ *addendp += h->root.u.c.size; -+ -+ return howto; -+} -+ -+#define coff_rtype_to_howto coff_avr_rtype_to_howto -+ -+#ifndef bfd_pe_print_pdata -+#define bfd_pe_print_pdata NULL -+#endif -+ -+#include "coffcode.h" -+ -+static const bfd_target * -+coff_avr_object_p(a) -+ bfd *a; -+{ -+ return coff_object_p (a); -+} -+ -+/* Handle all the abominations of AVR COFF: -+ -+ Generic COFF always uses the D1 slot to indicate the "most -+ important" derived type, and the D2...Dn slots for decreasing -+ importance. E. g., a function symbol will always have its DT_FCN -+ element in D1, an array its DT_ARY (its first DT_ARY in a -+ multi-dimensional array). In contrast, AVR COFF expects this most -+ important derived type specifier in the upmost Dn slot that is -+ allocated at all (i. e. that is != 0). -+ -+ Generic COFF says that "Any symbol that satisfies more than one -+ condition [... for AUX entries] should have a union format in its -+ auxiliary entry." AVR COFF uses sepearate AUX entries for multiple -+ derived types, and in some cases (like the ISFCN one), even puts -+ the most important one into the last allocated AUX entry. We -+ join/split them here at the border as well. Note that when -+ generating AUX entries (where we need to split them), the n_numaux -+ field must already have been set up properly (e. g. in -+ binutils/wrcoff.c) since the entry renumbering and pointerization -+ would not work otherwise. Thus, we only split the information into -+ multiple records if n_numaux > 1. For similar reasons, we keep -+ n_numaux > 1 on input to keep the appropriate AUX entries -+ allocated, so a symbol can be reconstructed if it is being passed -+ through one of the GNU tools. -+ -+ Note that this adjustment is called after the symbol itself has -+ been swapped in, but before the AUX entries are swapped in. This -+ is the only hook available that could swap (or merge) AUX entries -+ at all, so we have to operate on the external AUX entries still. */ -+ -+void -+avr_coff_adjust_sym_in_post (abfd, ext, in) -+ bfd *abfd; -+ PTR ext; -+ PTR in; -+{ -+ struct internal_syment *dst = (struct internal_syment *)in; -+ unsigned short dt, bt, ndt; -+ dt = dst->n_type & ~N_BTMASK; -+ bt = BTYPE (dst->n_type); -+ -+ /* Some AVR COFF producers seem to violate the COFF specs, and -+ produce symbols for tag names that have the C_FOO filled in -+ properly, but T_NULL as the base type value. Patch up here, -+ since some of our generic COFF tools (in particular -+ binutils/rdcoff.c) rely on the correct data. */ -+ if (bt == T_NULL) -+ switch (dst->n_sclass) -+ { -+ case C_STRTAG: -+ bt = T_STRUCT; -+ break; -+ -+ case C_UNTAG: -+ bt = T_UNION; -+ break; -+ -+ case C_ENTAG: -+ bt = T_ENUM; -+ break; -+ } -+ -+ /* Swap the derived type slots. */ -+ if (dt != 0) -+ { -+ ndt = 0; -+ while (dt != 0) -+ { -+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); -+ dt >>= N_TSHIFT; -+ } -+ dst->n_type = (ndt << N_BTSHFT) | bt; -+ } -+ else -+ dst->n_type = bt; -+ -+ /* If the derived type is function, and there is more than one AUX -+ entry, swap the first and the last AUX entry, so the most -+ interesting one will become the first. -+ -+ If the fundamental type is a tagged type (struct/union/enum), try -+ to find the AUX entry describing the tagged type (the one that -+ has x_sym.x_tagndx filled in), and merge the tag index into the -+ first AUX entry. Depending on the actual input file, there might -+ be further DT_PTR entries which we just ignore, since we could -+ not handle that information anyway. */ -+ if (dst->n_numaux > 1 && dst->n_sclass != C_FILE) -+ { -+ AUXENT caux, *auxp1, *auxp2; -+ size_t symesz; -+ unsigned int i; -+ -+ symesz = bfd_coff_symesz (abfd); -+ i = dst->n_numaux; -+ -+ auxp1 = (AUXENT *)((char *)ext + symesz); -+ auxp2 = (AUXENT *)((char *)ext + i * symesz); -+ -+ if (ISFCN (dst->n_type) -+ || (ISPTR(dst->n_type) -+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))) -+ { -+ caux = *auxp2; -+ *auxp2 = *auxp1; -+ *auxp1 = caux; -+ } -+ else -+ caux = *auxp1; -+ -+ if ((ISFCN (dst->n_type) || ISARY (dst->n_type)) -+ && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)) -+ { -+ while (i > 1) -+ { -+ auxp2 = (AUXENT *)((char *)ext + i * symesz); -+ -+ if (auxp2->x_sym.x_tagndx[0] != 0 || auxp2->x_sym.x_tagndx[1] != 0 -+ || auxp2->x_sym.x_tagndx[2] != 0 || auxp2->x_sym.x_tagndx[3] != 0) -+ { -+ memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx, -+ 4 * sizeof (char)); -+ break; -+ } -+ i--; -+ } -+ if (i > 1) -+ *auxp1 = caux; -+ } -+ } -+} -+ -+/* When exporting an AVR COFF file, just undo all that has been done -+ above. Again, we are called after the symbol itself has been -+ swapped out, but before the AUX entries are being written. -+ Unfortunately, we are only given a pointer to the symbol itself, so -+ we have to derive the pointer to the respective aux entries from -+ that address, which is a bit clumsy. */ -+void -+avr_coff_adjust_sym_out_post (abfd, in, ext) -+ bfd *abfd; -+ PTR in; -+ PTR ext; -+{ -+ struct internal_syment *src = (struct internal_syment *)(in); -+ struct external_syment *dst = (struct external_syment *)(ext); -+ unsigned short dt, bt, ndt; -+ -+ dt = src->n_type & ~N_BTMASK; -+ bt = BTYPE (src->n_type); -+ -+ if (dt != 0) -+ { -+ ndt = 0; -+ while (dt != 0) -+ { -+ ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); -+ dt >>= N_TSHIFT; -+ } -+ H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type); -+ } -+ -+ if (src->n_numaux > 1 && src->n_sclass != C_FILE) -+ { -+ combined_entry_type *srce, *dste; -+ char *hackp; -+ unsigned int i; -+ -+ /* Recover the original combinend_entry_type *. */ -+ hackp = (char *)in; -+ hackp -= offsetof(combined_entry_type, u.syment); -+ srce = (combined_entry_type *)hackp; -+ srce++; -+ -+ /* We simply duplicate the first AUX entry as many times as -+ needed. Since COFF itself normally uses just a single AUX -+ entry for all the information, this will work -- each COFF -+ consumer will then just pick the fields it is particularly -+ interested in. This would not work for the AVR COFF specific -+ DT_PTR AUX entries, but we don't support them anyway. */ -+ for (i = 1; i < src->n_numaux; i++) -+ { -+ dste = srce + i; -+ *dste = *srce; -+ } -+ } -+} -+ -+const bfd_target -+#ifdef TARGET_SYM -+ TARGET_SYM = -+#else -+ avrcoff_vec = -+#endif -+{ -+#ifdef TARGET_NAME -+ TARGET_NAME, -+#else -+ "coff-avr", /* name */ -+#endif -+ bfd_target_coff_flavour, -+ BFD_ENDIAN_LITTLE, /* data byte order is little */ -+ BFD_ENDIAN_LITTLE, /* header byte order is little */ -+ -+ (HAS_RELOC | EXEC_P | /* object flags */ -+ HAS_LINENO | HAS_DEBUG | -+ HAS_SYMS | HAS_LOCALS | WP_TEXT), -+ -+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -+ 0, /* leading char */ -+ '/', /* ar_pad_char */ -+ 15, /* ar_max_namelen */ -+ -+ bfd_getl64, bfd_getl_signed_64, bfd_putl64, -+ bfd_getl32, bfd_getl_signed_32, bfd_putl32, -+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ -+ bfd_getl64, bfd_getl_signed_64, bfd_putl64, -+ bfd_getl32, bfd_getl_signed_32, bfd_putl32, -+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ -+ -+/* Note that we allow an object file to be treated as a core file as well. */ -+ {_bfd_dummy_target, coff_avr_object_p, /* bfd_check_format */ -+ bfd_generic_archive_p, coff_avr_object_p}, -+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ -+ bfd_false}, -+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */ -+ _bfd_write_archive_contents, bfd_false}, -+ -+ BFD_JUMP_TABLE_GENERIC (coff), -+ BFD_JUMP_TABLE_COPY (coff), -+ BFD_JUMP_TABLE_CORE (_bfd_nocore), -+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), -+ BFD_JUMP_TABLE_SYMBOLS (coff), -+ BFD_JUMP_TABLE_RELOCS (coff), -+ BFD_JUMP_TABLE_WRITE (coff), -+ BFD_JUMP_TABLE_LINK (coff), -+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), -+ -+ NULL, -+ -+ COFF_SWAP_TABLE -+}; -diff -Nruw bfd/coff-ext-avr.c bfd/coff-ext-avr.c ---- bfd/coff-ext-avr.c 1970-01-01 05:30:00.000000000 +0530 -+++ bfd/coff-ext-avr.c 2010-02-10 17:35:58.222099600 +0530 -@@ -0,0 +1,428 @@ -+/* BFD back-end for Atmel AVR "extended" COFF files. -+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 -+ Free Software Foundation, Inc. -+ This is mostly the same as avr-coff, except of the presence of the -+ COFF optional header. -+ -+This file is part of BFD, the Binary File Descriptor library. -+ -+This program is free software; you can redistribute it and/or modify -+it under the terms of the GNU General Public License as published by -+the Free Software Foundation; either version 2 of the License, or -+(at your option) any later version. -+ -+This program is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+You should have received a copy of the GNU General Public License -+along with this program; if not, write to the Free Software -+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#include "bfd.h" -+#include "sysdep.h" -+#include "libbfd.h" -+ -+#define AVR_EXT_COFF 1 -+#include "coff/avr.h" -+ -+#include "coff/internal.h" -+ -+#include "libcoff.h" -+ -+static bfd_reloc_status_type coff_ext_avr_reloc -+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -+static reloc_howto_type *coff_ext_avr_rtype_to_howto -+ PARAMS ((bfd *, asection *, struct internal_reloc *, -+ struct coff_link_hash_entry *, struct internal_syment *, -+ bfd_vma *)); -+static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *)); -+ -+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -+/* The page size is a guess based on ELF. */ -+ -+#define COFF_PAGE_SIZE 0x1000 -+ -+/* For some reason when using avr COFF the value stored in the .text -+ section for a reference to a common symbol is the value itself plus -+ any desired offset. Ian Taylor, Cygnus Support. */ -+ -+/* If we are producing relocateable output, we need to do some -+ adjustments to the object file that are not done by the -+ bfd_perform_relocation function. This function is called by every -+ reloc type to make any required adjustments. */ -+ -+static bfd_reloc_status_type -+coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, -+ error_message) -+ bfd *abfd; -+ arelent *reloc_entry; -+ asymbol *symbol; -+ PTR data; -+ asection *input_section ATTRIBUTE_UNUSED; -+ bfd *output_bfd; -+ char **error_message ATTRIBUTE_UNUSED; -+{ -+ symvalue diff; -+ -+ if (output_bfd == (bfd *) NULL) -+ return bfd_reloc_continue; -+ -+ if (bfd_is_com_section (symbol->section)) -+ { -+ /* We are relocating a common symbol. The current value in the -+ object file is ORIG + OFFSET, where ORIG is the value of the -+ common symbol as seen by the object file when it was compiled -+ (this may be zero if the symbol was undefined) and OFFSET is -+ the offset into the common symbol (normally zero, but may be -+ non-zero when referring to a field in a common structure). -+ ORIG is the negative of reloc_entry->addend, which is set by -+ the CALC_ADDEND macro below. We want to replace the value in -+ the object file with NEW + OFFSET, where NEW is the value of -+ the common symbol which we are going to put in the final -+ object file. NEW is symbol->value. */ -+ diff = symbol->value + reloc_entry->addend; -+ } -+ else -+ { -+ /* For some reason bfd_perform_relocation always effectively -+ ignores the addend for a COFF target when producing -+ relocateable output. This seems to be always wrong for 860 -+ COFF, so we handle the addend here instead. */ -+ diff = reloc_entry->addend; -+ } -+ -+#define DOIT(x) \ -+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) -+ -+ if (diff != 0) -+ { -+ reloc_howto_type *howto = reloc_entry->howto; -+ unsigned char *addr = (unsigned char *) data + reloc_entry->address; -+ -+ switch (howto->size) -+ { -+ case 0: -+ { -+ char x = bfd_get_8 (abfd, addr); -+ DOIT (x); -+ bfd_put_8 (abfd, x, addr); -+ } -+ break; -+ -+ case 1: -+ { -+ short x = bfd_get_16 (abfd, addr); -+ DOIT (x); -+ bfd_put_16 (abfd, (bfd_vma) x, addr); -+ } -+ break; -+ -+ case 2: -+ { -+ long x = bfd_get_32 (abfd, addr); -+ DOIT (x); -+ bfd_put_32 (abfd, (bfd_vma) x, addr); -+ } -+ break; -+ -+ default: -+ abort (); -+ } -+ } -+ -+ /* Now let bfd_perform_relocation finish everything up. */ -+ return bfd_reloc_continue; -+} -+ -+#ifndef PCRELOFFSET -+#define PCRELOFFSET FALSE -+#endif -+ -+static reloc_howto_type howto_table[] = -+{ -+ EMPTY_HOWTO (0), -+ EMPTY_HOWTO (1), -+ EMPTY_HOWTO (2), -+ EMPTY_HOWTO (3), -+ EMPTY_HOWTO (4), -+ EMPTY_HOWTO (5), -+ HOWTO (R_DIR32, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "dir32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ TRUE), /* pcrel_offset */ -+ /* {7}, */ -+ HOWTO (R_IMAGEBASE, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "rva32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ FALSE), /* pcrel_offset */ -+ EMPTY_HOWTO (010), -+ EMPTY_HOWTO (011), -+ EMPTY_HOWTO (012), -+ EMPTY_HOWTO (013), -+ EMPTY_HOWTO (014), -+ EMPTY_HOWTO (015), -+ EMPTY_HOWTO (016), -+ HOWTO (R_RELBYTE, /* type */ -+ 0, /* rightshift */ -+ 0, /* size (0 = byte, 1 = short, 2 = long) */ -+ 8, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "8", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x000000ff, /* src_mask */ -+ 0x000000ff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_RELWORD, /* type */ -+ 0, /* rightshift */ -+ 1, /* size (0 = byte, 1 = short, 2 = long) */ -+ 16, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "16", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x0000ffff, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_RELLONG, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ FALSE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_bitfield, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRBYTE, /* type */ -+ 0, /* rightshift */ -+ 0, /* size (0 = byte, 1 = short, 2 = long) */ -+ 8, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "DISP8", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x000000ff, /* src_mask */ -+ 0x000000ff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRWORD, /* type */ -+ 0, /* rightshift */ -+ 1, /* size (0 = byte, 1 = short, 2 = long) */ -+ 16, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "DISP16", /* name */ -+ TRUE, /* partial_inplace */ -+ 0x0000ffff, /* src_mask */ -+ 0x0000ffff, /* dst_mask */ -+ PCRELOFFSET), /* pcrel_offset */ -+ HOWTO (R_PCRLONG, /* type */ -+ 0, /* rightshift */ -+ 2, /* size (0 = byte, 1 = short, 2 = long) */ -+ 32, /* bitsize */ -+ TRUE, /* pc_relative */ -+ 0, /* bitpos */ -+ complain_overflow_signed, /* complain_on_overflow */ -+ coff_ext_avr_reloc, /* special_function */ -+ "DISP32", /* name */ -+ TRUE, /* partial_inplace */ -+ 0xffffffff, /* src_mask */ -+ 0xffffffff, /* dst_mask */ -+ PCRELOFFSET) /* pcrel_offset */ -+}; -+ -+/* Turn a howto into a reloc nunmber */ -+ -+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -+#define BADMAG(x) AVRBADMAG(x) -+#define AVR 1 /* Customize coffcode.h */ -+ -+#define RTYPE2HOWTO(cache_ptr, dst) \ -+ (cache_ptr)->howto = howto_table + (dst)->r_type; -+ -+/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared -+ library. On some other COFF targets STYP_BSS is normally -+ STYP_NOLOAD. */ -+#define BSS_NOLOAD_IS_SHARED_LIBRARY -+ -+/* Compute the addend of a reloc. If the reloc is to a common symbol, -+ the object file contains the value of the common symbol. By the -+ time this is called, the linker may be using a different symbol -+ from a different object file with a different value. Therefore, we -+ hack wildly to locate the original symbol from this file so that we -+ can make the correct adjustment. This macro sets coffsym to the -+ symbol from the original file, and uses it to set the addend value -+ correctly. If this is not a common symbol, the usual addend -+ calculation is done, except that an additional tweak is needed for -+ PC relative relocs. -+ FIXME: This macro refers to symbols and asect; these are from the -+ calling function, not the macro arguments. */ -+ -+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ -+ { \ -+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ -+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ -+ coffsym = (obj_symbols (abfd) \ -+ + (cache_ptr->sym_ptr_ptr - symbols)); \ -+ else if (ptr) \ -+ coffsym = coff_symbol_from (abfd, ptr); \ -+ if (coffsym != (coff_symbol_type *) NULL \ -+ && coffsym->native->u.syment.n_scnum == 0) \ -+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \ -+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ -+ && ptr->section != (asection *) NULL) \ -+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \ -+ else \ -+ cache_ptr->addend = 0; \ -+ if (ptr && howto_table[reloc.r_type].pc_relative) \ -+ cache_ptr->addend += asect->vma; \ -+ } -+ -+/* We use the special COFF backend linker. */ -+#define coff_relocate_section _bfd_coff_generic_relocate_section -+ -+static reloc_howto_type * -+coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) -+ bfd *abfd ATTRIBUTE_UNUSED; -+ asection *sec; -+ struct internal_reloc *rel; -+ struct coff_link_hash_entry *h; -+ struct internal_syment *sym; -+ bfd_vma *addendp; -+{ -+ -+ reloc_howto_type *howto; -+ -+ howto = howto_table + rel->r_type; -+ -+ if (howto->pc_relative) -+ *addendp += sec->vma; -+ -+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) -+ { -+ /* This is a common symbol. The section contents include the -+ size (sym->n_value) as an addend. The relocate_section -+ function will be adding in the final value of the symbol. We -+ need to subtract out the current size in order to get the -+ correct result. */ -+ -+ BFD_ASSERT (h != NULL); -+ -+ /* I think we *do* want to bypass this. If we don't, I have seen some data -+ parameters get the wrong relcation address. If I link two versions -+ with and without this section bypassed and then do a binary comparison, -+ the addresses which are different can be looked up in the map. The -+ case in which this section has been bypassed has addresses which correspond -+ to values I can find in the map. */ -+ *addendp -= sym->n_value; -+ } -+ -+ /* If the output symbol is common (in which case this must be a -+ relocateable link), we need to add in the final size of the -+ common symbol. */ -+ if (h != NULL && h->root.type == bfd_link_hash_common) -+ *addendp += h->root.u.c.size; -+ -+ return howto; -+} -+ -+#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto -+ -+#ifndef bfd_pe_print_pdata -+#define bfd_pe_print_pdata NULL -+#endif -+ -+#include "coffcode.h" -+ -+static const bfd_target * -+coff_ext_avr_object_p(a) -+ bfd *a; -+{ -+ return coff_object_p (a); -+} -+ -+const bfd_target -+#ifdef TARGET_SYM -+ TARGET_SYM = -+#else -+ avrextcoff_vec = -+#endif -+{ -+#ifdef TARGET_NAME -+ TARGET_NAME, -+#else -+ "coff-ext-avr", /* name */ -+#endif -+ bfd_target_coff_flavour, -+ BFD_ENDIAN_LITTLE, /* data byte order is little */ -+ BFD_ENDIAN_LITTLE, /* header byte order is little */ -+ -+ (HAS_RELOC | EXEC_P | /* object flags */ -+ HAS_LINENO | HAS_DEBUG | -+ HAS_SYMS | HAS_LOCALS | WP_TEXT), -+ -+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -+ 0, /* leading char */ -+ '/', /* ar_pad_char */ -+ 15, /* ar_max_namelen */ -+ -+ bfd_getl64, bfd_getl_signed_64, bfd_putl64, -+ bfd_getl32, bfd_getl_signed_32, bfd_putl32, -+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ -+ bfd_getl64, bfd_getl_signed_64, bfd_putl64, -+ bfd_getl32, bfd_getl_signed_32, bfd_putl32, -+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ -+ -+/* Note that we allow an object file to be treated as a core file as well. */ -+ {_bfd_dummy_target, coff_ext_avr_object_p, /* bfd_check_format */ -+ bfd_generic_archive_p, coff_ext_avr_object_p}, -+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ -+ bfd_false}, -+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */ -+ _bfd_write_archive_contents, bfd_false}, -+ -+ BFD_JUMP_TABLE_GENERIC (coff), -+ BFD_JUMP_TABLE_COPY (coff), -+ BFD_JUMP_TABLE_CORE (_bfd_nocore), -+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), -+ BFD_JUMP_TABLE_SYMBOLS (coff), -+ BFD_JUMP_TABLE_RELOCS (coff), -+ BFD_JUMP_TABLE_WRITE (coff), -+ BFD_JUMP_TABLE_LINK (coff), -+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), -+ -+ NULL, -+ -+ COFF_SWAP_TABLE -+}; -diff -Nruw bfd/coffcode.h bfd/coffcode.h ---- bfd/coffcode.h 2009-09-10 17:17:12.000000000 +0530 -+++ bfd/coffcode.h 2010-02-10 17:35:58.253349600 +0530 -@@ -1,3 +1,4 @@ -+ - /* Support for the generic parts of most COFF variants, for BFD. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -@@ -1910,6 +1911,17 @@ - coff->relocbase = 0; - coff->local_toc_sym_map = 0; - -+ /* These members communicate important constants about the symbol -+ table to GDB's symbol-reading code. These `constants' -+ unfortunately vary among coff implementations... */ -+ coff->local_n_btmask = N_BTMASK; -+ coff->local_n_btshft = N_BTSHFT; -+ coff->local_n_tmask = N_TMASK; -+ coff->local_n_tshift = N_TSHIFT; -+ coff->local_symesz = bfd_coff_symesz (abfd); -+ coff->local_auxesz = bfd_coff_auxesz (abfd); -+ coff->local_linesz = bfd_coff_linesz (abfd); -+ - /* make_abs_section(abfd);*/ - - return TRUE; -@@ -1934,17 +1946,6 @@ - - coff->sym_filepos = internal_f->f_symptr; - -- /* These members communicate important constants about the symbol -- table to GDB's symbol-reading code. These `constants' -- unfortunately vary among coff implementations... */ -- coff->local_n_btmask = N_BTMASK; -- coff->local_n_btshft = N_BTSHFT; -- coff->local_n_tmask = N_TMASK; -- coff->local_n_tshift = N_TSHIFT; -- coff->local_symesz = bfd_coff_symesz (abfd); -- coff->local_auxesz = bfd_coff_auxesz (abfd); -- coff->local_linesz = bfd_coff_linesz (abfd); -- - coff->timestamp = internal_f->f_timdat; - - obj_raw_syment_count (abfd) = -@@ -2076,6 +2077,11 @@ - } - break; - #endif -+#ifdef AVRMAGIC -+ case AVRMAGIC: -+ arch = bfd_arch_avr; -+ break; -+#endif - #ifdef MC68MAGIC - case MC68MAGIC: - case M68MAGIC: -@@ -2871,6 +2877,13 @@ - return TRUE; - #endif - -+#ifdef AVRMAGIC -+ case bfd_arch_avr: -+ *magicp = AVRMAGIC; -+ return TRUE; -+ break; -+#endif -+ - #ifdef PPCMAGIC - case bfd_arch_powerpc: - *magicp = PPCMAGIC; -@@ -3698,6 +3711,11 @@ - section.s_page = 0; - #endif - -+#ifdef AVR -+ /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively -+ ignores s_vaddr. */ -+ section.s_paddr = current->vma; -+#endif - #ifdef COFF_WITH_PE - section.s_paddr = 0; - #endif -@@ -4042,6 +4060,17 @@ - internal_a.magic = ZMAGIC; - #endif - -+#ifdef AVR -+ /* a.out is a dummy for non-extended COFF */ -+ internal_a.magic = AVRAOUTMAGIC; -+ /* Upper nibble of f_flags must be set for historical reasons. -+ The upper byte remains blank on coff-avr, so undo the F_AR32WR -+ setting performed above. */ -+ internal_f.f_flags |= F_JUNK; -+ internal_f.f_flags &= ~F_UNUSED; -+#define __A_MAGIC_SET__ -+#endif /* AVR */ -+ - #if defined(PPC_PE) - #define __A_MAGIC_SET__ - internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; -@@ -4109,8 +4138,16 @@ - #endif - } - -+#ifdef AVR_EXT_COFF -+ /* Note that we do not set F_PTRINFO because the GNU toolchain -+ doesn't provide any information about the target of a pointer, -+ so we cannot derive which section our pointer target would be -+ in. */ -+ internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO; -+#else - /* FIXME: Does anybody ever set this to another value? */ - internal_a.vstamp = 0; -+#endif - - /* Now should write relocs, strings, syms. */ - obj_sym_filepos (abfd) = sym_base; -@@ -4668,6 +4705,10 @@ - /* In PE, 0x69 (105) denotes a weak external symbol. */ - case C_NT_WEAK: - #endif -+#ifdef AVR -+ /* Some AVR COFF compilers handle EXTDEF like EXT. */ -+ case C_EXTDEF: /* external definition */ -+#endif - switch (coff_classify_symbol (abfd, &src->u.syment)) - { - case COFF_SYMBOL_GLOBAL: -@@ -4891,7 +4932,9 @@ - && src->u.syment.n_scnum == 0) - break; - /* Fall through. */ -+#if !defined(AVR) - case C_EXTDEF: /* External definition. */ -+#endif - case C_ULABEL: /* Undefined label. */ - case C_USTATIC: /* Undefined static. */ - #ifndef COFF_WITH_PE -diff -Nruw bfd/coffgen.c bfd/coffgen.c ---- bfd/coffgen.c 2009-09-10 17:17:12.000000000 +0530 -+++ bfd/coffgen.c 2010-02-11 11:20:28.795092600 +0530 -@@ -699,6 +699,20 @@ - if (last_file != NULL) - last_file->n_value = native_index; - last_file = &(s->u.syment); -+ if (bfd_get_arch (bfd_ptr) == bfd_arch_avr -+ && bfd_coff_long_filenames (bfd_ptr) -+ && s->u.syment.n_numaux > 0) -+ { -+ /* AVR COFF records long filenames in successive aux -+ records. Adjust the number of aux records -+ required here, so the renumbering will account -+ for them. */ -+ unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr); -+ unsigned int namelen = strlen (coff_symbol_ptr->symbol.name); -+ unsigned int n = (namelen + filnmlen - 1) / filnmlen; -+ -+ s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n; -+ } - } - else - /* Modify the symbol values according to their section and -@@ -827,6 +841,20 @@ - { - if (name_length <= filnmlen) - strncpy (auxent->x_file.x_fname, name, filnmlen); -+ else if (bfd_get_arch (abfd) == bfd_arch_avr) -+ { -+ /* AVR COFF records long filenames in successive aux records. */ -+ int i = 1; -+ while (name_length > filnmlen && i < NAUXENTS) -+ { -+ strncpy (auxent->x_file.x_fname, name, filnmlen); -+ name += filnmlen; -+ name_length -= filnmlen; -+ i++; -+ auxent = &(native + i)->u.auxent; -+ } -+ strncpy (auxent->x_file.x_fname, name, filnmlen); -+ } - else - { - auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; -@@ -1272,6 +1300,10 @@ - if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) - return FALSE; - } -+ if (bfd_get_arch (abfd) == bfd_arch_avr) -+ /* AVR COFF handles long file names in aux records. */ -+ maxlen = name_length; -+ else - maxlen = bfd_coff_filnmlen (abfd); - } - else -@@ -1710,14 +1742,27 @@ - { - /* Ordinary short filename, put into memory anyway. The - Microsoft PE tools sometimes store a filename in -- multiple AUX entries. */ -+ multiple AUX entries. -+ AVR COFF does it that way, too. */ - if (internal_ptr->u.syment.n_numaux > 1 -- && coff_data (abfd)->pe) -- internal_ptr->u.syment._n._n_n._n_offset = -- ((bfd_hostptr_t) -- copy_name (abfd, -- (internal_ptr + 1)->u.auxent.x_file.x_fname, -- internal_ptr->u.syment.n_numaux * symesz)); -+ && (coff_data (abfd)->pe -+ || (bfd_get_arch (abfd) == bfd_arch_avr))) -+ { -+ char *b; -+ unsigned int i; -+ -+ /* We allocate enough storage to fit the contents of -+ this many aux records, and simply append a \0. -+ This ensures the string will always be -+ terminated, even in the case where it just fit -+ into the aux records. */ -+ b = (char *) bfd_alloc (abfd, -+ internal_ptr->u.syment.n_numaux * FILNMLEN + 1); -+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) b; -+ b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0'; -+ for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN) -+ memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN); -+ } - else - internal_ptr->u.syment._n._n_n._n_offset = - ((bfd_hostptr_t) -@@ -1823,9 +1868,9 @@ - - if (new_symbol == NULL) - return NULL; -- /* @@ The 10 is a guess at a plausible maximum number of aux entries -+ /* @@ The NAUXENTS is a guess at a plausible maximum number of aux entries - (but shouldn't be a constant). */ -- amt = sizeof (combined_entry_type) * 10; -+ amt = sizeof (combined_entry_type) * (NAUXENTS + 1); - new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt); - if (!new_symbol->native) - return NULL; -diff -Nruw bfd/coffswap.h bfd/coffswap.h ---- bfd/coffswap.h 2009-09-07 13:45:15.000000000 +0530 -+++ bfd/coffswap.h 2010-02-11 11:24:25.908936000 +0530 -@@ -383,7 +383,11 @@ - void * ext1, - int type, - int in_class, -- int indx, -+ int indx -+#if defined(AVR) && __GNUC__ -+ __attribute__((unused)) -+#endif -+ , - int numaux, - void * in1) - { -@@ -409,9 +413,13 @@ - #else - if (numaux > 1) - { -+#if defined(AVR) -+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT)); -+#else - if (indx == 0) - memcpy (in->x_file.x_fname, ext->x_file.x_fname, - numaux * sizeof (AUXENT)); -+#endif - } - else - memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); -diff -Nruw bfd/config.bfd bfd/config.bfd ---- bfd/config.bfd 2009-08-06 23:08:00.000000000 +0530 -+++ bfd/config.bfd 2010-02-10 17:35:58.300224600 +0530 -@@ -339,6 +339,7 @@ - - avr-*-*) - targ_defvec=bfd_elf32_avr_vec -+ targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec" - ;; - - bfin-*-*) -diff -Nruw bfd/configure bfd/configure ---- bfd/configure 2009-10-16 17:17:47.000000000 +0530 -+++ bfd/configure 2010-02-10 17:35:58.331474600 +0530 -@@ -14782,6 +14782,8 @@ - armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; - armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; - armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; -+ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; -+ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; - b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; - b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; - bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; -diff -Nruw bfd/configure.in bfd/configure.in ---- bfd/configure.in 2009-10-16 17:17:44.000000000 +0530 -+++ bfd/configure.in 2010-02-10 17:35:58.331474600 +0530 -@@ -670,6 +670,8 @@ - armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; - armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; - armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; -+ avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; -+ avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; - b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; - b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; - bfd_pei_ia64_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;; -diff -Nruw bfd/targets.c bfd/targets.c ---- bfd/targets.c 2009-09-10 17:17:13.000000000 +0530 -+++ bfd/targets.c 2010-02-10 17:35:58.347099600 +0530 -@@ -564,6 +564,8 @@ - extern const bfd_target armpe_little_vec; - extern const bfd_target armpei_big_vec; - extern const bfd_target armpei_little_vec; -+extern const bfd_target avrcoff_vec; -+extern const bfd_target avrextcoff_vec; - extern const bfd_target b_out_vec_big_host; - extern const bfd_target b_out_vec_little_host; - extern const bfd_target bfd_pei_ia64_vec; -@@ -890,6 +892,8 @@ - &armpe_little_vec, - &armpei_big_vec, - &armpei_little_vec, -+ &avrcoff_vec, -+ &avrextcoff_vec, - &b_out_vec_big_host, - &b_out_vec_little_host, - #ifdef BFD64 -diff -Nruw binutils/Makefile.am binutils/Makefile.am ---- binutils/Makefile.am 2009-09-09 13:43:23.000000000 +0530 -+++ binutils/Makefile.am 2010-02-10 17:35:57.972099600 +0530 -@@ -101,7 +101,7 @@ - resbin.c rescoff.c resrc.c resres.c \ - size.c srconv.c stabs.c strings.c sysdump.c \ - unwind-ia64.c version.c \ -- windres.c winduni.c wrstabs.c \ -+ windres.c winduni.c wrcoff.c wrstabs.c \ - windmc.c mclex.c - - GENERATED_CFILES = \ -@@ -109,7 +109,7 @@ - defparse.c deflex.c nlmheader.c rcparse.c mcparse.c - - DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c --WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c -+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c - - # Code shared by all the binutils. - BULIBS = bucomm.c version.c filemode.c -diff -Nruw binutils/Makefile.in binutils/Makefile.in ---- binutils/Makefile.in 2009-09-09 13:43:23.000000000 +0530 -+++ binutils/Makefile.in 2010-02-10 17:35:57.987724600 +0530 -@@ -126,7 +126,7 @@ - nm_new_OBJECTS = $(am_nm_new_OBJECTS) - nm_new_LDADD = $(LDADD) - am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \ -- ieee.$(OBJEXT) rdcoff.$(OBJEXT) -+ ieee.$(OBJEXT) rdcoff.$(OBJEXT) wrcoff.$(OBJEXT) - am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT) - am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \ - rename.$(OBJEXT) $(am__objects_3) $(am__objects_1) -@@ -439,7 +439,7 @@ - resbin.c rescoff.c resrc.c resres.c \ - size.c srconv.c stabs.c strings.c sysdump.c \ - unwind-ia64.c version.c \ -- windres.c winduni.c wrstabs.c \ -+ windres.c winduni.c wrcoff.c wrstabs.c \ - windmc.c mclex.c - - GENERATED_CFILES = \ -@@ -447,7 +447,7 @@ - defparse.c deflex.c nlmheader.c rcparse.c mcparse.c - - DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c --WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c -+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c - - # Code shared by all the binutils. - BULIBS = bucomm.c version.c filemode.c -diff -Nruw binutils/bucomm.c binutils/bucomm.c ---- binutils/bucomm.c 2009-09-14 17:13:26.000000000 +0530 -+++ binutils/bucomm.c 2010-02-10 17:35:58.034599600 +0530 -@@ -550,6 +550,32 @@ - return ret; - } - -+/* Return the basename of "file", i. e. everything minus whatever -+ directory part has been provided. Stolen from bfd/archive.c. -+ Should we also handle the VMS case (as in bfd/archive.c)? */ -+const char * -+bu_basename (file) -+ const char *file; -+{ -+ const char *filename = strrchr (file, '/'); -+ -+#ifdef HAVE_DOS_BASED_FILE_SYSTEM -+ { -+ /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ -+ char *bslash = strrchr (file, '\\'); -+ if (filename == NULL || (bslash != NULL && bslash > filename)) -+ filename = bslash; -+ if (filename == NULL && file[0] != '\0' && file[1] == ':') -+ filename = file + 1; -+ } -+#endif -+ if (filename != (char *) NULL) -+ filename++; -+ else -+ filename = file; -+ return filename; -+} -+ - /* Returns the size of the named file. If the file does not - exist, or if it is not a real file, then a suitable non-fatal - error message is printed and zero is returned. */ -diff -Nruw binutils/bucomm.h binutils/bucomm.h ---- binutils/bucomm.h 2009-09-02 12:52:31.000000000 +0530 -+++ binutils/bucomm.h 2010-02-10 17:35:58.050224600 +0530 -@@ -58,6 +58,8 @@ - - off_t get_file_size (const char *); - -+const char *bu_basename PARAMS ((const char *)); -+ - extern char *program_name; - - /* filemode.c */ -diff -Nruw binutils/budbg.h binutils/budbg.h ---- binutils/budbg.h 2009-09-02 12:52:31.000000000 +0530 -+++ binutils/budbg.h 2010-02-10 17:35:58.050224600 +0530 -@@ -52,8 +52,11 @@ - - extern bfd_boolean write_ieee_debugging_info (bfd *, void *); - --/* Routine used to read COFF debugging information. */ -+/* Routine used to read and write COFF debugging information. */ - - extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *); - -+extern bfd_boolean write_coff_debugging_info -+ (bfd *abfd, void *, long *symcountp, asymbol ***); -+ - #endif -diff -Nruw binutils/debug.c binutils/debug.c ---- binutils/debug.c 2009-09-14 17:13:26.000000000 +0530 -+++ binutils/debug.c 2010-02-11 10:50:38.043866600 +0530 -@@ -31,6 +31,7 @@ - #include - #include "bfd.h" - #include "libiberty.h" -+#include "bucomm.h" - #include "debug.h" - - /* Global information we keep for debugging. A pointer to this -@@ -552,6 +553,19 @@ - struct debug_type_s *t; - }; - -+/* Simple list, used for pathname translations. */ -+struct xlat_list -+{ -+ /* Next string on list. */ -+ struct xlat_list *next; -+ /* Old part to match against. */ -+ const char *old; -+ size_t olen; -+ /* New part to replace. */ -+ const char *newstr; -+ size_t nlen; -+}; -+ - /* Local functions. */ - - static void debug_error (const char *); -@@ -588,6 +602,11 @@ - (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); - static bfd_boolean debug_class_type_samep - (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); -+static const char *debug_xlat_pathname (const char *); -+ -+/* List of pathname translations. */ -+static struct xlat_list *xlat, *xltail; -+static bfd_boolean xlat_basename; - - /* Issue an error message. */ - -@@ -680,6 +699,8 @@ - - if (name == NULL) - name = ""; -+ else -+ name = debug_xlat_pathname (name); - - nfile = (struct debug_file *) xmalloc (sizeof *nfile); - memset (nfile, 0, sizeof *nfile); -@@ -720,6 +741,8 @@ - - if (name == NULL) - name = ""; -+ else -+ name = debug_xlat_pathname (name); - - if (info->current_unit == NULL) - { -@@ -3370,3 +3393,69 @@ - - return TRUE; - } -+ -+/* Register a pathname translation. */ -+void -+debug_register_pathname_xlat (oname, nname) -+ const char *oname; -+ const char *nname; -+{ -+ struct xlat_list *xlp; -+ -+ /* Special case: if oname is given as NULL, this means the -+ --basename option has been given to objcopy. */ -+ if (oname == NULL) -+ { -+ xlat_basename = TRUE; -+ return; -+ } -+ -+ xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list)); -+ xlp->next = NULL; -+ if (xlat == NULL) -+ xlat = xltail = xlp; -+ else -+ { -+ xltail->next = xlp; -+ xltail = xlp; -+ } -+ xlp->old = oname; -+ xlp->newstr = nname; -+ xlp->olen = strlen (oname); -+ xlp->nlen = strlen (nname); -+} -+ -+/* Try to translate a pathname. */ -+static const char * -+debug_xlat_pathname (oname) -+ const char *oname; -+{ -+ struct xlat_list *xlp; -+ char *cp; -+ size_t olen; -+ -+ if (xlat_basename) -+ return bu_basename (oname); -+ -+ olen = strlen (oname); -+ for (xlp = xlat; xlp; xlp = xlp->next) -+ { -+ if (xlp->olen > olen) -+ /* This cannot be our turn. */ -+ continue; -+ /* Since we have pre-computed all our length values to avoid -+ repetitively computing them, just use memcmp() since it's -+ faster than strcmp(). */ -+ if (memcmp (xlp->old, oname, xlp->olen) == 0) -+ { -+ cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1); -+ memcpy (cp, xlp->newstr, xlp->nlen); -+ memcpy (cp + xlp->nlen, oname + xlp->olen, -+ olen - xlp->olen + 1); -+ return cp; -+ } -+ } -+ -+ /* Not found, pass the original name on. */ -+ return oname; -+} -diff -Nruw binutils/debug.h binutils/debug.h ---- binutils/debug.h 2009-09-14 17:13:26.000000000 +0530 -+++ binutils/debug.h 2010-02-10 17:35:58.097099600 +0530 -@@ -440,6 +440,12 @@ - - extern bfd_boolean debug_start_source (void *, const char *); - -+/* Register a pathname translation for source (and include) filenames. -+ This is used by the --change-pathname option of objcopy. */ -+ -+extern void debug_register_pathname_xlat -+ PARAMS ((const char *, const char *)); -+ - /* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The bfd_boolean indicates whether the function is globally visible. -diff -Nruw binutils/doc/objcopy.1 binutils/doc/objcopy.1 ---- binutils/doc/objcopy.1 2009-10-16 17:22:19.000000000 +0530 -+++ binutils/doc/objcopy.1 2010-02-11 10:22:09.312500000 +0530 -@@ -202,6 +202,8 @@ - [\fB\-\-readonly\-text\fR] - [\fB\-\-pure\fR] - [\fB\-\-impure\fR] -+ [\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR] -+ [\fB\-\-basename\fR] - [\fB\-\-file\-alignment=\fR\fInum\fR] - [\fB\-\-heap=\fR\fIsize\fR] - [\fB\-\-image\-base=\fR\fIaddress\fR] -@@ -885,6 +887,23 @@ - It can also be a useful way of reducing the size of a \fB\-\-just\-symbols\fR - linker input file. - .RE -+.IP "\fB\-\-change\-pathname\fR \fIold\fR=\fInew\fR" 4 -+.IX Item "--change-pathname old=new" -+When converting debugging information using \fB\-\-debugging\fR, for -+every pathname that starts with \fIold\fR, replace the matching part -+by \fInew\fR. This is intented to map pathnames between different -+debugging tools, or when parts of the object file(s) had their -+pathnames recorded in a different build environment. Note that only -+leading directory name components might be changed that way, since the -+trailing filename could be recorded elsewhere as well (depending on the -+debugging format of the input file). -+.IP "\fB\-\-basename\fR" -+.IX Item "--basename" -+When converting debugging information using \fB\-\-debugging\fR, for -+every pathname, strip all leading directory information. This option -+takes precedence over any \fB\-\-change\-pathname\fR option. For some -+debugging formats that cannot handle long filenames, this options is -+implied (notably, some COFF debugging formats). - .IP "\fB\-V\fR" 4 - .IX Item "-V" - .PD 0 -diff -Nruw binutils/objcopy.c binutils/objcopy.c ---- binutils/objcopy.c 2009-09-14 17:13:26.000000000 +0530 -+++ binutils/objcopy.c 2010-02-11 10:56:56.890302300 +0530 -@@ -32,6 +32,7 @@ - #include "elf-bfd.h" - #include - #include "libbfd.h" -+#include "debug.h" - #include "coff/internal.h" - #include "libcoff.h" - -@@ -297,6 +298,8 @@ - OPTION_IMPURE, - OPTION_EXTRACT_SYMBOL, - OPTION_REVERSE_BYTES, -+ OPTION_CHANGE_PATHNAME, -+ OPTION_BASENAME, - OPTION_FILE_ALIGNMENT, - OPTION_HEAP, - OPTION_IMAGE_BASE, -@@ -346,10 +349,12 @@ - {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, - {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, - {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, -+ {"basename", no_argument, 0, OPTION_BASENAME}, - {"binary-architecture", required_argument, 0, 'B'}, - {"byte", required_argument, 0, 'b'}, - {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, - {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, -+ {"change-pathname", required_argument, 0, OPTION_CHANGE_PATHNAME}, - {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, - {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, - {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, -@@ -543,6 +548,8 @@ - --prefix-alloc-sections \n\ - Add to start of every allocatable\n\ - section name\n\ -+ --change-pathname = Change debug pathnames from to \n\ -+ --basename Strip directory part from debug pathnames\n\ - --file-alignment Set PE file alignment to \n\ - --heap [,] Set PE reserve/commit heap to /\n\ - \n\ -@@ -999,6 +1006,8 @@ - asymbol **from = isyms, **to = osyms; - long src_count = 0, dst_count = 0; - int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; -+ bfd_boolean need_for_debugging = convert_debugging -+ && bfd_get_arch (abfd) == bfd_arch_avr; - - for (; src_count < symcount; src_count++) - { -@@ -1099,7 +1108,8 @@ - || bfd_is_com_section (bfd_get_section (sym))) - keep = strip_symbols != STRIP_UNNEEDED; - else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ -- keep = (strip_symbols != STRIP_DEBUG -+ keep = need_for_debugging -+ || (strip_symbols != STRIP_DEBUG - && strip_symbols != STRIP_UNNEEDED - && ! convert_debugging); - else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) -@@ -2817,6 +2827,10 @@ - return write_ieee_debugging_info (obfd, dhandle); - - if (bfd_get_flavour (obfd) == bfd_target_coff_flavour -+ && bfd_get_arch (obfd) == bfd_arch_avr) -+ return write_coff_debugging_info (obfd, dhandle, symcountp, symppp); -+ -+ if (bfd_get_flavour (obfd) == bfd_target_coff_flavour - || bfd_get_flavour (obfd) == bfd_target_elf_flavour) - { - bfd_byte *syms, *strings; -@@ -3641,6 +3655,30 @@ - prefix_alloc_sections_string = optarg; - break; - -+ case OPTION_CHANGE_PATHNAME: -+ { -+ const char *s; -+ int len; -+ char *name; -+ -+ s = strchr (optarg, '='); -+ if (s == NULL) -+ fatal (_("bad format for %s"), "--change-pathname"); -+ -+ len = s - optarg; -+ name = (char *) xmalloc (len + 1); -+ strncpy (name, optarg, len); -+ name[len] = '\0'; -+ -+ debug_register_pathname_xlat (name, s + 1); -+ } -+ break; -+ -+ case OPTION_BASENAME: -+ /* very special case of pathname translation */ -+ debug_register_pathname_xlat (NULL, NULL); -+ break; -+ - case OPTION_READONLY_TEXT: - bfd_flags_to_set |= WP_TEXT; - bfd_flags_to_clear &= ~WP_TEXT; -diff -Nruw binutils/rdcoff.c binutils/rdcoff.c ---- binutils/rdcoff.c 2009-09-02 12:52:32.000000000 +0530 -+++ binutils/rdcoff.c 2010-02-10 17:35:58.128349600 +0530 -@@ -82,6 +82,9 @@ - struct coff_slots *slots; - /* Basic types. */ - debug_type basic[T_MAX + 1]; -+ /* Some general information, kept here for convenience. */ -+ size_t intsize; /* sizeof (int) */ -+ size_t doublesize; /* sizeof (double) */ - }; - - static debug_type *coff_get_slot (struct coff_types *, int); -@@ -101,6 +104,7 @@ - (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *, - void *, debug_type, bfd_boolean); - static bfd_boolean external_coff_symbol_p (int sym_class); -+static bfd_vma coff_convert_register (bfd *, bfd_vma); - - /* Return the slot for a type. */ - -@@ -271,8 +275,7 @@ - break; - - case T_INT: -- /* FIXME: Perhaps the size should depend upon the architecture. */ -- ret = debug_make_int_type (dhandle, 4, FALSE); -+ ret = debug_make_int_type (dhandle, types->intsize, FALSE); - name = "int"; - break; - -@@ -287,7 +290,7 @@ - break; - - case T_DOUBLE: -- ret = debug_make_float_type (dhandle, 8); -+ ret = debug_make_float_type (dhandle, types->doublesize); - name = "double"; - break; - -@@ -307,7 +310,7 @@ - break; - - case T_UINT: -- ret = debug_make_int_type (dhandle, 4, TRUE); -+ ret = debug_make_int_type (dhandle, types->intsize, TRUE); - name = "unsigned int"; - break; - -@@ -565,6 +568,8 @@ - - case C_WEAKEXT: - case C_EXT: -+ /* AVR COFF abuses C_EXTDEF */ -+ case C_EXTDEF: - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, - DEBUG_GLOBAL, bfd_asymbol_value (sym))) - return FALSE; -@@ -580,9 +585,9 @@ - break; - - case C_REG: -- /* FIXME: We may need to convert the register number. */ - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, -- DEBUG_REGISTER, bfd_asymbol_value (sym))) -+ DEBUG_REGISTER, -+ coff_convert_register (abfd, bfd_asymbol_value (sym)))) - return FALSE; - break; - -@@ -596,9 +601,9 @@ - break; - - case C_REGPARM: -- /* FIXME: We may need to convert the register number. */ - if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, -- DEBUG_PARM_REG, bfd_asymbol_value (sym))) -+ DEBUG_PARM_REG, -+ coff_convert_register (abfd, bfd_asymbol_value (sym)))) - return FALSE; - break; - -@@ -648,6 +653,28 @@ - return FALSE; - } - -+static bfd_vma -+coff_convert_register (abfd, val) -+ bfd *abfd; -+ bfd_vma val; -+{ -+ -+ switch (bfd_get_arch (abfd)) -+ { -+ case bfd_arch_avr: -+ /* AVR COFF wants to describe up to four registers by the four -+ bytes of the 32-bit value. Unused bytes are filled with -+ 0xff. In theory, this would allow for non-contiguous -+ register usage to hold a single value, but hopefully, no -+ compiler is going to use that feature. We could not handle -+ it anyway. */ -+ return val & 0xff; -+ -+ default: -+ return val; -+ } -+} -+ - /* This is the main routine. It looks through all the symbols and - handles them. */ - -@@ -674,6 +701,17 @@ - types.slots = NULL; - for (i = 0; i <= T_MAX; i++) - types.basic[i] = DEBUG_TYPE_NULL; -+ switch (bfd_get_arch (abfd)) -+ { -+ case bfd_arch_avr: -+ types.intsize = 2; -+ types.doublesize = 4; -+ break; -+ -+ default: -+ types.intsize = 4; -+ types.doublesize = 8; -+ } - - next_c_file = -1; - fnname = NULL; -@@ -734,7 +772,6 @@ - switch (syment.n_sclass) - { - case C_EFCN: -- case C_EXTDEF: - case C_ULABEL: - case C_USTATIC: - case C_LINE: -@@ -757,6 +794,8 @@ - /* Fall through. */ - case C_WEAKEXT: - case C_EXT: -+ /* AVR COFF abuses C_EXTDEF for C_EXT */ -+ case C_EXTDEF: - if (ISFCN (syment.n_type)) - { - fnname = name; -diff -Nruw binutils/wrcoff.c binutils/wrcoff.c ---- binutils/wrcoff.c 1970-01-01 05:30:00.000000000 +0530 -+++ binutils/wrcoff.c 2010-02-10 17:35:58.159599600 +0530 -@@ -0,0 +1,3410 @@ -+/* wrcoff.c -- Generate (AVR) COFF debugging information -+ Copyright 2003 Free Software Foundation, Inc. -+ -+ Written by Joerg Wunsch. -+ -+ This file is part of GNU Binutils. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ 02111-1307, USA. */ -+ -+/* This file contains code which writes out COFF debugging -+ information. By now, this has only been tested on the AVR -+ platform, though any attempt has been made to keep the conversion -+ applicable to possible other COFF debugging consumers as well. */ -+ -+#include -+#include -+ -+#include "sysdep.h" -+#include "bfd.h" -+#include "coff/internal.h" -+#include "bucomm.h" -+#include "libiberty.h" -+#include "safe-ctype.h" -+#include "debug.h" -+#include "budbg.h" -+ -+/* Enabling COFF_DEBUG will trace the internal callback functions and -+ their parameters as debug_write() calls them. */ -+//#define COFF_DEBUG 1 -+ -+#include "libcoff.h" -+ -+#define N_TMASK (coff_data (info->abfd)->local_n_tmask) -+#define N_BTSHFT (coff_data (info->abfd)->local_n_btshft) -+#define N_BTMASK (coff_data (info->abfd)->local_n_btmask) -+#define N_TSHIFT (coff_data (info->abfd)->local_n_tshift) -+ -+/* Structure of local symbols per compilation unit. */ -+struct coff_compilation_unit -+{ -+ const char *fname; -+ asymbol **syms; -+ long nsyms, totsyms; -+}; -+ -+enum ts_kind -+{ -+ TS_EMPTY, -+ TS_VOID, -+ TS_INT, -+ TS_FLOAT, -+ TS_COMPLEX, -+ TS_ENUM, -+ TS_POINTER, -+ TS_FUNC, -+ TS_ARRAY, -+ TS_STRUCT, -+ TS_NONE = -1 -+}; -+ -+/* Structure defining the pre-defined types. */ -+struct coff_predef_type -+{ -+ enum ts_kind kind; -+ unsigned int size; /* in bytes */ -+ bfd_boolean isunsigned; -+ int slot; -+}; -+ -+struct coff_type_stack; -+struct coff_hash_entry; -+ -+struct coff_struct_fields -+{ -+ const char *name; -+ bfd_vma bitpos; -+ bfd_vma bitsize; -+ enum debug_visibility visibility; -+ struct coff_type_stack *types; -+}; -+ -+/* Our type stack. */ -+struct coff_type_stack -+{ -+ struct coff_type_stack *next; -+ enum ts_kind tsk; -+ union -+ { -+ /* TS_INT */ -+ struct -+ { -+ unsigned int size; -+ bfd_boolean isunsigned; -+ } -+ ts_int; -+ -+ /* TS_FLOAT */ -+ struct -+ { -+ unsigned int size; -+ } -+ ts_float; -+ -+ /* TS_ENUM */ -+ struct -+ { -+ union -+ { -+ const char *fixtag; -+ char *malloctag; -+ } -+ tag; -+ bfd_boolean tagismalloced; -+ const char **names; -+ bfd_signed_vma *vals; -+ struct coff_enum_hash_entry *ehash; -+ } -+ ts_enum; -+ -+ /* TS_FUNC */ -+ struct -+ { -+ struct coff_type_stack *savedts; -+ } -+ ts_func; -+ -+ /* TS_ARRAY */ -+ struct -+ { -+ bfd_signed_vma low; -+ bfd_signed_vma high; -+ } -+ ts_array; -+ -+ /* TS_STRUCT */ -+ struct -+ { -+ union -+ { -+ const char *fixtag; -+ char *malloctag; -+ } -+ tag; -+ bfd_boolean tagismalloced; -+ unsigned int id; -+ bfd_boolean isstruct; -+ unsigned int size; -+ long nfields; -+ struct coff_struct_fields *fields; -+ struct coff_type_stack *savedts; -+ struct coff_struct_hash_entry *shash; -+ } -+ ts_struct; -+ } -+ u; -+}; -+ -+struct coff_name_type_hash_table -+{ -+ struct bfd_hash_table root; -+}; -+ -+struct coff_name_type_hash_entry -+{ -+ struct bfd_hash_entry root; -+ /* Information for this name. */ -+ struct coff_type_stack *types; -+ bfd_boolean emitted; -+}; -+ -+struct coff_struct_hash_table -+{ -+ struct bfd_hash_table root; -+}; -+ -+struct coff_struct_hash_entry -+{ -+ struct bfd_hash_entry root; -+ /* Information for this name. */ -+ struct coff_type_stack *types; -+ bfd_boolean emitted; -+ combined_entry_type *native; -+ /* list of symbol indices that need fixing */ -+ long *fixidxs; -+ unsigned nfixidxs; -+}; -+ -+struct coff_enum_hash_table -+{ -+ struct bfd_hash_table root; -+}; -+ -+struct coff_enum_hash_entry -+{ -+ struct bfd_hash_entry root; -+ /* Information for this name. */ -+ struct coff_type_stack *types; -+ bfd_boolean emitted; -+ combined_entry_type *native; -+ /* list of symbol indices that need fixing */ -+ long *fixidxs; -+ unsigned nfixidxs; -+}; -+ -+/* COFF private symbol data. Used as a cookie to pass data around -+ between various processing stages. The generic COFF handling code -+ doesn't use any private data. */ -+struct coff_private_symdata -+{ -+ unsigned int size; /* size of symbol, used in AVR register -+ translation */ -+ struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */ -+ struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */ -+}; -+ -+/* Stack of tags that need endndx fixing. */ -+struct coff_fix_stack -+{ -+ struct coff_fix_stack *next; -+ combined_entry_type *native; -+}; -+ -+/* This is the handle passed through debug_write. */ -+ -+struct coff_write_handle -+{ -+ /* The BFD. */ -+ bfd *abfd; -+ /* Pointers to .text and .data sections, can be used as defaults if -+ no other information is available. */ -+ asection *textsect; -+ asection *datasect; -+ /* Some special flags. */ -+ unsigned long flags; -+ /* Flags describing architecture options. */ -+#define COFF_FL_AVR 0x0001 /* COFF is for AVR platform. */ -+#define COFF_FL_EXT_AVR 0x0002 /* AVR "extended" COFF */ -+ /* Flags describing internal status information. */ -+#define COFF_FL_FIX_ENDNDX 0x10000 /* apply endndx fix at next symbol */ -+#define COFF_FL_START_FCN 0x20000 /* begin of function pending */ -+#define COFF_FL_FIX_BB 0x40000 /* fix last ".bb" symbol */ -+ /* List of our compilation units, from input symbol table. */ -+ struct coff_compilation_unit *units; -+ long nunits; -+ struct coff_compilation_unit *currentfile; -+ /* Global symbols from input symbol table. */ -+ asymbol **globals; -+ long nglobals; -+ /* Section syms for named sections. */ -+ coff_symbol_type **secsyms; -+ long nsecsyms; -+ /* Our COFF symbols. */ -+ asymbol **syms; -+ long nsyms; -+ /* Total line number count. */ -+ unsigned long totlnos; -+ /* Size of standard objects on this arch. */ -+ unsigned int pointersize; -+ unsigned int enumsize; -+ /* Pending information when starting a function. We have to defer -+ almost everything, some actions can be taken when seeing the -+ starting block of that function, some will even have to wait -+ until we see the end of the function. */ -+ const char *funname; /* name of function */ -+ bfd_boolean funglobal; /* global/local function? */ -+ unsigned int lastlno; /* last line number seen so far */ -+ long funcindex; /* index of ".func" symbol in syms */ -+ unsigned int nlnos; /* line numbers recorded for this function*/ -+ bfd_vma endaddr; /* last .eb address we have seen so far */ -+ unsigned int funlno; /* first line number in function */ -+ coff_symbol_type **fargs; /* function arguments */ -+ unsigned int nfargs; -+ asection *funcsection; /* section the current function is using */ -+ /* Type information */ -+ struct coff_type_stack *tstack; -+ struct coff_name_type_hash_table types; -+ struct coff_struct_hash_table structs; -+ struct coff_enum_hash_table enums; -+ unsigned nenums; /* counter for anonymous enum tags */ -+ /* Stack of pending endndx fixes, see coff_record_symbol(). */ -+ struct coff_fix_stack *fixes; -+}; -+ -+/* Predefined types, default to usual 32-bit architectures. -+ Arch-dependant different byte sizes will be tuned upon entering -+ write_coff_debugging_info(). The table is looked up from front to -+ end, so we put `more popular' types that might have the same size -+ as other types first (e. g. "int" precedes "long" and "short"). */ -+static struct coff_predef_type coff_predef_types[] = -+{ -+ { TS_INT, 4, FALSE, 4 }, /* signed int */ -+ { TS_INT, 1, FALSE, 2 }, /* signed char */ -+ { TS_INT, 2, FALSE, 3 }, /* signed short */ -+ { TS_INT, 4, FALSE, 5 }, /* long int */ -+ { TS_FLOAT, 8, FALSE, 7 }, /* double */ -+ { TS_FLOAT, 4, FALSE, 6 }, /* float */ -+ { TS_INT, 4, TRUE, 14 }, /* unsigned int */ -+ { TS_INT, 1, TRUE, 12 }, /* unsigned char */ -+ { TS_INT, 2, TRUE, 13 }, /* unsigned short */ -+ { TS_INT, 4, TRUE, 15 }, /* unsigned long */ -+}; -+ -+static bfd_boolean coff_copy_symbols -+ PARAMS ((struct coff_write_handle *, long, asymbol **)); -+static asymbol *coff_find_symbol -+ PARAMS ((struct coff_write_handle *, const char *, bfd_boolean, bfd_boolean)); -+static void coff_record_symbol -+ PARAMS ((struct coff_write_handle *, coff_symbol_type *)); -+static symvalue coff_fixup_avr_register PARAMS ((symvalue, int)); -+static struct bfd_hash_entry *coff_name_type_newfunc -+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -+static bfd_boolean coff_free_type_info -+ PARAMS ((struct coff_name_type_hash_entry *, PTR)); -+static struct bfd_hash_entry *coff_struct_newfunc -+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -+static bfd_boolean coff_free_struct_info -+ PARAMS ((struct coff_struct_hash_entry *, PTR)); -+static struct bfd_hash_entry *coff_enum_newfunc -+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -+static bfd_boolean coff_free_enum_info -+ PARAMS ((struct coff_enum_hash_entry *, PTR)); -+static unsigned int coff_get_fundamental_type -+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *)); -+static bfd_boolean coff_make_typed_symbol -+ PARAMS ((struct coff_write_handle *, coff_symbol_type **, enum ts_kind)); -+static bfd_boolean coff_emit_struct -+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *, -+ struct coff_struct_hash_entry *)); -+static bfd_boolean coff_emit_enum -+ PARAMS ((struct coff_write_handle *, struct coff_type_stack *, -+ struct coff_enum_hash_entry *)); -+static bfd_boolean coff_emit_ndebug_sym -+ PARAMS ((struct coff_write_handle *, asymbol *, bfd_boolean)); -+ -+static bfd_boolean coff_start_compilation_unit PARAMS ((PTR, const char *)); -+static bfd_boolean coff_start_source PARAMS ((PTR, const char *)); -+static bfd_boolean coff_empty_type PARAMS ((PTR)); -+static bfd_boolean coff_void_type PARAMS ((PTR)); -+static bfd_boolean coff_int_type PARAMS ((PTR, unsigned int, bfd_boolean)); -+static bfd_boolean coff_float_type PARAMS ((PTR, unsigned int)); -+static bfd_boolean coff_complex_type PARAMS ((PTR, unsigned int)); -+static bfd_boolean coff_bool_type PARAMS ((PTR, unsigned int)); -+static bfd_boolean coff_enum_type -+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); -+static bfd_boolean coff_pointer_type PARAMS ((PTR)); -+static bfd_boolean coff_function_type PARAMS ((PTR, int, bfd_boolean)); -+static bfd_boolean coff_reference_type PARAMS ((PTR)); -+static bfd_boolean coff_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); -+static bfd_boolean coff_array_type -+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean)); -+static bfd_boolean coff_set_type PARAMS ((PTR, bfd_boolean)); -+static bfd_boolean coff_offset_type PARAMS ((PTR)); -+static bfd_boolean coff_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean)); -+static bfd_boolean coff_const_type PARAMS ((PTR)); -+static bfd_boolean coff_volatile_type PARAMS ((PTR)); -+static bfd_boolean coff_start_struct_type -+ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int)); -+static bfd_boolean coff_struct_field -+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); -+static bfd_boolean coff_end_struct_type PARAMS ((PTR)); -+static bfd_boolean coff_start_class_type -+ PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, -+ bfd_boolean)); -+static bfd_boolean coff_class_static_member -+ PARAMS ((PTR, const char *, const char *, enum debug_visibility)); -+static bfd_boolean coff_class_baseclass -+ PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility)); -+static bfd_boolean coff_class_start_method PARAMS ((PTR, const char *)); -+static bfd_boolean coff_class_method_variant -+ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, -+ bfd_vma, bfd_boolean)); -+static bfd_boolean coff_class_static_method_variant -+ PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean)); -+static bfd_boolean coff_class_end_method PARAMS ((PTR)); -+static bfd_boolean coff_end_class_type PARAMS ((PTR)); -+static bfd_boolean coff_typedef_type PARAMS ((PTR, const char *)); -+static bfd_boolean coff_tag_type -+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); -+static bfd_boolean coff_typdef PARAMS ((PTR, const char *)); -+static bfd_boolean coff_tag PARAMS ((PTR, const char *)); -+static bfd_boolean coff_int_constant PARAMS ((PTR, const char *, bfd_vma)); -+static bfd_boolean coff_float_constant PARAMS ((PTR, const char *, double)); -+static bfd_boolean coff_typed_constant PARAMS ((PTR, const char *, bfd_vma)); -+static bfd_boolean coff_variable -+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); -+static bfd_boolean coff_start_function PARAMS ((PTR, const char *, bfd_boolean)); -+static bfd_boolean coff_function_parameter -+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); -+static bfd_boolean coff_start_block PARAMS ((PTR, bfd_vma)); -+static bfd_boolean coff_end_block PARAMS ((PTR, bfd_vma)); -+static bfd_boolean coff_end_function PARAMS ((PTR)); -+static bfd_boolean coff_lineno -+ PARAMS ((PTR, const char *, unsigned long, bfd_vma)); -+ -+static const struct debug_write_fns coff_fns = -+{ -+ coff_start_compilation_unit, -+ coff_start_source, -+ coff_empty_type, -+ coff_void_type, -+ coff_int_type, -+ coff_float_type, -+ coff_complex_type, -+ coff_bool_type, -+ coff_enum_type, -+ coff_pointer_type, -+ coff_function_type, -+ coff_reference_type, -+ coff_range_type, -+ coff_array_type, -+ coff_set_type, -+ coff_offset_type, -+ coff_method_type, -+ coff_const_type, -+ coff_volatile_type, -+ coff_start_struct_type, -+ coff_struct_field, -+ coff_end_struct_type, -+ coff_start_class_type, -+ coff_class_static_member, -+ coff_class_baseclass, -+ coff_class_start_method, -+ coff_class_method_variant, -+ coff_class_static_method_variant, -+ coff_class_end_method, -+ coff_end_class_type, -+ coff_typedef_type, -+ coff_tag_type, -+ coff_typdef, -+ coff_tag, -+ coff_int_constant, -+ coff_float_constant, -+ coff_typed_constant, -+ coff_variable, -+ coff_start_function, -+ coff_function_parameter, -+ coff_start_block, -+ coff_end_block, -+ coff_end_function, -+ coff_lineno -+}; -+ -+/* -+ * Copy our input (non-debugging) symbols. Local symbols will be -+ * maintained in one bucket per each compilation unit, global (and -+ * weak) symbols will be kept in a simple array. -+ */ -+static bfd_boolean -+coff_copy_symbols (info, count, sympp) -+ struct coff_write_handle *info; -+ long count; -+ asymbol **sympp; -+{ -+ asymbol *osym; -+ long i; -+ struct coff_compilation_unit *up; -+ -+ up = NULL; -+ -+ for (i = 0; i < count; i++) -+ { -+ osym = sympp[i]; -+ -+ /* Try to figure out the .text and .data sections from our input -+ symbols as we walk them. Unfortunately, this ought to be the -+ /input/ section pointers, so their ->output_section is -+ non-NULL. That's why we can't simply walk through all the -+ sections of our abfd since this is describing the output -+ only. */ -+ if (info->textsect == NULL && osym->section->flags & SEC_CODE) -+ /* Assume this to be our .text section. */ -+ info->textsect = osym->section; -+ else if (info->datasect == NULL && osym->section->flags & SEC_DATA) -+ /* Assume this to be our .data section. */ -+ info->datasect = osym->section; -+ -+ if (osym->flags & BSF_FILE) -+ { -+ /* New file name. */ -+ long l; -+ -+ up = NULL; -+ -+ /* Well, maybe an old one actually? If so, append it there. -+ This can happen for files that contribute to multiple -+ (input) sections that were concatenated by the linker -+ (like crt1.S). */ -+ for (l = 0; l < info->nunits; l++) -+ { -+ if (strcmp (info->units[l].fname, osym->name) == 0) -+ { -+ up = info->units + l; -+ break; -+ } -+ } -+ -+ if (up == NULL) -+ { -+ info->units = (struct coff_compilation_unit *) -+ xrealloc (info->units, -+ ++info->nunits * sizeof(struct coff_compilation_unit)); -+ up = info->units + (info->nunits - 1); -+ up->fname = osym->name; -+ up->syms = NULL; -+ up->nsyms = up->totsyms = 0; -+ } -+ } -+ else if (osym->flags & (BSF_GLOBAL | BSF_WEAK)) -+ { -+ /* Global (or weak) symbols are recorded outside compilation -+ units. */ -+ info->globals = (asymbol **) -+ xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *)); -+ info->globals[info->nglobals - 1] = osym; -+ continue; -+ } -+ else if (!bfd_is_const_section(osym->section)) -+ { -+ if (osym->flags & BSF_SECTION_SYM) -+ { -+ coff_symbol_type *csymp; -+ /* Just record them by now, they'll be fixed up later. */ -+ -+ if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0) -+ { -+ /* Very first symbol, fake a compilation unit name -+ for it. Historical precedence seems to dictate -+ this, but AVR COFF does not use that. */ -+ csymp = (coff_symbol_type *) -+ coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (""); -+ csymp->symbol.value = 0; -+ csymp->symbol.udata.p = NULL; -+ csymp->native->u.syment.n_sclass = C_FILE; -+ /* force filename into aux entry */ -+ csymp->native->u.syment.n_numaux = 1; -+ coff_record_symbol (info, csymp); -+ } -+ -+ /* convert to COFF native section symbol */ -+ csymp = (coff_symbol_type *) -+ coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (osym->section->name); -+ csymp->symbol.value = osym->section->output_section->vma; -+ csymp->symbol.flags = BSF_DEBUGGING | BSF_SECTION_SYM; -+ csymp->symbol.section = osym->section; -+ csymp->symbol.udata.p = NULL; -+ csymp->native->fix_scnlen = 1; -+ csymp->native->u.syment.n_sclass = C_STAT; -+ csymp->native->u.syment.n_type = T_NULL; -+ csymp->native->u.syment.n_numaux = 1; -+ -+ coff_record_symbol (info, csymp); -+ -+ info->secsyms = (coff_symbol_type **) -+ xrealloc (info->secsyms, -+ ++info->nsecsyms * sizeof(coff_symbol_type *)); -+ info->secsyms[info->nsecsyms - 1] = csymp; -+ } -+ else -+ { -+ /* Local symbol in a named section, will be recorded -+ within the respective compilation unit. */ -+ if (up == NULL) -+ { -+ fprintf (stderr, -+ _("Discarding local symbol outside any compilation unit")); -+ if (osym->name) -+ fprintf (stderr, ": %s", osym->name); -+ putc ('\n', stderr); -+ } -+ else -+ { -+ up->syms = (asymbol **) -+ xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *)); -+ up->syms[up->nsyms - 1] = osym; -+ up->totsyms = up->nsyms; -+ continue; -+ } -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/* Find a name in the symbol table. If found, the respective entry in -+ the symbol vector is zeroed, so after processing all debugging -+ symbols, only non-debugging symbols will remain. */ -+static asymbol * -+coff_find_symbol (info, name, isfunction, global) -+ struct coff_write_handle *info; -+ const char *name; -+ bfd_boolean isfunction; -+ bfd_boolean global; -+{ -+ asymbol *symp; -+ long i; -+ size_t namelen; -+ -+ if (global) -+ { -+ for (i = 0; i < info->nglobals; i++) -+ { -+ symp = info->globals[i]; -+ if (symp == NULL) -+ continue; -+ if (strcmp (name, symp->name) == 0 -+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) -+ { -+ info->globals[i] = NULL; -+ return symp; -+ } -+ } -+ return NULL; -+ } -+ -+ if (info->currentfile == NULL) -+ return NULL; -+ -+ /* For local symbols, the match optionally stops at a dot in the -+ symtab symbol's name; this is used by gcc to indicate -+ function-scope static symbols (e. g. symbol "foo" will become -+ "foo.1" in function scope). */ -+ namelen = strlen (name); -+ for (i = 0; i < info->currentfile->nsyms; i++) -+ { -+ symp = info->currentfile->syms[i]; -+ if (symp == NULL) -+ continue; -+ if (strncmp (name, symp->name, namelen) == 0 -+ && (symp->name[namelen] == '\0' || symp->name[namelen] == '.') -+ && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) -+ { -+ info->currentfile->syms[i] = NULL; -+ info->currentfile->totsyms--; -+ return symp; -+ } -+ } -+ return NULL; -+} -+ -+static void -+coff_record_symbol (info, csymp) -+ struct coff_write_handle *info; -+ coff_symbol_type *csymp; -+{ -+ struct coff_private_symdata *priv; -+ -+ info->syms = (asymbol **) xrealloc (info->syms, -+ ++info->nsyms * sizeof (asymbol *)); -+ info->syms[info->nsyms - 1] = (asymbol *)csymp; -+ -+ if ((priv = csymp->symbol.udata.p) != NULL) -+ { -+ if (priv->shash != NULL) -+ { -+ struct coff_struct_hash_entry *shash = priv->shash; -+ shash->fixidxs = (long *) -+ xrealloc (shash->fixidxs, ++shash->nfixidxs * sizeof (long)); -+ shash->fixidxs[shash->nfixidxs - 1] = info->nsyms - 1; -+ } -+ if (priv->ehash != NULL) -+ { -+ struct coff_enum_hash_entry *ehash = priv->ehash; -+ ehash->fixidxs = (long *) -+ xrealloc (ehash->fixidxs, ++ehash->nfixidxs * sizeof (long)); -+ ehash->fixidxs[ehash->nfixidxs - 1] = info->nsyms - 1; -+ } -+ free (priv); -+ csymp->symbol.udata.p = NULL; -+ } -+ -+ /* If there are any pending endndx fixes, pop the last element from -+ that stack, and record the current symbol for fixing. We need to -+ do this here since we need to record our current csymp->native -+ (where that csymp is completely unrelated to whatever symbol was -+ previously generated that requested the fixup). The stack of -+ pending fixes is required since several endndx fixes could be -+ nested, e. g. the start of a function has a pending fix that -+ needs to point to the first symbol after the function, but there -+ could be an anonymous struct definition inside that function's -+ local variables where the endndx needs to point after the last -+ symbol of this struct. Also, structs and unions could be nested. -+ -+ Each call to coff_record_symbol() can fix at most one endndx -+ (even if more are pending in the stack), but that's OK. -+ -+ Note that bfd/coffgen.c converts that csymp->native into a -+ symtable slot number after coff_renumber_symbols() has been -+ run. */ -+ if (info->flags & COFF_FL_FIX_ENDNDX) -+ { -+ struct coff_fix_stack *fsp, *ofsp; -+ union internal_auxent *aux; -+ -+ assert (info->fixes != NULL); -+ -+ fsp = info->fixes; -+ ofsp = NULL; -+ while (fsp->next != NULL) -+ { -+ ofsp = fsp; -+ fsp = fsp->next; -+ } -+ if (ofsp == NULL) -+ info->fixes = NULL; -+ else -+ ofsp->next = NULL; -+ -+ aux = &(fsp->native->u.auxent); -+ fsp->native->fix_end = 1; -+ aux->x_sym.x_fcnary.x_fcn.x_endndx.p = csymp->native; -+ free (fsp); -+ -+ info->flags &= ~COFF_FL_FIX_ENDNDX; -+ } -+} -+ -+/* Fixup AVR COFF register handling: they don't only mention the -+ starting register number, but all registers, each within one byte -+ of the value. Unused register positions are filled up with -+ 0xff. */ -+static symvalue -+coff_fixup_avr_register (val, size) -+ symvalue val; -+ int size; -+{ -+ union -+ { -+ unsigned char c[4]; -+ symvalue v; -+ } u; -+ -+ u.c[1] = u.c[2] = u.c[3] = 0xff; -+ u.c[0] = val; -+ if (size > 8) -+ u.c[1] = val + 1; -+ if (size > 16) -+ { -+ u.c[2] = val + 2; -+ u.c[3] = val + 3; -+ } -+ -+ return u.v; -+} -+ -+/* Initialize an entry in the hash tables. */ -+ -+static struct bfd_hash_entry * -+coff_name_type_newfunc (entry, table, string) -+ struct bfd_hash_entry *entry; -+ struct bfd_hash_table *table; -+ const char *string; -+{ -+ struct coff_name_type_hash_entry *ret = -+ (struct coff_name_type_hash_entry *) entry; -+ -+ /* Allocate the structure if it has not already been allocated by a -+ subclass. */ -+ if (ret == NULL) -+ ret = ((struct coff_name_type_hash_entry *) -+ bfd_hash_allocate (table, sizeof *ret)); -+ if (ret == NULL) -+ return NULL; -+ -+ /* Call the allocation method of the superclass. */ -+ ret = ((struct coff_name_type_hash_entry *) -+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); -+ if (ret) -+ { -+ /* Set local fields. */ -+ ret->types = NULL; -+ ret->emitted = FALSE; -+ } -+ -+ return (struct bfd_hash_entry *) ret; -+} -+ -+static struct bfd_hash_entry * -+coff_struct_newfunc (entry, table, string) -+ struct bfd_hash_entry *entry; -+ struct bfd_hash_table *table; -+ const char *string; -+{ -+ struct coff_struct_hash_entry *ret = -+ (struct coff_struct_hash_entry *) entry; -+ -+ /* Allocate the structure if it has not already been allocated by a -+ subclass. */ -+ if (ret == NULL) -+ ret = ((struct coff_struct_hash_entry *) -+ bfd_hash_allocate (table, sizeof *ret)); -+ if (ret == NULL) -+ return NULL; -+ -+ /* Call the allocation method of the superclass. */ -+ ret = ((struct coff_struct_hash_entry *) -+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); -+ if (ret) -+ { -+ /* Set local fields. */ -+ ret->types = NULL; -+ ret->emitted = FALSE; -+ ret->fixidxs = NULL; -+ ret->nfixidxs = 0; -+ ret->native = NULL; -+ } -+ -+ return (struct bfd_hash_entry *) ret; -+} -+ -+static struct bfd_hash_entry * -+coff_enum_newfunc (entry, table, string) -+ struct bfd_hash_entry *entry; -+ struct bfd_hash_table *table; -+ const char *string; -+{ -+ struct coff_enum_hash_entry *ret = -+ (struct coff_enum_hash_entry *) entry; -+ -+ /* Allocate the structure if it has not already been allocated by a -+ subclass. */ -+ if (ret == NULL) -+ ret = ((struct coff_enum_hash_entry *) -+ bfd_hash_allocate (table, sizeof *ret)); -+ if (ret == NULL) -+ return NULL; -+ -+ /* Call the allocation method of the superclass. */ -+ ret = ((struct coff_enum_hash_entry *) -+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); -+ if (ret) -+ { -+ /* Set local fields. */ -+ ret->types = NULL; -+ ret->emitted = FALSE; -+ ret->fixidxs = NULL; -+ ret->nfixidxs = 0; -+ ret->native = NULL; -+ } -+ -+ return (struct bfd_hash_entry *) ret; -+} -+ -+/* Look up an entry in the hash tables. */ -+ -+#define coff_name_type_hash_lookup(table, string, create, copy) \ -+ ((struct coff_name_type_hash_entry *) \ -+ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) -+ -+/* Traverse the hash table. */ -+ -+#define coff_name_type_hash_traverse(table, func, info) \ -+ (bfd_hash_traverse \ -+ (&(table)->root, \ -+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ -+ (info))) -+ -+#define coff_struct_hash_lookup(table, string, create, copy) \ -+ ((struct coff_struct_hash_entry *) \ -+ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) -+ -+/* Traverse the hash table. */ -+ -+#define coff_struct_hash_traverse(table, func, info) \ -+ (bfd_hash_traverse \ -+ (&(table)->root, \ -+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ -+ (info))) -+ -+#define coff_enum_hash_lookup(table, string, create, copy) \ -+ ((struct coff_enum_hash_entry *) \ -+ bfd_hash_lookup (&(table)->root, (string), (create), (copy))) -+ -+/* Traverse the hash table. */ -+ -+#define coff_enum_hash_traverse(table, func, info) \ -+ (bfd_hash_traverse \ -+ (&(table)->root, \ -+ (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ -+ (info))) -+ -+#define coff_push_type(kind) \ -+ tst = (struct coff_type_stack *) xmalloc (sizeof (struct coff_type_stack)); \ -+ memset (tst, 0, sizeof (*tst)); \ -+ tst->next = info->tstack; \ -+ tst->tsk = kind; \ -+ info->tstack = tst -+ -+#define coff_pop_type() \ -+ tst = info->tstack; \ -+ if (tst == NULL) { \ -+ fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \ -+ return FALSE; \ -+ } \ -+ info->tstack = tst->next; \ -+ tst->next = NULL -+ -+#define coff_complain_unsupp(s) \ -+ fprintf (stderr, _("%s type not supported in %s\n"), \ -+ s, info->abfd->xvec->name); \ -+ return FALSE -+ -+/* These function is called via the hash traverse routine when freeing -+ a hash table (at the end of a translation unit). */ -+static bfd_boolean -+coff_free_type_info (h, p) -+ struct coff_name_type_hash_entry *h; -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ struct coff_type_stack *tst, *otst; -+ -+ for (tst = h->types; tst != NULL;) -+ { -+ otst = tst; -+ tst = tst->next; -+ free (otst); -+ } -+ return TRUE; -+} -+ -+static bfd_boolean -+coff_free_struct_info (h, p) -+ struct coff_struct_hash_entry *h; -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ struct coff_type_stack *tst, *otst, *xtst, *xotst; -+ struct coff_struct_fields *fp; -+ long i; -+ -+ for (tst = h->types; tst != NULL;) -+ { -+ otst = tst; -+ if (tst->u.ts_struct.tagismalloced) -+ free (tst->u.ts_struct.tag.malloctag); -+ for (i = 0, fp = tst->u.ts_struct.fields; -+ i < tst->u.ts_struct.nfields; -+ i++, fp++) -+ { -+ xtst = fp->types; -+ while (xtst != NULL) -+ { -+ xotst = xtst->next; -+ free (xtst); -+ xtst = xotst; -+ } -+ } -+ free (tst->u.ts_struct.fields); -+ tst = tst->next; -+ free (otst); -+ } -+ return TRUE; -+} -+ -+static bfd_boolean -+coff_free_enum_info (h, p) -+ struct coff_enum_hash_entry *h; -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ struct coff_type_stack *tst, *otst; -+ -+ for (tst = h->types; tst != NULL;) -+ { -+ otst = tst; -+ if (tst->u.ts_enum.tagismalloced) -+ free (tst->u.ts_enum.tag.malloctag); -+ tst = tst->next; -+ free (otst); -+ } -+ return TRUE; -+} -+ -+static unsigned int -+coff_get_fundamental_type (info, tst) -+ struct coff_write_handle *info ATTRIBUTE_UNUSED; -+ struct coff_type_stack *tst; -+{ -+ size_t i; -+ -+ /* See if one of our predefined types will fit. */ -+ if (tst->tsk == TS_INT) -+ { -+ for (i = 0; -+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type); -+ i++) -+ { -+ if (coff_predef_types[i].kind == TS_INT -+ && coff_predef_types[i].size == tst->u.ts_int.size -+ && coff_predef_types[i].isunsigned == tst->u.ts_int.isunsigned) -+ return coff_predef_types[i].slot; -+ } -+ fprintf (stderr, -+ _("%ssigned %d-bit integer type not available in COFF\n"), -+ tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8); -+ } -+ else -+ { -+ for (i = 0; -+ i < sizeof coff_predef_types / sizeof (struct coff_predef_type); -+ i++) -+ { -+ if (coff_predef_types[i].kind == TS_FLOAT -+ && coff_predef_types[i].size == tst->u.ts_float.size) -+ return coff_predef_types[i].slot; -+ } -+ fprintf (stderr, _("%d-bit float type not available in COFF\n"), -+ tst->u.ts_float.size * 8); -+ } -+ -+ return T_NULL; -+} -+ -+static bfd_boolean -+coff_make_typed_symbol (info, csympp, stopat) -+ struct coff_write_handle *info; -+ coff_symbol_type **csympp; -+ enum ts_kind stopat; -+{ -+ struct coff_type_stack *tst; -+ union internal_auxent *aux; -+ struct coff_struct_hash_entry *shash; -+ struct coff_enum_hash_entry *ehash; -+ struct coff_private_symdata *priv; -+ unsigned int type, numaux, arydim, size, i, nele, nderived; -+ const char *name; -+ bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) -+ == COFF_FL_AVR; -+ -+ /* Synthesize a new internal COFF symbol. */ -+ *csympp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (*csympp == NULL) -+ return FALSE; -+ -+ priv = (struct coff_private_symdata *) xmalloc (sizeof *priv); -+ memset (priv, 0, sizeof *priv); -+ -+ type = arydim = size = nderived = 0; -+ -+ aux = &(((*csympp)->native + 1)->u.auxent); -+ -+ /* Now, walk the type stack, and see how we could convert the info -+ we've got to what COFF understands. */ -+ for (;;) -+ { -+ if (info->tstack == NULL) -+ break; -+ -+ /* If we have been advised to not pop the entire stack, stop -+ here. */ -+ if (info->tstack->tsk == stopat && info->tstack->next == NULL) -+ break; -+ -+ coff_pop_type (); -+ -+ switch (tst->tsk) -+ { -+ case TS_NONE: -+ /* cannot happen */ -+ break; -+ -+ case TS_EMPTY: -+ if (info->tstack != NULL && info->tstack->tsk != stopat) -+ fprintf (stderr, _("empty type not last on type stack\n")); -+ /* type |= T_NULL; */ -+ break; -+ -+ case TS_VOID: -+ if (info->tstack != NULL && info->tstack->tsk != stopat) -+ fprintf (stderr, _("void type not last on type stack\n")); -+ type |= T_VOID; -+ break; -+ -+ case TS_INT: -+ if (info->tstack != NULL && info->tstack->tsk != stopat) -+ fprintf (stderr, _("int type not last on type stack\n")); -+ type |= coff_get_fundamental_type (info, tst); -+ if (size == 0) -+ size = tst->u.ts_int.size; -+ break; -+ -+ case TS_FLOAT: -+ if (info->tstack != NULL && info->tstack->tsk != stopat) -+ fprintf (stderr, _("float type not last on type stack\n")); -+ type |= coff_get_fundamental_type (info, tst); -+ if (size == 0) -+ size = tst->u.ts_float.size; -+ break; -+ -+ case TS_POINTER: -+ nderived++; -+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT); -+ size = info->pointersize; -+ break; -+ -+ case TS_FUNC: -+ nderived++; -+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT); -+ /* AUX entry for DT_FCN will be filled in elsewhere. */ -+ break; -+ -+ case TS_ARRAY: -+ /* We need to limit arydim so the assignment below won't -+ overwrite random locations. */ -+ if (arydim >= DIMNUM) -+ { -+ fprintf (stderr, -+ _("More than %d array dimensions, result is invalid.\n"), -+ DIMNUM); -+ arydim = DIMNUM - 1; -+ } -+ nderived++; -+ type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_ARY << N_BTSHFT); -+ aux->x_sym.x_fcnary.x_ary.x_dimen[arydim++] = -+ tst->u.ts_array.high - tst->u.ts_array.low + 1; -+ -+ break; -+ -+ case TS_COMPLEX: -+ coff_complain_unsupp (_("complex")); -+ -+ case TS_ENUM: -+ type |= T_ENUM; -+ if (size == 0) -+ size = info->enumsize; -+ -+ if (tst->u.ts_enum.ehash != NULL) -+ { -+ /* enum tag will be fixed later. */ -+ priv->ehash = tst->u.ts_enum.ehash; -+ break; -+ } -+ if (tst->u.ts_enum.tagismalloced) -+ name = tst->u.ts_enum.tag.malloctag; -+ else -+ name = tst->u.ts_enum.tag.fixtag; -+ ehash = coff_enum_hash_lookup (&info->enums, name, -+ TRUE, tst->u.ts_enum.tagismalloced); -+ if (ehash == NULL) -+ return FALSE; -+ if (!ehash->emitted) -+ { -+ if (ehash->types == NULL) -+ { -+ ehash->types = (struct coff_type_stack *) -+ xmalloc (sizeof (struct coff_type_stack)); -+ memcpy (ehash->types, tst, sizeof (struct coff_type_stack)); -+ } -+ ehash->emitted = TRUE; -+ coff_emit_enum (info, tst, ehash); -+ if (ehash->nfixidxs != 0) -+ { -+ coff_symbol_type *symp; -+ unsigned i; -+ -+ for (i = 0; i < ehash->nfixidxs; i++) -+ { -+ combined_entry_type *np; -+ -+ symp = (coff_symbol_type *) info->syms[ehash->fixidxs[i]]; -+ symp->native->u.syment.n_type &= ~N_BTMASK; -+ symp->native->u.syment.n_type |= T_ENUM; -+ -+ if (oldavrcoff) -+ continue; -+ -+ np = symp->native + 1; -+ np->fix_tag = 1; -+ np->u.auxent.x_sym.x_tagndx.p = ehash->native; -+ if (np->u.auxent.x_sym.x_misc.x_fsize == 0) -+ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; -+ } -+ -+ free (ehash->fixidxs); -+ ehash->nfixidxs = 0; -+ } -+ } -+ if (!oldavrcoff) -+ { -+ ((*csympp)->native + 1)->fix_tag = 1; -+ aux->x_sym.x_tagndx.p = ehash->native; -+ if (aux->x_sym.x_misc.x_fsize == 0) -+ aux->x_sym.x_misc.x_lnsz.x_size = size; -+ } -+ break; -+ -+ case TS_STRUCT: -+ if (tst->u.ts_struct.isstruct) -+ type |= T_STRUCT; -+ else -+ type |= T_UNION; -+ if (size == 0) -+ size = tst->u.ts_struct.size; -+ -+ if (tst->u.ts_struct.shash != NULL) -+ { -+ /* struct tag will be fixed later. */ -+ priv->shash = tst->u.ts_struct.shash; -+ break; -+ } -+ if (tst->u.ts_struct.tagismalloced) -+ name = tst->u.ts_struct.tag.malloctag; -+ else -+ name = tst->u.ts_struct.tag.fixtag; -+ shash = coff_struct_hash_lookup (&info->structs, name, -+ TRUE, tst->u.ts_struct.tagismalloced); -+ if (shash == NULL) -+ return FALSE; -+ if (!shash->emitted) -+ { -+ if (shash->types == NULL) -+ { -+ shash->types = (struct coff_type_stack *) -+ xmalloc (sizeof (struct coff_type_stack)); -+ memcpy (shash->types, tst, sizeof (struct coff_type_stack)); -+ } -+ shash->emitted = TRUE; -+ coff_emit_struct (info, tst, shash); -+ if (shash->nfixidxs != 0) -+ { -+ coff_symbol_type *symp; -+ unsigned i; -+ -+ for (i = 0; i < shash->nfixidxs; i++) -+ { -+ combined_entry_type *np; -+ -+ symp = (coff_symbol_type *) info->syms[shash->fixidxs[i]]; -+ symp->native->u.syment.n_type &= ~N_BTMASK; -+ if (tst->u.ts_struct.isstruct) -+ symp->native->u.syment.n_type |= T_STRUCT; -+ else -+ symp->native->u.syment.n_type |= T_UNION; -+ -+ if (oldavrcoff) -+ continue; -+ -+ np = symp->native + 1; -+ np->fix_tag = 1; -+ np->u.auxent.x_sym.x_tagndx.p = shash->native; -+ if (np->u.auxent.x_sym.x_misc.x_fsize == 0) -+ np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; -+ } -+ -+ free (shash->fixidxs); -+ shash->nfixidxs = 0; -+ } -+ } -+ if (!oldavrcoff) -+ { -+ ((*csympp)->native + 1)->fix_tag = 1; -+ aux->x_sym.x_tagndx.p = shash->native; -+ if (aux->x_sym.x_misc.x_fsize == 0) -+ aux->x_sym.x_misc.x_lnsz.x_size = size; -+ } -+ break; -+ } -+ free (tst); -+ } -+ -+ if (nderived > 6) -+ fprintf (stderr, -+ _("More than 6 derived type specifiers, result is invalid.\n")); -+ -+ /* Our type computation so far used the reverse order for derived -+ type specifiers. Fix this here if there was more than one -+ derived type specifier. */ -+ if (nderived > 1) -+ { -+ unsigned int nty, bty; -+ bty = type & N_BTMASK; -+ type = type >> N_BTSHFT; -+ nty = 0; -+ while (nderived-- > 0) -+ { -+ nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT)); -+ type >>= N_TSHIFT; -+ } -+ type = (nty << N_BTSHFT) | bty; -+ } -+ -+ if (ISARY (type)) -+ { -+ /* Compute size of entire array. */ -+ for (i = 0, nele = 1; i < arydim; i++) -+ nele *= aux->x_sym.x_fcnary.x_ary.x_dimen[i]; -+ aux->x_sym.x_misc.x_lnsz.x_size = size * nele; -+ } -+ -+ numaux = 0; -+ if (ISARY (type) || ISFCN (type)) -+ numaux++; -+ if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION -+ || BTYPE (type) == T_ENUM) -+ && !oldavrcoff) -+ numaux++; -+ /* Only AVR COFF uses multiple AUX entries. */ -+ if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0) -+ numaux = 1; -+ -+ priv->size = size; -+ (*csympp)->symbol.udata.p = priv; -+ (*csympp)->native->u.syment.n_type = type; -+ (*csympp)->native->u.syment.n_numaux = numaux; -+ -+ /* If the fundamental type comes out as T_NULL, this means we don't -+ have any type information. Just don't emit any aux entries in -+ that case, and drop any derived type information as well. */ -+ if (BTYPE (type) == T_NULL) -+ { -+ printf ("coff_make_typed_symbol() -> T_NULL\n"); -+ //(*csympp)->native->u.syment.n_type = T_NULL; -+ (*csympp)->native->u.syment.n_numaux = 0; -+ } -+ -+ return TRUE; -+} -+ -+static bfd_boolean coff_emit_struct (info, tst, shash) -+ struct coff_write_handle *info; -+ struct coff_type_stack *tst; -+ struct coff_struct_hash_entry *shash; -+{ -+ coff_symbol_type *csymp, *scsymp, *ecsymp; -+ union internal_auxent *aux; -+ struct coff_fix_stack *fixp, *ofp; -+ bfd_boolean isstruct = tst->u.ts_struct.isstruct; -+ bfd_boolean isbitfield = FALSE; -+ struct coff_type_stack *savedtst; -+ struct coff_struct_fields *fp; -+ unsigned short sclass; -+ long i; -+ -+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == -+ COFF_FL_AVR) -+ /* old AVR COFF doesn't support struct debugging */ -+ return TRUE; -+ -+ /* Synthesize a new internal COFF symbol for the struct/union. */ -+ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (scsymp == NULL) -+ return FALSE; -+ -+ if (tst->u.ts_struct.tagismalloced) -+ scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag); -+ else -+ scsymp->symbol.name = tst->u.ts_struct.tag.fixtag; -+ scsymp->symbol.flags = BSF_NOT_AT_END; -+ scsymp->symbol.section = bfd_und_section_ptr; -+ scsymp->native->u.syment.n_sclass = isstruct? C_STRTAG: C_UNTAG; -+ scsymp->native->u.syment.n_type = isstruct? T_STRUCT: T_UNION; -+ scsymp->native->u.syment.n_numaux = 1; -+ scsymp->symbol.udata.p = NULL; -+ scsymp->symbol.value = 0; -+ -+ shash->native = scsymp->native; -+ -+ /* Synthesize a new internal COFF symbol for the end of struct/union. */ -+ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (ecsymp == NULL) -+ return FALSE; -+ -+ ecsymp->symbol.name = ".eos"; -+ ecsymp->symbol.flags = BSF_NOT_AT_END; -+ /* We need to use the com section here since bfd/coffgen.c -+ translates this into an N_UNDEF one without clobbering the -+ value. */ -+ ecsymp->symbol.section = bfd_com_section_ptr; -+ ecsymp->native->u.syment.n_sclass = C_EOS; -+ ecsymp->symbol.udata.p = NULL; -+ ecsymp->symbol.value = tst->u.ts_struct.size; -+ ecsymp->native->u.syment.n_numaux = 1; -+ (ecsymp->native + 1)->fix_tag = 1; -+ aux = &((ecsymp->native + 1)->u.auxent); -+ aux->x_sym.x_tagndx.p = scsymp->native; -+ aux->x_sym.x_misc.x_lnsz.x_size = tst->u.ts_struct.size; -+ -+ coff_record_symbol (info, scsymp); -+ -+ savedtst = info->tstack; -+ -+ if (isstruct) -+ { -+ /* First, make a quick walk along all the fields, and figure out -+ * whether we've got a genuine struct or a bitfield struct. */ -+ for (i = 0, fp = tst->u.ts_struct.fields; -+ i < tst->u.ts_struct.nfields; -+ i++, fp++) -+ if (fp->bitsize % 8 != 0) -+ { -+ isbitfield = TRUE; -+ break; -+ } -+ } -+ -+ sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU; -+ -+ for (i = 0, fp = tst->u.ts_struct.fields; -+ i < tst->u.ts_struct.nfields; -+ i++, fp++) -+ { -+ if (strlen (fp->name) == 0) -+ { -+ /* empty name could happen inside bitfield */ -+ fp->types = NULL; -+ continue; -+ } -+ -+ info->tstack = fp->types; -+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (fp->name); -+ csymp->symbol.flags = BSF_NOT_AT_END; -+ csymp->symbol.section = bfd_com_section_ptr; -+ csymp->native->u.syment.n_sclass = sclass; -+ csymp->symbol.value = isbitfield? fp->bitpos: fp->bitpos / 8; -+ if (isbitfield) -+ { -+ csymp->native->u.syment.n_numaux = 1; -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_sym.x_misc.x_lnsz.x_size = fp->bitsize; -+ } -+ -+ coff_record_symbol (info, csymp); -+ -+ fp->types = NULL; -+ } -+ -+ info->tstack = savedtst; -+ -+ /* Record our endndx field for later fixing. */ -+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); -+ fixp->native = scsymp->native + 1; /* points to first AUX */ -+ fixp->next = NULL; -+ if (info->fixes == NULL) -+ info->fixes = fixp; -+ else -+ { -+ for (ofp = info->fixes; ofp->next != NULL;) -+ ofp = ofp->next; -+ ofp->next = fixp; -+ } -+ -+ coff_record_symbol (info, ecsymp); -+ info->flags |= COFF_FL_FIX_ENDNDX; -+ -+ return TRUE; -+} -+ -+static bfd_boolean coff_emit_enum (info, tst, ehash) -+ struct coff_write_handle *info; -+ struct coff_type_stack *tst; -+ struct coff_enum_hash_entry *ehash; -+{ -+ coff_symbol_type *csymp, *scsymp, *ecsymp; -+ union internal_auxent *aux; -+ struct coff_fix_stack *fixp, *ofp; -+ int i; -+ -+ if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == -+ COFF_FL_AVR) -+ /* old AVR COFF doesn't support enum debugging */ -+ return TRUE; -+ -+ /* Synthesize a new internal COFF symbol for the enum. */ -+ scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (scsymp == NULL) -+ return FALSE; -+ -+ if (tst->u.ts_enum.tagismalloced) -+ scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag); -+ else -+ scsymp->symbol.name = tst->u.ts_enum.tag.fixtag; -+ scsymp->symbol.flags = BSF_NOT_AT_END; -+ scsymp->symbol.section = bfd_und_section_ptr; -+ scsymp->native->u.syment.n_sclass = C_ENTAG; -+ scsymp->native->u.syment.n_type = T_ENUM; -+ scsymp->native->u.syment.n_numaux = 1; -+ scsymp->symbol.udata.p = NULL; -+ scsymp->symbol.value = 0; -+ -+ ehash->native = scsymp->native; -+ -+ /* Synthesize a new internal COFF symbol for the end of struct/union. */ -+ ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (ecsymp == NULL) -+ return FALSE; -+ -+ ecsymp->symbol.name = ".eos"; -+ ecsymp->symbol.flags = BSF_NOT_AT_END; -+ /* We need to use the com section here since bfd/coffgen.c -+ translates this into an N_UNDEF one without clobbering the -+ value. */ -+ ecsymp->symbol.section = bfd_com_section_ptr; -+ ecsymp->native->u.syment.n_sclass = C_EOS; -+ ecsymp->symbol.udata.p = NULL; -+ ecsymp->symbol.value = info->enumsize; -+ ecsymp->native->u.syment.n_numaux = 1; -+ (ecsymp->native + 1)->fix_tag = 1; -+ aux = &((ecsymp->native + 1)->u.auxent); -+ aux->x_sym.x_tagndx.p = scsymp->native; -+ aux->x_sym.x_misc.x_lnsz.x_size = info->enumsize; -+ -+ coff_record_symbol (info, scsymp); -+ -+ for (i = 0;; i++) -+ { -+ const char *name = tst->u.ts_enum.names[i]; -+ if (name == NULL) -+ break; -+ -+ /* Synthesize a new internal COFF symbol for the enum. */ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (name); -+ csymp->symbol.flags = BSF_NOT_AT_END; -+ csymp->symbol.section = bfd_com_section_ptr; -+ csymp->native->u.syment.n_sclass = C_MOE; -+ csymp->symbol.udata.p = NULL; -+ csymp->symbol.value = tst->u.ts_enum.vals[i]; -+ -+ coff_record_symbol (info, csymp); -+ } -+ -+ /* Record our endndx field for later fixing. */ -+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); -+ fixp->native = scsymp->native + 1; /* points to first AUX */ -+ fixp->next = NULL; -+ if (info->fixes == NULL) -+ info->fixes = fixp; -+ else -+ { -+ for (ofp = info->fixes; ofp->next != NULL;) -+ ofp = ofp->next; -+ ofp->next = fixp; -+ } -+ -+ coff_record_symbol (info, ecsymp); -+ info->flags |= COFF_FL_FIX_ENDNDX; -+ -+ return TRUE; -+} -+ -+/* Emit a non-debugging symbol that came from the input symbol table, -+ and has not been claimed by one of the debugging symbols. */ -+static bfd_boolean -+coff_emit_ndebug_sym (info, osymp, localp) -+ struct coff_write_handle *info; -+ asymbol *osymp; -+ bfd_boolean localp; -+{ -+ coff_symbol_type *csymp; -+ -+ /* Create new COFF symbol. */ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (osymp->name); -+ csymp->symbol.value = osymp->value; -+ csymp->symbol.flags = localp? BSF_LOCAL: BSF_GLOBAL; -+ csymp->symbol.section = osymp->section; -+ csymp->symbol.udata.p = NULL; -+ csymp->native->u.syment.n_sclass = localp? C_STAT: C_EXT; -+ csymp->native->u.syment.n_type = T_NULL; -+ -+ coff_record_symbol (info, csymp); -+ -+ return TRUE; -+} -+ -+/* The general routine to write out COFF debugging information. This -+ synthesizes and accumulates the COFF symbols. Actual symbol table -+ output is performed later on by the BFD functions. ABFD is the BFD -+ and DHANDLE is the handle for the debugging information. symcountp -+ and symppp point to the incoming (parsed) symbol list on entry, and -+ will be updated to point to the new symbol table's values upon -+ exit. */ -+ -+bfd_boolean -+write_coff_debugging_info (abfd, dhandle, symcountp, symppp) -+ bfd *abfd; -+ PTR dhandle; -+ long *symcountp; -+ asymbol ***symppp; -+{ -+ struct coff_write_handle info; -+ long i, l; -+ asymbol *symp; -+ struct coff_compilation_unit *up; -+ coff_symbol_type *csymp; -+ -+ memset ((void *)&info, 0, sizeof info); -+ -+ info.abfd = abfd; -+ -+ info.pointersize = info.enumsize = 4; -+ -+ switch (bfd_get_arch (abfd)) -+ { -+ case bfd_arch_avr: -+ info.flags |= COFF_FL_AVR; -+ if (strcmp (abfd->xvec->name, "coff-ext-avr") == 0) -+ info.flags |= COFF_FL_EXT_AVR; -+ /* Fix the builtin type sizes. */ -+ coff_predef_types[0].size = 2; /* sizeof(int) == 2 */ -+ coff_predef_types[4].size = 4; /* sizeof(double) == 4 */ -+ coff_predef_types[6].size = 2; /* sizeof(unsigned int) == 2 */ -+ info.pointersize = info.enumsize = 2; -+ break; -+ -+ default: -+ ; -+ } -+ -+ coff_copy_symbols(&info, *symcountp, *symppp); -+ -+ if (info.textsect == NULL) -+ { -+ fprintf (stderr, _("Warning: no \"text\" section found in output file\n")); -+ info.textsect = bfd_abs_section_ptr; -+ } -+ if (info.datasect == NULL) -+ { -+ fprintf (stderr, _("Warning: no \"data\" section found in output file\n")); -+ info.datasect = bfd_abs_section_ptr; -+ } -+ -+ if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc, -+ sizeof(struct coff_name_type_hash_entry))) -+ return FALSE; -+ -+ if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc, -+ sizeof(struct coff_struct_hash_entry))) -+ return FALSE; -+ -+ if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc, -+ sizeof(struct coff_enum_hash_entry))) -+ return FALSE; -+ -+ if (! debug_write (dhandle, &coff_fns, (PTR) &info)) -+ return FALSE; -+ -+ /* If there is an old compilation unit that has got any local -+ non-debugging symbols left over, send them out now. */ -+ if (info.currentfile != NULL && info.currentfile->totsyms != 0) -+ for (i = 0; i < info.currentfile->nsyms; i++) -+ { -+ up = info.currentfile; -+ -+ if (up->syms[i] != NULL) -+ { -+ coff_emit_ndebug_sym (&info, up->syms[i], TRUE); -+ up->syms[i] = NULL; -+ up->totsyms--; -+ } -+ } -+ -+ /* See whether there are any non-debugging symbols left from the -+ input symbol table. First look at all local symbols which must -+ be from entire compilation units we didn't see yet in the -+ debugging information, because anything else has already been -+ handled at the end of each compilation unit (like in the loop -+ immediately above). Any compilation unit that has already been -+ processed that way is supposed to have its "totsyms" counted down -+ to 0 now, so we can skip them. -+ -+ Finally, put out all remaining global non-debugging symbols. */ -+ for (l = 0; l < info.nunits; l++) -+ { -+ const char *bn; -+ -+ up = info.units + l; -+ if (up->totsyms == 0) -+ continue; -+ -+ /* Create COFF symbol for this compilation unit. */ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info.abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ bn = bu_basename (up->fname); -+ -+ if (bfd_coff_long_filenames (info.abfd)) -+ csymp->symbol.name = up->fname; -+ else -+ csymp->symbol.name = bn; -+ -+ csymp->symbol.value = 0; -+ csymp->symbol.udata.p = NULL; -+ csymp->native->u.syment.n_sclass = C_FILE; -+ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ -+ coff_record_symbol (&info, csymp); -+ -+ for (i = 0; i < up->nsyms; i++) -+ { -+ symp = up->syms[i]; -+ if (symp == NULL) -+ continue; -+ -+ coff_emit_ndebug_sym (&info, symp, TRUE); -+ } -+ } -+ -+ for (i = 0; i < info.nglobals; i++) -+ { -+ symp = info.globals[i]; -+ if (symp == NULL) -+ continue; -+ -+ coff_emit_ndebug_sym (&info, symp, FALSE); -+ } -+ -+ /* Fixup the AUX entries for the section symbols we have emitted -+ earlier (so they are guaranteed to be at the beginning of the -+ symbol table). In particular, the line number count (which we -+ only have for the text section) is known right now. */ -+ for (i = 0; i < info.nsecsyms; i++) -+ { -+ union internal_auxent *aux; -+ -+ csymp = info.secsyms[i]; -+ -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_scn.x_scnlen = csymp->symbol.section->output_section->rawsize; -+ aux->x_scn.x_nreloc = csymp->symbol.section->reloc_count; -+ if (csymp->symbol.section == info.textsect) -+ aux->x_scn.x_nlinno = info.totlnos; -+ } -+ free (info.secsyms); -+ -+ coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL); -+ bfd_hash_table_free (&info.types.root); -+ -+ coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL); -+ bfd_hash_table_free (&info.structs.root); -+ -+ coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL); -+ bfd_hash_table_free (&info.enums.root); -+ -+ /* FIXME: free all the other stuff remembered in "info". */ -+ -+ free (*symppp); -+ -+ *symcountp = info.nsyms; -+ *symppp = (asymbol **)info.syms; -+ -+ return TRUE; -+} -+ -+/* Start writing out information for a compilation unit. */ -+ -+static bfd_boolean -+coff_start_compilation_unit (p, filename) -+ PTR p; -+ const char *filename; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ long i; -+ const char *bn; -+ bfd_boolean found; -+ coff_symbol_type *csymp; -+ -+#if COFF_DEBUG -+ printf ("coff_start_compilation_unit(%s)\n", filename); -+#endif -+ -+ /* If there is an old compilation unit that has got any local -+ non-debugging symbols left over, send them out now. */ -+ if (info->currentfile != NULL && info->currentfile->totsyms != 0) -+ for (i = 0; i < info->currentfile->nsyms; i++) -+ { -+ struct coff_compilation_unit *up = info->currentfile; -+ -+ if (up->syms[i] != NULL) -+ { -+ coff_emit_ndebug_sym (info, up->syms[i], TRUE); -+ up->syms[i] = NULL; -+ up->totsyms--; -+ } -+ } -+ -+ /* symtab (and thus COFF debugging) symbols can only transfer the -+ basename of the file, so strip the dirname */ -+ bn = bu_basename (filename); -+ -+ for (i = 0, found = FALSE; i < info->nunits; i++) -+ { -+ if (strcmp (info->units[i].fname, bn) == 0) -+ { -+ info->currentfile = info->units + i; -+ found = TRUE; -+ break; -+ } -+ } -+ if (!found) -+ { -+ fprintf(stderr, -+ _("Warning: file %s not found in symbol table, ignoring\n"), -+ filename); -+ info->currentfile = NULL; -+ return TRUE; -+ } -+ -+ /* Synthesize a new internal COFF symbol. */ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ /* Note that coff_fix_symbol_name() [coffgen.c] will fix this for -+ us: the symbol name will be replaced by ".file", and the filename -+ will be moved to the aux entries. We use the long name obtained -+ from the debugging information (that includes the full path) if -+ our COFF format supports long filenames, otherwise we only use -+ the basename of the file. */ -+ if (bfd_coff_long_filenames (info->abfd)) -+ csymp->symbol.name = filename; -+ else -+ csymp->symbol.name = bn; -+ csymp->symbol.value = 0; -+ csymp->symbol.udata.p = NULL; -+ csymp->native->u.syment.n_sclass = C_FILE; -+ csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ -+ coff_record_symbol (info, csymp); -+ -+ return TRUE; -+} -+ -+/* Start writing out information for a particular source file. */ -+ -+static bfd_boolean -+coff_start_source (p, filename) -+ PTR p ATTRIBUTE_UNUSED; -+ const char *filename ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_start_source(%s)\n", filename); -+#endif -+ -+ /* COFF cannot handle include filenames. */ -+ -+ return TRUE; -+} -+ -+/* Push an empty type. This shouldn't normally happen. */ -+ -+static bfd_boolean -+coff_empty_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_empty_type()\n"); -+#endif -+ -+ coff_push_type (TS_EMPTY); -+ -+ return TRUE; -+} -+ -+/* Push a void type. */ -+ -+static bfd_boolean -+coff_void_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_void_type()\n"); -+#endif -+ -+ coff_push_type (TS_VOID); -+ -+ return TRUE; -+} -+ -+/* Push an integer type. */ -+ -+static bfd_boolean -+coff_int_type (p, size, unsignedp) -+ PTR p; -+ unsigned int size; -+ bfd_boolean unsignedp; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_int_type(%d, %d)\n", size, unsignedp); -+#endif -+ -+ coff_push_type (TS_INT); -+ tst->u.ts_int.size = size; -+ tst->u.ts_int.isunsigned = unsignedp; -+ -+ return TRUE; -+} -+ -+/* Push a floating point type. */ -+ -+static bfd_boolean -+coff_float_type (p, size) -+ PTR p; -+ unsigned int size; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_float_type(%d)\n", size); -+#endif -+ -+ coff_push_type (TS_FLOAT); -+ tst->u.ts_float.size = size; -+ -+ return TRUE; -+} -+ -+/* Push a complex type. */ -+ -+static bfd_boolean -+coff_complex_type (p, size) -+ PTR p; -+ unsigned int size ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_complex_type(%d)\n", size); -+#endif -+ -+ coff_push_type (TS_COMPLEX); -+ -+ return TRUE; -+} -+ -+/* Push a bfd_boolean type. */ -+ -+static bfd_boolean -+coff_bool_type (p, size) -+ PTR p; -+ unsigned int size; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_bool_type(%d)\n", size); -+#endif -+ -+ coff_push_type (TS_INT); -+ tst->u.ts_int.size = size; -+ tst->u.ts_int.isunsigned = TRUE; -+ -+ return TRUE; -+} -+ -+/* Push an enum type. */ -+ -+static bfd_boolean -+coff_enum_type (p, tag, names, vals) -+ PTR p; -+ const char *tag; -+ const char **names; -+ bfd_signed_vma *vals; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ char buf[20]; -+ -+#if COFF_DEBUG -+ int idx; -+ printf ("coff_enum_type(%s [", tag); -+ for (idx = 0; names[idx] != NULL; idx++) -+ printf ("%s -> %d, ", names[idx], (int)vals[idx]); -+ printf ("])\n"); -+#endif -+ -+ coff_push_type (TS_ENUM); -+ -+ if (tag == NULL) -+ { -+ sprintf(buf, ".%dfake", info->nenums++); -+ tst->u.ts_enum.tag.malloctag = xstrdup (buf); -+ tst->u.ts_enum.tagismalloced = TRUE; -+ } -+ else -+ tst->u.ts_enum.tag.fixtag = tag; -+ tst->u.ts_enum.names = names; -+ tst->u.ts_enum.vals = vals; -+ -+ return TRUE; -+} -+ -+/* Push a pointer type. */ -+ -+static bfd_boolean -+coff_pointer_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_pointer_type()\n"); -+#endif -+ -+ coff_push_type (TS_POINTER); -+ -+ return TRUE; -+} -+ -+/* Push a function type. */ -+ -+static bfd_boolean -+coff_function_type (p, argcount, varargs) -+ PTR p; -+ int argcount; -+ bfd_boolean varargs ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_function_type(%d, %d)\n", argcount, varargs); -+#endif -+ -+ coff_push_type (TS_FUNC); -+ -+ /* FIXME should properly discard function arguments */ -+ if (argcount > -1) -+ { -+ fprintf (stderr, -+ _("coff_function_type() called with positive argcount\n")); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+/* Push a reference type. */ -+ -+static bfd_boolean -+coff_reference_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_reference_type()\n"); -+#endif -+ -+ coff_complain_unsupp (_("reference")); -+ -+ return TRUE; -+} -+ -+/* Push a range type. */ -+ -+static bfd_boolean -+coff_range_type (p, low, high) -+ PTR p; -+ bfd_signed_vma low ATTRIBUTE_UNUSED; -+ bfd_signed_vma high ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_range_type([%d..%d)\n", (int)low, (int)high); -+#endif -+ -+ coff_complain_unsupp (_("range")); -+ -+ return TRUE; -+} -+ -+/* Push an array type. */ -+ -+static bfd_boolean -+coff_array_type (p, low, high, stringp) -+ PTR p; -+ bfd_signed_vma low; -+ bfd_signed_vma high; -+ bfd_boolean stringp; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst; -+ -+#if COFF_DEBUG -+ printf ("coff_array_type([%d..%d], %d)\n", -+ (int)low, (int)high, stringp); -+#endif -+ -+ /* Pop the range type, but ignore it. COFF doesn't use it. */ -+ coff_pop_type (); -+ -+ /* FIXME What to do here? */ -+ if (stringp) -+ { -+ fprintf(stderr, _("coff_array_type(): stringp == TRUE\n")); -+ return FALSE; -+ } -+ -+ coff_push_type (TS_ARRAY); -+ tst->u.ts_array.low = low; -+ tst->u.ts_array.high = high; -+ -+ return TRUE; -+} -+ -+/* Push a set type. */ -+ -+static bfd_boolean -+coff_set_type (p, bitstringp) -+ PTR p; -+ bfd_boolean bitstringp ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_set_type(%d)\n", bitstringp); -+#endif -+ -+ coff_complain_unsupp (_("set")); -+ -+ return TRUE; -+} -+ -+/* Push an offset type. */ -+ -+static bfd_boolean -+coff_offset_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_offset_type()\n"); -+#endif -+ -+ coff_complain_unsupp (_("offset")); -+ -+ return TRUE; -+} -+ -+/* Push a method type. */ -+ -+static bfd_boolean -+coff_method_type (p, domainp, argcount, varargs) -+ PTR p; -+ bfd_boolean domainp ATTRIBUTE_UNUSED; -+ int argcount ATTRIBUTE_UNUSED; -+ bfd_boolean varargs ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_method_type(%d, %d, %d)\n", -+ domainp, argcount, varargs); -+#endif -+ -+ coff_complain_unsupp (_("method")); -+ -+ return TRUE; -+} -+ -+/* Push a const version of a type. */ -+ -+static bfd_boolean -+coff_const_type (p) -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_const_type()\n"); -+#endif -+ -+ /* const modifier is ignored by COFF */ -+ -+ return TRUE; -+} -+ -+/* Push a volatile version of a type. */ -+ -+static bfd_boolean -+coff_volatile_type (p) -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_volatile_type()\n"); -+#endif -+ -+ /* volatile modifier is ignored by COFF */ -+ -+ return TRUE; -+} -+ -+/* Start outputting a struct. */ -+ -+static bfd_boolean -+coff_start_struct_type (p, tag, id, structp, size) -+ PTR p; -+ const char *tag; -+ unsigned int id; -+ bfd_boolean structp; -+ unsigned int size; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *savedts; -+ struct coff_struct_hash_entry *shash; -+ char buf[20]; -+ const char *name; -+ -+#if COFF_DEBUG -+ printf ("coff_start_struct_type(%s, %d, %d, %d)\n", -+ tag, id, structp, size); -+#endif -+ -+ savedts = info->tstack; -+ info->tstack = NULL; -+ -+ coff_push_type (TS_STRUCT); -+ -+ if (tag == NULL) -+ { -+ sprintf(buf, ".%dfake", id); -+ name = tst->u.ts_struct.tag.malloctag = xstrdup (buf); -+ tst->u.ts_struct.tagismalloced = TRUE; -+ } -+ else -+ name = tst->u.ts_struct.tag.fixtag = tag; -+ tst->u.ts_struct.id = id; -+ tst->u.ts_struct.isstruct = structp; -+ tst->u.ts_struct.size = size; -+ tst->u.ts_struct.savedts = savedts; -+ -+ shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE); -+ if (shash != NULL && shash->types != NULL) -+ { -+#if COFF_DEBUG -+ printf ("new %s definition for %s\n", -+ tst->u.ts_struct.isstruct? "struct": "union", name); -+#endif -+ coff_free_struct_info (shash, NULL); -+ shash->types = NULL; -+ shash->emitted = FALSE; -+ } -+ else -+ (void)coff_struct_hash_lookup (&info->structs, name, -+ TRUE, tst->u.ts_struct.tagismalloced); -+ -+ return TRUE; -+} -+ -+/* Add a field to a struct. */ -+ -+static bfd_boolean -+coff_struct_field (p, name, bitpos, bitsize, visibility) -+ PTR p; -+ const char *name; -+ bfd_vma bitpos; -+ bfd_vma bitsize; -+ enum debug_visibility visibility; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *otst; -+ struct coff_struct_fields *fp; -+ struct coff_struct_hash_entry *shash; -+ struct coff_enum_hash_entry *ehash; -+ const char *tag; -+ -+#if COFF_DEBUG -+ printf ("coff_struct_field(%s, %d, %d, %d)\n", -+ name, (int)bitpos, (int)bitsize, (int)visibility); -+#endif -+ -+ /* Find the last element on the type stack. */ -+ assert (info->tstack != NULL); -+ for (tst = info->tstack, otst = NULL; tst->next != NULL;) -+ { -+ otst = tst; -+ tst = tst->next; -+ } -+ if (otst != NULL) -+ otst->next = NULL; -+ -+ if (tst->tsk != TS_STRUCT) -+ { -+ fprintf (stderr, "coff_struct_field() not within structure definition\n"); -+ return FALSE; -+ } -+ tst->u.ts_struct.fields = (struct coff_struct_fields *) -+ xrealloc (tst->u.ts_struct.fields, -+ ++tst->u.ts_struct.nfields * sizeof (struct coff_struct_fields)); -+ fp = tst->u.ts_struct.fields + (tst->u.ts_struct.nfields - 1); -+ fp->name = name; -+ fp->bitpos = bitpos; -+ fp->bitsize = bitsize; -+ fp->visibility = visibility; -+ otst = fp->types = info->tstack; -+ while (otst->next != NULL) -+ otst = otst->next; -+ if (otst->tsk == TS_STRUCT && otst->u.ts_struct.shash == NULL) -+ { -+ if (otst->u.ts_struct.tagismalloced) -+ tag = otst->u.ts_struct.tag.malloctag; -+ else -+ tag = otst->u.ts_struct.tag.fixtag; -+ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); -+ assert (shash != NULL); -+ if (!shash->emitted) -+ { -+ if (shash->types == NULL) -+ { -+ shash->types = (struct coff_type_stack *) -+ xmalloc (sizeof (struct coff_type_stack)); -+ memcpy (shash->types, otst, sizeof (struct coff_type_stack)); -+ } -+ shash->emitted = TRUE; -+ coff_emit_struct (info, otst, shash); -+ } -+ } -+ else if (otst->tsk == TS_ENUM) -+ { -+ if (otst->u.ts_enum.tagismalloced) -+ tag = otst->u.ts_enum.tag.malloctag; -+ else -+ tag = otst->u.ts_enum.tag.fixtag; -+ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); -+ assert (ehash != NULL); -+ if (!ehash->emitted) -+ { -+ if (ehash->types == NULL) -+ { -+ ehash->types = (struct coff_type_stack *) -+ xmalloc (sizeof (struct coff_type_stack)); -+ memcpy (ehash->types, otst, sizeof (struct coff_type_stack)); -+ } -+ ehash->emitted = TRUE; -+ coff_emit_enum (info, otst, ehash); -+ } -+ } -+ -+ info->tstack = tst; -+ -+ return TRUE; -+} -+ -+/* Finish up a struct. */ -+ -+static bfd_boolean -+coff_end_struct_type (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *savedts; -+ -+#if COFF_DEBUG -+ printf ("coff_end_struct_type()\n"); -+#endif -+ -+ /* Our struct definition should be the only type stack element by -+ now. */ -+ assert (info->tstack != NULL); -+ tst = info->tstack; -+ if (tst->tsk != TS_STRUCT || tst->next != NULL) -+ { -+ fprintf (stderr, "coff_struct_field() not within structure definition\n"); -+ return FALSE; -+ } -+ -+ /* Restore saved type stack, and push our now complete struct -+ definition on top. */ -+ savedts = tst->u.ts_struct.savedts; -+ tst->u.ts_struct.savedts = info->tstack; -+ info->tstack = savedts; -+ tst->next = info->tstack; -+ info->tstack = tst; -+ -+ return TRUE; -+} -+ -+/* Start outputting a class. */ -+ -+static bfd_boolean -+coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr) -+ PTR p; -+ const char *tag ATTRIBUTE_UNUSED; -+ unsigned int id ATTRIBUTE_UNUSED; -+ bfd_boolean structp ATTRIBUTE_UNUSED; -+ unsigned int size ATTRIBUTE_UNUSED; -+ bfd_boolean vptr ATTRIBUTE_UNUSED; -+ bfd_boolean ownvptr ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n", -+ tag, id, structp, size, vptr, ownvptr); -+#endif -+ -+ coff_complain_unsupp (_("class")); -+ -+ return TRUE; -+} -+ -+/* Add a static member to the class on the type stack. */ -+ -+static bfd_boolean -+coff_class_static_member (p, name, physname, visibility) -+ PTR p ATTRIBUTE_UNUSED; -+ const char *name ATTRIBUTE_UNUSED; -+ const char *physname ATTRIBUTE_UNUSED; -+ enum debug_visibility visibility ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_static_member(%s, %s, %d)\n", -+ name, physname, (int)visibility); -+#endif -+ -+ return TRUE; -+} -+ -+/* Add a base class to the class on the type stack. */ -+ -+static bfd_boolean -+coff_class_baseclass (p, bitpos, virtual, visibility) -+ PTR p ATTRIBUTE_UNUSED; -+ bfd_vma bitpos ATTRIBUTE_UNUSED; -+ bfd_boolean virtual ATTRIBUTE_UNUSED; -+ enum debug_visibility visibility ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_baseclass(%d, %d, %d)\n", -+ (int)bitpos, virtual, (int)visibility); -+#endif -+ -+ return TRUE; -+} -+ -+/* Start adding a method to the class on the type stack. */ -+ -+static bfd_boolean -+coff_class_start_method (p, name) -+ PTR p ATTRIBUTE_UNUSED; -+ const char *name ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_start_method(%s)\n", name); -+#endif -+ -+ return TRUE; -+} -+ -+/* Add a variant to the current method. */ -+ -+static bfd_boolean -+coff_class_method_variant (p, physname, visibility, constp, volatilep, -+ voffset, contextp) -+ PTR p ATTRIBUTE_UNUSED; -+ const char *physname ATTRIBUTE_UNUSED; -+ enum debug_visibility visibility ATTRIBUTE_UNUSED; -+ bfd_boolean constp ATTRIBUTE_UNUSED; -+ bfd_boolean volatilep ATTRIBUTE_UNUSED; -+ bfd_vma voffset ATTRIBUTE_UNUSED; -+ bfd_boolean contextp ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n", -+ physname, (int)visibility, constp, volatilep, -+ (int)voffset, contextp); -+#endif -+ -+ return TRUE; -+} -+ -+/* Add a static variant to the current method. */ -+ -+static bfd_boolean -+coff_class_static_method_variant (p, physname, visibility, constp, volatilep) -+ PTR p ATTRIBUTE_UNUSED; -+ const char *physname ATTRIBUTE_UNUSED; -+ enum debug_visibility visibility ATTRIBUTE_UNUSED; -+ bfd_boolean constp ATTRIBUTE_UNUSED; -+ bfd_boolean volatilep ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n", -+ physname, (int)visibility, constp, volatilep); -+#endif -+ -+ return TRUE; -+} -+ -+/* Finish up a method. */ -+ -+static bfd_boolean -+coff_class_end_method (p) -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_class_end_method()\n"); -+#endif -+ -+ return TRUE; -+} -+ -+/* Finish up a class. */ -+ -+static bfd_boolean -+coff_end_class_type (p) -+ PTR p ATTRIBUTE_UNUSED; -+{ -+ -+#if COFF_DEBUG -+ printf ("coff_end_class_type()\n"); -+#endif -+ -+ return TRUE; -+} -+ -+/* Push a typedef which was previously defined. */ -+ -+static bfd_boolean -+coff_typedef_type (p, name) -+ PTR p; -+ const char *name; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_name_type_hash_entry *nthash; -+ struct coff_type_stack *tst, *newchain, *newst, *temp; -+ -+#if COFF_DEBUG -+ printf ("coff_typedef_type(%s)\n", name); -+#endif -+ -+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); -+ -+ /* nthash should never be NULL, since that would imply that the -+ generic debugging code has asked for a typedef which it has not -+ yet defined. */ -+ assert (nthash != NULL); -+ -+ /* Just push the entire type stack snapshot we've got on top of the -+ existing typestack. See coff_typdef() below for how this -+ works. We need to copy over each element however, since anybody -+ popping elements off the typestack is supposed to free() each of -+ them. */ -+ -+ for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;) -+ { -+ temp = newst; -+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); -+ if (newchain == NULL) -+ newchain = newst; -+ memcpy (newst, tst, sizeof (*newst)); -+ if (temp != NULL) -+ temp->next = newst; -+ -+ tst = tst->next; -+ } -+ newst->next = info->tstack; -+ info->tstack = newchain; -+ -+ return TRUE; -+} -+ -+/* Push a struct, union or class tag. */ -+ -+static bfd_boolean -+coff_tag_type (p, name, id, kind) -+ PTR p; -+ const char *name; -+ unsigned int id ATTRIBUTE_UNUSED; -+ enum debug_type_kind kind; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *newchain, *newst, *temp; -+ struct coff_struct_hash_entry *shash; -+ struct coff_enum_hash_entry *ehash; -+ char buf[20]; -+ bfd_boolean needcopy = FALSE; -+ bfd_boolean isstruct = TRUE; -+ -+#if COFF_DEBUG -+ printf ("coff_tag_type(%s, %d, %d)\n", -+ name, id, kind); -+#endif -+ -+ if (name == NULL) -+ { -+ sprintf(buf, ".%dfake", id); -+ needcopy = TRUE; -+ } -+ -+ switch (kind) -+ { -+ case DEBUG_KIND_UNION: -+ case DEBUG_KIND_UNION_CLASS: -+ isstruct = FALSE; -+ /* FALLTHROUGH */ -+ case DEBUG_KIND_STRUCT: -+ case DEBUG_KIND_CLASS: -+ shash = coff_struct_hash_lookup (&info->structs, -+ name == NULL? buf: name, TRUE, needcopy); -+ assert (shash != NULL); -+ tst = shash->types; -+ if (tst == NULL) -+ { -+ /* This is a reference to a tag that has not yet been -+ defined (i. e., a forward reference). Synthesize a -+ ts_struct entry by now, and mark it for later fixup. */ -+ tst = (struct coff_type_stack *) xmalloc (sizeof *tst); -+ memset (tst, 0, sizeof *tst); -+ tst->tsk = TS_STRUCT; -+ tst->u.ts_struct.isstruct = isstruct; -+ tst->u.ts_struct.shash = shash; -+ } -+ docopystack: -+ /* Just push the entire type stack snapshot we've got on top of the -+ existing typestack. See coff_typdef() below for how this -+ works. We need to copy over each element however, since anybody -+ popping elements off the typestack is supposed to free() each of -+ them. */ -+ for (temp = newst = newchain = NULL; tst != NULL;) -+ { -+ temp = newst; -+ newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); -+ if (newchain == NULL) -+ newchain = newst; -+ memcpy (newst, tst, sizeof (*newst)); -+ if (temp != NULL) -+ temp->next = newst; -+ -+ tst = tst->next; -+ } -+ if (newst) -+ { -+ newst->next = info->tstack; -+ info->tstack = newchain; -+ } -+ break; -+ -+ case DEBUG_KIND_ENUM: -+ ehash = coff_enum_hash_lookup (&info->enums, -+ name == NULL? buf: name, TRUE, needcopy); -+ assert (ehash != NULL); -+ tst = ehash->types; -+ if (tst == NULL) -+ { -+ /* This is a reference to a tag that has not yet been -+ defined (i. e., a forward reference). Synthesize a -+ ts_enum entry by now, and mark it for later fixup. */ -+ tst = (struct coff_type_stack *) xmalloc (sizeof *tst); -+ memset (tst, 0, sizeof *tst); -+ tst->tsk = TS_ENUM; -+ tst->u.ts_enum.ehash = ehash; -+ } -+ goto docopystack; -+ -+ default: -+ fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"), -+ (int)kind); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+/* Define a typedef. */ -+ -+static bfd_boolean -+coff_typdef (p, name) -+ PTR p; -+ const char *name; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_name_type_hash_entry *nthash; -+ -+#if COFF_DEBUG -+ printf ("coff_typdef(%s)\n", name); -+#endif -+ -+ /* COFF cannot really handle typedefs. While there is the option to -+ mark a symbol using the storage class C_TPDEF (so the COFF reader -+ will know that name), there is no way to place a reference to -+ that typedef into the just 16 bits COFF reserves for all of its -+ type information. Thus, any use of the typedef must always fully -+ dereference the typedef again. We do this by "snapshotting" the -+ current type stack under the name of our typedef, and later on, -+ when BFD debugging tells us to make use of the typedef (in -+ coff_typedef_type()), we just look it up, and push all we've got -+ completely onto the type stack again. */ -+ -+ if (info->tstack == NULL) -+ { -+ fprintf (stderr, _("coff_typdef() on an empty type stack\n")); -+ return FALSE; -+ } -+ -+ nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); -+ if (nthash != NULL) -+ { -+#if COFF_DEBUG -+ printf ("new typedef for %s\n", name); -+#endif -+ coff_free_type_info (nthash, NULL); -+ } -+ else -+ nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE); -+ if (nthash == NULL) -+ return FALSE; -+ nthash->types = info->tstack; -+ -+ /* If the typestack is "sufficiently complex", emit a C_TPDEF symbol -+ for it. We assume it to be sufficiently complex if there are -+ either at least two derived types, or one derived type where the -+ base type is not a simple scalar one. */ -+ if (!nthash->emitted -+ && info->tstack->next != NULL -+ && (info->tstack->next->next != NULL || info->tstack->next->tsk >= TS_ENUM)) -+ { -+ struct coff_type_stack *newchain, *otst, *tst, *ntst; -+ coff_symbol_type *csymp; -+ -+ nthash->emitted = TRUE; -+ -+ for (tst = info->tstack, newchain = otst = NULL; -+ tst != NULL; -+ tst = tst->next) -+ { -+ ntst = (struct coff_type_stack *) -+ xmalloc (sizeof (struct coff_type_stack)); -+ memcpy (ntst, tst, sizeof (struct coff_type_stack)); -+ if (otst == NULL) -+ newchain = ntst; -+ else -+ otst->next = ntst; -+ otst = ntst; -+ } -+ info->tstack = newchain; -+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) -+ return FALSE; -+ -+ csymp->symbol.name = xstrdup (name); -+ csymp->symbol.flags = BSF_NOT_AT_END; -+ csymp->symbol.section = bfd_com_section_ptr; -+ csymp->native->u.syment.n_sclass = C_TPDEF; -+ csymp->symbol.value = 0; -+ -+ coff_record_symbol (info, csymp); -+ } -+ info->tstack = NULL; -+ -+ return TRUE; -+} -+ -+/* Define a tag. */ -+ -+static bfd_boolean -+coff_tag (p, tag) -+ PTR p; -+ const char *tag; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst = NULL; -+ struct coff_struct_hash_entry *shash; -+ struct coff_enum_hash_entry *ehash; -+ -+ -+#if COFF_DEBUG -+ printf ("coff_tag(%s)\n", tag); -+#endif -+ -+ if (info->tstack == NULL) -+ { -+ fprintf (stderr, _("coff_tag() called on an empty typestack\n")); -+ return FALSE; -+ } -+ -+ switch (info->tstack->tsk) -+ { -+ case TS_STRUCT: -+ shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); -+ assert (shash != NULL); -+ shash->types = info->tstack; -+ info->tstack = NULL; -+ break; -+ -+ case TS_ENUM: -+ ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE); -+ if (ehash != NULL && ehash->types != NULL) -+ { -+#if COFF_DEBUG -+ printf ("new enum definition for %s\n", tag); -+#endif -+ coff_free_enum_info (ehash, NULL); -+ } -+ else -+ ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); -+ if (ehash == NULL) -+ return FALSE; -+ ehash->types = info->tstack; -+ info->tstack = NULL; -+ break; -+ -+ default: -+ fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+/* Define an integer constant. */ -+ -+static bfd_boolean -+coff_int_constant (p, name, val) -+ PTR p; -+ const char *name ATTRIBUTE_UNUSED; -+ bfd_vma val ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_int_constant(%s, %d)\n", name, (int)val); -+#endif -+ -+ coff_complain_unsupp (_("int constant")); -+ -+ return TRUE; -+} -+ -+/* Define a floating point constant. */ -+ -+static bfd_boolean -+coff_float_constant (p, name, val) -+ PTR p; -+ const char *name ATTRIBUTE_UNUSED; -+ double val ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_float_constant(%s, %g)\n", name, val); -+#endif -+ -+ coff_complain_unsupp (_("float constant")); -+ -+ return TRUE; -+} -+ -+/* Define a typed constant. */ -+ -+static bfd_boolean -+coff_typed_constant (p, name, val) -+ PTR p; -+ const char *name ATTRIBUTE_UNUSED; -+ bfd_vma val ATTRIBUTE_UNUSED; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ -+#if COFF_DEBUG -+ printf ("coff_typed_constant(%s, %d)\n", name, (int)val); -+#endif -+ -+ coff_complain_unsupp (_("typed constant")); -+ -+ return TRUE; -+} -+ -+/* Record a variable. */ -+ -+static bfd_boolean -+coff_variable (p, name, kind, val) -+ PTR p; -+ const char *name; -+ enum debug_var_kind kind; -+ bfd_vma val; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ unsigned char class; -+ asymbol *symp = NULL; -+ coff_symbol_type *csymp; -+ bfd_boolean global = FALSE; -+ flagword flags = BSF_LOCAL; -+ bfd_vma vmadiff = 0; -+ -+#if COFF_DEBUG -+ printf ("coff_variable(%s, %d, %d)\n", -+ name, (int)kind, (int)val); -+#endif -+ -+ switch (kind) -+ { -+ default: -+ abort (); -+ -+ case DEBUG_GLOBAL: -+ flags = BSF_GLOBAL; -+ global = TRUE; -+ /* AVR COFF historically used C_EXTDEF for global variables, and -+ C_EXT for global functions. Since some AVR COFF consumers -+ apparently depend on this, we mimic this behaviour as -+ well. */ -+ class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT; -+ break; -+ -+ case DEBUG_STATIC: -+ case DEBUG_LOCAL_STATIC: -+ class = C_STAT; -+ break; -+ -+ case DEBUG_LOCAL: -+ class = C_AUTO; -+ break; -+ -+ case DEBUG_REGISTER: -+ class = C_REG; -+ break; -+ } -+ -+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) -+ return FALSE; -+ -+ if (class == C_REG && (info->flags & COFF_FL_AVR) != 0) -+ { -+ struct coff_private_symdata *priv = (struct coff_private_symdata *) -+ csymp->symbol.udata.p; -+ val = coff_fixup_avr_register (val, priv->size * 8); -+ } -+ -+ csymp->symbol.name = name; -+ csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */ -+ -+ /* Match the debugging symbol against the input symtab symbols. If -+ we found one, use the section information from it. Otherwise, we -+ are lost here and just use the absolute section that was -+ predeclared by coff_bfd_make_debug_symbol(). C_REG and C_AUTO -+ symbols (which we do not attempt to lookup in the symtab symbols -+ at all) go into the ABS section anyway. */ -+ if (class != C_REG && class != C_AUTO) -+ { -+ symp = coff_find_symbol (info, name, FALSE, global); -+ if (symp) -+ { -+ csymp->symbol.section = symp->section; -+ vmadiff = symp->section->vma; -+ } -+ } -+ -+ /* Symbols are relative to section vma. */ -+ csymp->symbol.value = val - vmadiff; -+ csymp->native->u.syment.n_sclass = class; -+ coff_record_symbol (info, csymp); -+ -+ return TRUE; -+} -+ -+/* Start outputting a function. */ -+ -+static bfd_boolean -+coff_start_function (p, name, globalp) -+ PTR p; -+ const char *name; -+ bfd_boolean globalp; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *savedts; -+ -+#if COFF_DEBUG -+ printf ("coff_start_function(%s, %d)\n", -+ name, globalp); -+#endif -+ -+ savedts = info->tstack; -+ info->tstack = NULL; -+ -+ coff_push_type (TS_FUNC); -+ -+ if (info->funname != NULL) -+ { -+ fprintf (stderr, -+ _("coff_start_function() called twice, pending %s, new %s\n"), -+ info->funname, name); -+ return FALSE; -+ } -+ info->funname = name; -+ info->funglobal = globalp; -+ info->flags |= COFF_FL_START_FCN; -+ tst->u.ts_func.savedts = savedts; -+ -+ return TRUE; -+} -+ -+/* Output a function parameter. */ -+ -+static bfd_boolean -+coff_function_parameter (p, name, kind, val) -+ PTR p; -+ const char *name; -+ enum debug_parm_kind kind; -+ bfd_vma val; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ coff_symbol_type *csymp; -+ unsigned char class; -+ -+#if COFF_DEBUG -+ printf ("coff_function_parameter(%s, %d, %d)\n", -+ name, (int)kind, (int)val); -+#endif -+ -+ switch (kind) -+ { -+ default: -+ abort (); -+ -+ case DEBUG_PARM_STACK: -+ class = C_ARG; -+ break; -+ -+ case DEBUG_PARM_REG: -+ class = C_REGPARM; -+ break; -+ -+ case DEBUG_PARM_REFERENCE: -+ case DEBUG_PARM_REF_REG: -+ fprintf (stderr, _("Reference parameters not available in COFF\n")); -+ return TRUE; -+ } -+ -+ if (!coff_make_typed_symbol (info, &csymp, TS_FUNC)) -+ return FALSE; -+ -+ if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0) -+ { -+ struct coff_private_symdata *priv = (struct coff_private_symdata *) -+ csymp->symbol.udata.p; -+ val = coff_fixup_avr_register (val, priv->size * 8); -+ } -+ -+ csymp->symbol.name = name; -+ csymp->symbol.value = val; -+ csymp->symbol.flags |= BSF_LOCAL; -+ csymp->native->u.syment.n_sclass = class; -+ -+ /* Since function parameters precede the actual function definition, -+ defer their output until the function has been created. */ -+ info->fargs = (coff_symbol_type **) -+ xrealloc (info->fargs, ++info->nfargs * sizeof (coff_symbol_type *)); -+ info->fargs[info->nfargs - 1] = csymp; -+ -+ return TRUE; -+} -+ -+/* Start a block. */ -+ -+static bfd_boolean -+coff_start_block (p, addr) -+ PTR p; -+ bfd_vma addr; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ struct coff_type_stack *tst, *otst; -+ struct coff_fix_stack *fixp, *ofp; -+ asymbol *symp; -+ coff_symbol_type *csymp; -+ unsigned int i; -+ bfd_boolean is_start_fcn; -+ -+#if COFF_DEBUG -+ printf ("coff_start_block(%#x)\n", (int)addr); -+#endif -+ -+ is_start_fcn = info->flags & COFF_FL_START_FCN; -+ -+ if (is_start_fcn) -+ { -+ /* This is the starting block of a function. We are going to -+ write three symbols here, one for the function itself, one -+ ".bf" symbol to indicate the begin of the function, and -+ finally one ".bb" for the first block inside the function. */ -+ info->flags &= ~COFF_FL_START_FCN; -+ -+ /* Our function definition should be the only type stack element -+ by now. */ -+ assert (info->tstack != NULL); -+ tst = info->tstack; -+ if (tst->tsk != TS_FUNC || tst->next != NULL) -+ { -+ fprintf (stderr, -+ _("coff_start_block() not within function definition\n")); -+ return FALSE; -+ } -+ -+ /* Restore saved type stack, and push our now complete function -+ definition on top. */ -+ info->tstack = tst->u.ts_func.savedts; -+ tst->next = info->tstack; -+ info->tstack = tst; -+ -+ if (info->currentfile == NULL) -+ { -+ fprintf (stderr, -+ _("Warning: ignoring function %s() outside any compilation unit\n"), -+ info->funname); -+ for (tst = info->tstack, otst = NULL; tst != NULL;) -+ { -+ otst = tst; -+ tst = otst->next; -+ if (otst->tsk == TS_ENUM && -+ otst->u.ts_enum.tagismalloced) -+ free (otst->u.ts_enum.tag.malloctag); -+ else if (otst->tsk == TS_STRUCT && -+ otst->u.ts_struct.tagismalloced) -+ free (otst->u.ts_struct.tag.malloctag); -+ free (otst); -+ } -+ info->tstack = NULL; -+ info->funname = NULL; -+ -+ return TRUE; -+ } -+ -+ if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) -+ return FALSE; -+ -+ csymp->symbol.name = info->funname; -+ csymp->symbol.flags = BSF_FUNCTION | -+ (info->funglobal? BSF_GLOBAL: BSF_LOCAL); -+ symp = coff_find_symbol (info, info->funname, TRUE, info->funglobal); -+ if (symp == NULL) -+ { -+ fprintf (stderr, -+ _("function %s not found in symbol table, defaulting to \"text\" section\n"), -+ info->funname); -+ csymp->symbol.section = info->funcsection = info->textsect; -+ } -+ else -+ csymp->symbol.section = info->funcsection = symp->section; -+ -+ /* Symbol addresses are relative to section vma. */ -+ csymp->symbol.value = addr - info->funcsection->vma; -+ csymp->native->u.syment.n_sclass = info->funglobal? C_EXT: C_STAT; -+ /* Create two initial line number entries. The first one holds -+ the function symbol, the second one is the trailing record -+ that is required by coffgen.c::coff_write_native_symbol() to -+ have a line number of zero. */ -+ csymp->lineno = (alent *) xmalloc (2 * sizeof (alent)); -+ memset (csymp->lineno, 0, 2 * sizeof (alent)); -+ info->nlnos = 2; -+ info->totlnos++; -+ csymp->lineno[0].u.sym = (asymbol *)csymp; -+ coff_record_symbol (info, csymp); -+ info->funcindex = info->nsyms - 1; /* remember for later */ -+ /* Record our endndx field for later fixing. */ -+ fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); -+ fixp->native = csymp->native + 1; /* points to first AUX */ -+ fixp->next = NULL; -+ if (info->fixes == NULL) -+ info->fixes = fixp; -+ else -+ { -+ for (ofp = info->fixes; ofp->next != NULL;) -+ ofp = ofp->next; -+ ofp->next = fixp; -+ } -+ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = ".bf"; -+ csymp->native->u.syment.n_sclass = C_FCN; -+ csymp->native->u.syment.n_numaux = 1; -+ csymp->symbol.value = addr - info->funcsection->vma; -+ csymp->symbol.section = info->funcsection; -+ csymp->symbol.udata.p = NULL; -+ coff_record_symbol (info, csymp); -+ } -+ -+ if (info->funname == NULL) -+ return TRUE; -+ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = ".bb"; -+ csymp->native->u.syment.n_sclass = C_BLOCK; -+ csymp->native->u.syment.n_numaux = 1; -+ csymp->symbol.value = addr - info->funcsection->vma; -+ csymp->symbol.section = info->funcsection; -+ csymp->symbol.udata.p = NULL; -+ coff_record_symbol (info, csymp); -+ -+ info->flags |= COFF_FL_FIX_BB; -+ -+ /* Output any pending function parameters, if any. */ -+ if (is_start_fcn && info->nfargs) -+ { -+ for (i = 0; i < info->nfargs; i++) -+ coff_record_symbol (info, info->fargs[i]); -+ -+ free (info->fargs); -+ info->fargs = NULL; -+ info->nfargs = 0; -+ } -+ -+ return TRUE; -+} -+ -+/* End a block. */ -+ -+static bfd_boolean -+coff_end_block (p, addr) -+ PTR p; -+ bfd_vma addr; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ coff_symbol_type *csymp; -+ union internal_auxent *aux; -+ -+#if COFF_DEBUG -+ printf ("coff_end_block(%#x)\n", (int)addr); -+#endif -+ -+ if (info->funname == NULL) -+ return TRUE; -+ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = ".eb"; -+ csymp->symbol.value = addr - info->funcsection->vma; -+ csymp->native->u.syment.n_sclass = C_BLOCK; -+ csymp->native->u.syment.n_numaux = 1; -+ csymp->symbol.udata.p = NULL; -+ csymp->symbol.section = info->funcsection; -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; -+ coff_record_symbol (info, csymp); -+ -+ info->endaddr = addr; -+ -+ return TRUE; -+} -+ -+/* End a function. */ -+ -+static bfd_boolean -+coff_end_function (p) -+ PTR p; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ coff_symbol_type *csymp; -+ union internal_auxent *aux; -+ -+#if COFF_DEBUG -+ printf ("coff_end_function()\n"); -+#endif -+ -+ if (info->funname == NULL) -+ return TRUE; -+ -+ csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); -+ if (csymp == NULL) -+ return FALSE; -+ -+ csymp->symbol.name = ".ef"; -+ csymp->symbol.value = info->endaddr - info->funcsection->vma; -+ csymp->native->u.syment.n_sclass = C_FCN; -+ csymp->native->u.syment.n_numaux = 1; -+ csymp->symbol.udata.p = NULL; -+ csymp->symbol.section = info->funcsection; -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; -+ -+ coff_record_symbol (info, csymp); -+ -+ csymp = (coff_symbol_type *) info->syms[info->funcindex]; -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_sym.x_misc.x_fsize = info->endaddr - csymp->symbol.value; -+ -+ info->flags |= COFF_FL_FIX_ENDNDX; -+ info->funname = NULL; -+ -+ return TRUE; -+} -+ -+/* Output a line number. */ -+ -+static bfd_boolean -+coff_lineno (p, file, lineno, addr) -+ PTR p; -+ const char *file ATTRIBUTE_UNUSED; -+ unsigned long lineno; -+ bfd_vma addr; -+{ -+ struct coff_write_handle *info = (struct coff_write_handle *) p; -+ coff_symbol_type *csymp; -+ union internal_auxent *aux; -+ long i; -+ -+#if COFF_DEBUG -+ printf ("coff_lineno(%s, %ld, %d)\n", -+ file, lineno, (int)addr); -+#endif -+ -+ /* COFF can inherently only handle line numbers inside of functions. -+ If we are not inside a function, punt. */ -+ if (info->funname == NULL) -+ return TRUE; -+ -+ if (info->nlnos == 2) -+ { -+ /* This is the first line number of this function. Fix the line -+ number for the .bf symbol immediately following the start of -+ function. We also have to remember the starting line number -+ of our function since all line number entries are relative to -+ it in COFF. Since regular line numbers must always be -+ non-zero, we artificially force the function to start one -+ line earlier. */ -+ csymp = (coff_symbol_type *) info->syms[info->funcindex + 1]; -+ aux = &((csymp->native + 1)->u.auxent); -+ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; -+ info->funlno = lineno - 1; -+ } -+ -+ if (info->flags & COFF_FL_FIX_BB) -+ { -+ /* This is the first line number after one (or more) .bb -+ symbols. Fix them. In order to cope with multiple blocks -+ starting at the same line number, we walk back the list of -+ symbols until we find a C_BLOCK one that had already been -+ fixed, or until we find a C_FCN symbol (presumably, the start -+ of our current function). */ -+ info->flags &= ~COFF_FL_FIX_BB; -+ -+ for (i = info->nsyms - 1; i >= 0; i--) -+ { -+ csymp = (coff_symbol_type *) info->syms[i]; -+ if (csymp->native->u.syment.n_sclass == C_FCN) -+ break; -+ if (csymp->native->u.syment.n_sclass == C_BLOCK) -+ { -+ aux = &((csymp->native + 1)->u.auxent); -+ if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0) -+ /* already set up properly */ -+ break; -+ aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; -+ } -+ } -+ } -+ -+ csymp = (coff_symbol_type *) info->syms[info->funcindex]; -+ csymp->lineno = (alent *) xrealloc (csymp->lineno, -+ ++info->nlnos * sizeof (alent)); -+ memset (csymp->lineno + info->nlnos - 1, 0, sizeof (alent)); -+ if (lineno > info->funlno) -+ csymp->lineno[info->nlnos - 2].line_number = lineno - info->funlno; -+ else -+ /* Line number unreasonable. Can e. g. happen for a line number -+ from an include file, which we cannot process in COFF. Just -+ set it to the first line, to avoid generating a large unsigned -+ short (~ 65000) line number. */ -+ csymp->lineno[info->nlnos - 2].line_number = 1; -+ csymp->lineno[info->nlnos - 2].u.offset = addr; -+ -+ info->lastlno = lineno; -+ info->totlnos++; -+ -+ return TRUE; -+} -diff -Nruw include/coff/avr.h include/coff/avr.h ---- include/coff/avr.h 1970-01-01 05:30:00.000000000 +0530 -+++ include/coff/avr.h 2010-02-10 17:35:58.362724600 +0530 -@@ -0,0 +1,110 @@ -+/* coff information for Atmel AVR. -+ -+ Copyright 2001 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+/* This file was hacked from i860.h */ -+ -+#define L_LNNO_SIZE 2 -+#include "coff/external.h" -+ -+/* Bits for f_flags: -+ F_RELFLG relocation info stripped from file -+ F_EXEC file is executable (no unresolved external references) -+ F_LNNO line numbers stripped from file -+ F_LSYMS local symbols stripped from file */ -+ -+#define F_RELFLG (0x0001) -+#define F_EXEC (0x0002) -+#define F_LNNO (0x0004) -+#define F_LSYMS (0x0008) -+/* Upper nibble of flags always needs to be set. This used to be -+ * undocumented, recent information from Atmel says that bit 7 used to -+ * differentiate between an old vendor-specific deviation of the -+ * format and the current format. */ -+#define F_JUNK (0x00f0) -+#define F_UNUSED (0xff00) -+ -+#define AVRMAGIC 0xa12 -+ -+#undef AOUTSZ -+#ifdef AVR_EXT_COFF -+ -+/* AVR "extended" COFF format. This uses the optional header ("a.out" -+ header) to inform the consumer about some additional features that -+ are supported. */ -+#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */ -+#define AOUTSZ 28 /* size of optional header in "extended" COFF */ -+ -+/* Flags in the optional header; they are stored in the vstamp field. */ -+#define F_FULLPATHS 0x0001 /* long filenames supported */ -+#define F_STRUCTINFO 0x0002 /* structure information contained */ -+#define F_PTRINFO 0x0004 /* inter-segment pointers supported */ -+ -+#else /* old AVR COFF */ -+ -+#define AOUTSZ 0 /* no a.out for AVR */ -+#endif -+ -+/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */ -+/* -+ * The following magic number causes AVR Studio 4.x to recognize -+ * avr-gcc/GNU binutils produced AVR extended COFF files. By now, -+ * the only special treatment for them is that the contents of .data -+ * will be appended after .text in the simulator flash. -+ * -+ * 0x9cc has been chosen since it resembles "gcc". ;-) -+ */ -+#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */ -+ -+/* By matching not only the magic number, but also the size of the -+ optional a.out header, we can differentiate between both -+ formats. */ -+#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ) -+ -+/* AVR COFF has several anomalities in the way the handle the derived -+ type information, and AUX entries, mainly because they apparently -+ didn't bother to learn how COFF is supposed to work before they -+ started. We fix many of them at the export/import boundary, so all -+ the internal generic COFF handling will work mostly as designed. */ -+ -+/* NB: these functions are only defined in bfd/coff-avr.c, but also -+ used in coff-ext-avr.c, so the latter can only be configured if the -+ former is also present. This is certainly always the case -+ anyway. */ -+extern void avr_coff_adjust_sym_in_post -+ PARAMS((bfd *, PTR, PTR)); -+ -+extern void avr_coff_adjust_sym_out_post -+ PARAMS((bfd *, PTR, PTR)); -+ -+#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \ -+ avr_coff_adjust_sym_in_post (ABFD, EXT, INT) -+ -+#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \ -+ avr_coff_adjust_sym_out_post (ABFD, INT, EXT) -+ -+/********************** RELOCATION DIRECTIVES **********************/ -+ -+struct external_reloc -+{ -+ char r_vaddr[4]; -+ char r_symndx[4]; -+ char r_type[2]; -+}; -+ -+#define RELOC struct external_reloc -+#define RELSZ 10 -diff -Nruw include/coff/internal.h include/coff/internal.h ---- include/coff/internal.h 2009-09-02 12:51:39.000000000 +0530 -+++ include/coff/internal.h 2010-02-10 17:35:58.378349600 +0530 -@@ -646,6 +646,8 @@ - - }; - -+#define NAUXENTS 10 /* number of pre-allocated aux entries */ -+ - /********************** RELOCATION DIRECTIVES **********************/ - - struct internal_reloc diff --git a/devel/avr-binutils/files/patch-newdevices b/devel/avr-binutils/files/patch-newdevices deleted file mode 100644 index b268955b87aa..000000000000 --- a/devel/avr-binutils/files/patch-newdevices +++ /dev/null @@ -1,135 +0,0 @@ -diff -ruw ggas/config/tc-avr.c gas/config/tc-avr.c ---- ggas/config/tc-avr.c 2009-09-09 13:43:29.000000000 +0530 -+++ gas/config/tc-avr.c 2010-02-12 20:42:30.742688700 +0530 -@@ -133,9 +133,12 @@ - {"atmega32u2", AVR_ISA_AVR35, bfd_mach_avr35}, - {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, - {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4}, -+ {"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4}, - {"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4}, - {"atmega88", AVR_ISA_AVR4, bfd_mach_avr4}, -+ {"atmega88a", AVR_ISA_AVR4, bfd_mach_avr4}, - {"atmega88p", AVR_ISA_AVR4, bfd_mach_avr4}, -+ {"atmega88pa", AVR_ISA_AVR4, bfd_mach_avr4}, - {"atmega8515", AVR_ISA_M8, bfd_mach_avr4}, - {"atmega8535", AVR_ISA_M8, bfd_mach_avr4}, - {"atmega8hva", AVR_ISA_AVR4, bfd_mach_avr4}, -@@ -150,40 +153,63 @@ - {"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4}, - {"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4}, - {"atmega16", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega16a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega161", AVR_ISA_M161, bfd_mach_avr5}, - {"atmega162", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega163", AVR_ISA_M161, bfd_mach_avr5}, -+ {"atmega164a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega164p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega165", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega165p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega168", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega168a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega168p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega169", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega169a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega169p", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega169pa",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega16c1", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega32", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega323", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega324a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega324p", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega324pa",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega325", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega325p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega3250", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega3250p",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega328", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega328p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega329", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega329p", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega329pa",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega3290", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega406", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega64", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega640", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega644", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega644a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega644p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega644pa",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega645", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega645a", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega645p", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega649", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega649p", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega649a", AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega6450", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega6450a",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega6450p",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega6490", AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega6490a",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega6490p",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega64hve",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5}, -+ {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5}, - {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5}, - {"at90can32" , AVR_ISA_AVR5, bfd_mach_avr5}, -diff -ruw ggas/doc/c-avr.texi gas/doc/c-avr.texi ---- ggas/doc/c-avr.texi 2009-09-02 12:54:21.000000000 +0530 -+++ gas/doc/c-avr.texi 2010-02-12 21:31:02.132717100 +0530 -@@ -43,9 +43,10 @@ - - Instruction set avr25 is for the classic AVR core with up to 8K program memory - space plus the MOVW instruction (MCU types: attiny13, attiny13a, attiny2313, --attiny2313a, attiny24, attiny24a, attiny4313, attiny44, attiny44a, attiny84, --attiny25, attiny45, attiny85, attiny261, attiny261a, attiny461, attiny861, --attiny861a, attiny87, attiny43u, attiny48, attiny88, at86rf401, ata6289). -+attiny2313a, attiny24, attiny24a, attiny4313, attiny43u, attiny44, attiny44a, -+attiny84, attiny25, attiny45, attiny85, attiny261, attiny261a, attiny461, -+attiny461a, attiny861, attiny861a, attiny87, attiny43u, attiny48, attiny88, -+at86rf401, ata6289). - - Instruction set avr3 is for the classic AVR core with up to 128K program - memory space (MCU types: at43usb355, at76c711). -@@ -58,20 +59,25 @@ - atmega16u2, atmega32u2). - - Instruction set avr4 is for the enhanced AVR core with up to 8K program --memory space (MCU types: atmega48, atmega48p,atmega8, atmega88, atmega88p, --atmega8515, atmega8535, atmega8hva, atmega4hvd, atmega8hvd, at90pwm1, --at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, at90pwm81, atmega8m1, atmega8c1). -+memory space (MCU types: atmega48, atmega48a, atmega48p,atmega8, atmega88, -+atmega88a, atmega88p, atmega88pa, atmega8515, atmega8535, atmega8hva, -+atmega4hvd, atmega8hvd, at90pwm1,at90pwm2, at90pwm2b, at90pwm3, at90pwm3b, -+at90pwm81, atmega8m1, atmega8c1). - - Instruction set avr5 is for the enhanced AVR core with up to 128K program --memory space (MCU types: atmega16, atmega161, atmega162, atmega163, atmega164p, --atmega165, atmega165p, atmega168, atmega168p, atmega169, atmega169p, atmega16c1, --atmega32, atmega323, atmega324p, atmega325, atmega325p, atmega3250, atmega3250p, --atmega328p, atmega329, atmega329p, atmega3290, atmega3290p, atmega406, atmega64, --atmega640, atmega644, atmega644p, atmega644pa, atmega645, atmega6450, atmega649, --atmega6490, atmega16hva, atmega16hvb, atmega32hvb, at90can32, at90can64, --at90pwm216, at90pwm316, atmega32c1, atmega64c1, atmega16m1, atmega32m1, --atmega64m1, atmega16u4, atmega32u4, atmega32u6, at90usb646, at90usb647, at94k, --at90scr100). -+memory space (MCU types: atmega16, atmega16a, atmega161, atmega162, atmega163, -+atmega164a, atmega164p, atmega165, atmega165a, atmega165p, atmega168, -+atmega168a, atmega168p, atmega169, atmega169p, atmega169pa, atmega16c1, -+atmega32, atmega323, atmega324a, atmega324p, atmega324pa, atmega325, -+atmega325p, atmega3250, atmega3250p, atmega328, atmega328p, atmega329, -+atmega329p, atmega329pa, atmega3290, atmega3290p, atmega406, atmega64, -+atmega640, atmega644, atmega644a, atmega644p, atmega644pa, atmega645, -+atmega645a, atmega645p, atmega6450, atmega6450a, atmega6450p, atmega649, -+atmega649a, atmega649p, atmega6490, atmega6490a, atmega6490p, atmega64hve, -+atmega16hva, atmega16hva2, atmega16hvb, atmega32hvb, at90can32, at90can64, -+at90pwm216, at90pwm316, atmega16u4, atmega32c1, atmega64c1, atmega64m1, -+atmega16m1, atmega32m1, atmega64m1, atmega16u4, atmega32u4, atmega32u6, -+at90usb646, at90usb647, at94k, at90scr100). - - Instruction set avr51 is for the enhanced AVR core with exactly 128K program - memory space (MCU types: atmega128, atmega1280, atmega1281, atmega1284p, diff --git a/devel/avr-binutils/files/patch-newsections b/devel/avr-binutils/files/patch-newsections deleted file mode 100644 index f14f04d960de..000000000000 --- a/devel/avr-binutils/files/patch-newsections +++ /dev/null @@ -1,38 +0,0 @@ -diff -ruw ld/scripttempl/avr.sc ld/scripttempl/avr.sc ---- ld/scripttempl/avr.sc 2009-10-09 18:42:35.000000000 +0530 -+++ ld/scripttempl/avr.sc 2010-02-12 20:09:24.070812400 +0530 -@@ -7,6 +7,9 @@ - text (rx) : ORIGIN = 0, LENGTH = $TEXT_LENGTH - data (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = $DATA_LENGTH - eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K -+ fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K -+ lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K -+ signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K - } - - SECTIONS -@@ -196,6 +199,24 @@ - ${RELOCATING+ __eeprom_end = . ; } - } ${RELOCATING+ > eeprom} - -+ .fuse ${RELOCATING-0}: -+ { -+ KEEP(*(.fuse)) -+ KEEP(*(.lfuse)) -+ KEEP(*(.hfuse)) -+ KEEP(*(.efuse)) -+ } ${RELOCATING+ > fuse} -+ -+ .lock ${RELOCATING-0}: -+ { -+ KEEP(*(.lock*)) -+ } ${RELOCATING+ > lock} -+ -+ .signature ${RELOCATING-0}: -+ { -+ KEEP(*(.signature*)) -+ } ${RELOCATING+ > signature} -+ - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } diff --git a/devel/avr-binutils/files/patch-xmega b/devel/avr-binutils/files/patch-xmega deleted file mode 100644 index 4ae41b55fd6f..000000000000 --- a/devel/avr-binutils/files/patch-xmega +++ /dev/null @@ -1,663 +0,0 @@ -diff -Nur ../binutils-2.20.orig/bfd/archures.c ./bfd/archures.c ---- ../binutils-2.20.orig/bfd/archures.c 2009-09-10 13:47:11.000000000 +0200 -+++ ./bfd/archures.c 2010-03-04 11:34:08.000000000 +0100 -@@ -368,6 +368,13 @@ - .#define bfd_mach_avr5 5 - .#define bfd_mach_avr51 51 - .#define bfd_mach_avr6 6 -+.#define bfd_mach_avrxmega1 101 -+.#define bfd_mach_avrxmega2 102 -+.#define bfd_mach_avrxmega3 103 -+.#define bfd_mach_avrxmega4 104 -+.#define bfd_mach_avrxmega5 105 -+.#define bfd_mach_avrxmega6 106 -+.#define bfd_mach_avrxmega7 107 - . bfd_arch_bfin, {* ADI Blackfin *} - .#define bfd_mach_bfin 1 - . bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *} -diff -Nur ../binutils-2.20.orig/bfd/bfd-in2.h ./bfd/bfd-in2.h ---- ../binutils-2.20.orig/bfd/bfd-in2.h 2009-09-10 13:47:11.000000000 +0200 -+++ ./bfd/bfd-in2.h 2010-03-04 11:34:08.000000000 +0100 -@@ -2035,6 +2035,13 @@ - #define bfd_mach_avr5 5 - #define bfd_mach_avr51 51 - #define bfd_mach_avr6 6 -+#define bfd_mach_avrxmega1 101 -+#define bfd_mach_avrxmega2 102 -+#define bfd_mach_avrxmega3 103 -+#define bfd_mach_avrxmega4 104 -+#define bfd_mach_avrxmega5 105 -+#define bfd_mach_avrxmega6 106 -+#define bfd_mach_avrxmega7 107 - bfd_arch_bfin, /* ADI Blackfin */ - #define bfd_mach_bfin 1 - bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ -diff -Nur ../binutils-2.20.orig/bfd/cpu-avr.c ./bfd/cpu-avr.c ---- ../binutils-2.20.orig/bfd/cpu-avr.c 2009-09-02 09:18:36.000000000 +0200 -+++ ./bfd/cpu-avr.c 2010-03-04 11:34:08.000000000 +0100 -@@ -133,7 +133,29 @@ - N (22, bfd_mach_avr51, "avr:51", FALSE, & arch_info_struct[9]), - - /* 3-Byte PC. */ -- N (22, bfd_mach_avr6, "avr:6", FALSE, NULL) -+ N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]), -+ -+ /* Xmega 1 */ -+ N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[11]), -+ -+ /* Xmega 2 */ -+ N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[12]), -+ -+ /* Xmega 3 */ -+ N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[13]), -+ -+ /* Xmega 4 */ -+ N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[14]), -+ -+ /* Xmega 5 */ -+ N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[15]), -+ -+ /* Xmega 6 */ -+ N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]), -+ -+ /* Xmega 7 */ -+ N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL) -+ - }; - - const bfd_arch_info_type bfd_avr_arch = -diff -Nur ../binutils-2.20.orig/bfd/elf32-avr.c ./bfd/elf32-avr.c ---- ../binutils-2.20.orig/bfd/elf32-avr.c 2009-09-02 09:18:36.000000000 +0200 -+++ ./bfd/elf32-avr.c 2010-03-04 11:34:08.000000000 +0100 -@@ -1328,6 +1328,34 @@ - case bfd_mach_avr6: - val = E_AVR_MACH_AVR6; - break; -+ -+ case bfd_mach_avrxmega1: -+ val = E_AVR_MACH_XMEGA1; -+ break; -+ -+ case bfd_mach_avrxmega2: -+ val = E_AVR_MACH_XMEGA2; -+ break; -+ -+ case bfd_mach_avrxmega3: -+ val = E_AVR_MACH_XMEGA3; -+ break; -+ -+ case bfd_mach_avrxmega4: -+ val = E_AVR_MACH_XMEGA4; -+ break; -+ -+ case bfd_mach_avrxmega5: -+ val = E_AVR_MACH_XMEGA5; -+ break; -+ -+ case bfd_mach_avrxmega6: -+ val = E_AVR_MACH_XMEGA6; -+ break; -+ -+ case bfd_mach_avrxmega7: -+ val = E_AVR_MACH_XMEGA7; -+ break; - } - - elf_elfheader (abfd)->e_machine = EM_AVR; -@@ -1390,6 +1418,34 @@ - case E_AVR_MACH_AVR6: - e_set = bfd_mach_avr6; - break; -+ -+ case E_AVR_MACH_XMEGA1: -+ e_set = bfd_mach_avrxmega1; -+ break; -+ -+ case E_AVR_MACH_XMEGA2: -+ e_set = bfd_mach_avrxmega2; -+ break; -+ -+ case E_AVR_MACH_XMEGA3: -+ e_set = bfd_mach_avrxmega3; -+ break; -+ -+ case E_AVR_MACH_XMEGA4: -+ e_set = bfd_mach_avrxmega4; -+ break; -+ -+ case E_AVR_MACH_XMEGA5: -+ e_set = bfd_mach_avrxmega5; -+ break; -+ -+ case E_AVR_MACH_XMEGA6: -+ e_set = bfd_mach_avrxmega6; -+ break; -+ -+ case E_AVR_MACH_XMEGA7: -+ e_set = bfd_mach_avrxmega7; -+ break; - } - } - return bfd_default_set_arch_mach (abfd, bfd_arch_avr, -diff -Nur ../binutils-2.20.orig/gas/config/tc-avr.c ./gas/config/tc-avr.c ---- ../binutils-2.20.orig/gas/config/tc-avr.c 2010-03-04 11:19:26.000000000 +0100 -+++ ./gas/config/tc-avr.c 2010-03-04 11:34:09.000000000 +0100 -@@ -27,20 +27,21 @@ - - struct avr_opcodes_s - { -- char * name; -- char * constraints; -- int insn_size; /* In words. */ -- int isa; -+ char *name; -+ char *constraints; -+ char *opcode; -+ int insn_size; /* In words. */ -+ int isa; - unsigned int bin_opcode; - }; - - #define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \ --{#NAME, CONSTR, SIZE, ISA, BIN}, -+{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN}, - - struct avr_opcodes_s avr_opcodes[] = - { - #include "opcode/avr.h" -- {NULL, NULL, 0, 0, 0} -+ {NULL, NULL, NULL, 0, 0, 0} - }; - - const char comment_chars[] = ";"; -@@ -79,6 +80,13 @@ - {"avr5", AVR_ISA_AVR51, bfd_mach_avr5}, - {"avr51", AVR_ISA_AVR51, bfd_mach_avr51}, - {"avr6", AVR_ISA_AVR6, bfd_mach_avr6}, -+ {"avrxmega1", AVR_ISA_XMEGA, bfd_mach_avrxmega1}, -+ {"avrxmega2", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, -+ {"avrxmega3", AVR_ISA_XMEGA, bfd_mach_avrxmega3}, -+ {"avrxmega4", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, -+ {"avrxmega5", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, -+ {"avrxmega6", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"avrxmega7", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, - {"at90s1200", AVR_ISA_1200, bfd_mach_avr1}, - {"attiny11", AVR_ISA_AVR1, bfd_mach_avr1}, - {"attiny12", AVR_ISA_AVR1, bfd_mach_avr1}, -@@ -241,6 +249,21 @@ - {"m3001b", AVR_ISA_AVR51, bfd_mach_avr51}, - {"atmega2560", AVR_ISA_AVR6, bfd_mach_avr6}, - {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6}, -+ {"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, -+ {"atxmega16d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, -+ {"atxmega32d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2}, -+ {"atxmega32a4", AVR_ISA_XMEGA, bfd_mach_avrxmega3}, -+ {"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, -+ {"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4}, -+ {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5}, -+ {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6}, -+ {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7}, - {NULL, 0, 0} - }; - -@@ -418,6 +441,11 @@ - " avr5 - enhanced AVR core with up to 64K program memory\n" - " avr51 - enhanced AVR core with up to 128K program memory\n" - " avr6 - enhanced AVR core with up to 256K program memory\n" -+ " avrxmega3 - XMEGA, > 8K, <= 64K FLASH, > 64K RAM\n" -+ " avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM\n" -+ " avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n" -+ " avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n" -+ " avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n" - " or immediate microcontroller name.\n")); - fprintf (stream, - _(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n" -@@ -845,7 +873,12 @@ - if (*str == '+') - { - ++str; -- op_mask |= 1; -+ char *s; -+ for (s = opcode->opcode; *s; ++s) -+ { -+ if (*s == '+') -+ op_mask |= (1 << (15 - (s - opcode->opcode))); -+ } - } - - /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+". */ -@@ -962,6 +995,16 @@ - } - break; - -+ case 'E': -+ { -+ unsigned int x; -+ -+ x = avr_get_constant (str, 15); -+ str = input_line_pointer; -+ op_mask |= (x << 4); -+ } -+ break; -+ - case '?': - break; - -diff -Nur ../binutils-2.20.orig/gas/doc/c-avr.texi ./gas/doc/c-avr.texi ---- ../binutils-2.20.orig/gas/doc/c-avr.texi 2010-03-04 11:19:26.000000000 +0100 -+++ ./gas/doc/c-avr.texi 2010-03-04 11:34:09.000000000 +0100 -@@ -86,6 +86,27 @@ - Instruction set avr6 is for the enhanced AVR core with a 3-byte PC (MCU types: - atmega2560, atmega2561). - -+Instruction set avrxmega2 is for the XMEGA AVR core with 8K to 64K program -+memory space and less than 64K data space (MCU types: atxmega16a4, atxmega16d4, -+atxmega32d4). -+ -+Instruction set avrxmega3 is for the XMEGA AVR core with 8K to 64K program -+memory space and greater than 64K data space (MCU types: atxmega32a4). -+ -+Instruction set avrxmega4 is for the XMEGA AVR core with up to 64K program -+memory space and less than 64K data space (MCU types: atxmega64a3, atxmega64d3). -+ -+Instruction set avrxmega5 is for the XMEGA AVR core with up to 64K program -+memory space and greater than 64K data space (MCU types: atxmega64a1). -+ -+Instruction set avrxmega6 is for the XMEGA AVR core with up to 256K program -+memory space and less than 64K data space (MCU types: atxmega128a3, -+atxmega128d3, atxmega192a3, atxmega192d3, atxmega256a3, atxmega256a3b, -+atxmega192d3). -+ -+Instruction set avrxmega7 is for the XMEGA AVR core with up to 256K program -+memory space and greater than 64K data space (MCU types: atxmega128a1). -+ - @cindex @code{-mall-opcodes} command line option, AVR - @item -mall-opcodes - Accept all AVR opcodes, even if not supported by @code{-mmcu}. -diff -Nur ../binutils-2.20.orig/include/elf/avr.h ./include/elf/avr.h ---- ../binutils-2.20.orig/include/elf/avr.h 2008-08-09 07:35:13.000000000 +0200 -+++ ./include/elf/avr.h 2010-03-04 11:34:09.000000000 +0100 -@@ -40,6 +40,13 @@ - #define E_AVR_MACH_AVR5 5 - #define E_AVR_MACH_AVR51 51 - #define E_AVR_MACH_AVR6 6 -+#define E_AVR_MACH_XMEGA1 101 -+#define E_AVR_MACH_XMEGA2 102 -+#define E_AVR_MACH_XMEGA3 103 -+#define E_AVR_MACH_XMEGA4 104 -+#define E_AVR_MACH_XMEGA5 105 -+#define E_AVR_MACH_XMEGA6 106 -+#define E_AVR_MACH_XMEGA7 107 - - /* Relocations. */ - START_RELOC_NUMBERS (elf_avr_reloc_type) -diff -Nur ../binutils-2.20.orig/include/opcode/avr.h ./include/opcode/avr.h ---- ../binutils-2.20.orig/include/opcode/avr.h 2008-08-09 07:35:13.000000000 +0200 -+++ ./include/opcode/avr.h 2010-03-04 11:34:09.000000000 +0100 -@@ -30,6 +30,8 @@ - #define AVR_ISA_BRK 0x0400 /* device has BREAK (on-chip debug) */ - #define AVR_ISA_EIND 0x0800 /* device has >128K program memory (none yet) */ - #define AVR_ISA_MOVW 0x1000 /* device has MOVW */ -+#define AVR_ISA_SPMX 0x2000 /* device has SPM Z[+] */ -+#define AVR_ISA_DES 0x4000 /* device has DES */ - - #define AVR_ISA_TINY1 (AVR_ISA_1200 | AVR_ISA_LPM) - #define AVR_ISA_2xxx (AVR_ISA_TINY1 | AVR_ISA_SRAM) -@@ -48,6 +50,8 @@ - #define AVR_ISA_94K (AVR_ISA_M603 | AVR_ISA_MUL | AVR_ISA_MOVW | AVR_ISA_LPMX) - #define AVR_ISA_M323 (AVR_ISA_M161 | AVR_ISA_BRK) - #define AVR_ISA_M128 (AVR_ISA_M323 | AVR_ISA_ELPM | AVR_ISA_ELPMX) -+#define AVR_ISA_M256 (AVR_ISA_M128 | AVR_ISA_EIND) -+#define AVR_ISA_XMEGA (AVR_ISA_M256 | AVR_ISA_SPMX | AVR_ISA_DES) - - #define AVR_ISA_AVR1 AVR_ISA_TINY1 - #define AVR_ISA_AVR2 AVR_ISA_2xxx -@@ -108,6 +112,7 @@ - L - signed pc relative offset from -2048 to 2047 - h - absolute code address (call, jmp) - S - immediate value from 0 to 7 (S = s << 4) -+ E - immediate value from 0 to 15, shifted left by 4 (des) - ? - use this opcode entry if no parameters, else use next opcode entry - - Order is important - some binary opcodes have more than one name, -@@ -168,7 +173,8 @@ - AVR_INSN (sleep,"", "1001010110001000", 1, AVR_ISA_1200, 0x9588) - AVR_INSN (break,"", "1001010110011000", 1, AVR_ISA_BRK, 0x9598) - AVR_INSN (wdr, "", "1001010110101000", 1, AVR_ISA_1200, 0x95a8) --AVR_INSN (spm, "", "1001010111101000", 1, AVR_ISA_SPM, 0x95e8) -+AVR_INSN (spm, "?", "1001010111101000", 1, AVR_ISA_SPM, 0x95e8) -+AVR_INSN (spm, "z", "10010101111+1000", 1, AVR_ISA_SPMX, 0x95e8) - - AVR_INSN (adc, "r,r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00) - AVR_INSN (add, "r,r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00) -@@ -282,3 +288,6 @@ - AVR_INSN (eicall, "", "1001010100011001", 1, AVR_ISA_EIND, 0x9519) - AVR_INSN (eijmp, "", "1001010000011001", 1, AVR_ISA_EIND, 0x9419) - -+/* DES instruction for encryption and decryption */ -+AVR_INSN (des, "E", "10010100EEEE1011", 1, AVR_ISA_DES, 0x940B) -+ -diff -Nur ../binutils-2.20.orig/ld/Makefile.am ./ld/Makefile.am ---- ../binutils-2.20.orig/ld/Makefile.am 2009-09-01 22:56:51.000000000 +0200 -+++ ./ld/Makefile.am 2010-03-04 11:34:09.000000000 +0100 -@@ -148,6 +148,13 @@ - eavr5.o \ - eavr51.o \ - eavr6.o \ -+ eavrxmega1.o \ -+ eavrxmega2.o \ -+ eavrxmega3.o \ -+ eavrxmega4.o \ -+ eavrxmega5.o \ -+ eavrxmega6.o \ -+ eavrxmega7.o \ - ecoff_i860.o \ - ecoff_sparc.o \ - eelf32_spu.o \ -@@ -727,6 +734,34 @@ - $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ - ${GEN_DEPENDS} - ${GENSCRIPTS} avr6 "$(tdir_avr2)" -+eavrxmega1.c: $(srcdir)/emulparams/avrxmega1.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega1 "$(tdir_avr2)" -+eavrxmega2.c: $(srcdir)/emulparams/avrxmega2.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega2 "$(tdir_avr2)" -+eavrxmega3.c: $(srcdir)/emulparams/avrxmega3.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega3 "$(tdir_avr2)" -+eavrxmega4.c: $(srcdir)/emulparams/avrxmega4.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega4 "$(tdir_avr2)" -+eavrxmega5.c: $(srcdir)/emulparams/avrxmega5.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega5 "$(tdir_avr2)" -+eavrxmega6.c: $(srcdir)/emulparams/avrxmega6.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega6 "$(tdir_avr2)" -+eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" - ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ - $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} - ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" -diff -Nur ../binutils-2.20.orig/ld/Makefile.in ./ld/Makefile.in ---- ../binutils-2.20.orig/ld/Makefile.in 2009-09-07 14:10:24.000000000 +0200 -+++ ./ld/Makefile.in 2010-03-04 11:34:09.000000000 +0100 -@@ -434,6 +434,13 @@ - eavr5.o \ - eavr51.o \ - eavr6.o \ -+ eavrxmega1.o \ -+ eavrxmega2.o \ -+ eavrxmega3.o \ -+ eavrxmega4.o \ -+ eavrxmega5.o \ -+ eavrxmega6.o \ -+ eavrxmega7.o \ - ecoff_i860.o \ - ecoff_sparc.o \ - eelf32_spu.o \ -@@ -2068,6 +2075,34 @@ - $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ - ${GEN_DEPENDS} - ${GENSCRIPTS} avr6 "$(tdir_avr2)" -+eavrxmega1.c: $(srcdir)/emulparams/avrxmega1.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega1 "$(tdir_avr2)" -+eavrxmega2.c: $(srcdir)/emulparams/avrxmega2.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega2 "$(tdir_avr2)" -+eavrxmega3.c: $(srcdir)/emulparams/avrxmega3.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega3 "$(tdir_avr2)" -+eavrxmega4.c: $(srcdir)/emulparams/avrxmega4.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega4 "$(tdir_avr2)" -+eavrxmega5.c: $(srcdir)/emulparams/avrxmega5.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega5 "$(tdir_avr2)" -+eavrxmega6.c: $(srcdir)/emulparams/avrxmega6.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega6 "$(tdir_avr2)" -+eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \ -+ $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \ -+ ${GEN_DEPENDS} -+ ${GENSCRIPTS} avrxmega7 "$(tdir_avr2)" - ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ - $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} - ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" -diff -Nur ../binutils-2.20.orig/ld/configure.tgt ./ld/configure.tgt ---- ../binutils-2.20.orig/ld/configure.tgt 2009-08-06 19:38:03.000000000 +0200 -+++ ./ld/configure.tgt 2010-03-04 11:34:09.000000000 +0100 -@@ -110,7 +110,7 @@ - xscale-*-elf) targ_emul=armelf - ;; - avr-*-*) targ_emul=avr2 -- targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6" -+ targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7" - ;; - bfin-*-elf) targ_emul=elf32bfin; - targ_extra_emuls="elf32bfinfd" -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega1.sh ./ld/emulparams/avrxmega1.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega1.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega1.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:101 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega2.sh ./ld/emulparams/avrxmega2.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega2.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega2.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:102 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega3.sh ./ld/emulparams/avrxmega3.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega3.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega3.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:103 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega4.sh ./ld/emulparams/avrxmega4.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega4.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega4.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:104 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega5.sh ./ld/emulparams/avrxmega5.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega5.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega5.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:105 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega6.sh ./ld/emulparams/avrxmega6.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega6.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega6.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:106 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emulparams/avrxmega7.sh ./ld/emulparams/avrxmega7.sh ---- ../binutils-2.20.orig/ld/emulparams/avrxmega7.sh 1970-01-01 01:00:00.000000000 +0100 -+++ ./ld/emulparams/avrxmega7.sh 2010-03-04 11:34:09.000000000 +0100 -@@ -0,0 +1,12 @@ -+ARCH=avr:107 -+MACHINE= -+SCRIPT_NAME=avr -+OUTPUT_FORMAT="elf32-avr" -+MAXPAGESIZE=1 -+EMBEDDED=yes -+TEMPLATE_NAME=elf32 -+ -+TEXT_LENGTH=1024K -+DATA_ORIGIN=0x802000 -+DATA_LENGTH=0xffa0 -+EXTRA_EM_FILE=avrelf -diff -Nur ../binutils-2.20.orig/ld/emultempl/avrelf.em ./ld/emultempl/avrelf.em ---- ../binutils-2.20.orig/ld/emultempl/avrelf.em 2009-09-02 09:25:35.000000000 +0200 -+++ ./ld/emultempl/avrelf.em 2010-03-04 11:34:09.000000000 +0100 -@@ -71,8 +71,10 @@ - - gld${EMULATION_NAME}_before_allocation (); - -- /* We only need stubs for the avr6 family. */ -- if (strcmp ("${EMULATION_NAME}","avr6")) -+ /* We only need stubs for avr6, avrxmega6, and avrxmega7. */ -+ if (strcmp ("${EMULATION_NAME}","avr6") -+ && strcmp ("${EMULATION_NAME}","avrxmega6") -+ && strcmp ("${EMULATION_NAME}","avrxmega7") ) - avr_no_stubs = TRUE; - - avr_elf_set_global_bfd_parameters (); -diff -Nur ../binutils-2.20.orig/opcodes/avr-dis.c ./opcodes/avr-dis.c ---- ../binutils-2.20.orig/opcodes/avr-dis.c 2008-11-06 13:03:24.000000000 +0100 -+++ ./opcodes/avr-dis.c 2010-03-04 11:34:09.000000000 +0100 -@@ -50,7 +50,7 @@ - - static int - avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constraint, -- char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr) -+ char *opcode_str, char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr) - { - int ok = 1; - *sym = 0; -@@ -118,8 +118,18 @@ - - case 'z': - *buf++ = 'Z'; -- if (insn & 0x1) -- *buf++ = '+'; -+ -+ /* Check for post-increment. */ -+ char *s; -+ for (s = opcode_str; *s; ++s) -+ { -+ if (*s == '+') -+ { -+ *buf++ = '+'; -+ break; -+ } -+ } -+ - *buf = '\0'; - if (AVR_UNDEF_P (insn)) - sprintf (comment, _("undefined")); -@@ -226,6 +236,10 @@ - sprintf (comment, "%d", x); - } - break; -+ -+ case 'E': -+ sprintf (buf, "%d", (insn >> 4) & 15); -+ break; - - case '?': - *buf = '\0'; -@@ -331,7 +345,8 @@ - - if (opcode->name) - { -- char *op = opcode->constraints; -+ char *constraints = opcode->constraints; -+ char *opcode_str = opcode->opcode; - - insn2 = 0; - ok = 1; -@@ -342,14 +357,14 @@ - cmd_len = 4; - } - -- if (*op && *op != '?') -+ if (*constraints && *constraints != '?') - { -- int regs = REGISTER_P (*op); -+ int regs = REGISTER_P (*constraints); - -- ok = avr_operand (insn, insn2, addr, *op, op1, comment1, 0, &sym_op1, &sym_addr1); -+ ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1, comment1, 0, &sym_op1, &sym_addr1); - -- if (ok && *(++op) == ',') -- ok = avr_operand (insn, insn2, addr, *(++op), op2, -+ if (ok && *(++constraints) == ',') -+ ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str, op2, - *comment1 ? comment2 : comment1, regs, &sym_op2, &sym_addr2); - } - } diff --git a/devel/avr-binutils/pkg-descr b/devel/avr-binutils/pkg-descr index 4e1e878472cb..ccb3061e03c1 100644 --- a/devel/avr-binutils/pkg-descr +++ b/devel/avr-binutils/pkg-descr @@ -7,14 +7,7 @@ generate AVR (extended) COFF files to be used on Atmel AVR Studio and VMLAB. Note that this patch has known issues, see http://www.sax.de/~joerg/README.coff-avr-patch -In addition to the stock binutils-2.18 distribution, support for the -following AVR devices has been added by a private patch: - - ATtiny43U, ATtiny48/88, ATtiny167 - AT90PWM2B/PWM3B, AT90PWM216/PWM316 - ATmega32C1, ATmega32M1, ATmega32U4 - ATmega48P/88P/168P/328P - ATmega32HVB, ATmega1284P - ATxmega64A1, ATxmega128A1 +The support for additional devices has been synchronize with the +latest public Atmel AVR Tools package. WWW: http://www.sourceware.org/binutils/ -- cgit v1.2.3