diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h --- a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h @@ -137,7 +137,37 @@ /// /// Fixup expression /// Fixup <- (Target - *{1}Fixup - Addend) - R_RISCV_SUB8 + R_RISCV_SUB8, + + /// Local label assignment + /// + /// Fixup expression: + /// Fixup <- (Target + Addend) + R_RISCV_SET6, + + /// Local label assignment + /// + /// Fixup expression: + /// Fixup <- (Target + Addend) + R_RISCV_SET8, + + /// Local label assignment + /// + /// Fixup expression: + /// Fixup <- (Target + Addend) + R_RISCV_SET16, + + /// Local label assignment + /// + /// Fixup expression: + /// Fixup <- (Target + Addend) + R_RISCV_SET32, + + /// Local label assignment + /// + /// Fixup expression: + /// Fixup <- (Target - Fixup + Addend) + R_RISCV_32_PCREL, }; /// Returns a string name for the given riscv edge. For debugging purposes diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -359,6 +359,39 @@ *FixupPtr = static_cast(Value); break; } + case R_RISCV_SET6: { + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + uint32_t RawData = *(little32_t *)FixupPtr; + int64_t Word6 = Value & 0x3f; + *(little32_t *)FixupPtr = (RawData & 0xffffffc0) | Word6; + break; + } + case R_RISCV_SET8: { + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + uint32_t RawData = *(little32_t *)FixupPtr; + int64_t Word8 = Value & 0xff; + *(little32_t *)FixupPtr = (RawData & 0xffffff00) | Word8; + break; + } + case R_RISCV_SET16: { + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + uint32_t RawData = *(little32_t *)FixupPtr; + int64_t Word16 = Value & 0xffff; + *(little32_t *)FixupPtr = (RawData & 0xffff0000) | Word16; + break; + } + case R_RISCV_SET32: { + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + int64_t Word32 = Value & 0xffffffff; + *(little32_t *)FixupPtr = Word32; + break; + } + case R_RISCV_32_PCREL: { + int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + int64_t Word32 = Value & 0xffffffff; + *(little32_t *)FixupPtr = Word32; + break; + } } return Error::success(); } @@ -409,6 +442,16 @@ return EdgeKind_riscv::R_RISCV_SUB16; case ELF::R_RISCV_SUB8: return EdgeKind_riscv::R_RISCV_SUB8; + case ELF::R_RISCV_SET6: + return EdgeKind_riscv::R_RISCV_SET6; + case ELF::R_RISCV_SET8: + return EdgeKind_riscv::R_RISCV_SET8; + case ELF::R_RISCV_SET16: + return EdgeKind_riscv::R_RISCV_SET16; + case ELF::R_RISCV_SET32: + return EdgeKind_riscv::R_RISCV_SET32; + case ELF::R_RISCV_32_PCREL: + return EdgeKind_riscv::R_RISCV_32_PCREL; } return make_error("Unsupported riscv relocation:" + diff --git a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp @@ -54,6 +54,16 @@ return "R_RISCV_SUB16"; case R_RISCV_SUB8: return "R_RISCV_SUB8"; + case R_RISCV_SET6: + return "R_RISCV_SET6"; + case R_RISCV_SET8: + return "R_RISCV_SET8"; + case R_RISCV_SET16: + return "R_RISCV_SET16"; + case R_RISCV_SET32: + return "R_RISCV_SET32"; + case R_RISCV_32_PCREL: + return "R_RISCV_32_PCREL"; } return getGenericEdgeKindName(K); } diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_relative.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_relative.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_relative.s @@ -0,0 +1,19 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t/riscv64_pc_relative.o %s +# RUN: llvm-mc -triple=riscv32 -filetype=obj -o %t/riscv32_pc_relative.o %s +# RUN: llvm-jitlink -noexec -check %s %t/riscv64_pc_relative.o +# RUN: llvm-jitlink -noexec -check %s %t/riscv32_pc_relative.o + +# jitlink-check: *{4}(foo) = 0x4 + +.global main +main: + lw a0, foo + +.section ".text","",@progbits +.type foo,@function +foo: + nop + nop + .reloc foo, R_RISCV_32_PCREL, foo+4 + .size foo, 8 diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_reloc_set.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_reloc_set.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_reloc_set.s @@ -0,0 +1,31 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t/riscv64_reloc_set.o %s +# RUN: llvm-mc -triple=riscv32 -filetype=obj -o %t/riscv32_reloc_set.o %s +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0xfff0f0f0 -slab-page-size 4096 \ +# RUN: -check %s %t/riscv64_reloc_set.o +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0xfff0f0f0 -slab-page-size 4096 \ +# RUN: -check %s %t/riscv32_reloc_set.o + +# jitlink-check: *{4}(foo) = foo +# jitlink-check: *{2}(foo+4) = foo[15:0] +# jitlink-check: *{1}(foo+6) = foo[7:0] +# jitlink-check: *{1}(foo+7) = foo[5:0] + +.global main +main: + lw a0, foo + +.section ".rodata","",@progbits +.type foo,@object +foo: + .reloc foo, R_RISCV_SET32, foo + .reloc foo+4, R_RISCV_SET16, foo + .reloc foo+6, R_RISCV_SET8, foo + .reloc foo+7, R_RISCV_SET6, foo + .word 0 + .half 0 + .byte 0 + .byte 0 + .size foo, 8