diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp index 936cae17f004f..cd231896d691b 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 @@ -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 47334b9a8a453..7d771d2242045 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 0000000000000..f78d3042a1f51 --- /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