From: Alan Modra Date: Tue, 8 Jan 2019 11:51:57 +0000 (+1030) Subject: PR24065, 32-bit objcopy fails with 64-bit address ... out of range X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a9859e01726d085db79cff88550fdb38e2434e42;p=binutils-gdb.git PR24065, 32-bit objcopy fails with 64-bit address ... out of range PR 23699 PR 24065 * ihex.c (ihex_write_object_contents): Properly check 32-bit address range. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3d619e46ed2..3b24c239e50 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2019-01-08 Alan Modra + + PR 23699 + PR 24065 + * ihex.c (ihex_write_object_contents): Properly check 32-bit + address range. + 2019-01-05 Yoshinori Sato * bfd/archures.c: Add bfd_mach_rx_v2 and bfd_mach_rx_v3. diff --git a/bfd/ihex.c b/bfd/ihex.c index 5d7d8fffeaa..101e0a76155 100644 --- a/bfd/ihex.c +++ b/bfd/ihex.c @@ -775,25 +775,29 @@ ihex_write_object_contents (bfd *abfd) bfd_vma where; bfd_byte *p; bfd_size_type count; - const bfd_vma sign = (bfd_vma) 0xffffffff80000000ULL; - const bfd_vma top = (bfd_vma) 0xffffffff00000000ULL; where = l->where; - /* Check for unacceptable addresses sign extension. - See PR 23699 for more details. */ - if ((where & sign) == top - || ((where & top) != 0 && (where & top) != top)) - { - _bfd_error_handler - /* xgettext:c-format */ - (_("%pB 64-bit address %#" PRIx64 " out of range for Intel Hex file"), - abfd, (uint64_t) where); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - +#ifdef BFD64 + /* IHex only supports 32-bit addresses, and we want to check + that 64-bit addresses are in range. This isn't quite as + obvious as it may seem, since some targets have 32-bit + addresses that are sign extended to 64 bits. So complain + only if addresses overflow both unsigned and signed 32-bit + integers. */ + if (where > 0xffffffff + && where + 0x80000000 > 0xffffffff) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB 64-bit address %#" PRIx64 + " out of range for Intel Hex file"), + abfd, (uint64_t) where); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } where &= 0xffffffff; +#endif p = l->data; count = l->size;