Index: llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -55,6 +55,10 @@ ELFLdSt32Abs12, ELFLdSt64Abs12, ELFLdSt128Abs12, + ELFMovwAbsG0, + ELFMovwAbsG1, + ELFMovwAbsG2, + ELFMovwAbsG3, ELFAbs64, ELFPrel32, ELFPrel64, @@ -83,6 +87,14 @@ return ELFLdSt64Abs12; case ELF::R_AARCH64_LDST128_ABS_LO12_NC: return ELFLdSt128Abs12; + case ELF::R_AARCH64_MOVW_UABS_G0_NC: + return ELFMovwAbsG0; + case ELF::R_AARCH64_MOVW_UABS_G1_NC: + return ELFMovwAbsG1; + case ELF::R_AARCH64_MOVW_UABS_G2_NC: + return ELFMovwAbsG2; + case ELF::R_AARCH64_MOVW_UABS_G3: + return ELFMovwAbsG3; case ELF::R_AARCH64_ABS64: return ELFAbs64; case ELF::R_AARCH64_PREL32: @@ -216,6 +228,50 @@ Kind = aarch64::PageOffset12; break; } + case ELFMovwAbsG0: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isMoveWideImm16(Instr) || + aarch64::getMoveWide16Shift(Instr) != 0) + return make_error( + "R_AARCH64_MOVW_UABS_G0_NC target is not a " + "MOVK/MOVZ (imm16, LSL #0) instruction"); + + Kind = aarch64::MoveWide16; + break; + } + case ELFMovwAbsG1: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isMoveWideImm16(Instr) || + aarch64::getMoveWide16Shift(Instr) != 16) + return make_error( + "R_AARCH64_MOVW_UABS_G1_NC target is not a " + "MOVK/MOVZ (imm16, LSL #16) instruction"); + + Kind = aarch64::MoveWide16; + break; + } + case ELFMovwAbsG2: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isMoveWideImm16(Instr) || + aarch64::getMoveWide16Shift(Instr) != 32) + return make_error( + "R_AARCH64_MOVW_UABS_G2_NC target is not a " + "MOVK/MOVZ (imm16, LSL #32) instruction"); + + Kind = aarch64::MoveWide16; + break; + } + case ELFMovwAbsG3: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isMoveWideImm16(Instr) || + aarch64::getMoveWide16Shift(Instr) != 48) + return make_error( + "R_AARCH64_MOVW_UABS_G3 target is not a " + "MOVK/MOVZ (imm16, LSL #48) instruction"); + + Kind = aarch64::MoveWide16; + break; + } case ELFAbs64: { Kind = aarch64::Pointer64; break; @@ -268,6 +324,14 @@ return "ELFLdSt64Abs12"; case ELFLdSt128Abs12: return "ELFLdSt128Abs12"; + case ELFMovwAbsG0: + return "ELFMovwAbsG0"; + case ELFMovwAbsG1: + return "ELFMovwAbsG1"; + case ELFMovwAbsG2: + return "ELFMovwAbsG2"; + case ELFMovwAbsG3: + return "ELFMovwAbsG3"; case ELFAbs64: return "ELFAbs64"; case ELFPrel32: Index: llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s =================================================================== --- llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s +++ llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s @@ -141,6 +141,60 @@ str x0, [x1, :lo12:named_data] .size test_str_64bit, .-test_str_64bit + +# Check R_AARCH64_MOVW_UABS_G*_NC relocation of a local symbol +# +# The immediate value should be the symbol address right shifted according to LSL value +# +# jitlink-check: decode_operand(test_movz_g0_nc, 1) = named_data[15:0] +# jitlink-check: decode_operand(test_movk_g0_nc, 2) = named_data[15:0] +# jitlink-check: decode_operand(test_movz_g1_nc, 1) = named_data[31:16] +# jitlink-check: decode_operand(test_movk_g1_nc, 2) = named_data[31:16] +# jitlink-check: decode_operand(test_movz_g2_nc, 1) = named_data[47:32] +# jitlink-check: decode_operand(test_movk_g2_nc, 2) = named_data[47:32] +# jitlink-check: decode_operand(test_movz_g3, 1) = named_data[63:48] +# jitlink-check: decode_operand(test_movk_g3, 2) = named_data[63:48] + + .globl test_movz_g0_nc +test_movz_g0_nc: + movz x0, #:abs_g0_nc:named_data + .size test_movz_g0_nc, .-test_movz_g0_nc + + .globl test_movk_g0_nc +test_movk_g0_nc: + movk x0, #:abs_g0_nc:named_data + .size test_movk_g0_nc, .-test_movk_g0_nc + + .globl test_movz_g1_nc +test_movz_g1_nc: + movz x0, #:abs_g1_nc:named_data + .size test_movz_g1_nc, .-test_movz_g1_nc + + .globl test_movk_g1_nc +test_movk_g1_nc: + movk x0, #:abs_g1_nc:named_data + .size test_movk_g1_nc, .-test_movk_g1_nc + + .globl test_movz_g2_nc +test_movz_g2_nc: + movz x0, #:abs_g2_nc:named_data + .size test_movz_g2_nc, .-test_movz_g2_nc + + .globl test_movk_g2_nc +test_movk_g2_nc: + movk x0, #:abs_g2_nc:named_data + .size test_movk_g2_nc, .-test_movk_g2_nc + + .globl test_movk_g3 +test_movk_g3: + movk x0, #:abs_g3:named_data + .size test_movk_g3, .-test_movk_g3 + + .globl test_movz_g3 +test_movz_g3: + movz x0, #:abs_g3:named_data + .size test_movz_g3, .-test_movz_g3 + # Check R_AARCH64_ABS64 relocation of a function pointer to local symbol # # jitlink-check: *{8}local_func_addr_quad = named_func