diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def index 45445095044495..9a126df0153119 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def @@ -54,3 +54,4 @@ ELF_RELOC(R_RISCV_SET16, 55) ELF_RELOC(R_RISCV_SET32, 56) ELF_RELOC(R_RISCV_32_PCREL, 57) ELF_RELOC(R_RISCV_IRELATIVE, 58) +ELF_RELOC(R_RISCV_PLT32, 59) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index b4f7e8658c735c..ee88fe7fe858a0 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -61,7 +62,9 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_RISCV_NONE; case FK_Data_4: case FK_PCRel_4: - return ELF::R_RISCV_32_PCREL; + return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT + ? ELF::R_RISCV_PLT32 + : ELF::R_RISCV_32_PCREL; case RISCV::fixup_riscv_pcrel_hi20: return ELF::R_RISCV_PCREL_HI20; case RISCV::fixup_riscv_pcrel_lo12_i: diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp index 52083714931ae4..d67e38d691ca81 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp @@ -18,6 +18,8 @@ void RISCVELFTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { TargetLoweringObjectFileELF::Initialize(Ctx, TM); + PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT; + SmallDataSection = getContext().getELFSection( ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS, diff --git a/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll b/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll new file mode 100644 index 00000000000000..0979967614b8a2 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/dso_local_equivalent.ll @@ -0,0 +1,12 @@ +; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --match-full-lines +; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --match-full-lines + +declare void @extern_func() + +; CHECK-LABEL: const: +; CHECK-NEXT: .word extern_func@PLT-const + +;; Note that for riscv32, the ptrtoint will actually upcast the ptr it to an +;; oversized 64-bit pointer that eventually gets truncated. This isn't needed +;; for riscv32, but this unifies the RV64 and RV32 test cases. +@const = dso_local constant i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @extern_func to i64), i64 ptrtoint (ptr @const to i64)) to i32) diff --git a/llvm/test/MC/RISCV/elf-reloc-plt32.s b/llvm/test/MC/RISCV/elf-reloc-plt32.s new file mode 100644 index 00000000000000..8f3a40d36a3901 --- /dev/null +++ b/llvm/test/MC/RISCV/elf-reloc-plt32.s @@ -0,0 +1,11 @@ +# RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o - \ +# RUN: | llvm-readobj -r - | FileCheck %s +# RUN: llvm-mc -triple=riscv32 -filetype=obj %s -o - \ +# RUN: | llvm-readobj -r - | FileCheck %s + +.data +.word extern_func@PLT - . + 4 + +# CHECK: Section ({{.*}}) .rela.data { +# CHECK-NEXT: 0x0 R_RISCV_PLT32 extern_func 0x4 +# CHECK-NEXT: }