-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[llvm] Support indirect symbol replacement with R_ARM_GOT_PREL #81916
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
Conversation
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.
@llvm/pr-subscribers-backend-arm @llvm/pr-subscribers-mc Author: Shoaib Meenai (smeenai) ChangesR_ARM_GOT_PREL is equivalent to GOTPCREL on other architectures, so we Full diff: https://github.com/llvm/llvm-project/pull/81916.diff 3 Files Affected:
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
|
The test failure is unrelated (it's caused by fc0b67e). |
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.