summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex White <alex.white@oarcorp.com>2023-09-08 14:57:19 -0500
committerJoel Sherrill <joel@rtems.org>2023-09-12 11:20:58 -0500
commit2bb23c7e842768162f74ac526098b5d1c83e5c3f (patch)
tree3979075a5518f09edf8285179388870a446a75fd
parentd2d1fa18a93d39b79421ed205755fd6623b2153b (diff)
microblaze: Fix relocation targets
Previously the addend was only used in 64 bit relocations. This behavior was incorrect but did not cause the RTEMS libdl tests to fail.
-rw-r--r--cpukit/libdl/rtl-mdreloc-microblaze.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/cpukit/libdl/rtl-mdreloc-microblaze.c b/cpukit/libdl/rtl-mdreloc-microblaze.c
index 0daba19a47..0956e22bc7 100644
--- a/cpukit/libdl/rtl-mdreloc-microblaze.c
+++ b/cpukit/libdl/rtl-mdreloc-microblaze.c
@@ -141,8 +141,10 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
where = (Elf_Addr *)(sect->base + rela->r_offset);
+ /* Target value */
+ target = (Elf_Addr)symvalue + addend;
/* Final PCREL value */
- Elf_Word pcrel_val = symvalue - ((Elf_Word)where);
+ Elf_Word pcrel_val = target - ((Elf_Word)where);
if (parsing) {
return rtems_rtl_elf_rel_no_error;
@@ -153,7 +155,6 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
break;
case R_TYPE(64):
- target = (Elf_Addr)symvalue + addend;
/* Set the lower 16 bits of where to the upper 16 bits of target */
write16le(where,
(read16le(where) & 0xFFFF0000) | (target >> 16));
@@ -180,18 +181,18 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
unsigned offset = addr & 3;
/*
- * Combine `symvalue` with `value_down` and `value_up` to form the new
+ * Combine `target` with `value_down` and `value_up` to form the new
* values to write.
*/
uint32_t new_value_down = (value_down & ((1 << (offset * 8)) - 1)) |
- (symvalue << (offset * 8));
+ (target << (offset * 8));
uint32_t new_value_up = (value_up & ~((1 << (offset * 8)) - 1)) |
- (symvalue >> ((4 - offset) * 8));
+ (target >> ((4 - offset) * 8));
write32le((void*)addr_down, new_value_down);
write32le((void*)addr_up, new_value_up);
} else {
- write32le(where, symvalue);
+ write32le(where, target);
}
}
break;
@@ -208,13 +209,13 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
/*
* Compensate for the fact that the PC is 4 bytes ahead of the instruction
*/
- target = pcrel_val - 4;
+ pcrel_val -= 4;
/* Set the lower 16 bits of where to the upper 16 bits of target */
write16le(where,
- (read16le(where) & 0xFFFF0000) | (target >> 16));
+ (read16le(where) & 0xFFFF0000) | (pcrel_val >> 16));
/* Set the lower 16 bits of where + 4 to the lower 16 bits of target */
write16le(where + 1,
- (read16le(where + 1) & 0xFFFF0000) | (target & 0xFFFF));
+ (read16le(where + 1) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
printf ("rtl: R_MICROBLAZE_64_PCREL %p @ %p in %s\n",