Index: llvm/include/llvm/ExecutionEngine/JITLink/riscv.h =================================================================== --- llvm/include/llvm/ExecutionEngine/JITLink/riscv.h +++ llvm/include/llvm/ExecutionEngine/JITLink/riscv.h @@ -19,7 +19,8 @@ namespace jitlink { namespace riscv { -/// Represets riscv fixups +/// Represents riscv fixups. Ordered in the same way as the relocations in +/// include/llvm/BinaryFormat/ELFRelocs/RISCV.def. enum EdgeKind_riscv : Edge::Kind { // TODO: Capture and replace to generic fixups @@ -51,24 +52,24 @@ /// R_RISCV_JAL, - /// High 20 bits of 32-bit pointer value relocation + /// PC relative call /// - /// Fixup expression - /// Fixup <- (Target + Addend + 0x800) >> 12 - R_RISCV_HI20, + /// Fixup expression: + /// Fixup <- (Target - Fixup + Addend) + R_RISCV_CALL, - /// Low 12 bits of 32-bit pointer value relocation, used by S type instruction - /// format + /// PC relative call by PLT /// - /// Fixup expression - /// Fixup <- (Target + Addend) & 0xFFF - R_RISCV_LO12_S, + /// Fixup expression: + /// Fixup <- (Target - Fixup + Addend) + R_RISCV_CALL_PLT, - /// Low 12 bits of 32-bit pointer value relocation + /// PC relative GOT offset /// - /// Fixup expression - /// Fixup <- (Target + Addend) & 0xFFF - R_RISCV_LO12_I, + /// Fixup expression: + /// Fixup <- (GOT - Fixup + Addend) >> 12 + R_RISCV_GOT_HI20, + /// High 20 bits of PC relative relocation /// /// Fixup expression: @@ -87,35 +88,36 @@ /// Fixup <- (Target - Fixup + Addend) & 0xFFF R_RISCV_PCREL_LO12_S, - /// PC relative call + /// High 20 bits of 32-bit pointer value relocation /// - /// Fixup expression: - /// Fixup <- (Target - Fixup + Addend) - R_RISCV_CALL, + /// Fixup expression + /// Fixup <- (Target + Addend + 0x800) >> 12 + R_RISCV_HI20, - /// 32 bits PC relative relocation + /// Low 12 bits of 32-bit pointer value relocation /// - /// Fixup expression: - /// Fixup <- (Target - Fixup + Addend) - R_RISCV_32_PCREL, + /// Fixup expression + /// Fixup <- (Target + Addend) & 0xFFF + R_RISCV_LO12_I, - /// PC relative GOT offset + /// Low 12 bits of 32-bit pointer value relocation, used by S type instruction + /// format /// - /// Fixup expression: - /// Fixup <- (GOT - Fixup + Addend) >> 12 - R_RISCV_GOT_HI20, + /// Fixup expression + /// Fixup <- (Target + Addend) & 0xFFF + R_RISCV_LO12_S, - /// PC relative call by PLT + /// 8 bits label addition /// - /// Fixup expression: - /// Fixup <- (Target - Fixup + Addend) - R_RISCV_CALL_PLT, + /// Fixup expression + /// Fixup <- (Target - *{1}Fixup + Addend) + R_RISCV_ADD8, - /// 64 bits label addition + /// 16 bits label addition /// - /// Fixup expression: - /// Fixup <- (Target - *{8}Fixup + Addend) - R_RISCV_ADD64, + /// Fixup expression + /// Fixup <- (Target - *{2}Fixup + Addend) + R_RISCV_ADD16, /// 32 bits label addition /// @@ -123,23 +125,23 @@ /// Fixup <- (Target - *{4}Fixup + Addend) R_RISCV_ADD32, - /// 16 bits label addition + /// 64 bits label addition /// - /// Fixup expression - /// Fixup <- (Target - *{2}Fixup + Addend) - R_RISCV_ADD16, + /// Fixup expression: + /// Fixup <- (Target - *{8}Fixup + Addend) + R_RISCV_ADD64, - /// 8 bits label addition + /// 8 bits label subtraction /// /// Fixup expression - /// Fixup <- (Target - *{1}Fixup + Addend) - R_RISCV_ADD8, + /// Fixup <- (Target - *{1}Fixup - Addend) + R_RISCV_SUB8, - /// 64 bits label subtraction + /// 16 bits label subtraction /// /// Fixup expression - /// Fixup <- (Target - *{8}Fixup - Addend) - R_RISCV_SUB64, + /// Fixup <- (Target - *{2}Fixup - Addend) + R_RISCV_SUB16, /// 32 bits label subtraction /// @@ -147,17 +149,11 @@ /// Fixup <- (Target - *{4}Fixup - Addend) R_RISCV_SUB32, - /// 16 bits label subtraction - /// - /// Fixup expression - /// Fixup <- (Target - *{2}Fixup - Addend) - R_RISCV_SUB16, - - /// 8 bits label subtraction + /// 64 bits label subtraction /// /// Fixup expression - /// Fixup <- (Target - *{1}Fixup - Addend) - R_RISCV_SUB8, + /// Fixup <- (Target - *{8}Fixup - Addend) + R_RISCV_SUB64, /// 6 bits label subtraction /// @@ -188,6 +184,12 @@ /// Fixup expression: /// Fixup <- (Target + Addend) R_RISCV_SET32, + + /// 32 bits PC relative relocation + /// + /// Fixup expression: + /// Fixup <- (Target - Fixup + Addend) + R_RISCV_32_PCREL, }; /// Returns a string name for the given riscv edge. For debugging purposes Index: llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -227,37 +227,6 @@ *(little32_t *)FixupPtr = RawInstr | Imm20 | Imm10_1 | Imm11 | Imm19_12; break; } - case R_RISCV_HI20: { - int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); - int64_t Hi = Value + 0x800; - if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32))) - return makeTargetOutOfRangeError(G, B, E); - uint32_t RawInstr = *(little32_t *)FixupPtr; - *(little32_t *)FixupPtr = - (RawInstr & 0xFFF) | (static_cast(Hi & 0xFFFFF000)); - break; - } - case R_RISCV_LO12_I: { - // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs - // with current relocation R_RISCV_LO12_I. So here may need a check. - int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); - int32_t Lo = Value & 0xFFF; - uint32_t RawInstr = *(little32_t *)FixupPtr; - *(little32_t *)FixupPtr = - (RawInstr & 0xFFFFF) | (static_cast(Lo & 0xFFF) << 20); - break; - } - case R_RISCV_LO12_S: { - // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs - // with current relocation R_RISCV_LO12_S. So here may need a check. - int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); - int64_t Lo = Value & 0xFFF; - uint32_t Imm31_25 = extractBits(Lo, 5, 7) << 25; - uint32_t Imm11_7 = extractBits(Lo, 0, 5) << 7; - uint32_t RawInstr = *(little32_t *)FixupPtr; - *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7; - break; - } case R_RISCV_CALL: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; int64_t Hi = Value + 0x800; @@ -272,6 +241,9 @@ RawInstrJalr | (static_cast(Lo) << 20); break; } + // The relocations by R_RISCV_CALL_PLT and R_RISCV_GOT_HI20 are handled by + // PerGraphGOTAndPLTStubsBuilder_ELF_riscv and transformed into R_RISCV_CALL + // and R_RISCV_PCREL_HI20. case R_RISCV_PCREL_HI20: { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; int64_t Hi = Value + 0x800; @@ -314,13 +286,53 @@ *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7; break; } - case R_RISCV_ADD64: { + case R_RISCV_HI20: { + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + int64_t Hi = Value + 0x800; + if (LLVM_UNLIKELY(!isInRangeForImm(Hi, 32))) + return makeTargetOutOfRangeError(G, B, E); + uint32_t RawInstr = *(little32_t *)FixupPtr; + *(little32_t *)FixupPtr = + (RawInstr & 0xFFF) | (static_cast(Hi & 0xFFFFF000)); + break; + } + case R_RISCV_LO12_I: { + // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs + // with current relocation R_RISCV_LO12_I. So here may need a check. + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + int32_t Lo = Value & 0xFFF; + uint32_t RawInstr = *(little32_t *)FixupPtr; + *(little32_t *)FixupPtr = + (RawInstr & 0xFFFFF) | (static_cast(Lo & 0xFFF) << 20); + break; + } + case R_RISCV_LO12_S: { + // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs + // with current relocation R_RISCV_LO12_S. So here may need a check. + int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue(); + int64_t Lo = Value & 0xFFF; + uint32_t Imm31_25 = extractBits(Lo, 5, 7) << 25; + uint32_t Imm11_7 = extractBits(Lo, 0, 5) << 7; + uint32_t RawInstr = *(little32_t *)FixupPtr; + *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7; + break; + } + case R_RISCV_ADD8: { + int64_t Value = + (E.getTarget().getAddress() + + *(reinterpret_cast(FixupAddress.getValue())) + + E.getAddend()) + .getValue(); + *FixupPtr = static_cast(Value); + break; + } + case R_RISCV_ADD16: { int64_t Value = (E.getTarget().getAddress() + - support::endian::read64le(reinterpret_cast( + support::endian::read16le(reinterpret_cast( FixupAddress.getValue())) + E.getAddend()) .getValue(); - *(little64_t *)FixupPtr = static_cast(Value); + *(little16_t *)FixupPtr = static_cast(Value); break; } case R_RISCV_ADD32: { @@ -332,29 +344,27 @@ *(little32_t *)FixupPtr = static_cast(Value); break; } - case R_RISCV_ADD16: { + case R_RISCV_ADD64: { int64_t Value = (E.getTarget().getAddress() + - support::endian::read16le(reinterpret_cast( + support::endian::read64le(reinterpret_cast( FixupAddress.getValue())) + E.getAddend()) .getValue(); - *(little16_t *)FixupPtr = static_cast(Value); + *(little64_t *)FixupPtr = static_cast(Value); break; } - case R_RISCV_ADD8: { + case R_RISCV_SUB8: { int64_t Value = - (E.getTarget().getAddress() + - *(reinterpret_cast(FixupAddress.getValue())) + - E.getAddend()) - .getValue(); + *(reinterpret_cast(FixupAddress.getValue())) - + E.getTarget().getAddress().getValue() - E.getAddend(); *FixupPtr = static_cast(Value); break; } - case R_RISCV_SUB64: { - int64_t Value = support::endian::read64le(reinterpret_cast( + case R_RISCV_SUB16: { + int64_t Value = support::endian::read16le(reinterpret_cast( FixupAddress.getValue())) - E.getTarget().getAddress().getValue() - E.getAddend(); - *(little64_t *)FixupPtr = static_cast(Value); + *(little16_t *)FixupPtr = static_cast(Value); break; } case R_RISCV_SUB32: { @@ -364,18 +374,11 @@ *(little32_t *)FixupPtr = static_cast(Value); break; } - case R_RISCV_SUB16: { - int64_t Value = support::endian::read16le(reinterpret_cast( + case R_RISCV_SUB64: { + int64_t Value = support::endian::read64le(reinterpret_cast( FixupAddress.getValue())) - E.getTarget().getAddress().getValue() - E.getAddend(); - *(little16_t *)FixupPtr = static_cast(Value); - break; - } - case R_RISCV_SUB8: { - int64_t Value = - *(reinterpret_cast(FixupAddress.getValue())) - - E.getTarget().getAddress().getValue() - E.getAddend(); - *FixupPtr = static_cast(Value); + *(little64_t *)FixupPtr = static_cast(Value); break; } case R_RISCV_SUB6: { @@ -438,40 +441,40 @@ return EdgeKind_riscv::R_RISCV_BRANCH; case ELF::R_RISCV_JAL: return EdgeKind_riscv::R_RISCV_JAL; - case ELF::R_RISCV_HI20: - return EdgeKind_riscv::R_RISCV_HI20; - case ELF::R_RISCV_LO12_I: - return EdgeKind_riscv::R_RISCV_LO12_I; - case ELF::R_RISCV_LO12_S: - return EdgeKind_riscv::R_RISCV_LO12_S; case ELF::R_RISCV_CALL: return EdgeKind_riscv::R_RISCV_CALL; + case ELF::R_RISCV_CALL_PLT: + return EdgeKind_riscv::R_RISCV_CALL_PLT; + case ELF::R_RISCV_GOT_HI20: + return EdgeKind_riscv::R_RISCV_GOT_HI20; case ELF::R_RISCV_PCREL_HI20: return EdgeKind_riscv::R_RISCV_PCREL_HI20; case ELF::R_RISCV_PCREL_LO12_I: return EdgeKind_riscv::R_RISCV_PCREL_LO12_I; case ELF::R_RISCV_PCREL_LO12_S: return EdgeKind_riscv::R_RISCV_PCREL_LO12_S; - case ELF::R_RISCV_GOT_HI20: - return EdgeKind_riscv::R_RISCV_GOT_HI20; - case ELF::R_RISCV_CALL_PLT: - return EdgeKind_riscv::R_RISCV_CALL_PLT; - case ELF::R_RISCV_ADD64: - return EdgeKind_riscv::R_RISCV_ADD64; - case ELF::R_RISCV_ADD32: - return EdgeKind_riscv::R_RISCV_ADD32; - case ELF::R_RISCV_ADD16: - return EdgeKind_riscv::R_RISCV_ADD16; + case ELF::R_RISCV_HI20: + return EdgeKind_riscv::R_RISCV_HI20; + case ELF::R_RISCV_LO12_I: + return EdgeKind_riscv::R_RISCV_LO12_I; + case ELF::R_RISCV_LO12_S: + return EdgeKind_riscv::R_RISCV_LO12_S; case ELF::R_RISCV_ADD8: return EdgeKind_riscv::R_RISCV_ADD8; - case ELF::R_RISCV_SUB64: - return EdgeKind_riscv::R_RISCV_SUB64; - case ELF::R_RISCV_SUB32: - return EdgeKind_riscv::R_RISCV_SUB32; - case ELF::R_RISCV_SUB16: - return EdgeKind_riscv::R_RISCV_SUB16; + case ELF::R_RISCV_ADD16: + return EdgeKind_riscv::R_RISCV_ADD16; + case ELF::R_RISCV_ADD32: + return EdgeKind_riscv::R_RISCV_ADD32; + case ELF::R_RISCV_ADD64: + return EdgeKind_riscv::R_RISCV_ADD64; case ELF::R_RISCV_SUB8: return EdgeKind_riscv::R_RISCV_SUB8; + case ELF::R_RISCV_SUB16: + return EdgeKind_riscv::R_RISCV_SUB16; + case ELF::R_RISCV_SUB32: + return EdgeKind_riscv::R_RISCV_SUB32; + case ELF::R_RISCV_SUB64: + return EdgeKind_riscv::R_RISCV_SUB64; case ELF::R_RISCV_SUB6: return EdgeKind_riscv::R_RISCV_SUB6; case ELF::R_RISCV_SET6: Index: llvm/lib/ExecutionEngine/JITLink/riscv.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/riscv.cpp +++ llvm/lib/ExecutionEngine/JITLink/riscv.cpp @@ -28,42 +28,40 @@ return "R_RISCV_BRANCH"; case R_RISCV_JAL: return "R_RISCV_JAL"; - case R_RISCV_HI20: - return "R_RISCV_HI20"; - case R_RISCV_LO12_I: - return "R_RISCV_LO12_I"; - case R_RISCV_LO12_S: - return "R_RISCV_LO12_S"; + case R_RISCV_CALL: + return "R_RISCV_CALL"; + case R_RISCV_CALL_PLT: + return "R_RISCV_CALL_PLT"; + case R_RISCV_GOT_HI20: + return "R_RISCV_GOT_HI20"; case R_RISCV_PCREL_HI20: return "R_RISCV_PCREL_HI20"; case R_RISCV_PCREL_LO12_I: return "R_RISCV_PCREL_LO12_I"; case R_RISCV_PCREL_LO12_S: return "R_RISCV_PCREL_LO12_S"; - case R_RISCV_CALL: - return "R_RISCV_CALL"; - case R_RISCV_32_PCREL: - return "R_RISCV_32_PCREL"; - case R_RISCV_GOT_HI20: - return "R_RISCV_GOT_HI20"; - case R_RISCV_CALL_PLT: - return "R_RISCV_CALL_PLT"; - case R_RISCV_ADD64: - return "R_RISCV_ADD64"; - case R_RISCV_ADD32: - return "R_RISCV_ADD32"; - case R_RISCV_ADD16: - return "R_RISCV_ADD16"; + case R_RISCV_HI20: + return "R_RISCV_HI20"; + case R_RISCV_LO12_I: + return "R_RISCV_LO12_I"; + case R_RISCV_LO12_S: + return "R_RISCV_LO12_S"; case R_RISCV_ADD8: return "R_RISCV_ADD8"; - case R_RISCV_SUB64: - return "R_RISCV_SUB64"; - case R_RISCV_SUB32: - return "R_RISCV_SUB32"; - case R_RISCV_SUB16: - return "R_RISCV_SUB16"; + case R_RISCV_ADD16: + return "R_RISCV_ADD16"; + case R_RISCV_ADD32: + return "R_RISCV_ADD32"; + case R_RISCV_ADD64: + return "R_RISCV_ADD64"; case R_RISCV_SUB8: return "R_RISCV_SUB8"; + case R_RISCV_SUB16: + return "R_RISCV_SUB16"; + case R_RISCV_SUB32: + return "R_RISCV_SUB32"; + case R_RISCV_SUB64: + return "R_RISCV_SUB64"; case R_RISCV_SUB6: return "R_RISCV_SUB6"; case R_RISCV_SET6: @@ -74,6 +72,8 @@ 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); }