[llvm] cdb9a0c - [MC][CodeGen] Define R_RISCV_PLT32 and lower dso_local_equivalent to it

Leonard Chan via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 22 17:28:16 PST 2023


Author: Leonard Chan
Date: 2023-02-23T01:26:27Z
New Revision: cdb9a0c086a5b7e0972957be91f5864647b05038

URL: https://github.com/llvm/llvm-project/commit/cdb9a0c086a5b7e0972957be91f5864647b05038
DIFF: https://github.com/llvm/llvm-project/commit/cdb9a0c086a5b7e0972957be91f5864647b05038.diff

LOG: [MC][CodeGen] Define R_RISCV_PLT32 and lower dso_local_equivalent to it

This introduces R_RISCV_PLT32, PC-relative data relocation that takes
the 32-bit relative offset to a function or its PLT entry from its
relocation location.

This is needed to support relative vtables on RISCV.

Github PR: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/363

The lld handling of this reloc is D143115.

Differential Revision: https://reviews.llvm.org/D143226

Added: 
    llvm/test/CodeGen/RISCV/dso_local_equivalent.ll
    llvm/test/MC/RISCV/elf-reloc-plt32.s

Modified: 
    llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
    llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index 4544509504449..9a126df015311 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 b4f7e8658c735..ee88fe7fe858a 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 52083714931ae..d67e38d691ca8 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 0000000000000..0979967614b8a
--- /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 at 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.
+ at 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 0000000000000..8f3a40d36a390
--- /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 at PLT - . + 4
+
+# CHECK:      Section ({{.*}}) .rela.data {
+# CHECK-NEXT:   0x0 R_RISCV_PLT32 extern_func 0x4
+# CHECK-NEXT: }


        


More information about the llvm-commits mailing list