diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -280,6 +280,7 @@ return R_PC; case R_RISCV_CALL: case R_RISCV_CALL_PLT: + case R_RISCV_PLT32: return R_PLT_PC; case R_RISCV_GOT_HI20: return R_GOT_PC; @@ -473,6 +474,7 @@ return; case R_RISCV_SET32: case R_RISCV_32_PCREL: + case R_RISCV_PLT32: write32le(loc, val); return; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -517,6 +517,7 @@ case R_RISCV_CALL_PLT: case R_RISCV_RVC_BRANCH: case R_RISCV_RVC_JUMP: + case R_RISCV_PLT32: return p; default: return 0; diff --git a/lld/test/ELF/riscv-reloc-plt32.s b/lld/test/ELF/riscv-reloc-plt32.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/riscv-reloc-plt32.s @@ -0,0 +1,21 @@ +// RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=riscv64 %S/Inputs/abs256.s -o %t256.o + +// RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2 +// RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s + +// CHECK: Contents of section .data: +/// 12158: S = 0x100, A = 0, P = 0x12158 +/// S + A - P = 0xfffedfa8 +/// 1215c: S = 0x100, A = 1, P = 0x1215c +/// S + A - P = 0xfffedfa5 +/// 12160: S = 0x100, A = -1, P = 0x12160 +/// S + A - P = 0xfffedf9f +// CHECK-NEXT: 12158 a8dffeff a5dffeff 9fdffeff + + .globl _start + _start: +.data + .word foo@PLT - . + .word foo@PLT - . + 1 + .word foo@PLT - . - 1 diff --git a/lld/test/ELF/riscv-undefined-weak.s b/lld/test/ELF/riscv-undefined-weak.s --- a/lld/test/ELF/riscv-undefined-weak.s +++ b/lld/test/ELF/riscv-undefined-weak.s @@ -84,3 +84,6 @@ # PC-NOT: .plt: # PLT: .plt: + +.word target@plt - . +# RELOC: 0xC R_RISCV_PLT32 target 0x0 diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def @@ -54,3 +54,4 @@ 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 --- 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 @@ 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 --- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp @@ -18,6 +18,8 @@ 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/MC/RISCV/elf-reloc-plt32.s b/llvm/test/MC/RISCV/elf-reloc-plt32.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/elf-reloc-plt32.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o - | \ +// RUN: llvm-readobj -r - | FileCheck %s + + .section .data +this: + .word extern_func@PLT - this + 4 + +// CHECK: Section ({{.*}}) .rela.data +// CHECK-NEXT: 0x0 R_RISCV_PLT32 extern_func 0x4 +// CHECK-NEXT: }