Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[llvm] Support indirect symbol replacement with R_ARM_GOT_PREL #81916

Merged
merged 1 commit into from
Feb 16, 2024

Conversation

smeenai
Copy link
Collaborator

@smeenai smeenai commented Feb 15, 2024

R_ARM_GOT_PREL is equivalent to GOTPCREL on other architectures, so we
can use it for indirect symbol replacement the same way. This is the
equivalent of #67754 for x86_64
and #78003 for AArch64 and
64-bit RISC-V.

R_ARM_GOT_PREL is equivalent to GOTPCREL on other architectures, so we
can use it for indirect symbol replacement the same way. This is the
equivalent of llvm#67754 for x86_64
and llvm#78003 for AArch64 and
64-bit RISC-V.
@llvmbot llvmbot added backend:ARM mc Machine (object) code labels Feb 15, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 15, 2024

@llvm/pr-subscribers-backend-arm

@llvm/pr-subscribers-mc

Author: Shoaib Meenai (smeenai)

Changes

R_ARM_GOT_PREL is equivalent to GOTPCREL on other architectures, so we
can use it for indirect symbol replacement the same way. This is the
equivalent of #67754 for x86_64
and #78003 for AArch64 and
64-bit RISC-V.


Full diff: https://github.com/llvm/llvm-project/pull/81916.diff

3 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMTargetObjectFile.cpp (+11)
  • (modified) llvm/lib/Target/ARM/ARMTargetObjectFile.h (+7)
  • (added) llvm/test/MC/ELF/rtti-proxy-arm-got-prel.ll (+45)
diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
index 936cae17f004fb..cd231896d691b0 100644
--- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp
@@ -16,6 +16,7 @@
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/MCValue.h"
 #include "llvm/MC/SectionKind.h"
 #include "llvm/Target/TargetMachine.h"
 #include <cassert>
@@ -56,6 +57,16 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
 
 MCRegister ARMElfTargetObjectFile::getStaticBase() const { return ARM::R9; }
 
+const MCExpr *ARMElfTargetObjectFile::getIndirectSymViaGOTPCRel(
+    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
+    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
+  int64_t FinalOffset = Offset + MV.getConstant();
+  const MCExpr *Res = MCSymbolRefExpr::create(
+      Sym, MCSymbolRefExpr::VK_ARM_GOT_PREL, getContext());
+  const MCExpr *Off = MCConstantExpr::create(FinalOffset, getContext());
+  return MCBinaryExpr::createAdd(Res, Off, getContext());
+}
+
 const MCExpr *ARMElfTargetObjectFile::
 getIndirectSymViaRWPI(const MCSymbol *Sym) const {
   return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_ARM_SBREL,
diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.h b/llvm/lib/Target/ARM/ARMTargetObjectFile.h
index 47334b9a8a453e..7d771d22420455 100644
--- a/llvm/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.h
@@ -19,12 +19,19 @@ class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
 public:
   ARMElfTargetObjectFile() {
     PLTRelativeVariantKind = MCSymbolRefExpr::VK_ARM_PREL31;
+    SupportIndirectSymViaGOTPCRel = true;
   }
 
   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
 
   MCRegister getStaticBase() const override;
 
+  const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
+                                          const MCSymbol *Sym,
+                                          const MCValue &MV, int64_t Offset,
+                                          MachineModuleInfo *MMI,
+                                          MCStreamer &Streamer) const override;
+
   const MCExpr *getIndirectSymViaRWPI(const MCSymbol *Sym) const override;
 
   const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
diff --git a/llvm/test/MC/ELF/rtti-proxy-arm-got-prel.ll b/llvm/test/MC/ELF/rtti-proxy-arm-got-prel.ll
new file mode 100644
index 00000000000000..f78d3042a1f512
--- /dev/null
+++ b/llvm/test/MC/ELF/rtti-proxy-arm-got-prel.ll
@@ -0,0 +1,45 @@
+; REQUIRES: arm-registered-target
+
+;; Verify that the generated assembly omits the RTTI proxy and uses the correct
+;; relocations and addends.
+; RUN: llc %s -mtriple=armv7 -o - | FileCheck %s
+
+;; Verify that the generated object uses the correct relocations and addends.
+; RUN: llc %s -filetype=obj -mtriple=thumbv7 -o %t.o
+; RUN: llvm-readelf --relocs --hex-dump=.rodata %t.o | FileCheck --check-prefix=OBJ %s
+
+@vtable = dso_local unnamed_addr constant i32 sub (i32 ptrtoint (ptr @rtti.proxy to i32), i32 ptrtoint (ptr @vtable to i32)), align 4
+
+@vtable_with_offset = dso_local unnamed_addr constant [2 x i32] [i32 0, i32 sub (i32 ptrtoint (ptr @rtti.proxy to i32), i32 ptrtoint (ptr @vtable_with_offset to i32))], align 4
+
+@vtable_with_negative_offset = dso_local unnamed_addr constant [2 x i32] [
+  i32 sub (
+    i32 ptrtoint (ptr @rtti.proxy to i32),
+    i32 ptrtoint (ptr getelementptr inbounds ([2 x i32], ptr @vtable_with_negative_offset, i32 0, i32 1) to i32)
+  ),
+  i32 0
+], align 4
+
+@rtti = external global i8, align 4
+@rtti.proxy = linkonce_odr hidden unnamed_addr constant ptr @rtti
+
+; CHECK-NOT: rtti.proxy
+
+; CHECK-LABEL: vtable:
+; CHECK-NEXT:    .long   rtti(GOT_PREL)+0{{$}}
+
+; CHECK-LABEL: vtable_with_offset:
+; CHECK-NEXT:    .long   0
+; CHECK-NEXT:    .long   rtti(GOT_PREL)+4{{$}}
+
+; CHECK-LABEL: vtable_with_negative_offset:
+; CHECK-NEXT:    .long   rtti(GOT_PREL)-4{{$}}
+; CHECK-NEXT:    .long   0
+
+; OBJ-LABEL: Relocation section '.rel.rodata' at offset [[#%#x,]] contains 3 entries:
+; OBJ:       {{^}}00000000 [[#]] R_ARM_GOT_PREL [[#]] rtti{{$}}
+; OBJ-NEXT:  {{^}}00000008 [[#]] R_ARM_GOT_PREL [[#]] rtti{{$}}
+; OBJ-NEXT:  {{^}}0000000c [[#]] R_ARM_GOT_PREL [[#]] rtti{{$}}
+
+; OBJ-LABEL: Hex dump of section '.rodata':
+; OBJ-NEXT:  0x00000000 00000000 00000000 04000000 fcffffff

@smeenai
Copy link
Collaborator Author

smeenai commented Feb 15, 2024

The test failure is unrelated (it's caused by fc0b67e).

@smeenai smeenai merged commit ac45220 into llvm:main Feb 16, 2024
6 of 7 checks passed
@smeenai smeenai deleted the arm-got-prel branch February 16, 2024 01:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:ARM mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants