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.
This commit is contained in:
Ranulfo Raphael
2025-01-23 18:17:09 -03:00
parent 1a4e26e3ea
commit 49a8ead4e2

View File

@@ -315,6 +315,10 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj,
return rtems_rtl_elf_rel_failure; 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); tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue); 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; 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); tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
tmp = tramp_addr + addend; tmp = tramp_addr + addend;
if (isThumb(symvalue)) { if (isThumb(symvalue)) {
@@ -526,11 +534,9 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj,
tmp = tmp - (Elf_Addr)where; tmp = tmp - (Elf_Addr)where;
} else { } else {
/* /*
* The B[L]X expects ARM code at the target. Align tramp_brk as * The B[L]X expects ARM code at the target.
* necessary. */
*/ tramp_addr = (Elf_Addr) obj->tramp_brk;
obj->tramp_brk = (void *)RTEMS_ALIGN_UP((uintptr_t)obj->tramp_brk, 4);
tramp_addr = (Elf_Addr) obj->tramp_brk;
obj->tramp_brk = set_arm_veneer(obj->tramp_brk, symvalue); obj->tramp_brk = set_arm_veneer(obj->tramp_brk, symvalue);
/* /*
* where[1:0] are set to 0 for ARM-targeted relocations because the jump * where[1:0] are set to 0 for ARM-targeted relocations because the jump