[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