diff -up avr-binutils-2.35/binutils-2.35/binutils/size.c.avr-size avr-binutils-2.35/binutils-2.35/binutils/size.c --- avr-binutils-2.35/binutils-2.35/binutils/size.c.avr-size 2020-07-24 11:12:19.000000000 +0200 +++ avr-binutils-2.35/binutils-2.35/binutils/size.c 2020-11-09 16:42:59.484661508 +0100 @@ -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|-C|-G --format={sysv|berkeley|avr|gnu} 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\ @@ -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) { @@ -168,6 +412,10 @@ main (int argc, char **argv) case 's': selected_output_format = FORMAT_SYSV; break; + case 'C': + case 'c': + selected_output_format = FORMAT_AVR; + break; case 'G': case 'g': selected_output_format = FORMAT_GNU; @@ -178,6 +426,10 @@ main (int argc, char **argv) } break; + case OPTION_MCU: + avrmcu = optarg; + break; + case OPTION_TARGET: target = optarg; break; @@ -211,6 +463,9 @@ main (int argc, char **argv) case 'B': selected_output_format = FORMAT_BERKLEY; break; + case 'C': + selected_output_format = FORMAT_AVR; + break; case 'G': selected_output_format = FORMAT_GNU; break; @@ -317,6 +572,100 @@ calculate_common_size (bfd *abfd) free (syms); } + +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 (section); + if ((section = bfd_get_section_by_name (file, ".text")) != NULL) + textsize = bfd_section_size (section); + if ((section = bfd_get_section_by_name (file, ".bss")) != NULL) + 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 = 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"); + } +} + + /* Display stats on file or archive member ABFD. */ static void @@ -663,6 +1012,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); }