aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStafford Horne <shorne@gmail.com>2022-02-02 20:11:56 +0900
committerStafford Horne <shorne@gmail.com>2022-02-02 20:11:56 +0900
commitc7c6e55b60b072cdcc5c3fc27164b890a0f34520 (patch)
tree107c07240dc4eb049999322d336551e7fd8212fd
parent14f983573850419b8354a112f6ab048cb4bc130d (diff)
downloadfsf-binutils-gdb-c7c6e55b60b072cdcc5c3fc27164b890a0f34520.zip
fsf-binutils-gdb-c7c6e55b60b072cdcc5c3fc27164b890a0f34520.tar.gz
fsf-binutils-gdb-c7c6e55b60b072cdcc5c3fc27164b890a0f34520.tar.bz2
or1k: Avoid R_OR1K_GOT16 signed overflow by using special howto
Previously when fixing PR 21464 we masked out upper bits of the relocation value in order to avoid overflow complaints when acceptable. It turns out this does not work when the relocation value ends up being signed. To fix this this patch introduces a special howto with complain_on_overflow set to complain_overflow_dont. This is used in place of the normal R_OR1K_GOT16 howto when we detect R_OR1K_GOT_AHI16 relocations. bfd/ChangeLog: PR 28735 * elf32-or1k.c (or1k_elf_got16_no_overflow_howto): Define. (or1k_elf_relocate_section): Use new howto instead of trying to mask out relocation bits.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-or1k.c24
2 files changed, 27 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 91abfb5..b213764 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2022-02-02 Stafford Horne <shorne@gmail.com>
+
+ PR 28735
+ * elf32-or1k.c (or1k_elf_got16_no_overflow_howto): Define.
+ (or1k_elf_relocate_section): Use new howto instead of trying to
+ mask out relocation bits.
+
2022-01-24 Roland McGrath <mcgrathr@google.com>
* doc/local.mk (%D%/bfdver.texi): Add mkdir command.
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index 192e83a..2a06b3e 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -828,6 +828,23 @@ static reloc_howto_type or1k_elf_howto_table[] =
false), /* pcrel_offset */
};
+/* A copy of the R_OR1K_GOT16 used in the presense of R_OR1K_GOT_AHI16
+ relocations when we know we can ignore overflows. */
+static reloc_howto_type or1k_elf_got16_no_overflow_howto =
+ HOWTO (R_OR1K_GOT16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false); /* pcrel_offset */
+
/* Map BFD reloc types to Or1k ELF reloc types. */
struct or1k_reloc_map
@@ -1506,12 +1523,11 @@ or1k_elf_relocate_section (bfd *output_bfd,
if (r_type == R_OR1K_GOT_AHI16)
saw_gotha = true;
- /* If we have a R_OR1K_GOT16 followed by a R_OR1K_GOT_AHI16
+ /* If we have a R_OR1K_GOT16 following a R_OR1K_GOT_AHI16
relocation we assume the code is doing the right thing to avoid
- overflows. Here we mask the lower 16-bit of the relocation to
- avoid overflow validation failures. */
+ overflows. */
if (r_type == R_OR1K_GOT16 && saw_gotha)
- relocation &= 0xffff;
+ howto = &or1k_elf_got16_no_overflow_howto;
/* Addend should be zero. */
if (rel->r_addend != 0)