From a769999502695a037b2d7840484e0fdd416acfe9 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 28 Apr 2017 23:41:36 +0000 Subject: [PATCH] [llvm-readobj] Use LLVMDebugInfoCodeView to parse line tables. The llvm-readobj parsing code currently exists in our CodeView library, so we use that to parse instead of re-writing the logic in the tool. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301718 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp | 3 -- tools/llvm-readobj/COFFDumper.cpp | 71 +++++++++----------------- 2 files changed, 23 insertions(+), 51 deletions(-) diff --git a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp index 56e415a3d54..e5eb01d5f52 100644 --- a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -73,9 +73,6 @@ Error ModuleDebugStream::reload() { iterator_range ModuleDebugStream::symbols(bool *HadError) const { - // It's OK if the stream is empty. - if (SymbolsSubstream.getUnderlyingStream().getLength() == 0) - return make_range(SymbolsSubstream.end(), SymbolsSubstream.end()); return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); } diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 4d8ebecae17..ac28c1a7cb8 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -26,6 +26,7 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" @@ -39,11 +40,12 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" @@ -892,45 +894,28 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, ListScope S(W, "FunctionLineTable"); W.printString("LinkageName", Name); - DataExtractor DE(FunctionLineTables[Name], true, 4); - uint32_t Offset = 6; // Skip relocations. - uint16_t Flags = DE.getU16(&Offset); - W.printHex("Flags", Flags); - bool HasColumnInformation = Flags & codeview::LineFlags::HaveColumns; - uint32_t FunctionSize = DE.getU32(&Offset); - W.printHex("CodeSize", FunctionSize); - while (DE.isValidOffset(Offset)) { - // For each range of lines with the same filename, we have a segment - // in the line table. The filename string is accessed using double - // indirection to the string table subsection using the index subsection. - uint32_t OffsetInIndex = DE.getU32(&Offset), - NumLines = DE.getU32(&Offset), - FullSegmentSize = DE.getU32(&Offset); - - uint32_t ColumnOffset = Offset + 8 * NumLines; - DataExtractor ColumnDE(DE.getData(), true, 4); - - if (FullSegmentSize != - 12 + 8 * NumLines + (HasColumnInformation ? 4 * NumLines : 0)) { - error(object_error::parse_failed); - return; - } + BinaryByteStream LineTableInfo(FunctionLineTables[Name], support::little); + BinaryStreamReader Reader(LineTableInfo); + + ModuleDebugLineFragment LineInfo; + error(LineInfo.initialize(Reader)); + + W.printHex("Flags", LineInfo.header()->Flags); + W.printHex("CodeSize", LineInfo.header()->CodeSize); + for (const auto &Entry : LineInfo) { ListScope S(W, "FilenameSegment"); - printFileNameForOffset("Filename", OffsetInIndex); - for (unsigned LineIdx = 0; - LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { - // Then go the (PC, LineNumber) pairs. The line number is stored in the - // least significant 31 bits of the respective word in the table. - uint32_t PC = DE.getU32(&Offset), LineData = DE.getU32(&Offset); - if (PC >= FunctionSize) { + printFileNameForOffset("Filename", Entry.NameIndex); + for (const auto &Line : Entry.LineNumbers) { + if (Line.Offset >= LineInfo.header()->CodeSize) { error(object_error::parse_failed); return; } - char Buffer[32]; - format("+0x%X", PC).snprint(Buffer, 32); - ListScope PCScope(W, Buffer); - LineInfo LI(LineData); + + std::string PC = formatv("+{0:X}", uint32_t(Line.Offset)); + ListScope PCScope(W, PC); + codeview::LineInfo LI(Line.Flags); + if (LI.isAlwaysStepInto()) W.printString("StepInto", StringRef("Always")); else if (LI.isNeverStepInto()) @@ -939,19 +924,9 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, W.printNumber("LineNumberStart", LI.getStartLine()); W.printNumber("LineNumberEndDelta", LI.getLineDelta()); W.printBoolean("IsStatement", LI.isStatement()); - if (HasColumnInformation && - ColumnDE.isValidOffsetForDataOfSize(ColumnOffset, 4)) { - uint16_t ColStart = ColumnDE.getU16(&ColumnOffset); - W.printNumber("ColStart", ColStart); - uint16_t ColEnd = ColumnDE.getU16(&ColumnOffset); - W.printNumber("ColEnd", ColEnd); - } - } - // Skip over the column data. - if (HasColumnInformation) { - for (unsigned LineIdx = 0; - LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { - DE.getU32(&Offset); + if (LineInfo.header()->Flags & HaveColumns) { + W.printNumber("ColStart", Entry.Columns[0].StartColumn); + W.printNumber("ColEnd", Entry.Columns[0].EndColumn); } } } -- 2.11.0