diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/libdl/rtl-mdreloc-aarch64.c | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/cpukit/libdl/rtl-mdreloc-aarch64.c b/cpukit/libdl/rtl-mdreloc-aarch64.c index e44238e636..1eb1d1e87d 100644 --- a/cpukit/libdl/rtl-mdreloc-aarch64.c +++ b/cpukit/libdl/rtl-mdreloc-aarch64.c @@ -78,9 +78,11 @@ __RCSID("$NetBSD: mdreloc.c,v 1.14 2020/06/16 21:01:30 joerg Exp $"); #include "rtl-elf.h" #include "rtl-error.h" #include <rtems/rtl/rtl-trace.h> -#include "rtl-unwind-arm.h" #include <rtems/score/tls.h> +#include "rtl-unwind.h" +#include "rtl-unwind-dw2.h" + struct tls_data { size_t td_tlsindex; Elf_Addr td_tlsoffs; @@ -107,7 +109,7 @@ checkoverflow(Elf_Addr addr, int bitwidth, Elf_Addr targetaddr, const Elf_Addr mask = ~__BITS(bitwidth - 1, 0); if (((addr & mask) != 0) && ((addr & mask) != mask)) { - printf("kobj_reloc: Relocation 0x%jx too far from %p" + printf("kobj_reloc: Relocation 0x%" PRIxPTR " too far from %p" " (base+0x%jx) for %dbit%s\n", (uintptr_t)targetaddr, where, off, bitwidth, bitscale); return true; @@ -120,7 +122,7 @@ static inline bool checkalign(Elf_Addr addr, int alignbyte, void *where, Elf64_Addr off) { if ((addr & (alignbyte - 1)) != 0) { - printf("kobj_reloc: Relocation 0x%jx unaligned at %p" + printf("kobj_reloc: Relocation 0x%" PRIxPTR " unaligned at %p" " (base+0x%jx). must be aligned %d\n", (uintptr_t)addr, where, off, alignbyte); return true; @@ -161,6 +163,12 @@ get_veneer_size(int type) return 16; } +uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj) +{ + (void) obj; + return sizeof(uint64_t); +} + size_t rtems_rtl_elf_relocate_tramp_max_size (void) { @@ -257,7 +265,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc 64/GLOB_DAT in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); } break; @@ -270,10 +278,10 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, */ case R_TYPE(RELATIVE): /* Delta(S) + A */ if (!parsing) { - *where = (Elf_Addr)(sect->base + rela->r_addend); + *where = (Elf_Addr)(uintptr_t)(sect->base + rela->r_addend); if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) printf ("rtl: reloc RELATIVE in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); } break; @@ -304,16 +312,12 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, shift = 12; break; default: - printf("illegal rtype: %ld\n", ELF_R_TYPE(rela->r_info)); + printf("illegal rtype: %" PRIu64 "\n", ELF_R_TYPE(rela->r_info)); break; } if (!parsing) { - target = (Elf_Addr)symvalue + rela->r_addend; - /* Calculate offset accounting for the DTV */ - target -= (uintptr_t)_TLS_Data_begin; - target += sizeof(TLS_Dynamic_thread_vector); - + target = (Elf_Addr)symvalue; target >>= shift; target &= WIDTHMASK(12); if (of_check && target >= of_check) { @@ -329,6 +333,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, case R_AARCH_LDST16_ABS_LO12_NC: case R_AARCH_LDST32_ABS_LO12_NC: case R_AARCH_LDST64_ABS_LO12_NC: + case R_AARCH64_LDST128_ABS_LO12_NC: switch (ELF_R_TYPE(rela->r_info)) { case R_AARCH64_ADD_ABS_LO12_NC: case R_AARCH64_LDST8_ABS_LO12_NC: @@ -343,8 +348,11 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, case R_AARCH_LDST64_ABS_LO12_NC: shift = 3; break; + case R_AARCH64_LDST128_ABS_LO12_NC: + shift = 4; + break; default: - printf("illegal rtype: %ld\n", ELF_R_TYPE(rela->r_info)); + printf("illegal rtype: %" PRIu64 "\n", ELF_R_TYPE(rela->r_info)); break; } @@ -360,9 +368,9 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, target = (Elf_Addr)symvalue + rela->r_addend; if (checkalign(target, 1 << shift, where, off)) { printf ("rtl: reloc checkalign failed in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); - printf("ELF_R_TYPE is : %ld\n", ELF_R_TYPE(rela->r_info)); + printf("ELF_R_TYPE is : %" PRIu64 "\n", ELF_R_TYPE(rela->r_info)); break; } target &= WIDTHMASK(12); @@ -384,6 +392,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, target -= (uintptr_t)where >> 12; if (checkoverflow(target, 21, raddr, " x 4k", where, off)) { + printf("]] %d\n", __LINE__); return rtems_rtl_elf_rel_failure; } @@ -414,6 +423,13 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, return rtems_rtl_elf_rel_failure; } + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) + printf ( + "rtl: JUMP26/PC26/CALL: insn=%p where=%p target=%p raddr=%p parsing=%d\n", + insn, (void*) where, (void*)(uintptr_t) target, (void*)(uintptr_t) raddr, + parsing + ); + target = (intptr_t)target >> 2; if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) { @@ -433,9 +449,8 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, return rtems_rtl_elf_rel_failure; } - tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1); + tramp_addr = ((Elf_Addr)(uintptr_t) obj->tramp_brk) | (symvalue & 1); obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue); - target = tramp_addr + rela->r_addend - (uintptr_t)where; target = (uintptr_t)target >> 2; } @@ -460,6 +475,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, raddr = (Elf_Addr)symvalue + rela->r_addend; target = raddr - (uintptr_t)where; if (checkoverflow(target, 32, raddr, "", where, off)) { + printf("]] %d\n", __LINE__); return rtems_rtl_elf_rel_failure; } *where32 = target; @@ -468,29 +484,30 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, case R_TYPE(TLSDESC): printf ("rtl: reloc TLSDESC in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); break; case R_TLS_TYPE(TLS_DTPREL): printf ("rtl: reloc TLS_DTPREL in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); break; case R_TLS_TYPE(TLS_DTPMOD): printf ("rtl: reloc TLS_DTPMOD in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); break; case R_TLS_TYPE(TLS_TPREL): printf ("rtl: reloc TLS_TPREL in %s --> %p in %s\n", - sect->name, (void *)*where, + sect->name, (void *)(uintptr_t)*where, rtems_rtl_obj_oname (obj)); break; default: - printf ("rtl: Unsupported relocation type (%ld) in %s --> %p in %s\n", + printf ("rtl: Unsupported relocation type (%" PRIu64 + ") in %s --> %p in %s\n", ELF_R_TYPE(rela->r_info), sect->name, (void *)where, rtems_rtl_obj_oname (obj)); return rtems_rtl_elf_rel_failure; @@ -556,3 +573,20 @@ rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj, rtems_rtl_set_error (EINVAL, "rela type record not supported"); return rtems_rtl_elf_rel_failure; } + +bool +rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj, + const char* name, + uint32_t flags) { + return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags); +} + +bool +rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) { + return rtems_rtl_elf_unwind_dw2_register (obj); +} + +bool +rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) { + return rtems_rtl_elf_unwind_dw2_deregister (obj); +} |