summaryrefslogtreecommitdiff
path: root/cpukit
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 /cpukit
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.
Diffstat (limited to 'cpukit')
-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",