diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 200 |
1 files changed, 99 insertions, 101 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 032f611f20e..5cff7abaa44 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -83,7 +83,7 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { if (Insertion.second) { // We have to compute the full filepath and emit a .cv_file directive. StringRef FullPath = getFullFilepath(F); - NextId = Asm->OutStreamer->EmitCVFileDirective(NextId, FullPath); + NextId = OS.EmitCVFileDirective(NextId, FullPath); assert(NextId == FileIdMap.size() && ".cv_file directive failed"); } return Insertion.first->second; @@ -150,24 +150,25 @@ void CodeViewDebug::maybeRecordLocation(DebugLoc DL, } } - Asm->OutStreamer->EmitCVLocDirective(FuncId, FileId, DL.getLine(), - DL.getCol(), /*PrologueEnd=*/false, - /*IsStmt=*/false, DL->getFilename()); + OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(), + /*PrologueEnd=*/false, + /*IsStmt=*/false, DL->getFilename()); } CodeViewDebug::CodeViewDebug(AsmPrinter *AP) - : Asm(nullptr), CurFn(nullptr) { + : Asm(AP), OS(*Asm->OutStreamer), CurFn(nullptr) { MachineModuleInfo *MMI = AP->MMI; // If module doesn't have named metadata anchors or COFF debug section // is not available, skip any debug info related stuff. if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") || - !AP->getObjFileLowering().getCOFFDebugSymbolsSection()) + !AP->getObjFileLowering().getCOFFDebugSymbolsSection()) { + Asm = nullptr; return; + } // Tell MMI that we have debug info. MMI->setDebugInfoAvailability(true); - Asm = AP; } void CodeViewDebug::endModule() { @@ -180,10 +181,9 @@ void CodeViewDebug::endModule() { // sections that are comdat associative with the main function instead of // having one big .debug$S section. assert(Asm != nullptr); - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getCOFFDebugSymbolsSection()); - Asm->OutStreamer->AddComment("Debug section magic"); - Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC); + OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugSymbolsSection()); + OS.AddComment("Debug section magic"); + OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4); // The COFF .debug$S section consists of several subsections, each starting // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length @@ -198,22 +198,21 @@ void CodeViewDebug::endModule() { emitDebugInfoForFunction(P.first, P.second); // This subsection holds a file index to offset in string table table. - Asm->OutStreamer->AddComment("File index to string table offset subsection"); - Asm->OutStreamer->EmitCVFileChecksumsDirective(); + OS.AddComment("File index to string table offset subsection"); + OS.EmitCVFileChecksumsDirective(); // This subsection holds the string table. - Asm->OutStreamer->AddComment("String table"); - Asm->OutStreamer->EmitCVStringTableDirective(); + OS.AddComment("String table"); + OS.EmitCVStringTableDirective(); clear(); } void CodeViewDebug::emitTypeInformation() { // Start the .debug$T section with 0x4. - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getCOFFDebugTypesSection()); - Asm->OutStreamer->AddComment("Debug section magic"); - Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC); + OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); + OS.AddComment("Debug section magic"); + OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4); NamedMDNode *CU_Nodes = Asm->MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); @@ -224,48 +223,48 @@ void CodeViewDebug::emitTypeInformation() { // frame info. All functions are assigned a simple 'void ()' type. Emit that // type here. TypeIndex ArgListIdx = getNextTypeIndex(); - Asm->OutStreamer->AddComment("Type record length"); - Asm->EmitInt16(2 + sizeof(ArgList)); - Asm->OutStreamer->AddComment("Leaf type: LF_ARGLIST"); - Asm->EmitInt16(LF_ARGLIST); - Asm->OutStreamer->AddComment("Number of arguments"); - Asm->EmitInt32(0); + OS.AddComment("Type record length"); + OS.EmitIntValue(2 + sizeof(ArgList), 2); + OS.AddComment("Leaf type: LF_ARGLIST"); + OS.EmitIntValue(LF_ARGLIST, 2); + OS.AddComment("Number of arguments"); + OS.EmitIntValue(0, 4); TypeIndex VoidProcIdx = getNextTypeIndex(); - Asm->OutStreamer->AddComment("Type record length"); - Asm->EmitInt16(2 + sizeof(ProcedureType)); - Asm->OutStreamer->AddComment("Leaf type: LF_PROCEDURE"); - Asm->EmitInt16(LF_PROCEDURE); - Asm->OutStreamer->AddComment("Return type index"); - Asm->EmitInt32(TypeIndex::Void().getIndex()); - Asm->OutStreamer->AddComment("Calling convention"); - Asm->EmitInt8(char(CallingConvention::NearC)); - Asm->OutStreamer->AddComment("Function options"); - Asm->EmitInt8(char(FunctionOptions::None)); - Asm->OutStreamer->AddComment("# of parameters"); - Asm->EmitInt16(0); - Asm->OutStreamer->AddComment("Argument list type index"); - Asm->EmitInt32(ArgListIdx.getIndex()); + OS.AddComment("Type record length"); + OS.EmitIntValue(2 + sizeof(ProcedureType), 2); + OS.AddComment("Leaf type: LF_PROCEDURE"); + OS.EmitIntValue(LF_PROCEDURE, 2); + OS.AddComment("Return type index"); + OS.EmitIntValue(TypeIndex::Void().getIndex(), 4); + OS.AddComment("Calling convention"); + OS.EmitIntValue(char(CallingConvention::NearC), 1); + OS.AddComment("Function options"); + OS.EmitIntValue(char(FunctionOptions::None), 1); + OS.AddComment("# of parameters"); + OS.EmitIntValue(0, 2); + OS.AddComment("Argument list type index"); + OS.EmitIntValue(ArgListIdx.getIndex(), 4); for (MDNode *N : CU_Nodes->operands()) { auto *CUNode = cast<DICompileUnit>(N); for (auto *SP : CUNode->getSubprograms()) { StringRef DisplayName = SP->getDisplayName(); - Asm->OutStreamer->AddComment("Type record length"); - Asm->EmitInt16(2 + sizeof(FuncId) + DisplayName.size() + 1); - Asm->OutStreamer->AddComment("Leaf type: LF_FUNC_ID"); - Asm->EmitInt16(LF_FUNC_ID); - - Asm->OutStreamer->AddComment("Scope type index"); - Asm->EmitInt32(TypeIndex().getIndex()); - Asm->OutStreamer->AddComment("Function type"); - Asm->EmitInt32(VoidProcIdx.getIndex()); + OS.AddComment("Type record length"); + OS.EmitIntValue(2 + sizeof(FuncId) + DisplayName.size() + 1, 2); + OS.AddComment("Leaf type: LF_FUNC_ID"); + OS.EmitIntValue(LF_FUNC_ID, 2); + + OS.AddComment("Scope type index"); + OS.EmitIntValue(TypeIndex().getIndex(), 4); + OS.AddComment("Function type"); + OS.EmitIntValue(VoidProcIdx.getIndex(), 4); { SmallString<32> NullTerminatedString(DisplayName); if (NullTerminatedString.empty() || NullTerminatedString.back() != '\0') NullTerminatedString.push_back('\0'); - Asm->OutStreamer->AddComment("Function name"); - Asm->OutStreamer->EmitBytes(NullTerminatedString); + OS.AddComment("Function name"); + OS.EmitBytes(NullTerminatedString); } TypeIndex FuncIdIdx = getNextTypeIndex(); @@ -278,7 +277,6 @@ void CodeViewDebug::emitInlineeLinesSubsection() { if (InlinedSubprograms.empty()) return; - MCStreamer &OS = *Asm->OutStreamer; MCSymbol *InlineBegin = Asm->MMI->getContext().createTempSymbol(), *InlineEnd = Asm->MMI->getContext().createTempSymbol(); @@ -350,18 +348,18 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, TypeIndex InlineeIdx = SubprogramToFuncId[Site.Inlinee]; // SymbolRecord - Asm->OutStreamer->AddComment("Record length"); + OS.AddComment("Record length"); EmitLabelDiff(OS, InlineBegin, InlineEnd, 2); // RecordLength OS.EmitLabel(InlineBegin); - Asm->OutStreamer->AddComment("Record kind: S_INLINESITE"); - Asm->EmitInt16(SymbolRecordKind::S_INLINESITE); // RecordKind + OS.AddComment("Record kind: S_INLINESITE"); + OS.EmitIntValue(SymbolRecordKind::S_INLINESITE, 2); // RecordKind - Asm->OutStreamer->AddComment("PtrParent"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("PtrEnd"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("Inlinee type index"); - Asm->EmitInt32(InlineeIdx.getIndex()); + OS.AddComment("PtrParent"); + OS.EmitIntValue(0, 4); + OS.AddComment("PtrEnd"); + OS.EmitIntValue(0, 4); + OS.AddComment("Inlinee type index"); + OS.EmitIntValue(InlineeIdx.getIndex(), 4); unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); unsigned StartLineNum = Site.Inlinee->getLine(); @@ -382,10 +380,10 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, } // Close the scope. - Asm->OutStreamer->AddComment("Record length"); - Asm->EmitInt16(2); // RecordLength - Asm->OutStreamer->AddComment("Record kind: S_INLINESITE_END"); - Asm->EmitInt16(SymbolRecordKind::S_INLINESITE_END); // RecordKind + OS.AddComment("Record length"); + OS.EmitIntValue(2, 2); // RecordLength + OS.AddComment("Record kind: S_INLINESITE_END"); + OS.EmitIntValue(SymbolRecordKind::S_INLINESITE_END, 2); // RecordKind } void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, @@ -406,53 +404,53 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, // Emit a symbol subsection, required by VS2012+ to find function boundaries. MCSymbol *SymbolsBegin = Asm->MMI->getContext().createTempSymbol(), *SymbolsEnd = Asm->MMI->getContext().createTempSymbol(); - Asm->OutStreamer->AddComment("Symbol subsection for " + Twine(FuncName)); - Asm->EmitInt32(unsigned(ModuleSubstreamKind::Symbols)); - Asm->OutStreamer->AddComment("Subsection size"); + OS.AddComment("Symbol subsection for " + Twine(FuncName)); + OS.EmitIntValue(unsigned(ModuleSubstreamKind::Symbols), 4); + OS.AddComment("Subsection size"); EmitLabelDiff(*Asm->OutStreamer, SymbolsBegin, SymbolsEnd); - Asm->OutStreamer->EmitLabel(SymbolsBegin); + OS.EmitLabel(SymbolsBegin); { MCSymbol *ProcRecordBegin = Asm->MMI->getContext().createTempSymbol(), *ProcRecordEnd = Asm->MMI->getContext().createTempSymbol(); - Asm->OutStreamer->AddComment("Record length"); + OS.AddComment("Record length"); EmitLabelDiff(*Asm->OutStreamer, ProcRecordBegin, ProcRecordEnd, 2); - Asm->OutStreamer->EmitLabel(ProcRecordBegin); + OS.EmitLabel(ProcRecordBegin); - Asm->OutStreamer->AddComment("Record kind: S_GPROC32_ID"); - Asm->EmitInt16(unsigned(SymbolRecordKind::S_GPROC32_ID)); + OS.AddComment("Record kind: S_GPROC32_ID"); + OS.EmitIntValue(unsigned(SymbolRecordKind::S_GPROC32_ID), 2); // These fields are filled in by tools like CVPACK which run after the fact. - Asm->OutStreamer->AddComment("PtrParent"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("PtrEnd"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("PtrNext"); - Asm->OutStreamer->EmitIntValue(0, 4); + OS.AddComment("PtrParent"); + OS.EmitIntValue(0, 4); + OS.AddComment("PtrEnd"); + OS.EmitIntValue(0, 4); + OS.AddComment("PtrNext"); + OS.EmitIntValue(0, 4); // This is the important bit that tells the debugger where the function // code is located and what's its size: - Asm->OutStreamer->AddComment("Code size"); + OS.AddComment("Code size"); EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End); - Asm->OutStreamer->AddComment("Offset after prologue"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("Offset before epilogue"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("Function type index"); - Asm->OutStreamer->EmitIntValue(0, 4); - Asm->OutStreamer->AddComment("Function section relative address"); - Asm->OutStreamer->EmitCOFFSecRel32(Fn); - Asm->OutStreamer->AddComment("Function section index"); - Asm->OutStreamer->EmitCOFFSectionIndex(Fn); - Asm->OutStreamer->AddComment("Flags"); - Asm->EmitInt8(0); + OS.AddComment("Offset after prologue"); + OS.EmitIntValue(0, 4); + OS.AddComment("Offset before epilogue"); + OS.EmitIntValue(0, 4); + OS.AddComment("Function type index"); + OS.EmitIntValue(0, 4); + OS.AddComment("Function section relative address"); + OS.EmitCOFFSecRel32(Fn); + OS.AddComment("Function section index"); + OS.EmitCOFFSectionIndex(Fn); + OS.AddComment("Flags"); + OS.EmitIntValue(0, 1); // Emit the function display name as a null-terminated string. - Asm->OutStreamer->AddComment("Function name"); + OS.AddComment("Function name"); { SmallString<32> NullTerminatedString(FuncName); if (NullTerminatedString.empty() || NullTerminatedString.back() != '\0') NullTerminatedString.push_back('\0'); - Asm->OutStreamer->EmitBytes(NullTerminatedString); + OS.EmitBytes(NullTerminatedString); } - Asm->OutStreamer->EmitLabel(ProcRecordEnd); + OS.EmitLabel(ProcRecordEnd); // Emit inlined call site information. Only emit functions inlined directly // into the parent function. We'll emit the other sites recursively as part @@ -464,17 +462,17 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, } // We're done with this function. - Asm->OutStreamer->AddComment("Record length"); - Asm->EmitInt16(0x0002); - Asm->OutStreamer->AddComment("Record kind: S_PROC_ID_END"); - Asm->EmitInt16(unsigned(SymbolRecordKind::S_PROC_ID_END)); + OS.AddComment("Record length"); + OS.EmitIntValue(0x0002, 2); + OS.AddComment("Record kind: S_PROC_ID_END"); + OS.EmitIntValue(unsigned(SymbolRecordKind::S_PROC_ID_END), 2); } - Asm->OutStreamer->EmitLabel(SymbolsEnd); + OS.EmitLabel(SymbolsEnd); // Every subsection must be aligned to a 4-byte boundary. - Asm->OutStreamer->EmitValueToAlignment(4); + OS.EmitValueToAlignment(4); // We have an assembler directive that takes care of the whole line table. - Asm->OutStreamer->EmitCVLinetableDirective(FI.FuncId, Fn, FI.End); + OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End); } void CodeViewDebug::beginFunction(const MachineFunction *MF) { |