aboutsummaryrefslogtreecommitdiff
path: root/bfd/ihex.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-01-08 22:21:57 +1030
committerAlan Modra <amodra@gmail.com>2019-01-08 22:25:09 +1030
commita9859e01726d085db79cff88550fdb38e2434e42 (patch)
treec9a7e89fd796fe42b7c13b35f227f979b773a7f4 /bfd/ihex.c
parent171b8e19575654ab32321eb99f3fd112663ae7fa (diff)
downloadfsf-binutils-gdb-a9859e01726d085db79cff88550fdb38e2434e42.zip
fsf-binutils-gdb-a9859e01726d085db79cff88550fdb38e2434e42.tar.gz
fsf-binutils-gdb-a9859e01726d085db79cff88550fdb38e2434e42.tar.bz2
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.
Diffstat (limited to 'bfd/ihex.c')
-rw-r--r--bfd/ihex.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/bfd/ihex.c b/bfd/ihex.c
index 5d7d8ff..101e0a7 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;