diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 123 |
1 files changed, 59 insertions, 64 deletions
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); |
