diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
30 files changed, 580 insertions, 430 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp index 03e63321e3c4..1940f46232d3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp @@ -38,8 +38,19 @@ void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA, // unsigned long personality; /* Pointer to the personality routine */ // } - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getCompactUnwindSection()); + auto *EHInfo = + cast<MCSectionXCOFF>(Asm->getObjFileLowering().getCompactUnwindSection()); + if (Asm->TM.getFunctionSections()) { + // If option -ffunction-sections is on, append the function name to the + // name of EH Info Table csect so that each function has its own EH Info + // Table csect. This helps the linker to garbage-collect EH info of unused + // functions. + SmallString<128> NameStr = EHInfo->getName(); + raw_svector_ostream(NameStr) << '.' << Asm->MF->getFunction().getName(); + EHInfo = Asm->OutContext.getXCOFFSection(NameStr, EHInfo->getKind(), + EHInfo->getCsectProp()); + } + Asm->OutStreamer->switchSection(EHInfo); MCSymbol *EHInfoLabel = TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF); Asm->OutStreamer->emitLabel(EHInfoLabel); @@ -74,8 +85,8 @@ void AIXException::endFunction(const MachineFunction *MF) { const Function &F = MF->getFunction(); assert(F.hasPersonalityFn() && "Landingpads are presented, but no personality routine is found."); - const GlobalValue *Per = - dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts()); + const auto *Per = + cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts()); const MCSymbol *PerSym = Asm->TM.getSymbol(Per); emitExceptionInfoTable(LSDALabel, PerSym); diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp index 223840c21d8b..e04a29fbb42b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -14,21 +14,14 @@ #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" +#include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetOptions.h" using namespace llvm; ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} -ARMException::~ARMException() {} +ARMException::~ARMException() = default; ARMTargetStreamer &ARMException::getTargetStreamer() { MCTargetStreamer &TS = *Asm->OutStreamer->getTargetStreamer(); @@ -101,7 +94,7 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding, // Emit the Catch TypeInfos. if (VerboseAsm && !TypeInfos.empty()) { Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); - Asm->OutStreamer->AddBlankLine(); + Asm->OutStreamer->addBlankLine(); Entry = TypeInfos.size(); } @@ -116,7 +109,7 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding, // Emit the Exception Specifications. if (VerboseAsm && !FilterIds.empty()) { Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); - Asm->OutStreamer->AddBlankLine(); + Asm->OutStreamer->addBlankLine(); Entry = 0; } for (std::vector<unsigned>::const_iterator diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp index 65c45f73e965..b10d79f4b5a6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -18,7 +18,6 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" -#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" @@ -563,7 +562,7 @@ void llvm::emitDWARF5AccelTable( if (CompUnits.empty()) return; - Asm->OutStreamer->SwitchSection( + Asm->OutStreamer->switchSection( Asm->getObjFileLowering().getDwarfDebugNamesSection()); Contents.finalize(Asm, "names"); diff --git a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp index 21da9d50efba..32d8dc793510 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -17,7 +17,7 @@ using namespace llvm; unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) { - HasBeenUsed = true; + resetUsedFlag(true); auto IterBool = Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS))); return IterBool.first->second.Number; @@ -44,7 +44,7 @@ void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { return; // Start the dwarf addr section. - Asm.OutStreamer->SwitchSection(AddrSection); + Asm.OutStreamer->switchSection(AddrSection); MCSymbol *EndLabel = nullptr; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 3e8e190eecc3..4a31bf85446b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/ConstantFolding.h" @@ -48,7 +49,6 @@ #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/MachineOperand.h" @@ -82,33 +82,26 @@ #include "llvm/IR/PseudoProbe.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" -#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" -#include "llvm/MC/MCSymbolXCOFF.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" -#include "llvm/MC/TargetRegistry.h" #include "llvm/Pass.h" -#include "llvm/Remarks/Remark.h" -#include "llvm/Remarks/RemarkFormat.h" #include "llvm/Remarks/RemarkStreamer.h" -#include "llvm/Remarks/RemarkStringTable.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -125,7 +118,6 @@ #include <cinttypes> #include <cstdint> #include <iterator> -#include <limits> #include <memory> #include <string> #include <utility> @@ -135,11 +127,6 @@ using namespace llvm; #define DEBUG_TYPE "asm-printer" -// FIXME: this option currently only applies to DWARF, and not CodeView, tables -static cl::opt<bool> - DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, - cl::desc("Disable debug info printing")); - const char DWARFGroupName[] = "dwarf"; const char DWARFGroupDescription[] = "DWARF Emission"; const char DbgTimerName[] = "emit"; @@ -167,6 +154,178 @@ static gcp_map_type &getGCMap(void *&P) { return *(gcp_map_type*)P; } +namespace { +class AddrLabelMapCallbackPtr final : CallbackVH { + AddrLabelMap *Map = nullptr; + +public: + AddrLabelMapCallbackPtr() = default; + AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} + + void setPtr(BasicBlock *BB) { + ValueHandleBase::operator=(BB); + } + + void setMap(AddrLabelMap *map) { Map = map; } + + void deleted() override; + void allUsesReplacedWith(Value *V2) override; +}; +} // namespace + +class llvm::AddrLabelMap { + MCContext &Context; + struct AddrLabelSymEntry { + /// The symbols for the label. + TinyPtrVector<MCSymbol *> Symbols; + + Function *Fn; // The containing function of the BasicBlock. + unsigned Index; // The index in BBCallbacks for the BasicBlock. + }; + + DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; + + /// Callbacks for the BasicBlock's that we have entries for. We use this so + /// we get notified if a block is deleted or RAUWd. + std::vector<AddrLabelMapCallbackPtr> BBCallbacks; + + /// This is a per-function list of symbols whose corresponding BasicBlock got + /// deleted. These symbols need to be emitted at some point in the file, so + /// AsmPrinter emits them after the function body. + DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>> + DeletedAddrLabelsNeedingEmission; + +public: + AddrLabelMap(MCContext &context) : Context(context) {} + + ~AddrLabelMap() { + assert(DeletedAddrLabelsNeedingEmission.empty() && + "Some labels for deleted blocks never got emitted"); + } + + ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); + + void takeDeletedSymbolsForFunction(Function *F, + std::vector<MCSymbol *> &Result); + + void UpdateForDeletedBlock(BasicBlock *BB); + void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); +}; + +ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { + assert(BB->hasAddressTaken() && + "Shouldn't get label for block without address taken"); + AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; + + // If we already had an entry for this block, just return it. + if (!Entry.Symbols.empty()) { + assert(BB->getParent() == Entry.Fn && "Parent changed"); + return Entry.Symbols; + } + + // Otherwise, this is a new entry, create a new symbol for it and add an + // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. + BBCallbacks.emplace_back(BB); + BBCallbacks.back().setMap(this); + Entry.Index = BBCallbacks.size() - 1; + Entry.Fn = BB->getParent(); + MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() + : Context.createTempSymbol(); + Entry.Symbols.push_back(Sym); + return Entry.Symbols; +} + +/// If we have any deleted symbols for F, return them. +void AddrLabelMap::takeDeletedSymbolsForFunction( + Function *F, std::vector<MCSymbol *> &Result) { + DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I = + DeletedAddrLabelsNeedingEmission.find(F); + + // If there are no entries for the function, just return. + if (I == DeletedAddrLabelsNeedingEmission.end()) + return; + + // Otherwise, take the list. + std::swap(Result, I->second); + DeletedAddrLabelsNeedingEmission.erase(I); +} + +//===- Address of Block Management ----------------------------------------===// + +ArrayRef<MCSymbol *> +AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) { + // Lazily create AddrLabelSymbols. + if (!AddrLabelSymbols) + AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext); + return AddrLabelSymbols->getAddrLabelSymbolToEmit( + const_cast<BasicBlock *>(BB)); +} + +void AsmPrinter::takeDeletedSymbolsForFunction( + const Function *F, std::vector<MCSymbol *> &Result) { + // If no blocks have had their addresses taken, we're done. + if (!AddrLabelSymbols) + return; + return AddrLabelSymbols->takeDeletedSymbolsForFunction( + const_cast<Function *>(F), Result); +} + +void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { + // If the block got deleted, there is no need for the symbol. If the symbol + // was already emitted, we can just forget about it, otherwise we need to + // queue it up for later emission when the function is output. + AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); + AddrLabelSymbols.erase(BB); + assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); + BBCallbacks[Entry.Index] = nullptr; // Clear the callback. + +#if !LLVM_MEMORY_SANITIZER_BUILD + // BasicBlock is destroyed already, so this access is UB detectable by msan. + assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && + "Block/parent mismatch"); +#endif + + for (MCSymbol *Sym : Entry.Symbols) { + if (Sym->isDefined()) + return; + + // If the block is not yet defined, we need to emit it at the end of the + // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list + // for the containing Function. Since the block is being deleted, its + // parent may already be removed, we have to get the function from 'Entry'. + DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); + } +} + +void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { + // Get the entry for the RAUW'd block and remove it from our map. + AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); + AddrLabelSymbols.erase(Old); + assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); + + AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; + + // If New is not address taken, just move our symbol over to it. + if (NewEntry.Symbols.empty()) { + BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. + NewEntry = std::move(OldEntry); // Set New's entry. + return; + } + + BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. + + // Otherwise, we need to add the old symbols to the new block's set. + llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); +} + +void AddrLabelMapCallbackPtr::deleted() { + Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); +} + +void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { + Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); +} + /// getGVAlignment - Return the alignment to use for the specified global /// value. This rounds up to the preferred alignment if possible and legal. Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL, @@ -271,6 +430,10 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { bool AsmPrinter::doInitialization(Module &M) { auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>(); MMI = MMIWP ? &MMIWP->getMMI() : nullptr; + HasSplitStack = false; + HasNoSplitStack = false; + + AddrLabelSymbols = nullptr; // Initialize TargetLoweringObjectFile. const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) @@ -281,9 +444,6 @@ bool AsmPrinter::doInitialization(Module &M) { OutStreamer->initSections(false, *TM.getMCSubtargetInfo()); - if (DisableDebugInfoPrinting) - MMI->setDebugInfoAvailability(false); - // Emit the version-min deployment target directive if needed. // // FIXME: If we end up with a collection of these sorts of Darwin-specific @@ -335,11 +495,11 @@ bool AsmPrinter::doInitialization(Module &M) { // Emit module-level inline asm if it exists. if (!M.getModuleInlineAsm().empty()) { OutStreamer->AddComment("Start of file scope inline assembly"); - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); emitInlineAsm(M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(), TM.Options.MCOptions); OutStreamer->AddComment("End of file scope inline assembly"); - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); } if (MAI->doesSupportDebugInformation()) { @@ -351,7 +511,7 @@ bool AsmPrinter::doInitialization(Module &M) { CodeViewLineTablesGroupDescription); } if (!EmitCodeView || M.getDwarfVersion()) { - if (!DisableDebugInfoPrinting) { + if (MMI->hasDebugInfo()) { DD = new DwarfDebug(this); Handlers.emplace_back(std::unique_ptr<DwarfDebug>(DD), DbgTimerName, DbgTimerDescription, DWARFGroupName, @@ -536,9 +696,9 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { if (isVerbose()) { // When printing the control variable __emutls_v.*, // we don't need to print the original TLS variable name. - GV->printAsOperand(OutStreamer->GetCommentOS(), - /*PrintType=*/false, GV->getParent()); - OutStreamer->GetCommentOS() << '\n'; + GV->printAsOperand(OutStreamer->getCommentOS(), + /*PrintType=*/false, GV->getParent()); + OutStreamer->getCommentOS() << '\n'; } } @@ -652,7 +812,7 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { TheSection = getObjFileLowering().getTLSBSSSection(); OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment.value()); } else if (GVKind.isThreadData()) { - OutStreamer->SwitchSection(TheSection); + OutStreamer->switchSection(TheSection); emitAlignment(Alignment, GV); OutStreamer->emitLabel(MangSym); @@ -661,12 +821,12 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { GV->getInitializer()); } - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); // Emit the variable struct for the runtime. MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection(); - OutStreamer->SwitchSection(TLVSect); + OutStreamer->switchSection(TLVSect); // Emit the linkage here. emitLinkage(GV, GVSym); OutStreamer->emitLabel(GVSym); @@ -681,13 +841,13 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { OutStreamer->emitIntValue(0, PtrSize); OutStreamer->emitSymbolValue(MangSym, PtrSize); - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); return; } MCSymbol *EmittedInitSym = GVSym; - OutStreamer->SwitchSection(TheSection); + OutStreamer->switchSection(TheSection); emitLinkage(GV, EmittedInitSym); emitAlignment(Alignment, GV); @@ -704,7 +864,7 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { OutStreamer->emitELFSize(EmittedInitSym, MCConstantExpr::create(Size, OutContext)); - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); } /// Emit the directive and value for debug thread local expression @@ -723,7 +883,7 @@ void AsmPrinter::emitFunctionHeader() { const Function &F = MF->getFunction(); if (isVerbose()) - OutStreamer->GetCommentOS() + OutStreamer->getCommentOS() << "-- Begin function " << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n'; @@ -737,7 +897,7 @@ void AsmPrinter::emitFunctionHeader() { MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM)); else MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM)); - OutStreamer->SwitchSection(MF->getSection()); + OutStreamer->switchSection(MF->getSection()); if (!MAI->hasVisibilityOnlyWithLinkage()) emitVisibility(CurrentFnSym, F.getVisibility()); @@ -756,10 +916,10 @@ void AsmPrinter::emitFunctionHeader() { OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold); if (isVerbose()) { - F.printAsOperand(OutStreamer->GetCommentOS(), - /*PrintType=*/false, F.getParent()); + F.printAsOperand(OutStreamer->getCommentOS(), + /*PrintType=*/false, F.getParent()); emitFunctionHeaderComment(); - OutStreamer->GetCommentOS() << '\n'; + OutStreamer->getCommentOS() << '\n'; } // Emit the prefix data. @@ -817,7 +977,7 @@ void AsmPrinter::emitFunctionHeader() { // references to the dangling symbols. Emit them at the start of the function // so that we don't get references to undefined symbols. std::vector<MCSymbol*> DeadBlockSyms; - MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms); + takeDeletedSymbolsForFunction(&F, DeadBlockSyms); for (MCSymbol *DeadBlockSym : DeadBlockSyms) { OutStreamer->AddComment("Address taken block that was later removed"); OutStreamer->emitLabel(DeadBlockSym); @@ -844,6 +1004,24 @@ void AsmPrinter::emitFunctionHeader() { // Emit the prologue data. if (F.hasPrologueData()) emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData()); + + // Emit the function prologue data for the indirect call sanitizer. + if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) { + assert(TM.getTargetTriple().getArch() == Triple::x86 || + TM.getTargetTriple().getArch() == Triple::x86_64); + assert(MD->getNumOperands() == 2); + + auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0)); + auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1)); + assert(PrologueSig && FTRTTIProxy); + emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig); + + const MCExpr *Proxy = lowerConstant(FTRTTIProxy); + const MCExpr *FnExp = MCSymbolRefExpr::create(CurrentFnSym, OutContext); + const MCExpr *PCRel = MCBinaryExpr::createSub(Proxy, FnExp, OutContext); + // Use 32 bit since only small code model is supported. + OutStreamer->emitValue(PCRel, 4u); + } } /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the @@ -912,7 +1090,7 @@ void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const { << printReg(RegNo, MF->getSubtarget().getRegisterInfo()); OutStreamer->AddComment(OS.str()); - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); } static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { @@ -925,7 +1103,7 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo()); } AP.OutStreamer->AddComment(OS.str()); - AP.OutStreamer->AddBlankLine(); + AP.OutStreamer->addBlankLine(); } /// emitDebugValueComment - This method handles the target-independent form @@ -1147,32 +1325,42 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { const MCSymbol *FunctionSymbol = getFunctionBegin(); - OutStreamer->PushSection(); - OutStreamer->SwitchSection(BBAddrMapSection); + OutStreamer->pushSection(); + OutStreamer->switchSection(BBAddrMapSection); + OutStreamer->AddComment("version"); + OutStreamer->emitInt8(OutStreamer->getContext().getBBAddrMapVersion()); + OutStreamer->AddComment("feature"); + OutStreamer->emitInt8(0); + OutStreamer->AddComment("function address"); OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize()); - // Emit the total number of basic blocks in this function. + OutStreamer->AddComment("number of basic blocks"); OutStreamer->emitULEB128IntValue(MF.size()); + const MCSymbol *PrevMBBEndSymbol = FunctionSymbol; // Emit BB Information for each basic block in the funciton. for (const MachineBasicBlock &MBB : MF) { const MCSymbol *MBBSymbol = MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); - // Emit the basic block offset. - emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol); + // Emit the basic block offset relative to the end of the previous block. + // This is zero unless the block is padded due to alignment. + emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol); // Emit the basic block size. When BBs have alignments, their size cannot // always be computed from their offsets. emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol); OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB)); + PrevMBBEndSymbol = MBB.getEndSymbol(); } - OutStreamer->PopSection(); + OutStreamer->popSection(); } void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) { - auto GUID = MI.getOperand(0).getImm(); - auto Index = MI.getOperand(1).getImm(); - auto Type = MI.getOperand(2).getImm(); - auto Attr = MI.getOperand(3).getImm(); - DILocation *DebugLoc = MI.getDebugLoc(); - PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc); + if (PP) { + auto GUID = MI.getOperand(0).getImm(); + auto Index = MI.getOperand(1).getImm(); + auto Type = MI.getOperand(2).getImm(); + auto Attr = MI.getOperand(3).getImm(); + DILocation *DebugLoc = MI.getDebugLoc(); + PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc); + } } void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { @@ -1189,15 +1377,16 @@ void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { if (FrameInfo.hasVarSizedObjects()) return; - OutStreamer->PushSection(); - OutStreamer->SwitchSection(StackSizeSection); + OutStreamer->pushSection(); + OutStreamer->switchSection(StackSizeSection); const MCSymbol *FunctionSymbol = getFunctionBegin(); - uint64_t StackSize = FrameInfo.getStackSize(); + uint64_t StackSize = + FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize()); OutStreamer->emitULEB128IntValue(StackSize); - OutStreamer->PopSection(); + OutStreamer->popSection(); } void AsmPrinter::emitStackUsage(const MachineFunction &MF) { @@ -1208,7 +1397,8 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) { return; const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); - uint64_t StackSize = FrameInfo.getStackSize(); + uint64_t StackSize = + FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); if (StackUsageStream == nullptr) { std::error_code EC; @@ -1298,7 +1488,7 @@ void AsmPrinter::emitFunctionBody() { } if (isVerbose()) - emitComments(MI, OutStreamer->GetCommentOS()); + emitComments(MI, OutStreamer->getCommentOS()); switch (MI.getOpcode()) { case TargetOpcode::CFI_INSTRUCTION: @@ -1460,7 +1650,7 @@ void AsmPrinter::emitFunctionBody() { } // Switch to the original section in case basic block sections was used. - OutStreamer->SwitchSection(MF->getSection()); + OutStreamer->switchSection(MF->getSection()); const Function &F = MF->getFunction(); for (const auto &BB : F) { @@ -1527,9 +1717,9 @@ void AsmPrinter::emitFunctionBody() { emitPatchableFunctionEntries(); if (isVerbose()) - OutStreamer->GetCommentOS() << "-- End function\n"; + OutStreamer->getCommentOS() << "-- End function\n"; - OutStreamer->AddBlankLine(); + OutStreamer->addBlankLine(); } /// Compute the number of Global Variables that uses a Constant. @@ -1617,10 +1807,7 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) { // Treat bitcasts of functions as functions also. This is important at least // on WebAssembly where object and function addresses can't alias each other. if (!IsFunction) - if (auto *CE = dyn_cast<ConstantExpr>(GA.getAliasee())) - if (CE->getOpcode() == Instruction::BitCast) - IsFunction = - CE->getOperand(0)->getType()->getPointerElementType()->isFunctionTy(); + IsFunction = isa<Function>(GA.getAliasee()->stripPointerCasts()); // AIX's assembly directive `.set` is not usable for aliasing purpose, // so AIX has to use the extra-label-at-definition strategy. At this @@ -1650,13 +1837,13 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) { if (IsFunction) { OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction); if (TM.getTargetTriple().isOSBinFormatCOFF()) { - OutStreamer->BeginCOFFSymbolDef(Name); - OutStreamer->EmitCOFFSymbolStorageClass( + OutStreamer->beginCOFFSymbolDef(Name); + OutStreamer->emitCOFFSymbolStorageClass( GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL); - OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION + OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT); - OutStreamer->EndCOFFSymbolDef(); + OutStreamer->endCOFFSymbolDef(); } } @@ -1734,7 +1921,7 @@ void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) { // Switch to the remarks section. MCSection *RemarksSection = OutContext.getObjectFileInfo()->getRemarksSection(); - OutStreamer->SwitchSection(RemarksSection); + OutStreamer->switchSection(RemarksSection); OutStreamer->emitBinaryData(OS.str()); } @@ -1805,7 +1992,7 @@ bool AsmPrinter::doFinalization(Module &M) { // Output stubs for external and common global variables. MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); if (!Stubs.empty()) { - OutStreamer->SwitchSection(TLOF.getDataSection()); + OutStreamer->switchSection(TLOF.getDataSection()); const DataLayout &DL = M.getDataLayout(); emitAlignment(Align(DL.getPointerSize())); @@ -1829,7 +2016,7 @@ bool AsmPrinter::doFinalization(Module &M) { for (const auto &Stub : Stubs) { SmallString<256> SectionName = StringRef(".rdata$"); SectionName += Stub.first->getName(); - OutStreamer->SwitchSection(OutContext.getCOFFSection( + OutStreamer->switchSection(OutContext.getCOFFSection( SectionName, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_LNK_COMDAT, @@ -1920,31 +2107,14 @@ bool AsmPrinter::doFinalization(Module &M) { // Emit bytes for llvm.commandline metadata. emitModuleCommandLines(M); - // Emit __morestack address if needed for indirect calls. - if (MMI->usesMorestackAddr()) { - Align Alignment(1); - MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant( - getDataLayout(), SectionKind::getReadOnly(), - /*C=*/nullptr, Alignment); - OutStreamer->SwitchSection(ReadOnlySection); - - MCSymbol *AddrSymbol = - OutContext.getOrCreateSymbol(StringRef("__morestack_addr")); - OutStreamer->emitLabel(AddrSymbol); - - unsigned PtrSize = MAI->getCodePointerSize(); - OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"), - PtrSize); - } - // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if // split-stack is used. - if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) { - OutStreamer->SwitchSection( - OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0)); - if (MMI->hasNosplitStack()) - OutStreamer->SwitchSection( - OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0)); + if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) { + OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack", + ELF::SHT_PROGBITS, 0)); + if (HasNoSplitStack) + OutStreamer->switchSection(OutContext.getELFSection( + ".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0)); } // If we don't have any trampolines, then we don't require stack memory @@ -1952,7 +2122,7 @@ bool AsmPrinter::doFinalization(Module &M) { Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) if (MCSection *S = MAI->getNonexecutableStackSection(OutContext)) - OutStreamer->SwitchSection(S); + OutStreamer->switchSection(S); if (TM.Options.EmitAddrsig) { // Emit address-significance attributes for all globals. @@ -1973,7 +2143,7 @@ bool AsmPrinter::doFinalization(Module &M) { GV.getVisibility() != GlobalValue::DefaultVisibility) continue; - OutStreamer->SwitchSection( + OutStreamer->switchSection( OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0, "", false, ++UniqueID, nullptr)); OutStreamer->emitBytes(GV.getPartition()); @@ -1989,8 +2159,9 @@ bool AsmPrinter::doFinalization(Module &M) { emitEndOfAsmFile(M); MMI = nullptr; + AddrLabelSymbols = nullptr; - OutStreamer->Finish(); + OutStreamer->finish(); OutStreamer->reset(); OwnedMLI.reset(); OwnedMDT.reset(); @@ -2009,6 +2180,16 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { this->MF = &MF; const Function &F = MF.getFunction(); + // Record that there are split-stack functions, so we will emit a special + // section to tell the linker. + if (MF.shouldSplitStack()) { + HasSplitStack = true; + + if (!MF.getFrameInfo().needsSplitStackProlog()) + HasNoSplitStack = true; + } else + HasNoSplitStack = true; + // Get the function symbol. if (!MAI->needsFunctionDescriptors()) { CurrentFnSym = getSymbol(&MF.getFunction()); @@ -2113,7 +2294,7 @@ void AsmPrinter::emitConstantPool() { continue; if (CurSection != CPSections[i].S) { - OutStreamer->SwitchSection(CPSections[i].S); + OutStreamer->switchSection(CPSections[i].S); emitAlignment(Align(CPSections[i].Alignment)); CurSection = CPSections[i].S; Offset = 0; @@ -2156,7 +2337,7 @@ void AsmPrinter::emitJumpTableInfo() { if (JTInDiffSection) { // Drop it in the readonly section. MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM); - OutStreamer->SwitchSection(ReadOnlySection); + OutStreamer->switchSection(ReadOnlySection); } emitAlignment(Align(MJTI->getEntryAlignment(DL))); @@ -2392,7 +2573,7 @@ void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List, MCSection *OutputSection = (IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym) : Obj.getStaticDtorSection(S.Priority, KeySym)); - OutStreamer->SwitchSection(OutputSection); + OutStreamer->switchSection(OutputSection); if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection()) emitAlignment(Align); emitXXStructor(DL, S.Func); @@ -2423,8 +2604,8 @@ void AsmPrinter::emitModuleCommandLines(Module &M) { if (!NMD || !NMD->getNumOperands()) return; - OutStreamer->PushSection(); - OutStreamer->SwitchSection(CommandLine); + OutStreamer->pushSection(); + OutStreamer->switchSection(CommandLine); OutStreamer->emitZeros(1); for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { const MDNode *N = NMD->getOperand(i); @@ -2434,7 +2615,7 @@ void AsmPrinter::emitModuleCommandLines(Module &M) { OutStreamer->emitBytes(S->getString()); OutStreamer->emitZeros(1); } - OutStreamer->PopSection(); + OutStreamer->popSection(); } //===--------------------------------------------------------------------===// @@ -2471,7 +2652,7 @@ void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, unsigned Size, bool IsSectionRelative) const { if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { - OutStreamer->EmitCOFFSecRel32(Label, Offset); + OutStreamer->emitCOFFSecRel32(Label, Offset); if (Size > 4) OutStreamer->emitZeros(Size - 4); return; @@ -2541,6 +2722,9 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { llvm_unreachable("Unknown constant value to lower!"); } + // The constant expression opcodes are limited to those that are necessary + // to represent relocations on supported targets. Expressions involving only + // constant addresses are constant folded instead. switch (CE->getOpcode()) { case Instruction::AddrSpaceCast: { const Constant *Op = CE->getOperand(0); @@ -2658,34 +2842,17 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { return RelocExpr; } } + + const MCExpr *LHS = lowerConstant(CE->getOperand(0)); + const MCExpr *RHS = lowerConstant(CE->getOperand(1)); + return MCBinaryExpr::createSub(LHS, RHS, Ctx); + break; } - // else fallthrough - LLVM_FALLTHROUGH; - // The MC library also has a right-shift operator, but it isn't consistently - // signed or unsigned between different targets. - case Instruction::Add: - case Instruction::Mul: - case Instruction::SDiv: - case Instruction::SRem: - case Instruction::Shl: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: { + case Instruction::Add: { const MCExpr *LHS = lowerConstant(CE->getOperand(0)); const MCExpr *RHS = lowerConstant(CE->getOperand(1)); - switch (CE->getOpcode()) { - default: llvm_unreachable("Unknown binary operator constant cast expr"); - case Instruction::Add: return MCBinaryExpr::createAdd(LHS, RHS, Ctx); - case Instruction::Sub: return MCBinaryExpr::createSub(LHS, RHS, Ctx); - case Instruction::Mul: return MCBinaryExpr::createMul(LHS, RHS, Ctx); - case Instruction::SDiv: return MCBinaryExpr::createDiv(LHS, RHS, Ctx); - case Instruction::SRem: return MCBinaryExpr::createMod(LHS, RHS, Ctx); - case Instruction::Shl: return MCBinaryExpr::createShl(LHS, RHS, Ctx); - case Instruction::And: return MCBinaryExpr::createAnd(LHS, RHS, Ctx); - case Instruction::Or: return MCBinaryExpr::createOr (LHS, RHS, Ctx); - case Instruction::Xor: return MCBinaryExpr::createXor(LHS, RHS, Ctx); - } + return MCBinaryExpr::createAdd(LHS, RHS, Ctx); } } } @@ -2719,7 +2886,7 @@ static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) { assert(Size % 8 == 0); // Extend the element to take zero padding into account. - APInt Value = CI->getValue().zextOrSelf(Size); + APInt Value = CI->getValue().zext(Size); if (!Value.isSplat(8)) return -1; @@ -2768,8 +2935,8 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL, if (isa<IntegerType>(CDS->getElementType())) { for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { if (AP.isVerbose()) - AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n", - CDS->getElementAsInteger(i)); + AP.OutStreamer->getCommentOS() + << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(i)); AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(i), ElementByteSize); } @@ -2855,8 +3022,8 @@ static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) { if (AP.isVerbose()) { SmallString<8> StrVal; APF.toString(StrVal); - ET->print(AP.OutStreamer->GetCommentOS()); - AP.OutStreamer->GetCommentOS() << ' ' << StrVal << '\n'; + ET->print(AP.OutStreamer->getCommentOS()); + AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n'; } // Now iterate through the APInt chunks, emitting them in endian-correct @@ -3061,8 +3228,8 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, if (StoreSize <= 8) { if (AP.isVerbose()) - AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n", - CI->getZExtValue()); + AP.OutStreamer->getCommentOS() + << format("0x%" PRIx64 "\n", CI->getZExtValue()); AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize); } else { emitGlobalConstantLargeInt(CI, AP); @@ -3163,11 +3330,12 @@ MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const { } MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { - return MMI->getAddrLabelSymbol(BA->getBasicBlock()); + return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol( + BA->getBasicBlock()); } MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { - return MMI->getAddrLabelSymbol(BB); + return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB); } /// GetCPISymbol - Return the symbol for the specified constant pool entry. @@ -3272,7 +3440,7 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB, // Otherwise, it is a loop header. Print out information about child and // parent loops. - raw_ostream &OS = AP.OutStreamer->GetCommentOS(); + raw_ostream &OS = AP.OutStreamer->getCommentOS(); PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); @@ -3308,7 +3476,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { // entry block is always placed in the function section and is handled // separately. if (MBB.isBeginSection() && !MBB.isEntryBlock()) { - OutStreamer->SwitchSection( + OutStreamer->switchSection( getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(), MBB, TM)); CurrentSectionBeginSym = MBB.getSymbol(); @@ -3326,7 +3494,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { // MBBs can have their address taken as part of CodeGen without having // their corresponding BB's address taken in IR if (BB && BB->hasAddressTaken()) - for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB)) + for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB)) OutStreamer->emitLabel(Sym); } @@ -3334,9 +3502,9 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { if (isVerbose()) { if (BB) { if (BB->hasName()) { - BB->printAsOperand(OutStreamer->GetCommentOS(), + BB->printAsOperand(OutStreamer->getCommentOS(), /*PrintType=*/false, BB->getModule()); - OutStreamer->GetCommentOS() << '\n'; + OutStreamer->getCommentOS() << '\n'; } } @@ -3563,7 +3731,7 @@ void AsmPrinter::emitXRayTable() { // range of sleds associated with a function. auto &Ctx = OutContext; MCSymbol *SledsStart = OutContext.createTempSymbol("xray_sleds_start", true); - OutStreamer->SwitchSection(InstMap); + OutStreamer->switchSection(InstMap); OutStreamer->emitLabel(SledsStart); for (const auto &Sled : Sleds) { MCSymbol *Dot = Ctx.createTempSymbol(); @@ -3590,11 +3758,11 @@ void AsmPrinter::emitXRayTable() { // Each entry here will be 2 * word size aligned, as we're writing down two // pointers. This should work for both 32-bit and 64-bit platforms. if (FnSledIndex) { - OutStreamer->SwitchSection(FnSledIndex); + OutStreamer->switchSection(FnSledIndex); OutStreamer->emitCodeAlignment(2 * WordSizeBytes, &getSubtargetInfo()); OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false); OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false); - OutStreamer->SwitchSection(PrevSection); + OutStreamer->switchSection(PrevSection); } Sleds.clear(); } @@ -3639,7 +3807,7 @@ void AsmPrinter::emitPatchableFunctionEntries() { } LinkedToSym = cast<MCSymbolELF>(CurrentFnSym); } - OutStreamer->SwitchSection(OutContext.getELFSection( + OutStreamer->switchSection(OutContext.getELFSection( "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(), MCSection::NonUniqueID, LinkedToSym)); emitAlignment(Align(PointerSize)); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index fc127f4cf9da..719fec06aa33 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "ByteStreamer.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" @@ -19,14 +18,11 @@ #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetMachine.h" #include <cstdint> using namespace llvm; @@ -162,7 +158,7 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label, if (MAI->needsDwarfSectionOffsetDirective()) { assert(!isDwarf64() && "emitting DWARF64 is not implemented for COFF targets"); - OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0); + OutStreamer->emitCOFFSecRel32(Label, /*Offset=*/0); return; } @@ -277,6 +273,12 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { case MCCFIInstruction::OpUndefined: OutStreamer->emitCFIUndefined(Inst.getRegister()); break; + case MCCFIInstruction::OpRememberState: + OutStreamer->emitCFIRememberState(); + break; + case MCCFIInstruction::OpRestoreState: + OutStreamer->emitCFIRestoreState(); + break; } } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 5d0cadefdbf7..88c82cbc958b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -17,8 +17,8 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DiagnosticInfo.h" @@ -26,9 +26,10 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" @@ -115,7 +116,7 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); Parser->setAssemblerDialect(Dialect); - Parser->setTargetParser(*TAP.get()); + Parser->setTargetParser(*TAP); // Enable lexing Masm binary and hex integer literals in intel inline // assembly. if (Dialect == InlineAsm::AD_Intel) @@ -398,9 +399,9 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const { if (!RestrRegs.empty()) { std::string Msg = "inline asm clobber list contains reserved registers: "; ListSeparator LS; - for (const Register &RR : RestrRegs) { + for (const Register RR : RestrRegs) { Msg += LS; - Msg += TRI->getName(RR); + Msg += TRI->getRegAsmName(RR); } const char *Note = "Reserved registers on the clobber list may not be " diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 52c74713551c..701c0affdfa6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "CodeViewDebug.h" -#include "DwarfExpression.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -29,7 +28,6 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -41,7 +39,6 @@ #include "llvm/DebugInfo/CodeView/EnumTables.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" @@ -58,11 +55,8 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/BinaryByteStream.h" -#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -230,7 +224,7 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { break; } } - bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes, + bool Success = OS.emitCVFileDirective(NextId, FullPath, ChecksumAsBytes, static_cast<unsigned>(CSKind)); (void)Success; assert(Success && ".cv_file directive failed"); @@ -251,7 +245,7 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt, .SiteFuncId; Site->SiteFuncId = NextFuncId++; - OS.EmitCVInlineSiteIdDirective( + OS.emitCVInlineSiteIdDirective( Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()), InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc()); Site->Inlinee = Inlinee; @@ -515,7 +509,7 @@ void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL, if (!DL || DL == PrevInstLoc) return; - const DIScope *Scope = DL.get()->getScope(); + const DIScope *Scope = DL->getScope(); if (!Scope) return; @@ -614,18 +608,16 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) { void CodeViewDebug::beginModule(Module *M) { // If module doesn't have named metadata anchors or COFF debug section // is not available, skip any debug info related stuff. - NamedMDNode *CUs = M->getNamedMetadata("llvm.dbg.cu"); - if (!CUs || !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) { + if (!MMI->hasDebugInfo() || + !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) { Asm = nullptr; return; } - // Tell MMI that we have and need debug info. - MMI->setDebugInfoAvailability(true); TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch()); // Get the current source language. - const MDNode *Node = *CUs->operands().begin(); + const MDNode *Node = *M->debug_compile_units_begin(); const auto *CU = cast<DICompileUnit>(Node); CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage()); @@ -727,7 +719,7 @@ void CodeViewDebug::emitTypeInformation() { return; // Start the .debug$T or .debug$P section with 0x4. - OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); + OS.switchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); emitCodeViewMagicVersion(); TypeTableCollection Table(TypeTable.records()); @@ -760,7 +752,7 @@ void CodeViewDebug::emitTypeGlobalHashes() { // Start the .debug$H section with the version and hash algorithm, currently // hardcoded to version 0, SHA1. - OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection()); + OS.switchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection()); OS.emitValueToAlignment(4); OS.AddComment("Magic"); @@ -826,6 +818,8 @@ static Version parseVersion(StringRef Name) { if (isdigit(C)) { V.Part[N] *= 10; V.Part[N] += C - '0'; + V.Part[N] = + std::min<int>(V.Part[N], std::numeric_limits<uint16_t>::max()); } else if (C == '.') { ++N; if (N >= 4) @@ -867,7 +861,6 @@ void CodeViewDebug::emitCompilerInformation() { Version FrontVer = parseVersion(CompilerVersion); OS.AddComment("Frontend version"); for (int N : FrontVer.Part) { - N = std::min<int>(N, std::numeric_limits<uint16_t>::max()); OS.emitInt16(N); } @@ -985,11 +978,11 @@ void CodeViewDebug::emitInlineeLinesSubsection() { assert(TypeIndices.count({SP, nullptr})); TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}]; - OS.AddBlankLine(); + OS.addBlankLine(); unsigned FileId = maybeRecordFile(SP->getFile()); OS.AddComment("Inlined function " + SP->getName() + " starts at " + SP->getFilename() + Twine(':') + Twine(SP->getLine())); - OS.AddBlankLine(); + OS.addBlankLine(); OS.AddComment("Type index of inlined function"); OS.emitInt32(InlineeIdx.getIndex()); OS.AddComment("Offset into filechecksum table"); @@ -1051,7 +1044,7 @@ void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) { Asm->getObjFileLowering().getCOFFDebugSymbolsSection()); DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym); - OS.SwitchSection(DebugSec); + OS.switchSection(DebugSec); // Emit the magic version number if this is the first time we've switched to // this section. @@ -1080,9 +1073,9 @@ void CodeViewDebug::emitDebugInfoForThunk(const Function *GV, OS.AddComment("PtrNext"); OS.emitInt32(0); OS.AddComment("Thunk section relative address"); - OS.EmitCOFFSecRel32(Fn, /*Offset=*/0); + OS.emitCOFFSecRel32(Fn, /*Offset=*/0); OS.AddComment("Thunk section index"); - OS.EmitCOFFSectionIndex(Fn); + OS.emitCOFFSectionIndex(Fn); OS.AddComment("Code size"); OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2); OS.AddComment("Ordinal"); @@ -1132,7 +1125,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, // Emit FPO data, but only on 32-bit x86. No other platforms use it. if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86) - OS.EmitCVFPOData(Fn); + OS.emitCVFPOData(Fn); // Emit a symbol subsection, required by VS2012+ to find function boundaries. OS.AddComment("Symbol subsection for " + Twine(FuncName)); @@ -1160,9 +1153,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, OS.AddComment("Function type index"); OS.emitInt32(getFuncIdForSubprogram(GV->getSubprogram()).getIndex()); OS.AddComment("Function section relative address"); - OS.EmitCOFFSecRel32(Fn, /*Offset=*/0); + OS.emitCOFFSecRel32(Fn, /*Offset=*/0); OS.AddComment("Function section index"); - OS.EmitCOFFSectionIndex(Fn); + OS.emitCOFFSectionIndex(Fn); OS.AddComment("Flags"); OS.emitInt8(0); // Emit the function display name as a null-terminated string. @@ -1207,9 +1200,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, MCSymbol *Label = Annot.first; MDTuple *Strs = cast<MDTuple>(Annot.second); MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION); - OS.EmitCOFFSecRel32(Label, /*Offset=*/0); + OS.emitCOFFSecRel32(Label, /*Offset=*/0); // FIXME: Make sure we don't overflow the max record size. - OS.EmitCOFFSectionIndex(Label); + OS.emitCOFFSectionIndex(Label); OS.emitInt16(Strs->getNumOperands()); for (Metadata *MD : Strs->operands()) { // MDStrings are null terminated, so we can do EmitBytes and get the @@ -1227,9 +1220,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, const DIType *DITy = std::get<2>(HeapAllocSite); MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE); OS.AddComment("Call site offset"); - OS.EmitCOFFSecRel32(BeginLabel, /*Offset=*/0); + OS.emitCOFFSecRel32(BeginLabel, /*Offset=*/0); OS.AddComment("Call site section index"); - OS.EmitCOFFSectionIndex(BeginLabel); + OS.emitCOFFSectionIndex(BeginLabel); OS.AddComment("Call instruction length"); OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2); OS.AddComment("Type index"); @@ -1249,9 +1242,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, OS.emitCVLinetableDirective(FI.FuncId, Fn, FI.End); } -CodeViewDebug::LocalVarDefRange +CodeViewDebug::LocalVarDef CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) { - LocalVarDefRange DR; + LocalVarDef DR; DR.InMemory = -1; DR.DataOffset = Offset; assert(DR.DataOffset == Offset && "truncation"); @@ -1303,19 +1296,19 @@ void CodeViewDebug::collectVariableInfoFromMFTable( "Frame offsets with a scalable component are not supported"); // Calculate the label ranges. - LocalVarDefRange DefRange = + LocalVarDef DefRange = createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset); + LocalVariable Var; + Var.DIVar = VI.Var; + for (const InsnRange &Range : Scope->getRanges()) { const MCSymbol *Begin = getLabelBeforeInsn(Range.first); const MCSymbol *End = getLabelAfterInsn(Range.second); End = End ? End : Asm->getFunctionEnd(); - DefRange.Ranges.emplace_back(Begin, End); + Var.DefRanges[DefRange].emplace_back(Begin, End); } - LocalVariable Var; - Var.DIVar = VI.Var; - Var.DefRanges.emplace_back(std::move(DefRange)); if (Deref) Var.UseReferenceType = true; @@ -1374,24 +1367,18 @@ void CodeViewDebug::calculateRanges( // We can only handle a register or an offseted load of a register. if (Location->Register == 0 || Location->LoadChain.size() > 1) continue; - { - LocalVarDefRange DR; - DR.CVRegister = TRI->getCodeViewRegNum(Location->Register); - DR.InMemory = !Location->LoadChain.empty(); - DR.DataOffset = - !Location->LoadChain.empty() ? Location->LoadChain.back() : 0; - if (Location->FragmentInfo) { - DR.IsSubfield = true; - DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8; - } else { - DR.IsSubfield = false; - DR.StructOffset = 0; - } - if (Var.DefRanges.empty() || - Var.DefRanges.back().isDifferentLocation(DR)) { - Var.DefRanges.emplace_back(std::move(DR)); - } + LocalVarDef DR; + DR.CVRegister = TRI->getCodeViewRegNum(Location->Register); + DR.InMemory = !Location->LoadChain.empty(); + DR.DataOffset = + !Location->LoadChain.empty() ? Location->LoadChain.back() : 0; + if (Location->FragmentInfo) { + DR.IsSubfield = true; + DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8; + } else { + DR.IsSubfield = false; + DR.StructOffset = 0; } // Compute the label range. @@ -1408,7 +1395,7 @@ void CodeViewDebug::calculateRanges( // If the last range end is our begin, just extend the last range. // Otherwise make a new range. SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R = - Var.DefRanges.back().Ranges; + Var.DefRanges[DR]; if (!R.empty() && R.back().second == Begin) R.back().second = End; else @@ -1525,7 +1512,7 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) { // FIXME: Set GuardCfg when it is implemented. CurFn->FrameProcOpts = FPO; - OS.EmitCVFuncIdDirective(CurFn->FuncId); + OS.emitCVFuncIdDirective(CurFn->FuncId); // Find the end of the function prolog. First known non-DBG_VALUE and // non-frame setup location marks the beginning of the function body. @@ -1825,6 +1812,7 @@ TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) { break; case dwarf::DW_ATE_UTF: switch (ByteSize) { + case 1: STK = SimpleTypeKind::Character8; break; case 2: STK = SimpleTypeKind::Character16; break; case 4: STK = SimpleTypeKind::Character32; break; } @@ -2820,7 +2808,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, // records and on disk formats are described in SymbolRecords.h. BytePrefix // should be big enough to hold all forms without memory allocation. SmallString<20> BytePrefix; - for (const LocalVarDefRange &DefRange : Var.DefRanges) { + for (const auto &Pair : Var.DefRanges) { + LocalVarDef DefRange = Pair.first; + const auto &Ranges = Pair.second; BytePrefix.clear(); if (DefRange.InMemory) { int Offset = DefRange.DataOffset; @@ -2844,7 +2834,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, : (EncFP == FI.EncodedLocalFramePtrReg))) { DefRangeFramePointerRelHeader DRHdr; DRHdr.Offset = Offset; - OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr); + OS.emitCVDefRangeDirective(Ranges, DRHdr); } else { uint16_t RegRelFlags = 0; if (DefRange.IsSubfield) { @@ -2856,7 +2846,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, DRHdr.Register = Reg; DRHdr.Flags = RegRelFlags; DRHdr.BasePointerOffset = Offset; - OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr); + OS.emitCVDefRangeDirective(Ranges, DRHdr); } } else { assert(DefRange.DataOffset == 0 && "unexpected offset into register"); @@ -2865,12 +2855,12 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, DRHdr.Register = DefRange.CVRegister; DRHdr.MayHaveNoName = 0; DRHdr.OffsetInParent = DefRange.StructOffset; - OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr); + OS.emitCVDefRangeDirective(Ranges, DRHdr); } else { DefRangeRegisterHeader DRHdr; DRHdr.Register = DefRange.CVRegister; DRHdr.MayHaveNoName = 0; - OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr); + OS.emitCVDefRangeDirective(Ranges, DRHdr); } } } @@ -2894,9 +2884,9 @@ void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block, OS.AddComment("Code size"); OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4); // Code Size OS.AddComment("Function section relative address"); - OS.EmitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset + OS.emitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset OS.AddComment("Function section index"); - OS.EmitCOFFSectionIndex(FI.Begin); // Func Symbol + OS.emitCOFFSectionIndex(FI.Begin); // Func Symbol OS.AddComment("Lexical block name"); emitNullTerminatedSymbolName(OS, Block.Name); // Name endSymbolRecord(RecordEnd); @@ -3181,6 +3171,11 @@ void CodeViewDebug::collectGlobalVariableInfo() { for (const auto *GVE : CU->getGlobalVariables()) { const DIGlobalVariable *DIGV = GVE->getVariable(); const DIExpression *DIE = GVE->getExpression(); + // Don't emit string literals in CodeView, as the only useful parts are + // generally the filename and line number, which isn't possible to output + // in CodeView. String literals should be the only unnamed GlobalVariable + // with debug info. + if (DIGV->getName().empty()) continue; if ((DIE->getNumElements() == 2) && (DIE->getElement(0) == dwarf::DW_OP_plus_uconst)) @@ -3380,10 +3375,10 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) { if (CVGlobalVariableOffsets.find(DIGV) != CVGlobalVariableOffsets.end()) // Use the offset seen while collecting info on globals. Offset = CVGlobalVariableOffsets[DIGV]; - OS.EmitCOFFSecRel32(GVSym, Offset); + OS.emitCOFFSecRel32(GVSym, Offset); OS.AddComment("Segment"); - OS.EmitCOFFSectionIndex(GVSym); + OS.emitCOFFSectionIndex(GVSym); OS.AddComment("Name"); const unsigned LengthOfDataRecord = 12; emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord); diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index d1fc3cdccb20..16f0082723ed 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -50,18 +50,8 @@ class MachineFunction; /// Collects and handles line tables information in a CodeView format. class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { - MCStreamer &OS; - BumpPtrAllocator Allocator; - codeview::GlobalTypeTableBuilder TypeTable; - - /// Whether to emit type record hashes into .debug$H. - bool EmitDebugGlobalHashes = false; - - /// The codeview CPU type used by the translation unit. - codeview::CPUType TheCPU; - - /// Represents the most general definition range. - struct LocalVarDefRange { +public: + struct LocalVarDef { /// Indicates that variable data is stored in memory relative to the /// specified register. int InMemory : 1; @@ -79,23 +69,40 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { /// location containing the data. uint16_t CVRegister; - /// Compares all location fields. This includes all fields except the label - /// ranges. - bool isDifferentLocation(LocalVarDefRange &O) { - return InMemory != O.InMemory || DataOffset != O.DataOffset || - IsSubfield != O.IsSubfield || StructOffset != O.StructOffset || - CVRegister != O.CVRegister; + uint64_t static toOpaqueValue(const LocalVarDef DR) { + uint64_t Val = 0; + std::memcpy(&Val, &DR, sizeof(Val)); + return Val; } - SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1> Ranges; + LocalVarDef static createFromOpaqueValue(uint64_t Val) { + LocalVarDef DR; + std::memcpy(&DR, &Val, sizeof(Val)); + return DR; + } }; - static LocalVarDefRange createDefRangeMem(uint16_t CVRegister, int Offset); + static_assert(sizeof(uint64_t) == sizeof(LocalVarDef), ""); + +private: + MCStreamer &OS; + BumpPtrAllocator Allocator; + codeview::GlobalTypeTableBuilder TypeTable; + + /// Whether to emit type record hashes into .debug$H. + bool EmitDebugGlobalHashes = false; + + /// The codeview CPU type used by the translation unit. + codeview::CPUType TheCPU; + + static LocalVarDef createDefRangeMem(uint16_t CVRegister, int Offset); /// Similar to DbgVariable in DwarfDebug, but not dwarf-specific. struct LocalVariable { const DILocalVariable *DIVar = nullptr; - SmallVector<LocalVarDefRange, 1> DefRanges; + MapVector<LocalVarDef, + SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 1>> + DefRanges; bool UseReferenceType = false; }; @@ -493,6 +500,27 @@ public: void beginInstruction(const MachineInstr *MI) override; }; +template <> struct DenseMapInfo<CodeViewDebug::LocalVarDef> { + + static inline CodeViewDebug::LocalVarDef getEmptyKey() { + return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL); + } + + static inline CodeViewDebug::LocalVarDef getTombstoneKey() { + return CodeViewDebug::LocalVarDef::createFromOpaqueValue(~0ULL - 1ULL); + } + + static unsigned getHashValue(const CodeViewDebug::LocalVarDef &DR) { + return CodeViewDebug::LocalVarDef::toOpaqueValue(DR) * 37ULL; + } + + static bool isEqual(const CodeViewDebug::LocalVarDef &LHS, + const CodeViewDebug::LocalVarDef &RHS) { + return CodeViewDebug::LocalVarDef::toOpaqueValue(LHS) == + CodeViewDebug::LocalVarDef::toOpaqueValue(RHS); + } +}; + } // end namespace llvm #endif // LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 396322c4979d..617ddbd66e4e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -13,21 +13,15 @@ #include "llvm/CodeGen/DIE.h" #include "DwarfCompileUnit.h" #include "DwarfDebug.h" -#include "DwarfUnit.h" -#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Config/llvm-config.h" -#include "llvm/IR/DataLayout.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" -#include "llvm/Support/FormattedStream.h" #include "llvm/Support/LEB128.h" -#include "llvm/Support/MD5.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -170,7 +164,7 @@ DIEAbbrev &DIEAbbrevSet::uniqueAbbreviation(DIE &Die) { void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const { if (!Abbreviations.empty()) { // Start the debug abbrev section. - AP->OutStreamer->SwitchSection(Section); + AP->OutStreamer->switchSection(Section); AP->emitDwarfAbbrevs(Abbreviations); } } @@ -204,6 +198,7 @@ const DIE *DIE::getUnitDie() const { const DIE *p = this; while (p) { if (p->getTag() == dwarf::DW_TAG_compile_unit || + p->getTag() == dwarf::DW_TAG_skeleton_unit || p->getTag() == dwarf::DW_TAG_type_unit) return p; p = p->getParent(); @@ -378,7 +373,7 @@ void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_flag_present: // Emit something to keep the lines and comments in sync. // FIXME: Is there a better way to do this? - Asm->OutStreamer->AddBlankLine(); + Asm->OutStreamer->addBlankLine(); return; case dwarf::DW_FORM_flag: case dwarf::DW_FORM_ref1: diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp index e175854f7b93..5da50d7aab9f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -19,7 +19,6 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp index dd795079ac1a..1358f4d25990 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" @@ -204,7 +203,7 @@ void DbgValueHistoryMap::trimLocationRanges( if (auto R = intersects(StartMI, EndMI, ScopeRanges, Ordering)) { // Adjust ScopeRanges to exclude ranges which subsequent location ranges // cannot possibly intersect. - ScopeRanges = ArrayRef<InsnRange>(R.getValue(), ScopeRanges.end()); + ScopeRanges = ArrayRef<InsnRange>(*R, ScopeRanges.end()); } else { // If the location range does not intersect any scope range then the // DBG_VALUE which opened this location range is usless, mark it for diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 18fc46c74eb4..660a064687d3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -13,7 +13,6 @@ #include "llvm/CodeGen/DebugHandlerBase.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp index 63343d2519f9..5f187acf13dc 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -11,23 +11,13 @@ //===----------------------------------------------------------------------===// #include "DwarfException.h" -#include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -53,7 +43,7 @@ void DwarfCFIExceptionBase::endFragment() { DwarfCFIException::DwarfCFIException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} -DwarfCFIException::~DwarfCFIException() {} +DwarfCFIException::~DwarfCFIException() = default; /// endModule - Emit all exception information that should come after the /// content. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 5913c687db48..b3f99d346faa 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -21,7 +21,6 @@ #include "llvm/CodeGen/DIE.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -67,13 +66,13 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, /// DW_FORM_addr or DW_FORM_GNU_addr_index. void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label) { + if ((Skeleton || !DD->useSplitDwarf()) && Label) + DD->addArangeLabel(SymbolCU(this, Label)); + // Don't use the address pool in non-fission or in the skeleton unit itself. if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) return addLocalLabelAddress(Die, Attribute, Label); - if (Label) - DD->addArangeLabel(SymbolCU(this, Label)); - bool UseAddrOffsetFormOrExpressions = DD->useAddrOffsetForm() || DD->useAddrOffsetExpressions(); @@ -109,9 +108,6 @@ void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label) { if (Label) - DD->addArangeLabel(SymbolCU(this, Label)); - - if (Label) addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIELabel(Label)); else addAttribute(Die, Attribute, dwarf::DW_FORM_addr, DIEInteger(0)); @@ -169,7 +165,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( } else { DeclContext = GV->getScope(); // Add name and type. - addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); + StringRef DisplayName = GV->getDisplayName(); + if (!DisplayName.empty()) + addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName()); if (GTy) addType(*VariableDIE, GTy); @@ -303,8 +301,11 @@ void DwarfCompileUnit::addLocationAttribute( DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address : dwarf::DW_OP_form_tls_address); } - } else if (Asm->TM.getRelocationModel() == Reloc::RWPI || - Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) { + } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI || + Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) && + !Asm->getObjFileLowering() + .getKindForGlobal(Global, Asm->TM) + .isReadOnly()) { auto FormAndOp = GetPointerSizedFormAndOp(); // Constant addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op); @@ -505,7 +506,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { // FIXME: when writing dwo, we need to avoid relocations. Probably // the "right" solution is to treat globals the way func and data // symbols are (with entries in .debug_addr). - // For now, since we only ever use index 0, this should work as-is. + // For now, since we only ever use index 0, this should work as-is. addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index); } addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index f2e1f6346803..61412cde34c8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -25,7 +25,6 @@ #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/Casting.h" -#include <algorithm> #include <cassert> #include <cstdint> #include <memory> diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 609b568f28be..866338a949f3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -31,8 +31,8 @@ #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" @@ -45,14 +45,11 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MachineLocation.h" #include "llvm/MC/SectionKind.h" -#include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -360,7 +357,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A) DebuggerTuning = Asm->TM.Options.DebuggerTuning; else if (IsDarwin) DebuggerTuning = DebuggerKind::LLDB; - else if (TT.isPS4CPU()) + else if (TT.isPS()) DebuggerTuning = DebuggerKind::SCE; else if (TT.isOSAIX()) DebuggerTuning = DebuggerKind::DBX; @@ -2315,7 +2312,7 @@ void DwarfDebug::emitStringOffsetsTableHeader() { template <typename AccelTableT> void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section, StringRef TableName) { - Asm->OutStreamer->SwitchSection(Section); + Asm->OutStreamer->switchSection(Section); // Emit the full data. emitAppleAccelTable(Asm, Accel, TableName, Section->getBeginSymbol()); @@ -2434,12 +2431,12 @@ void DwarfDebug::emitDebugPubSections() { bool GnuStyle = TheU->getCUNode()->getNameTableKind() == DICompileUnit::DebugNameTableKind::GNU; - Asm->OutStreamer->SwitchSection( + Asm->OutStreamer->switchSection( GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() : Asm->getObjFileLowering().getDwarfPubNamesSection()); emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames()); - Asm->OutStreamer->SwitchSection( + Asm->OutStreamer->switchSection( GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() : Asm->getObjFileLowering().getDwarfPubTypesSection()); emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes()); @@ -2849,7 +2846,7 @@ void DwarfDebug::emitDebugLocImpl(MCSection *Sec) { if (DebugLocs.getLists().empty()) return; - Asm->OutStreamer->SwitchSection(Sec); + Asm->OutStreamer->switchSection(Sec); MCSymbol *TableEnd = nullptr; if (getDwarfVersion() >= 5) @@ -2880,7 +2877,7 @@ void DwarfDebug::emitDebugLocDWO() { } for (const auto &List : DebugLocs.getLists()) { - Asm->OutStreamer->SwitchSection( + Asm->OutStreamer->switchSection( Asm->getObjFileLowering().getDwarfLocDWOSection()); Asm->OutStreamer->emitLabel(List.Label); @@ -2953,8 +2950,8 @@ void DwarfDebug::emitDebugARanges() { // Sort the symbols by offset within the section. llvm::stable_sort(List, [&](const SymbolCU &A, const SymbolCU &B) { - unsigned IA = A.Sym ? Asm->OutStreamer->GetSymbolOrder(A.Sym) : 0; - unsigned IB = B.Sym ? Asm->OutStreamer->GetSymbolOrder(B.Sym) : 0; + unsigned IA = A.Sym ? Asm->OutStreamer->getSymbolOrder(A.Sym) : 0; + unsigned IB = B.Sym ? Asm->OutStreamer->getSymbolOrder(B.Sym) : 0; // Symbols with no order assigned should be placed at the end. // (e.g. section end labels) @@ -2987,7 +2984,7 @@ void DwarfDebug::emitDebugARanges() { } // Start the dwarf aranges section. - Asm->OutStreamer->SwitchSection( + Asm->OutStreamer->switchSection( Asm->getObjFileLowering().getDwarfARangesSection()); unsigned PtrSize = Asm->MAI->getCodePointerSize(); @@ -3045,15 +3042,22 @@ void DwarfDebug::emitDebugARanges() { for (const ArangeSpan &Span : List) { Asm->emitLabelReference(Span.Start, PtrSize); - // Calculate the size as being from the span start to it's end. - if (Span.End) { + // Calculate the size as being from the span start to its end. + // + // If the size is zero, then round it up to one byte. The DWARF + // specification requires that entries in this table have nonzero + // lengths. + auto SizeRef = SymSize.find(Span.Start); + if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) { Asm->emitLabelDifference(Span.End, Span.Start, PtrSize); } else { // For symbols without an end marker (e.g. common), we // write a single arange entry containing just that one symbol. - uint64_t Size = SymSize[Span.Start]; - if (Size == 0) + uint64_t Size; + if (SizeRef == SymSize.end() || SizeRef->second == 0) Size = 1; + else + Size = SizeRef->second; Asm->OutStreamer->emitIntValue(Size, PtrSize); } @@ -3087,7 +3091,7 @@ void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section return !Pair.second->getCUNode()->isDebugDirectivesOnly(); })); - Asm->OutStreamer->SwitchSection(Section); + Asm->OutStreamer->switchSection(Section); MCSymbol *TableEnd = nullptr; if (getDwarfVersion() >= 5) @@ -3239,7 +3243,7 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) { DIMacroNodeArray Macros = CUNode->getMacros(); if (Macros.empty()) continue; - Asm->OutStreamer->SwitchSection(Section); + Asm->OutStreamer->switchSection(Section); Asm->OutStreamer->emitLabel(U.getMacroLabelBegin()); if (UseDebugMacroSection) emitMacroHeader(Asm, *this, U, getDwarfVersion()); @@ -3447,22 +3451,6 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, CU.addDIETypeSignature(RefDie, Signature); } -DwarfDebug::NonTypeUnitContext::NonTypeUnitContext(DwarfDebug *DD) - : DD(DD), - TypeUnitsUnderConstruction(std::move(DD->TypeUnitsUnderConstruction)), AddrPoolUsed(DD->AddrPool.hasBeenUsed()) { - DD->TypeUnitsUnderConstruction.clear(); - DD->AddrPool.resetUsedFlag(); -} - -DwarfDebug::NonTypeUnitContext::~NonTypeUnitContext() { - DD->TypeUnitsUnderConstruction = std::move(TypeUnitsUnderConstruction); - DD->AddrPool.resetUsedFlag(AddrPoolUsed); -} - -DwarfDebug::NonTypeUnitContext DwarfDebug::enterNonTypeUnitContext() { - return NonTypeUnitContext(this); -} - // Add the Name along with its companion DIE to the appropriate accelerator // table (for AccelTableKind::Dwarf it's always AccelDebugNames, for // AccelTableKind::Apple, we use the table we got as an argument). If @@ -3555,6 +3543,6 @@ Optional<MD5::MD5Result> DwarfDebug::getMD5AsBytes(const DIFile *File) const { // An MD5 checksum is 16 bytes. std::string ChecksumString = fromHex(Checksum->Value); MD5::MD5Result CKMem; - std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.Bytes.data()); + std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.data()); return CKMem; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 4e1a1b1e068d..31e4081b7141 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -14,14 +14,13 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H #include "AddressPool.h" -#include "DebugLocStream.h" #include "DebugLocEntry.h" +#include "DebugLocStream.h" #include "DwarfFile.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -31,7 +30,6 @@ #include "llvm/CodeGen/AccelTable.h" #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" #include "llvm/CodeGen/DebugHandlerBase.h" -#include "llvm/CodeGen/MachineInstr.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Metadata.h" @@ -80,7 +78,7 @@ private: public: DbgEntity(const DINode *N, const DILocation *IA, DbgEntityKind ID) : Entity(N), InlinedAt(IA), SubclassID(ID) {} - virtual ~DbgEntity() {} + virtual ~DbgEntity() = default; /// Accessors. /// @{ @@ -667,19 +665,6 @@ public: void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy); - class NonTypeUnitContext { - DwarfDebug *DD; - decltype(DwarfDebug::TypeUnitsUnderConstruction) TypeUnitsUnderConstruction; - bool AddrPoolUsed; - friend class DwarfDebug; - NonTypeUnitContext(DwarfDebug *DD); - public: - NonTypeUnitContext(NonTypeUnitContext&&) = default; - ~NonTypeUnitContext(); - }; - - NonTypeUnitContext enterNonTypeUnitContext(); - /// Add a label so that arange data can be generated for it. void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index fe438102ee98..1c21d5ee8bb1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -329,7 +329,16 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, return false; } - assert(DwarfRegs.size() == 1); + // TODO: We should not give up here but the following code needs to be changed + // to deal with multiple (sub)registers first. + if (DwarfRegs.size() > 1) { + LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to " + "multi-register usage.\n"); + DwarfRegs.clear(); + LocationKind = Unknown; + return false; + } + auto Reg = DwarfRegs[0]; bool FBReg = isFrameRegister(TRI, MachineReg); int SignedOffset = 0; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp index a67d0f032cf6..a497aa07284e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -12,9 +12,7 @@ #include "DwarfUnit.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/Metadata.h" #include "llvm/MC/MCStreamer.h" -#include <algorithm> #include <cstdint> using namespace llvm; @@ -47,7 +45,7 @@ void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) { if (llvm::empty(TheU->getUnitDie().values())) return; - Asm->OutStreamer->SwitchSection(S); + Asm->OutStreamer->switchSection(S); TheU->emitHeader(UseOffsets); Asm->emitDwarfDIE(TheU->getUnitDie()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp index a876f8ccace9..67b72f0b455d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp @@ -39,7 +39,7 @@ DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) { DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm, StringRef Str) { auto &MapEntry = getEntryImpl(Asm, Str); - return EntryRef(MapEntry, false); + return EntryRef(MapEntry); } DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm, @@ -47,7 +47,7 @@ DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm, auto &MapEntry = getEntryImpl(Asm, Str); if (!MapEntry.getValue().isIndexed()) MapEntry.getValue().Index = NumIndexedStrings++; - return EntryRef(MapEntry, true); + return EntryRef(MapEntry); } void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm, @@ -55,7 +55,7 @@ void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSymbol *StartSym) { if (getNumIndexedStrings() == 0) return; - Asm.OutStreamer->SwitchSection(Section); + Asm.OutStreamer->switchSection(Section); unsigned EntrySize = Asm.getDwarfOffsetByteSize(); // We are emitting the header for a contribution to the string offsets // table. The header consists of an entry with the contribution's @@ -78,7 +78,7 @@ void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection, return; // Start the dwarf str section. - Asm.OutStreamer->SwitchSection(StrSection); + Asm.OutStreamer->switchSection(StrSection); // Get all of the string pool entries and sort them by their offset. SmallVector<const StringMapEntry<EntryTy> *, 64> Entries; @@ -117,7 +117,7 @@ void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection, Entries[Entry.getValue().Index] = &Entry; } - Asm.OutStreamer->SwitchSection(OffsetSection); + Asm.OutStreamer->switchSection(OffsetSection); unsigned size = Asm.getDwarfOffsetByteSize(); for (const auto &Entry : Entries) if (UseRelativeOffsets) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 5a2bd479f277..81238b0fe0d2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -17,12 +17,8 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/None.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetRegisterInfo.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalValue.h" @@ -32,9 +28,7 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MachineLocation.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include <cassert> #include <cstdint> @@ -380,6 +374,8 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, CU = getUnitDie().getUnit(); if (!EntryCU) EntryCU = getUnitDie().getUnit(); + assert(EntryCU == CU || !DD->useSplitDwarf() || DD->shareAcrossDWOCUs() || + !static_cast<const DwarfUnit*>(CU)->isDwoUnit()); addAttribute(Die, Attribute, EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr, Entry); @@ -596,10 +592,8 @@ DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE, // Skip updating the accelerator tables since this is not the full type. if (MDString *TypeId = CTy->getRawIdentifier()) DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); - else { - auto X = DD->enterNonTypeUnitContext(); + else finishNonUnitTypeDIE(TyDIE, CTy); - } return &TyDIE; } constructTypeDIE(TyDIE, CTy); @@ -805,7 +799,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { // or reference types. if (DTy->getDWARFAddressSpace()) addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, - DTy->getDWARFAddressSpace().getValue()); + *DTy->getDWARFAddressSpace()); } void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { @@ -1350,6 +1344,9 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, if (SP->isRecursive()) addFlag(SPDie, dwarf::DW_AT_recursive); + if (!SP->getTargetFuncName().empty()) + addString(SPDie, dwarf::DW_AT_trampoline, SP->getTargetFuncName()); + if (DD->getDwarfVersion() >= 5 && SP->isDeleted()) addFlag(SPDie, dwarf::DW_AT_deleted); } @@ -1442,7 +1439,8 @@ DIE *DwarfUnit::getIndexTyDie() { addString(*IndexTyDie, dwarf::DW_AT_name, Name); addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, None, sizeof(int64_t)); addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, - dwarf::DW_ATE_unsigned); + dwarf::getArrayIndexTypeEncoding( + (dwarf::SourceLanguage)getLanguage())); DD->addAccelType(*CUNode, Name, *IndexTyDie, /*Flags*/ 0); return IndexTyDie; } @@ -1847,11 +1845,5 @@ void DwarfUnit::addRnglistsBase() { } void DwarfTypeUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) { - addFlag(D, dwarf::DW_AT_declaration); - StringRef Name = CTy->getName(); - if (!Name.empty()) - addString(D, dwarf::DW_AT_name, Name); - if (Name.startswith("_STN") || !Name.contains('<')) - addTemplateParams(D, CTy->getTemplateParams()); - getCU().createTypeDIE(CTy); + DD->getAddressPool().resetUsedFlag(true); } diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp index 39f40b172c1b..31644959bdca 100644 --- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -19,7 +19,6 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" -#include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -458,7 +457,7 @@ MCSymbol *EHStreamer::emitExceptionTable() { // Sometimes we want not to emit the data into separate section (e.g. ARM // EHABI). In this case LSDASection will be NULL. if (LSDASection) - Asm->OutStreamer->SwitchSection(LSDASection); + Asm->OutStreamer->switchSection(LSDASection); Asm->emitAlignment(Align(4)); // Emit the LSDA. @@ -806,7 +805,7 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) { // Emit the Catch TypeInfos. if (VerboseAsm && !TypeInfos.empty()) { Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); - Asm->OutStreamer->AddBlankLine(); + Asm->OutStreamer->addBlankLine(); Entry = TypeInfos.size(); } @@ -821,7 +820,7 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) { // Emit the Exception Specifications. if (VerboseAsm && !FilterIds.empty()) { Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); - Asm->OutStreamer->AddBlankLine(); + Asm->OutStreamer->addBlankLine(); Entry = 0; } for (std::vector<unsigned>::const_iterator diff --git a/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp index 70777f07fc6c..62fd15d89512 100644 --- a/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp @@ -23,7 +23,6 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetLoweringObjectFile.h" using namespace llvm; @@ -46,9 +45,8 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info, unsigned IntPtrSize = M.getDataLayout().getPointerSize(); // Put this in a custom .note section. - OS.SwitchSection( - AP.getObjFileLowering().getContext().getELFSection(".note.gc", - ELF::SHT_PROGBITS, 0)); + OS.switchSection(AP.getObjFileLowering().getContext().getELFSection( + ".note.gc", ELF::SHT_PROGBITS, 0)); // For each function... for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(), diff --git a/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 3ade262d9af2..74fa30ab321b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -72,10 +72,10 @@ static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) { void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) { - AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getTextSection()); + AP.OutStreamer->switchSection(AP.getObjFileLowering().getTextSection()); EmitCamlGlobal(M, AP, "code_begin"); - AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection()); + AP.OutStreamer->switchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(M, AP, "data_begin"); } @@ -99,16 +99,16 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) { unsigned IntPtrSize = M.getDataLayout().getPointerSize(); - AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getTextSection()); + AP.OutStreamer->switchSection(AP.getObjFileLowering().getTextSection()); EmitCamlGlobal(M, AP, "code_end"); - AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection()); + AP.OutStreamer->switchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(M, AP, "data_end"); // FIXME: Why does ocaml emit this?? AP.OutStreamer->emitIntValue(0, IntPtrSize); - AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection()); + AP.OutStreamer->switchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(M, AP, "frametable"); int NumDescriptors = 0; @@ -147,7 +147,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AP.OutStreamer->AddComment("live roots for " + Twine(FI->getFunction().getName())); - AP.OutStreamer->AddBlankLine(); + AP.OutStreamer->addBlankLine(); for (GCFunctionInfo::iterator J = FI->begin(), JE = FI->end(); J != JE; ++J) { diff --git a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp index bab187f46535..135eabc34838 100644 --- a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp @@ -13,7 +13,7 @@ #include "PseudoProbePrinter.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/Module.h" +#include "llvm/IR/Function.h" #include "llvm/IR/PseudoProbe.h" #include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCStreamer.h" diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp index a17a2ca2790e..a514ff161cee 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "WasmException.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.h b/llvm/lib/CodeGen/AsmPrinter/WasmException.h index f06de786bd76..2abbe37cb6d9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WasmException.h +++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.h @@ -15,9 +15,12 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_WASMEXCEPTION_H #include "EHStreamer.h" -#include "llvm/CodeGen/AsmPrinter.h" namespace llvm { +class AsmPrinter; +class MachineFunction; +struct LandingPadInfo; +template <typename T> class SmallVectorImpl; class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer { public: diff --git a/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp b/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp index ad8432343a60..5d813b72c0b7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp @@ -15,11 +15,8 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineOperand.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Metadata.h" -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/IR/InstrTypes.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCStreamer.h" @@ -29,7 +26,7 @@ using namespace llvm; WinCFGuard::WinCFGuard(AsmPrinter *A) : Asm(A) {} -WinCFGuard::~WinCFGuard() {} +WinCFGuard::~WinCFGuard() = default; void WinCFGuard::endFunction(const MachineFunction *MF) { @@ -110,19 +107,19 @@ void WinCFGuard::endModule() { // Emit the symbol index of each GFIDs entry to form the .gfids section. auto &OS = *Asm->OutStreamer; - OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGFIDsSection()); + OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGFIDsSection()); for (const MCSymbol *S : GFIDsEntries) - OS.EmitCOFFSymbolIndex(S); + OS.emitCOFFSymbolIndex(S); // Emit the symbol index of each GIATs entry to form the .giats section. - OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGIATsSection()); + OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGIATsSection()); for (const MCSymbol *S : GIATsEntries) { - OS.EmitCOFFSymbolIndex(S); + OS.emitCOFFSymbolIndex(S); } // Emit the symbol index of each longjmp target to form the .gljmp section. - OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGLJMPSection()); + OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGLJMPSection()); for (const MCSymbol *S : LongjmpTargets) { - OS.EmitCOFFSymbolIndex(S); + OS.emitCOFFSymbolIndex(S); } } diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index ef57031c7294..c3ca9c92bf71 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -23,19 +23,13 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/CodeGen/WinEHFuncInfo.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" using namespace llvm; WinException::WinException(AsmPrinter *A) : EHStreamer(A) { @@ -46,7 +40,7 @@ WinException::WinException(AsmPrinter *A) : EHStreamer(A) { isThumb = Asm->TM.getTargetTriple().isThumb(); } -WinException::~WinException() {} +WinException::~WinException() = default; /// endModule - Emit all exception information that should come after the /// content. @@ -55,13 +49,13 @@ void WinException::endModule() { const Module *M = MMI->getModule(); for (const Function &F : *M) if (F.hasFnAttribute("safeseh")) - OS.EmitCOFFSafeSEH(Asm->getSymbol(&F)); + OS.emitCOFFSafeSEH(Asm->getSymbol(&F)); if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) { // Emit the symbol index of each ehcont target. - OS.SwitchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection()); + OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection()); for (const MCSymbol *S : EHContTargets) { - OS.EmitCOFFSymbolIndex(S); + OS.emitCOFFSymbolIndex(S); } } } @@ -122,7 +116,7 @@ void WinException::beginFunction(const MachineFunction *MF) { void WinException::markFunctionEnd() { if (isAArch64 && CurrentFuncletEntry && (shouldEmitMoves || shouldEmitPersonality)) - Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd(); + Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd(); } /// endFunction - Gather and emit post-function exception information. @@ -151,12 +145,12 @@ void WinException::endFunction(const MachineFunction *MF) { return; if (shouldEmitPersonality || shouldEmitLSDA) { - Asm->OutStreamer->PushSection(); + Asm->OutStreamer->pushSection(); // Just switch sections to the right xdata section. MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection( Asm->OutStreamer->getCurrentSectionOnly()); - Asm->OutStreamer->SwitchSection(XData); + Asm->OutStreamer->switchSection(XData); // Emit the tables appropriate to the personality function in use. If we // don't recognize the personality, assume it uses an Itanium-style LSDA. @@ -171,7 +165,7 @@ void WinException::endFunction(const MachineFunction *MF) { else emitExceptionTable(); - Asm->OutStreamer->PopSection(); + Asm->OutStreamer->popSection(); } if (!MF->getCatchretTargets().empty()) { @@ -211,11 +205,11 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, Sym = getMCSymbolForMBB(Asm, &MBB); // Describe our funclet symbol as a function with internal linkage. - Asm->OutStreamer->BeginCOFFSymbolDef(Sym); - Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); - Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION + Asm->OutStreamer->beginCOFFSymbolDef(Sym); + Asm->OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); + Asm->OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT); - Asm->OutStreamer->EndCOFFSymbolDef(); + Asm->OutStreamer->endCOFFSymbolDef(); // We want our funclet's entry point to be aligned such that no nops will be // present after the label. @@ -229,7 +223,7 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, // Mark 'Sym' as starting our funclet. if (shouldEmitMoves || shouldEmitPersonality) { CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly(); - Asm->OutStreamer->EmitWinCFIStartProc(Sym); + Asm->OutStreamer->emitWinCFIStartProc(Sym); } if (shouldEmitPersonality) { @@ -248,15 +242,15 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, // inliner doesn't allow inlining them, this isn't a major problem in // practice. if (!CurrentFuncletEntry->isCleanupFuncletEntry()) - Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true); + Asm->OutStreamer->emitWinEHHandler(PersHandlerSym, true, true); } } void WinException::endFunclet() { if (isAArch64 && CurrentFuncletEntry && (shouldEmitMoves || shouldEmitPersonality)) { - Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection); - Asm->OutStreamer->EmitWinCFIFuncletOrFuncEnd(); + Asm->OutStreamer->switchSection(CurrentFuncletTextSection); + Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd(); } endFuncletImpl(); } @@ -276,7 +270,7 @@ void WinException::endFuncletImpl() { if (Per == EHPersonality::MSVC_CXX && shouldEmitPersonality && !CurrentFuncletEntry->isCleanupFuncletEntry()) { // Emit an UNWIND_INFO struct describing the prologue. - Asm->OutStreamer->EmitWinEHHandlerData(); + Asm->OutStreamer->emitWinEHHandlerData(); // If this is a C++ catch funclet (or the parent function), // emit a reference to the LSDA for the parent function. @@ -287,14 +281,14 @@ void WinException::endFuncletImpl() { } else if (Per == EHPersonality::MSVC_TableSEH && MF->hasEHFunclets() && !CurrentFuncletEntry->isEHFuncletEntry()) { // Emit an UNWIND_INFO struct describing the prologue. - Asm->OutStreamer->EmitWinEHHandlerData(); + Asm->OutStreamer->emitWinEHHandlerData(); // If this is the parent function in Win64 SEH, emit the LSDA immediately // following .seh_handlerdata. emitCSpecificHandlerTable(MF); } else if (shouldEmitPersonality || shouldEmitLSDA) { // Emit an UNWIND_INFO struct describing the prologue. - Asm->OutStreamer->EmitWinEHHandlerData(); + Asm->OutStreamer->emitWinEHHandlerData(); // In these cases, no further info is written to the .xdata section // right here, but is written by e.g. emitExceptionTable in endFunction() // above. @@ -307,8 +301,8 @@ void WinException::endFuncletImpl() { // Switch back to the funclet start .text section now that we are done // writing to .xdata, and emit an .seh_endproc directive to mark the end of // the function. - Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection); - Asm->OutStreamer->EmitWinCFIEndProc(); + Asm->OutStreamer->switchSection(CurrentFuncletTextSection); + Asm->OutStreamer->emitWinCFIEndProc(); } // Let's make sure we don't try to end the same funclet twice. @@ -699,7 +693,12 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { } int UnwindHelpOffset = 0; - if (Asm->MAI->usesWindowsCFI()) + // TODO: The check for UnwindHelpFrameIdx against max() below (and the + // second check further below) can be removed if MS C++ unwinding is + // implemented for ARM, when test/CodeGen/ARM/Windows/wineh-basic.ll + // passes without the check. + if (Asm->MAI->usesWindowsCFI() && + FuncInfo.UnwindHelpFrameIdx != std::numeric_limits<int>::max()) UnwindHelpOffset = getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx, FuncInfo); @@ -761,7 +760,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { AddComment("IPToStateXData"); OS.emitValue(create32bitRef(IPToStateXData), 4); - if (Asm->MAI->usesWindowsCFI()) { + if (Asm->MAI->usesWindowsCFI() && + FuncInfo.UnwindHelpFrameIdx != std::numeric_limits<int>::max()) { AddComment("UnwindHelp"); OS.emitInt32(UnwindHelpOffset); } |
