Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -360,6 +360,9 @@ << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) << "\n"); + const uint64_t AbsVal = Value + Addend; + const uint64_t RelVal = AbsVal - FinalAddress; + switch (Type) { default: llvm_unreachable("Relocation type not implemented yet!"); @@ -367,40 +370,39 @@ case ELF::R_AARCH64_ABS64: write(isBE, TargetPtr, Value + Addend); break; - case ELF::R_AARCH64_PREL32: { - uint64_t Result = Value + Addend - FinalAddress; - assert(static_cast(Result) >= INT32_MIN && - static_cast(Result) <= UINT32_MAX); - write(isBE, TargetPtr, static_cast(Result & 0xffffffffU)); + case ELF::R_AARCH64_PREL32: + assert(static_cast(RelVal) >= INT32_MIN && + static_cast(RelVal) <= UINT32_MAX); + write(isBE, TargetPtr, static_cast(RelVal & 0xffffffffU)); + break; + case ELF::R_AARCH64_PREL64: + write(isBE, TargetPtr, RelVal); break; - } case ELF::R_AARCH64_CALL26: // fallthrough case ELF::R_AARCH64_JUMP26: { // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the // calculation. - uint64_t BranchImm = Value + Addend - FinalAddress; - // "Check that -2^27 <= result < 2^27". - assert(isInt<28>(BranchImm)); - or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2); + assert(isInt<28>(RelVal)); + or32le(TargetPtr, (RelVal & 0x0FFFFFFC) >> 2); break; } case ELF::R_AARCH64_MOVW_UABS_G3: - or32le(TargetPtr, ((Value + Addend) & 0xFFFF000000000000) >> 43); + or32le(TargetPtr, (AbsVal & 0xFFFF000000000000) >> 43); break; case ELF::R_AARCH64_MOVW_UABS_G2_NC: - or32le(TargetPtr, ((Value + Addend) & 0xFFFF00000000) >> 27); + or32le(TargetPtr, (AbsVal & 0xFFFF00000000) >> 27); break; case ELF::R_AARCH64_MOVW_UABS_G1_NC: - or32le(TargetPtr, ((Value + Addend) & 0xFFFF0000) >> 11); + or32le(TargetPtr, (AbsVal & 0xFFFF0000) >> 11); break; case ELF::R_AARCH64_MOVW_UABS_G0_NC: - or32le(TargetPtr, ((Value + Addend) & 0xFFFF) << 5); + or32le(TargetPtr, (AbsVal & 0xFFFF) << 5); break; case ELF::R_AARCH64_ADR_PREL_PG_HI21: { // Operation: Page(S+A) - Page(P) uint64_t Result = - ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL); + (AbsVal & ~0xfffULL) - (FinalAddress & ~0xfffULL); // Check that -2^32 <= X < 2^32 assert(isInt<33>(Result) && "overflow check failed for relocation"); @@ -414,19 +416,19 @@ // Operation: S + A // Immediate goes in bits 21:10 of LD/ST instruction, taken // from bits 11:0 of X - or32AArch64Imm(TargetPtr, Value + Addend); + or32AArch64Imm(TargetPtr, AbsVal); break; case ELF::R_AARCH64_LDST32_ABS_LO12_NC: // Operation: S + A // Immediate goes in bits 21:10 of LD/ST instruction, taken // from bits 11:2 of X - or32AArch64Imm(TargetPtr, getBits(Value + Addend, 2, 11)); + or32AArch64Imm(TargetPtr, getBits(AbsVal, 2, 11)); break; case ELF::R_AARCH64_LDST64_ABS_LO12_NC: // Operation: S + A // Immediate goes in bits 21:10 of LD/ST instruction, taken // from bits 11:3 of X - or32AArch64Imm(TargetPtr, getBits(Value + Addend, 3, 11)); + or32AArch64Imm(TargetPtr, getBits(AbsVal, 3, 11)); break; } } Index: test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s =================================================================== --- test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s +++ test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_relocations.s @@ -27,13 +27,15 @@ .p2align 3 k: .xword f - .size k, 8 + .xword f - . + .size k, 16 # rtdyld-check: *{4}(g) = 0xd2e02460 # rtdyld-check: *{4}(g + 4) = 0xf2c8ace0 # rtdyld-check: *{4}(g + 8) = 0xf2b13560 # rtdyld-check: *{4}(g + 12) = 0xf299bde0 # rtdyld-check: *{8}k = f +# rtdyld-check: *{8}(k + 8) = f - (k + 8) ## f & 0xFFF = 0xdef (bits 11:0 of f) ## 0xdef << 10 = 0x37bc00