[llvm] r257846 - [codeview] Translate file table offsets to filenames and print them
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 14 16:11:22 PST 2016
Author: rnk
Date: Thu Jan 14 18:11:21 2016
New Revision: 257846
URL: http://llvm.org/viewvc/llvm-project?rev=257846&view=rev
Log:
[codeview] Translate file table offsets to filenames and print them
Modified:
llvm/trunk/test/tools/llvm-readobj/codeview-inlining.test
llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
Modified: llvm/trunk/test/tools/llvm-readobj/codeview-inlining.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/codeview-inlining.test?rev=257846&r1=257845&r2=257846&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/codeview-inlining.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/codeview-inlining.test Thu Jan 14 18:11:21 2016
@@ -38,7 +38,7 @@ RUN: llvm-readobj -s -codeview -section-
; CHECK-NEXT: SubSectionSize: 0x3C
; CHECK-NEXT: InlineeSourceLine {
; CHECK-NEXT: Inlinee: bar (0x1002)
-; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: FileID: d:\src\llvm\build\t.cpp (0x30)
; CHECK-NEXT: SourceLineNum: 2
; CHECK-NEXT: ExtraFileCount: 0
; CHECK-NEXT: ExtraFiles [
@@ -46,7 +46,7 @@ RUN: llvm-readobj -s -codeview -section-
; CHECK-NEXT: }
; CHECK-NEXT: InlineeSourceLine {
; CHECK-NEXT: Inlinee: baz (0x1003)
-; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: FileID: d:\src\llvm\build\t.cpp (0x30)
; CHECK-NEXT: SourceLineNum: 5
; CHECK-NEXT: ExtraFileCount: 0
; CHECK-NEXT: ExtraFiles [
@@ -55,11 +55,11 @@ RUN: llvm-readobj -s -codeview -section-
; The 'foo' inline site has extra files due to includes.
; CHECK-NEXT: InlineeSourceLine {
; CHECK-NEXT: Inlinee: foo (0x1004)
-; CHECK-NEXT: FileID: 0x0
+; CHECK-NEXT: FileID: d:\src\llvm\build\a.h (0x0)
; CHECK-NEXT: SourceLineNum: 1
; CHECK-NEXT: ExtraFileCount: 2
; CHECK-NEXT: ExtraFiles [
-; CHECK-NEXT: FileID: 0x18
-; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: FileID: d:\src\llvm\build\b.h (0x18)
+; CHECK-NEXT: FileID: d:\src\llvm\build\t.cpp (0x30)
; CHECK-NEXT: ]
; CHECK-NEXT: }
Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=257846&r1=257845&r2=257846&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Thu Jan 14 18:11:21 2016
@@ -86,6 +86,8 @@ private:
void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
void printCodeViewFieldList(StringRef FieldData);
StringRef getTypeName(TypeIndex Ty);
+ StringRef getFileNameForFileOffset(uint32_t FileOffset);
+ void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
void printTypeIndex(StringRef FieldName, TypeIndex TI);
void printCodeViewSymbolsSubsection(StringRef Subsection,
@@ -103,6 +105,9 @@ private:
void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec,
StringRef SectionContents, StringRef Block);
+ /// Given a .debug$S section, find the string table and file checksum table.
+ void initializeFileAndStringTables(StringRef Data);
+
void cacheRelocations();
std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
@@ -122,7 +127,7 @@ private:
const llvm::object::COFFObjectFile *Obj;
bool RelocCached = false;
RelocMapTy RelocMap;
- StringRef CVFileIndexToStringOffsetTable;
+ StringRef CVFileChecksumTable;
StringRef CVStringTable;
/// All user defined type records in .debug$T live in here. Type indices
@@ -942,6 +947,30 @@ static std::error_code consumeUInt32(Str
return std::error_code();
}
+void COFFDumper::initializeFileAndStringTables(StringRef Data) {
+ while (!Data.empty() && (CVFileChecksumTable.data() == nullptr ||
+ CVStringTable.data() == nullptr)) {
+ // The section consists of a number of subsection in the following format:
+ // |SubSectionType|SubSectionSize|Contents...|
+ uint32_t SubType, SubSectionSize;
+ error(consumeUInt32(Data, SubType));
+ error(consumeUInt32(Data, SubSectionSize));
+ if (SubSectionSize > Data.size())
+ return error(object_error::parse_failed);
+ switch (ModuleSubstreamKind(SubType)) {
+ case ModuleSubstreamKind::FileChecksums:
+ CVFileChecksumTable = Data.substr(0, SubSectionSize);
+ break;
+ case ModuleSubstreamKind::StringTable:
+ CVStringTable = Data.substr(0, SubSectionSize);
+ break;
+ default:
+ break;
+ }
+ Data = Data.drop_front(alignTo(SubSectionSize, 4));
+ }
+}
+
void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
const SectionRef &Section) {
StringRef SectionContents;
@@ -962,6 +991,8 @@ void COFFDumper::printCodeViewSymbolSect
if (Magic != COFF::DEBUG_SECTION_MAGIC)
return error(object_error::parse_failed);
+ initializeFileAndStringTables(Data);
+
while (!Data.empty()) {
// The section consists of a number of subsection in the following format:
// |SubSectionType|SubSectionSize|Contents...|
@@ -1025,27 +1056,6 @@ void COFFDumper::printCodeViewSymbolSect
FunctionNames.push_back(LinkageName);
break;
}
- case ModuleSubstreamKind::StringTable:
- if (SubSectionSize == 0 || CVStringTable.data() != nullptr ||
- Contents.back() != '\0') {
- // Empty or duplicate or non-null-terminated subsection.
- error(object_error::parse_failed);
- return;
- }
- CVStringTable = Contents;
- break;
- case ModuleSubstreamKind::FileChecksums:
- // Holds the translation table from file indices
- // to offsets in the string table.
-
- if (SubSectionSize == 0 ||
- CVFileIndexToStringOffsetTable.data() != nullptr) {
- // Empty or duplicate subsection.
- error(object_error::parse_failed);
- return;
- }
- CVFileIndexToStringOffsetTable = Contents;
- break;
case ModuleSubstreamKind::FrameData: {
const size_t RelocationSize = 4;
if (SubSectionSize != sizeof(FrameData) + RelocationSize) {
@@ -1106,28 +1116,8 @@ void COFFDumper::printCodeViewSymbolSect
return;
}
- uint32_t FilenameOffset;
- {
- DataExtractor SDE(CVFileIndexToStringOffsetTable, true, 4);
- uint32_t OffsetInSDE = OffsetInIndex;
- if (!SDE.isValidOffset(OffsetInSDE)) {
- error(object_error::parse_failed);
- return;
- }
- FilenameOffset = SDE.getU32(&OffsetInSDE);
- }
-
- if (FilenameOffset == 0 || FilenameOffset + 1 >= CVStringTable.size() ||
- CVStringTable.data()[FilenameOffset - 1] != '\0') {
- // Each string in an F3 subsection should be preceded by a null
- // character.
- error(object_error::parse_failed);
- return;
- }
-
- StringRef Filename(CVStringTable.data() + FilenameOffset);
ListScope S(W, "FilenameSegment");
- W.printString("Filename", Filename);
+ 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
@@ -1453,10 +1443,10 @@ void COFFDumper::printCodeViewSymbolsSub
break;
case ChangeCodeOffsetAndLineOffset: {
uint32_t Annotation = GetCompressedAnnotation();
- uint32_t SourceDelta = Annotation >> 4;
+ int32_t LineOffset = DecodeSignedOperand(Annotation >> 4);
uint32_t CodeOffset = Annotation & 0xf;
- W.startLine() << "ChangeCodeOffsetAndLineOffset: {SourceDelta: "
- << SourceDelta << ", CodeOffset: " << W.hex(CodeOffset)
+ W.startLine() << "ChangeCodeOffsetAndLineOffset: {LineOffset: "
+ << LineOffset << ", CodeOffset: " << W.hex(CodeOffset)
<< "}\n";
break;
}
@@ -1722,7 +1712,7 @@ void COFFDumper::printCodeViewInlineeLin
error(consumeObject(Data, ISL));
DictScope S(W, "InlineeSourceLine");
printTypeIndex("Inlinee", ISL->Inlinee);
- W.printHex("FileID", ISL->FileID);
+ printFileNameForOffset("FileID", ISL->FileID);
W.printNumber("SourceLineNum", ISL->SourceLineNum);
if (HasExtraFiles) {
@@ -1733,7 +1723,7 @@ void COFFDumper::printCodeViewInlineeLin
for (unsigned I = 0; I < ExtraFileCount; ++I) {
uint32_t FileID;
error(consumeUInt32(Data, FileID));
- W.printHex("FileID", FileID);
+ printFileNameForOffset("FileID", FileID);
}
}
}
@@ -1792,6 +1782,31 @@ void COFFDumper::printTypeIndex(StringRe
W.printHex(FieldName, TI.getIndex());
}
+StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) {
+ // The file checksum subsection should precede all references to it.
+ if (!CVFileChecksumTable.data() || !CVStringTable.data())
+ error(object_error::parse_failed);
+ // Check if the file checksum table offset is valid.
+ if (FileOffset >= CVFileChecksumTable.size())
+ error(object_error::parse_failed);
+
+ // The string table offset comes first before the file checksum.
+ StringRef Data = CVFileChecksumTable.drop_front(FileOffset);
+ uint32_t StringOffset;
+ error(consumeUInt32(Data, StringOffset));
+
+ // Check if the string table offset is valid.
+ if (StringOffset >= CVStringTable.size())
+ error(object_error::parse_failed);
+
+ // Return the null-terminated string.
+ return CVStringTable.drop_front(StringOffset).split('\0').first;
+}
+
+void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {
+ W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset);
+}
+
static StringRef getLeafTypeName(TypeLeafKind LT) {
switch (LT) {
case LF_STRING_ID: return "StringId";
More information about the llvm-commits
mailing list