diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -640,15 +640,27 @@ // Examples where there would be no symbol emitted are available_externally // and private linkages. auto stubLinkage = vtableHasLocalLinkage ? llvm::GlobalValue::InternalLinkage - : llvm::GlobalValue::ExternalLinkage; + //: llvm::GlobalValue::ExternalLinkage; + : llvm::GlobalValue::LinkOnceODRLinkage; llvm::Constant *target; if (auto *func = dyn_cast(globalVal)) { target = llvm::DSOLocalEquivalent::get(func); } else { + //if (globalVal->getName() == "_ZTIN6icu_717UObjectE") { + // globalVal->print(llvm::errs()); + // llvm::errs() << "\n"; + //} + llvm::SmallString<16> rttiProxyName(globalVal->getName()); rttiProxyName.append(".rtti_proxy"); + //if (globalVal->isDeclaration()) { + // // The RTTI component may be externally referenced in this + //} else { + + //} + // The RTTI component may not always be emitted in the same linkage unit as // the vtable. As a general case, we can make a dso_local proxy to the RTTI // that points to the actual RTTI struct somewhere. This will result in a diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1716,6 +1716,8 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD) { llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits()); + //llvm::errs() << "Emitting vtable 1?\n"; + //VTable->print(llvm::errs()); llvm::errs() << "\n"; if (VTable->hasInitializer()) return; @@ -1774,6 +1776,9 @@ if (!VTable->isDSOLocal()) CGVT.GenerateRelativeVTableAlias(VTable, VTable->getName()); } + + //llvm::errs() << "Emitting vtable 2?\n"; + //VTable->print(llvm::errs()); llvm::errs() << "\n"; } bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField( @@ -3890,6 +3895,10 @@ TypeName->setPartition(CGM.getCodeGenOpts().SymbolPartition); GV->setPartition(CGM.getCodeGenOpts().SymbolPartition); + //if (CGM.getItaniumVTableContext().isRelativeLayout()) { + // GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + //} + return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); } diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -110,6 +110,10 @@ const TargetMachine &TM) const override; MCSection *getSectionForCommandLines() const override; + + const MCExpr *getIndirectSymViaGOTPCRel( + const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, + int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const override; }; class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1749,8 +1749,10 @@ // GlobalVariable or Function, i.e., as GlobalValue. if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() || !GV->isDiscardableIfUnused() || - !isa(GV->getOperand(0))) + !isa(GV->getOperand(0))) { + //llvm::errs() << "Failed isGOTEquivalentCandidate for " << GV->getName() << "\n"; return false; + } // To be a got equivalent, at least one of its users need to be a constant // expression used by another global variable. @@ -3172,6 +3174,8 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, const Constant *BaseCst, uint64_t Offset) { + //llvm::errs() << "BaseCst:\n"; BaseCst->print(llvm::errs()); llvm::errs() << "\n"; + //llvm::errs() << "ME: " << (**ME) << "\n"; // The global @foo below illustrates a global that uses a got equivalent. // // @bar = global i32 42 @@ -3193,7 +3197,14 @@ // cstexpr := - + gotpcrelcst, where // gotpcrelcst := + MCValue MV; - if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) + if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr)) { + //llvm::errs() << "ME not relocatable\n"; + return; + } + + //llvm::errs() << "MV: "; MV.print(llvm::errs()); llvm::errs() << "\n"; + + if (MV.isAbsolute()) return; const MCSymbolRefExpr *SymA = MV.getSymA(); if (!SymA) @@ -3201,19 +3212,24 @@ // Check that GOT equivalent symbol is cached. const MCSymbol *GOTEquivSym = &SymA->getSymbol(); - if (!AP.GlobalGOTEquivs.count(GOTEquivSym)) + if (!AP.GlobalGOTEquivs.count(GOTEquivSym)) { + //llvm::errs() << "No GlobalGOTEquivs for " << *GOTEquivSym << "\n"; return; + } const GlobalValue *BaseGV = dyn_cast_or_null(BaseCst); if (!BaseGV) return; + //llvm::errs() << "Good BaseGV\n"; // Check for a valid base symbol const MCSymbol *BaseSym = AP.getSymbol(BaseGV); const MCSymbolRefExpr *SymB = MV.getSymB(); - if (!SymB || BaseSym != &SymB->getSymbol()) + if (!SymB || BaseSym != &SymB->getSymbol()) { + //llvm::errs() << "Bad base symbol\n"; return; + } // Make sure to match: // @@ -3223,8 +3239,9 @@ // displacement into the GOTPCREL. We can also can have an extra offset // if the target knows how to encode it. int64_t GOTPCRelCst = Offset + MV.getConstant(); - if (GOTPCRelCst < 0) - return; + //llvm::errs() << "GOTPCRelCst: " << GOTPCRelCst << "\n"; + //if (GOTPCRelCst < 0) + // return; if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0) return; @@ -3250,6 +3267,7 @@ const MCSymbol *FinalSym = AP.getSymbol(FinalGV); *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel( FinalGV, FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer); + assert(*ME); // Update GOT equivalent usage information --NumUses; @@ -3261,6 +3279,7 @@ AsmPrinter &AP, const Constant *BaseCV, uint64_t Offset, AsmPrinter::AliasMapTy *AliasList) { + //llvm::errs() << "CV:\n"; CV->print(llvm::errs()); llvm::errs() << "\n"; emitGlobalAliasInline(AP, Offset, AliasList); uint64_t Size = DL.getTypeAllocSize(CV->getType()); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1425,6 +1425,15 @@ return SSym; } +const MCExpr *TargetLoweringObjectFileELF::getIndirectSymViaGOTPCRel( + const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, + int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { + const MCExpr *Res = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext()); + const MCExpr *Off = MCConstantExpr::create(Offset, getContext()); + return MCBinaryExpr::createAdd(Res, Off, getContext()); +} + const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h --- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h +++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -21,6 +21,7 @@ public: AArch64_ELFTargetObjectFile() { PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT; + SupportIndirectSymViaGOTPCRel = true; } }; diff --git a/llvm/lib/Target/X86/X86TargetObjectFile.h b/llvm/lib/Target/X86/X86TargetObjectFile.h --- a/llvm/lib/Target/X86/X86TargetObjectFile.h +++ b/llvm/lib/Target/X86/X86TargetObjectFile.h @@ -42,6 +42,7 @@ public: X86ELFTargetObjectFile() { PLTRelativeVariantKind = MCSymbolRefExpr::VK_PLT; + SupportIndirectSymViaGOTPCRel = true; } /// Describe a TLS variable address within debug info. const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override;