From 49a8ead4e2784ca2f57112ef2001ba9623c253b6 Mon Sep 17 00:00:00 2001 From: Ranulfo Raphael Date: Thu, 23 Jan 2025 18:17:09 -0300 Subject: [PATCH] cpukit/libdl/arm: Fix trampoline alignment This commit aligns trampolines for THUMB and ARM instructions (CALL/JUMP24 and THM_JUMP24/THM_PC22). According to the ARM technical reference in section "Register-relative and PC-relative expressions": In Thumb code: - For B, BL, CBNZ, and CBZ instructions, the value of the PC is the address of the current instruction plus 4 bytes. - For all other instructions that use labels, the value of the PC is the address of the current instruction plus 4 bytes, with bit[1] of the result cleared to 0 to make it word-aligned. --- cpukit/libdl/rtl-mdreloc-arm.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c index 9421b0d5d4..221ac4014d 100644 --- a/cpukit/libdl/rtl-mdreloc-arm.c +++ b/cpukit/libdl/rtl-mdreloc-arm.c @@ -315,6 +315,10 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj, return rtems_rtl_elf_rel_failure; } + /* + * Align tramp_brk as necessary. + */ + obj->tramp_brk = (void *)RTEMS_ALIGN_UP((uintptr_t)obj->tramp_brk, 4); tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1); obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue); @@ -519,6 +523,10 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj, return rtems_rtl_elf_rel_failure; } + /* + * Align tramp_brk as necessary. + */ + obj->tramp_brk = (void *)RTEMS_ALIGN_UP((uintptr_t)obj->tramp_brk, 4); tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1); tmp = tramp_addr + addend; if (isThumb(symvalue)) { @@ -526,11 +534,9 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj, tmp = tmp - (Elf_Addr)where; } else { /* - * The B[L]X expects ARM code at the target. Align tramp_brk as - * necessary. - */ - obj->tramp_brk = (void *)RTEMS_ALIGN_UP((uintptr_t)obj->tramp_brk, 4); - tramp_addr = (Elf_Addr) obj->tramp_brk; + * The B[L]X expects ARM code at the target. + */ + tramp_addr = (Elf_Addr) obj->tramp_brk; obj->tramp_brk = set_arm_veneer(obj->tramp_brk, symvalue); /* * where[1:0] are set to 0 for ARM-targeted relocations because the jump