| diff --git a/binutils/size.c b/binutils/size.c |
| index 3697087714..f99d45a6bf 100644 |
| --- a/binutils/size.c |
| +++ b/binutils/size.c |
| @@ -51,7 +51,8 @@ enum output_format |
| { |
| FORMAT_BERKLEY, |
| FORMAT_SYSV, |
| - FORMAT_GNU |
| + FORMAT_GNU, |
| + FORMAT_AVR |
| }; |
| static enum output_format selected_output_format = |
| #if BSD_DEFAULT |
| @@ -74,6 +75,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. */ |
| @@ -89,7 +330,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|-G --format={sysv|berkeley|gnu} Select output style (default is %s)\n\ |
| + -A|-B|-G|-C --format={sysv|berkeley|gnu|avr} Select output style (default is %s)\n\ |
| + --mcu=<avrmcu> 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\ |
| @@ -113,6 +355,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[] = |
| { |
| @@ -120,6 +363,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}, |
| @@ -153,7 +397,7 @@ main (int argc, char **argv) |
| fatal (_("fatal error: libbfd ABI mismatch")); |
| set_default_bfd_target (); |
| |
| - while ((c = getopt_long (argc, argv, "ABGHhVvdfotx", long_options, |
| + while ((c = getopt_long (argc, argv, "ABCGHhVvdfotx", long_options, |
| (int *) 0)) != EOF) |
| switch (c) |
| { |
| @@ -172,12 +416,20 @@ main (int argc, char **argv) |
| case 'g': |
| selected_output_format = FORMAT_GNU; |
| break; |
| + case 'A': |
| + case 'a': |
| + selected_output_format = FORMAT_AVR; |
| + break; |
| default: |
| non_fatal (_("invalid argument to --format: %s"), optarg); |
| usage (stderr, 1); |
| } |
| break; |
| |
| + case OPTION_MCU: |
| + avrmcu = optarg; |
| + break; |
| + |
| case OPTION_TARGET: |
| target = optarg; |
| break; |
| @@ -214,6 +466,9 @@ main (int argc, char **argv) |
| case 'G': |
| selected_output_format = FORMAT_GNU; |
| break; |
| + case 'C': |
| + selected_output_format = FORMAT_AVR; |
| + break; |
| case 'v': |
| case 'V': |
| show_version = 1; |
| @@ -656,6 +911,98 @@ 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 my_datasize = 0; |
| + bfd_size_type my_textsize = 0; |
| + bfd_size_type my_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) |
| + my_datasize = bfd_section_size (section); |
| + if ((section = bfd_get_section_by_name (file, ".text")) != NULL) |
| + my_textsize = bfd_section_size (section); |
| + if ((section = bfd_get_section_by_name (file, ".bss")) != NULL) |
| + my_bsssize = bfd_section_size (section); |
| + if ((section = bfd_get_section_by_name (file, ".bootloader")) != NULL) |
| + bootloadersize = bfd_section_size (section); |
| + if ((section = bfd_get_section_by_name (file, ".noinit")) != NULL) |
| + noinitsize = bfd_section_size (section); |
| + if ((section = bfd_get_section_by_name (file, ".eeprom")) != NULL) |
| + eepromsize = bfd_section_size (section); |
| + |
| + bfd_size_type text = my_textsize + my_datasize + bootloadersize; |
| + bfd_size_type data = my_datasize + my_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) |
| { |
| @@ -663,6 +1010,8 @@ print_sizes (bfd *file) |
| calculate_common_size (file); |
| if (selected_output_format == FORMAT_SYSV) |
| print_sysv_format (file); |
| + else if (selected_output_format == FORMAT_AVR) |
| + print_avr_format (file); |
| else |
| print_berkeley_or_gnu_format (file); |
| } |