Index: binutils/size.c =================================================================== RCS file: /cvs/src/src/binutils/size.c,v retrieving revision 1.32 diff -u -r1.32 size.c --- binutils/size.c 10 Sep 2009 13:40:44 -0000 1.32 +++ binutils/size.c 7 Nov 2012 23:35:09 -0000 @@ -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 @@ } 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,157 @@ /* 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 AVR24K 24576UL +#define AVR32K 32768UL +#define AVR40K 40960UL +#define AVR64K 65536UL +#define AVR128K 131072UL +#define AVR256K 262144UL + +typedef struct +{ + char *name; + long flash; + long ram; + long eeprom; +} avr_device_t; + +avr_device_t avr[] = +{ + {"atmega2560", AVR256K, AVR8K, AVR4K}, + {"atmega2561", AVR256K, AVR8K, AVR4K}, + + {"at43usb320", AVR128K, 608UL, 0}, + {"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}, + {"atmega103", AVR128K, 4000UL, AVR4K}, + {"atxmega128a1",AVR128K, AVR8K, AVR2K}, + + {"at90can64", AVR64K, AVR4K, AVR2K}, + {"at90usb646", AVR64K, AVR4K, AVR2K}, + {"at90usb647", AVR64K, AVR4K, AVR2K}, + {"atmega64", AVR64K, AVR4K, AVR2K}, + {"atmega640", AVR64K, AVR8K, AVR4K}, + {"atmega644", AVR64K, AVR4K, AVR2K}, + {"atmega644p", AVR64K, AVR4K, AVR2K}, + {"atmega645", AVR64K, AVR4K, AVR2K}, + {"atmega6450", AVR64K, AVR4K, AVR2K}, + {"atmega649", AVR64K, AVR4K, AVR2K}, + {"atmega6490", AVR64K, AVR4K, AVR2K}, + {"atxmega64a1", AVR64K, AVR4K, AVR2K}, + + {"atmega406", AVR40K, AVR512, AVR2K}, + + {"at90can32", AVR32K, AVR2K, AVR1K}, + {"at94k", AVR32K, AVR4K, 0}, + {"atmega32", AVR32K, AVR2K, AVR1K}, + {"atmega323", AVR32K, AVR2K, AVR1K}, + {"atmega324p", AVR32K, AVR2K, AVR1K}, + {"atmega325", AVR32K, AVR2K, AVR1K}, + {"atmega325p", AVR32K, AVR2K, AVR1K}, + {"atmega3250", AVR32K, AVR2K, AVR1K}, + {"atmega3250p", AVR32K, AVR2K, AVR1K}, + {"atmega328p", AVR32K, AVR2K, AVR1K}, + {"atmega329", AVR32K, AVR2K, AVR1K}, + {"atmega329p", AVR32K, AVR2K, AVR1K}, + {"atmega3290", AVR32K, AVR2K, AVR1K}, + {"atmega3290p", AVR32K, AVR2K, AVR1K}, + {"atmega32hvb", AVR32K, AVR2K, AVR1K}, + {"atmega32c1", AVR32K, AVR2K, AVR1K}, + {"atmega32m1", AVR32K, AVR2K, AVR1K}, + {"atmega32u4", AVR32K, 2560UL, AVR1K}, + + {"at43usb355", AVR24K, 1120, 0}, + + {"at76c711", AVR16K, AVR2K, 0}, + {"at90pwm216", AVR16K, AVR1K, AVR512}, + {"at90pwm316", AVR16K, AVR1K, AVR512}, + {"at90usb162", AVR16K, AVR512, AVR512}, + {"atmega16", AVR16K, AVR1K, AVR512}, + {"atmega161", AVR16K, AVR1K, AVR512}, + {"atmega162", AVR16K, AVR1K, AVR512}, + {"atmega163", AVR16K, AVR1K, AVR512}, + {"atmega164", AVR16K, AVR1K, AVR512}, + {"atmega164p", AVR16K, AVR1K, AVR512}, + {"atmega165", AVR16K, AVR1K, AVR512}, + {"atmega165p", AVR16K, AVR1K, AVR512}, + {"atmega168", AVR16K, AVR1K, AVR512}, + {"atmega168p", AVR16K, AVR1K, AVR512}, + {"atmega169", AVR16K, AVR1K, AVR512}, + {"atmega169p", AVR16K, AVR1K, AVR512}, + {"attiny167", AVR16K, AVR512, AVR512}, + {"atxmega16d4", AVR16K, AVR2K, AVR1K}, + + {"at90c8534", AVR8K, 352, AVR512}, + {"at90pwm1", AVR8K, AVR512, AVR512}, + {"at90pwm2", AVR8K, AVR512, AVR512}, + {"at90pwm2b", AVR8K, AVR512, AVR512}, + {"at90pwm3", AVR8K, AVR512, AVR512}, + {"at90pwm3b", AVR8K, AVR512, AVR512}, + {"at90s8515", AVR8K, AVR512, AVR512}, + {"at90s8535", AVR8K, AVR512, AVR512}, + {"at90usb82", AVR8K, AVR512, AVR512}, + {"atmega8", AVR8K, AVR1K, AVR512}, + {"atmega8515", AVR8K, AVR512, AVR512}, + {"atmega8535", AVR8K, AVR512, AVR512}, + {"atmega88", AVR8K, AVR1K, AVR512}, + {"atmega88p", AVR8K, AVR1K, AVR512}, + {"attiny84", AVR8K, AVR512, AVR512}, + {"attiny85", AVR8K, AVR512, AVR512}, + {"attiny861", AVR8K, AVR512, AVR512}, + {"attiny88", AVR8K, AVR256, AVR64}, + + {"at90s4414", AVR4K, 352, AVR256}, + {"at90s4433", AVR4K, AVR128, AVR256}, + {"at90s4434", AVR4K, 352, AVR256}, + {"atmega48", AVR4K, AVR512, AVR256}, + {"atmega48p", AVR4K, AVR512, AVR256}, + {"attiny43u", AVR4K, AVR256, AVR64}, + {"attiny44", AVR4K, AVR256, AVR256}, + {"attiny45", AVR4K, AVR256, AVR256}, + {"attiny461", AVR4K, AVR256, AVR256}, + {"attiny48", AVR4K, AVR256, AVR64}, + + {"at86rf401", AVR2K, 224, AVR128}, + {"at90s2313", AVR2K, AVR128, AVR128}, + {"at90s2323", AVR2K, AVR128, AVR128}, + {"at90s2333", AVR2K, 224, AVR128}, + {"at90s2343", AVR2K, AVR128, AVR128}, + {"attiny22", AVR2K, 224, AVR128}, + {"attiny2313", AVR2K, AVR128, AVR128}, + {"attiny24", AVR2K, AVR128, AVR128}, + {"attiny25", AVR2K, AVR128, AVR128}, + {"attiny26", AVR2K, AVR128, AVR128}, + {"attiny261", AVR2K, AVR128, AVR128}, + {"attiny28", AVR2K, 0, 0}, + + {"at90s1200", AVR1K, 0, AVR64}, + {"attiny11", AVR1K, 0, AVR64}, + {"attiny12", AVR1K, 0, AVR64}, + {"attiny13", AVR1K, AVR64, AVR64}, + {"attiny15", AVR1K, 0, AVR64}, +}; + +static char *avrmcu = NULL; + + static char *target = NULL; /* Forward declarations. */ @@ -79,7 +250,8 @@ 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 +260,7 @@ -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 +271,7 @@ #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 +279,7 @@ {"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 +311,7 @@ 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 +320,15 @@ { 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 +336,10 @@ } break; + case OPTION_MCU: + avrmcu = optarg; + break; + case OPTION_TARGET: target = optarg; break; @@ -190,11 +368,14 @@ 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 +421,7 @@ 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 +780,117 @@ 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 data_size = 0; + bfd_size_type text_size = 0; + bfd_size_type bss_size = 0; + bfd_size_type bootloader_size = 0; + bfd_size_type noinit_size = 0; + bfd_size_type eeprom_size = 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) + data_size = bfd_section_size (file, section); + if ((section = bfd_get_section_by_name (file, ".text")) != NULL) + text_size = bfd_section_size (file, section); + if ((section = bfd_get_section_by_name (file, ".bss")) != NULL) + bss_size = bfd_section_size (file, section); + if ((section = bfd_get_section_by_name (file, ".bootloader")) != NULL) + bootloader_size = bfd_section_size (file, section); + if ((section = bfd_get_section_by_name (file, ".noinit")) != NULL) + noinit_size = bfd_section_size (file, section); + if ((section = bfd_get_section_by_name (file, ".eeprom")) != NULL) + eeprom_size = bfd_section_size (file, section); + + bfd_size_type text = text_size + data_size + bootloader_size; + bfd_size_type data = data_size + bss_size + noinit_size; + bfd_size_type eeprom = eeprom_size; + + 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; + } }