#include "Rts.h" #include "elf_compat.h" #include "elf_reloc_aarch64.h" #include "util.h" #include "elf_util.h" #include "elf_plt.h" #include #if defined(aarch64_HOST_ARCH) #if defined(OBJFORMAT_ELF) #define Page(x) ((x) & ~0xFFF) typedef uint64_t addr_t; bool isBranch(addr_t p); bool isBranchLink(addr_t p); bool isAdrp(addr_t p); bool isLoadStore(addr_t p); bool isAddSub(addr_t p); bool isVectorOp(addr_t p); int64_t decodeAddendAarch64(Section * section, Elf_Rel * rel) GNU_ATTRIBUTE(__noreturn__); bool encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend); bool isBranch(addr_t p) { return (*(addr_t*)p & 0xFC000000) == 0x14000000; } bool isBranchLink(addr_t p) { return (*(addr_t*)p & 0xFC000000) == 0x94000000; } bool isAdrp(addr_t p) { return (*(addr_t*)p & 0x9F000000) == 0x90000000; } bool isLoadStore(addr_t p) { return (*(addr_t*)p & 0x3B000000) == 0x39000000; } bool isAddSub(addr_t p) { return (*(addr_t*)p & 0x11C00000) == 0x11000000; } bool isVectorOp(addr_t p) { return (*(addr_t*)p & 0x04800000) == 0x04800000; } /* instructions are 32bit */ typedef uint32_t inst_t; int64_t decodeAddendAarch64(Section * section __attribute__((unused)), Elf_Rel * rel __attribute__((unused))) { abort(/* we don't support Rel locations yet. */); } bool encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) { /* instructions are 32bit! */ addr_t P = (addr_t)((uint8_t*)section->start + rel->r_offset); int exp_shift = -1; switch(ELF64_R_TYPE(rel->r_info)) { /* static misc relocations */ /* static data relocations */ case COMPAT_R_AARCH64_ABS64: case COMPAT_R_AARCH64_PREL64: *(uint64_t*)P = (uint64_t)addend; break; case COMPAT_R_AARCH64_ABS32: CHECK(isInt64(32, addend)); FALLTHROUGH; case COMPAT_R_AARCH64_PREL32: CHECK(isInt64(32, addend)); *(uint32_t*)P = (uint32_t)addend; break; case COMPAT_R_AARCH64_ABS16: CHECK(isInt64(16, addend)); FALLTHROUGH; case COMPAT_R_AARCH64_PREL16: CHECK(isInt64(16, addend)); *(uint16_t*)P = (uint16_t)addend; break; /* static aarch64 relocations */ /* - pc relative relocations */ case COMPAT_R_AARCH64_ADR_PREL_PG_HI21: { // adrp ,