diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index b92bffbe6239b..9e4cf1ea99682 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -113,6 +113,9 @@ static std::unique_ptr createTLOF(const Triple &TT) { if (TT.isOSBinFormatCOFF()) return std::make_unique(); + + if (TT.getArch() == Triple::x86_64) + return std::make_unique(); return std::make_unique(); } diff --git a/llvm/lib/Target/X86/X86TargetObjectFile.cpp b/llvm/lib/Target/X86/X86TargetObjectFile.cpp index 53c692060f08c..e2ddf43e398cb 100644 --- a/llvm/lib/Target/X86/X86TargetObjectFile.cpp +++ b/llvm/lib/Target/X86/X86TargetObjectFile.cpp @@ -57,7 +57,7 @@ const MCExpr *X86ELFTargetObjectFile::getDebugThreadLocalSymbol( return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext()); } -const MCExpr *X86ELFTargetObjectFile::getIndirectSymViaGOTPCRel( +const MCExpr *X86_64ELFTargetObjectFile::getIndirectSymViaGOTPCRel( const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { int64_t FinalOffset = Offset + MV.getConstant(); diff --git a/llvm/lib/Target/X86/X86TargetObjectFile.h b/llvm/lib/Target/X86/X86TargetObjectFile.h index ed9390d1fad1a..a0e1762a2cb50 100644 --- a/llvm/lib/Target/X86/X86TargetObjectFile.h +++ b/llvm/lib/Target/X86/X86TargetObjectFile.h @@ -36,16 +36,22 @@ namespace llvm { MCStreamer &Streamer) const override; }; - /// This implementation is used for X86 ELF targets that don't - /// have a further specialization. + /// This implementation is used for X86 ELF targets that don't have a further + /// specialization (and as a base class for X86_64, which does). class X86ELFTargetObjectFile : public TargetLoweringObjectFileELF { public: X86ELFTargetObjectFile() { PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT; - SupportIndirectSymViaGOTPCRel = true; } /// Describe a TLS variable address within debug info. const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override; + }; + + /// This implementation is used for X86_64 ELF targets, and defers to + /// X86ELFTargetObjectFile for commonalities with 32-bit targets. + class X86_64ELFTargetObjectFile : public X86ELFTargetObjectFile { + public: + X86_64ELFTargetObjectFile() { SupportIndirectSymViaGOTPCRel = true; } const MCExpr * getIndirectSymViaGOTPCRel(const GlobalValue *GV, const MCSymbol *Sym, diff --git a/llvm/test/MC/ELF/rtti-proxy-i686.ll b/llvm/test/MC/ELF/rtti-proxy-i686.ll new file mode 100644 index 0000000000000..afa62ebea4d77 --- /dev/null +++ b/llvm/test/MC/ELF/rtti-proxy-i686.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86-registered-target + +;; Validate that we produce RTTI proxies for 32-bit x86. +; RUN: llc %s -mtriple=i686-elf -o - | FileCheck %s + +;; Validate that we produce a valid object file. +; RUN: llc %s -mtriple=i686-elf --filetype=obj -o %t.o +; RUN: llvm-readobj --relocs %t.o | FileCheck --check-prefix=RELOCS %s + +@vtable = dso_local unnamed_addr constant i32 trunc (i64 sub (i64 ptrtoint (ptr @rtti.proxy to i64), i64 ptrtoint (ptr @vtable to i64)) to i32), align 4 +@rtti = external global i8, align 8 +@rtti.proxy = linkonce_odr hidden unnamed_addr constant ptr @rtti + +; CHECK-LABEL: vtable: +; CHECK-NEXT: .long rtti.proxy-vtable + +; CHECK-LABEL: rtti.proxy: +; CHECK-NEXT: .long rtti + +; RELOCS: R_386_32 rtti