From e8c83191cc6fee517d2029109c61981b4092439d Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Mon, 20 May 2024 13:33:55 +0100 Subject: Include .rodata size in avr-objdump -P mem-usage. PR 31687 --- binutils/od-elf32_avr.c | 111 ++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 66 deletions(-) (limited to 'binutils') diff --git a/binutils/od-elf32_avr.c b/binutils/od-elf32_avr.c index 4e6b6fa..4466c5f 100644 --- a/binutils/od-elf32_avr.c +++ b/binutils/od-elf32_avr.c @@ -167,79 +167,60 @@ elf32_avr_get_device_info (bfd *abfd, char *description, device->name = str_table + device_name_index; } -static void -elf32_avr_get_memory_usage (bfd *abfd, - bfd_size_type *text_usage, - bfd_size_type *data_usage, - bfd_size_type *eeprom_usage) -{ +/* Get the size of section *SECNAME, truncated to a reasonable value in + order to catch PR 27285 and dysfunctional binaries. */ - bfd_size_type avr_datasize = 0; - bfd_size_type avr_textsize = 0; - bfd_size_type avr_bsssize = 0; - bfd_size_type bootloadersize = 0; - bfd_size_type noinitsize = 0; - bfd_size_type eepromsize = 0; - bfd_size_type res; +static bfd_size_type +elf32_avr_get_truncated_size (bfd *abfd, const char *secname) +{ + /* Max size of around 1 MiB is more than any reasonable AVR will + ever be able to swallow. And it's small enough so that we won't + get overflows / UB as demonstrated in PR 27285. */ + const bfd_size_type max_size = 1000000; + bfd_size_type size = 0; asection *section; - if ((section = bfd_get_section_by_name (abfd, ".data")) != NULL) - avr_datasize = bfd_section_size (section); - if ((section = bfd_get_section_by_name (abfd, ".text")) != NULL) - avr_textsize = bfd_section_size (section); - if ((section = bfd_get_section_by_name (abfd, ".bss")) != NULL) - avr_bsssize = bfd_section_size (section); - if ((section = bfd_get_section_by_name (abfd, ".bootloader")) != NULL) - bootloadersize = bfd_section_size (section); - if ((section = bfd_get_section_by_name (abfd, ".noinit")) != NULL) - noinitsize = bfd_section_size (section); - if ((section = bfd_get_section_by_name (abfd, ".eeprom")) != NULL) - eepromsize = bfd_section_size (section); - - /* PR 27285: Check for overflow. */ - res = avr_textsize + avr_datasize; - if (res < avr_textsize || res < avr_datasize) - { - fprintf (stderr, _("Warning: textsize (%#lx) + datasize (%#lx) overflows size type\n"), - (long) avr_textsize, (long) avr_datasize); - res = (bfd_size_type) -1; - } - else + section = bfd_get_section_by_name (abfd, secname); + + if (section != NULL) { - bfd_size_type res2; - res2 = res + bootloadersize; - if (res2 < bootloadersize || res2 < res) + size = bfd_section_size (section); + if (size > INT32_MAX) { - fprintf (stderr, _("Warning: textsize (%#lx) + datasize (%#lx) + bootloadersize (%#lx) overflows size type\n"), - (long) avr_textsize, (long) avr_datasize, (long) bootloadersize); - res2 = (bfd_size_type) -1; + fprintf (stderr, _("Warning: section %s has a negative size of" + " %ld bytes, saturating to 0 bytes\n"), + secname, (long) (int32_t) size); + size = 0; } - res = res2; - } - *text_usage = res; - - res = avr_datasize + avr_bsssize; - if (res < avr_datasize || res < avr_bsssize) - { - fprintf (stderr, _("Warning: datatsize (%#lx) + bssssize (%#lx) overflows size type\n"), - (long) avr_datasize, (long) avr_bsssize); - res = (bfd_size_type) -1; - } - else - { - bfd_size_type res2; - - res2 = res + noinitsize; - if (res2 < res || res2 < noinitsize) + else if (size > max_size) { - fprintf (stderr, _("Warning: datasize (%#lx) + bsssize (%#lx) + noinitsize (%#lx) overflows size type\n"), - (long) avr_datasize, (long) avr_bsssize, (long) noinitsize); - res2 = (bfd_size_type) -1; + fprintf (stderr, _("Warning: section %s has an impossible size of" + " %lu bytes, truncating to %lu bytes\n"), + secname, (unsigned long) size, (unsigned long) max_size); + size = max_size; } - res = res2; } - *data_usage = res; + return size; +} + +static void +elf32_avr_get_memory_usage (bfd *abfd, + bfd_size_type *text_usage, + bfd_size_type *data_usage, + bfd_size_type *eeprom_usage) +{ + bfd_size_type avr_textsize = elf32_avr_get_truncated_size (abfd, ".text"); + bfd_size_type avr_datasize = elf32_avr_get_truncated_size (abfd, ".data");; + bfd_size_type avr_bsssize = elf32_avr_get_truncated_size (abfd, ".bss"); + bfd_size_type noinitsize = elf32_avr_get_truncated_size (abfd, ".noinit"); + bfd_size_type rodatasize = elf32_avr_get_truncated_size (abfd, ".rodata"); + bfd_size_type eepromsize = elf32_avr_get_truncated_size (abfd, ".eeprom"); + bfd_size_type bootloadersize = elf32_avr_get_truncated_size (abfd, + ".bootloader"); + + *text_usage = avr_textsize + avr_datasize + rodatasize + bootloadersize; + *data_usage = avr_datasize + avr_bsssize + noinitsize; *eeprom_usage = eepromsize; } @@ -277,7 +258,7 @@ elf32_avr_dump_mem_usage (bfd *abfd) if (device.flash_size > 0) printf (" (%2.1f%% Full)", (double) text_usage / device.flash_size * 100); - printf ("\n(.text + .data + .bootloader)\n\n"); + printf ("\n(.text + .data + .rodata + .bootloader)\n\n"); /* Data size */ printf ("Data: %8" PRIu64 " bytes", (uint64_t) data_usage); @@ -350,7 +331,6 @@ elf32_avr_dump_avr_prop (bfd *abfd) free (r_list); } - static void elf32_avr_dump_avr_deviceinfo (bfd *abfd) { @@ -398,7 +378,6 @@ elf32_avr_dump_avr_deviceinfo (bfd *abfd) free (contents); } - static void elf32_avr_dump (bfd *abfd) { -- cgit v1.1