diff --git a/binutils/size.c b/binutils/size.c index 93ec02691e..ad7cbee7c5 100644 --- binutils/size.c +++ binutils/size.c @@ -34,10 +34,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 @@ -46,9 +67,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; @@ -62,6 +82,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. */ @@ -77,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\ @@ -86,11 +347,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) @@ -101,6 +358,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[] = { @@ -108,6 +366,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 +400,7 @@ main (int argc, char **argv) fatal (_("fatal error: libbfd ABI mismatch")); 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 +425,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 +510,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; @@ -606,13 +876,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; + } }