[llvm] r302052 - [llvm-readobj] Update readobj to re-use parsing code.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 10:11:12 PDT 2017


Author: zturner
Date: Wed May  3 12:11:11 2017
New Revision: 302052

URL: http://llvm.org/viewvc/llvm-project?rev=302052&view=rev
Log:
[llvm-readobj] Update readobj to re-use parsing code.

llvm-readobj hand rolls some CodeView parsing code for string
tables, so this patch updates it to re-use some of the newly
introduced parsing code in LLVMDebugInfoCodeView.

Differential Revision: https://reviews.llvm.org/D32772

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/StringTable.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
    llvm/trunk/include/llvm/Support/BinaryStreamRef.h
    llvm/trunk/lib/DebugInfo/CodeView/StringTable.cpp
    llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
    llvm/trunk/tools/llvm-pdbdump/Diff.cpp
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/tools/llvm-readobj/llvm-readobj.h
    llvm/trunk/unittests/DebugInfo/PDB/ErrorChecking.h
    llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/StringTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StringTable.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StringTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StringTable.h Wed May  3 12:11:11 2017
@@ -34,9 +34,11 @@ class StringTableRef {
 public:
   StringTableRef();
 
-  Error initialize(BinaryStreamReader &Stream);
+  Error initialize(BinaryStreamRef Contents);
 
-  StringRef getString(uint32_t Offset) const;
+  Expected<StringRef> getString(uint32_t Offset) const;
+
+  bool valid() const { return Stream.valid(); }
 
 private:
   BinaryStreamRef Stream;

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h Wed May  3 12:11:11 2017
@@ -19,13 +19,15 @@ class BinaryStreamReader;
 
 namespace codeview {
 
+class StringTableRef;
+
 class SymbolVisitorDelegate {
 public:
   virtual ~SymbolVisitorDelegate() = default;
 
   virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
   virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
-  virtual StringRef getStringTable() = 0;
+  virtual StringTableRef getStringTable() = 0;
 };
 
 } // end namespace codeview

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h Wed May  3 12:11:11 2017
@@ -1,5 +1,4 @@
-//===- PDBStringTable.h - PDB String Table -------------------------*- C++
-//-*-===//
+//===- PDBStringTable.h - PDB String Table -----------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -41,8 +40,8 @@ public:
   uint32_t getHashVersion() const;
   uint32_t getSignature() const;
 
-  StringRef getStringForID(uint32_t ID) const;
-  uint32_t getIDForString(StringRef Str) const;
+  Expected<StringRef> getStringForID(uint32_t ID) const;
+  Expected<uint32_t> getIDForString(StringRef Str) const;
 
   FixedStreamArray<support::ulittle32_t> name_ids() const;
 

Modified: llvm/trunk/include/llvm/Support/BinaryStreamRef.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BinaryStreamRef.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/BinaryStreamRef.h (original)
+++ llvm/trunk/include/llvm/Support/BinaryStreamRef.h Wed May  3 12:11:11 2017
@@ -98,6 +98,9 @@ public:
   BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
                   uint32_t Length) = delete;
 
+  /// Check if a Stream is valid.
+  bool valid() const { return Stream != nullptr; }
+
   /// Given an Offset into this StreamRef and a Size, return a reference to a
   /// buffer owned by the stream.
   ///

Modified: llvm/trunk/lib/DebugInfo/CodeView/StringTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/StringTable.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/StringTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/StringTable.cpp Wed May  3 12:11:11 2017
@@ -18,17 +18,17 @@ using namespace llvm::codeview;
 
 StringTableRef::StringTableRef() {}
 
-Error StringTableRef::initialize(BinaryStreamReader &Reader) {
-  return Reader.readStreamRef(Stream, Reader.bytesRemaining());
+Error StringTableRef::initialize(BinaryStreamRef Contents) {
+  Stream = Contents;
+  return Error::success();
 }
 
-StringRef StringTableRef::getString(uint32_t Offset) const {
+Expected<StringRef> StringTableRef::getString(uint32_t Offset) const {
   BinaryStreamReader Reader(Stream);
   Reader.setOffset(Offset);
   StringRef Result;
-  Error EC = Reader.readCString(Result);
-  assert(!EC);
-  consumeError(std::move(EC));
+  if (auto EC = Reader.readCString(Result))
+    return std::move(EC);
   return Result;
 }
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp Wed May  3 12:11:11 2017
@@ -13,6 +13,7 @@
 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
 #include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/StringTable.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -369,14 +370,14 @@ Error CVSymbolDumperImpl::visitKnownReco
   DictScope S(W, "DefRangeSubfield");
 
   if (ObjDelegate) {
-    StringRef StringTable = ObjDelegate->getStringTable();
-    auto ProgramStringTableOffset = DefRangeSubfield.Program;
-    if (ProgramStringTableOffset >= StringTable.size())
+    StringTableRef Strings = ObjDelegate->getStringTable();
+    auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
+    if (!ExpectedProgram) {
+      consumeError(ExpectedProgram.takeError());
       return llvm::make_error<CodeViewError>(
           "String table offset outside of bounds of String Table!");
-    StringRef Program =
-        StringTable.drop_front(ProgramStringTableOffset).split('\0').first;
-    W.printString("Program", Program);
+    }
+    W.printString("Program", *ExpectedProgram);
   }
   W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
   printLocalVariableAddrRange(DefRangeSubfield.Range,
@@ -390,14 +391,14 @@ Error CVSymbolDumperImpl::visitKnownReco
   DictScope S(W, "DefRange");
 
   if (ObjDelegate) {
-    StringRef StringTable = ObjDelegate->getStringTable();
-    auto ProgramStringTableOffset = DefRange.Program;
-    if (ProgramStringTableOffset >= StringTable.size())
+    StringTableRef Strings = ObjDelegate->getStringTable();
+    auto ExpectedProgram = Strings.getString(DefRange.Program);
+    if (!ExpectedProgram) {
+      consumeError(ExpectedProgram.takeError());
       return llvm::make_error<CodeViewError>(
           "String table offset outside of bounds of String Table!");
-    StringRef Program =
-        StringTable.drop_front(ProgramStringTableOffset).split('\0').first;
-    W.printString("Program", Program);
+    }
+    W.printString("Program", *ExpectedProgram);
   }
   printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
   printLocalVariableAddrGap(DefRange.Gaps);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp Wed May  3 12:11:11 2017
@@ -42,7 +42,11 @@ Error PDBStringTable::readHeader(BinaryS
 }
 
 Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
-  if (auto EC = Strings.initialize(Reader)) {
+  BinaryStreamRef Stream;
+  if (auto EC = Reader.readStreamRef(Stream))
+    return EC;
+
+  if (auto EC = Strings.initialize(Stream)) {
     return joinErrors(std::move(EC),
                       make_error<RawError>(raw_error_code::corrupt_file,
                                            "Invalid hash table byte length"));
@@ -99,11 +103,11 @@ Error PDBStringTable::reload(BinaryStrea
   return Error::success();
 }
 
-StringRef PDBStringTable::getStringForID(uint32_t ID) const {
+Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
   return Strings.getString(ID);
 }
 
-uint32_t PDBStringTable::getIDForString(StringRef Str) const {
+Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
   uint32_t Hash =
       (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
   size_t Count = IDs.size();
@@ -115,12 +119,14 @@ uint32_t PDBStringTable::getIDForString(
     uint32_t Index = (Start + I) % Count;
 
     uint32_t ID = IDs[Index];
-    StringRef S = getStringForID(ID);
-    if (S == Str)
+    auto ExpectedStr = getStringForID(ID);
+    if (!ExpectedStr)
+      return ExpectedStr.takeError();
+
+    if (*ExpectedStr == Str)
       return ID;
   }
-  // IDs[0] contains the ID of the "invalid" entry.
-  return IDs[0];
+  return make_error<RawError>(raw_error_code::no_entry);
 }
 
 FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {

Modified: llvm/trunk/tools/llvm-pdbdump/Diff.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/Diff.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/Diff.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/Diff.cpp Wed May  3 12:11:11 2017
@@ -394,11 +394,17 @@ Error DiffStyle::diffStringTable() {
       StringRef S1, S2;
       if (I < IdList1.size()) {
         Id1 = IdList1[I];
-        S1 = ST1.getStringForID(*Id1);
+        if (auto Result = ST1.getStringForID(*Id1))
+          S1 = *Result;
+        else
+          return Result.takeError();
       }
       if (I < IdList2.size()) {
         Id2 = IdList2[I];
-        S2 = ST2.getStringForID(*Id2);
+        if (auto Result = ST2.getStringForID(*Id2))
+          S2 = *Result;
+        else
+          return Result.takeError();
       }
       if (Id1 == Id2 && S1 == S2)
         continue;
@@ -418,10 +424,18 @@ Error DiffStyle::diffStringTable() {
     std::vector<StringRef> Strings1, Strings2;
     Strings1.reserve(IdList1.size());
     Strings2.reserve(IdList2.size());
-    for (auto ID : IdList1)
-      Strings1.push_back(ST1.getStringForID(ID));
-    for (auto ID : IdList2)
-      Strings2.push_back(ST2.getStringForID(ID));
+    for (auto ID : IdList1) {
+      auto S = ST1.getStringForID(ID);
+      if (!S)
+        return S.takeError();
+      Strings1.push_back(*S);
+    }
+    for (auto ID : IdList2) {
+      auto S = ST2.getStringForID(ID);
+      if (!S)
+        return S.takeError();
+      Strings2.push_back(*S);
+    }
 
     SmallVector<StringRef, 64> OnlyP;
     SmallVector<StringRef, 64> OnlyQ;

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Wed May  3 12:11:11 2017
@@ -525,14 +525,17 @@ Error LLVMOutputStyle::dumpStringTable()
 
   DictScope D(P, "String Table");
   for (uint32_t I : IS->name_ids()) {
-    StringRef S = IS->getStringForID(I);
-    if (!S.empty()) {
-      llvm::SmallString<32> Str;
-      Str.append("'");
-      Str.append(S);
-      Str.append("'");
-      P.printString(Str);
-    }
+    auto ES = IS->getStringForID(I);
+    if (!ES)
+      return ES.takeError();
+
+    if (ES->empty())
+      continue;
+    llvm::SmallString<32> Str;
+    Str.append("'");
+    Str.append(*ES);
+    Str.append("'");
+    P.printString(Str);
   }
   return Error::success();
 }
@@ -688,8 +691,11 @@ Error LLVMOutputStyle::dumpTpiStream(uin
     const auto &ST = *ExpectedST;
     for (const auto &E : Tpi->getHashAdjusters()) {
       DictScope DHA(P);
-      StringRef Name = ST.getStringForID(E.first);
-      P.printString("Type", Name);
+      auto Name = ST.getStringForID(E.first);
+      if (!Name)
+        return Name.takeError();
+
+      P.printString("Type", *Name);
       P.printHex("TI", E.second);
     }
   }

Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp Wed May  3 12:11:11 2017
@@ -233,9 +233,12 @@ Error YAMLOutputStyle::dumpStringTable()
 
   const auto &ST = ExpectedST.get();
   for (auto ID : ST.name_ids()) {
-    StringRef S = ST.getStringForID(ID);
-    if (!S.empty())
-      Obj.StringTable->push_back(S);
+    auto S = ST.getStringForID(ID);
+    if (!S)
+      return S.takeError();
+    if (S->empty())
+      continue;
+    Obj.StringTable->push_back(*S);
   }
   return Error::success();
 }

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Wed May  3 12:11:11 2017
@@ -29,6 +29,7 @@
 #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/StringTable.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
@@ -124,7 +125,7 @@ private:
                                   StringRef SectionContents, StringRef Block);
 
   /// Given a .debug$S section, find the string table and file checksum table.
-  void initializeFileAndStringTables(StringRef Data);
+  void initializeFileAndStringTables(BinaryStreamReader &Reader);
 
   void cacheRelocations();
 
@@ -145,8 +146,12 @@ private:
   const llvm::object::COFFObjectFile *Obj;
   bool RelocCached = false;
   RelocMapTy RelocMap;
-  StringRef CVFileChecksumTable;
-  StringRef CVStringTable;
+
+  BinaryByteStream ChecksumContents;
+  VarStreamArray<FileChecksumEntry> CVFileChecksumTable;
+
+  BinaryByteStream StringTableContents;
+  StringTableRef CVStringTable;
 
   ScopedPrinter &Writer;
   TypeDatabase TypeDB;
@@ -186,7 +191,7 @@ public:
     return CD.getFileNameForFileOffset(FileOffset);
   }
 
-  StringRef getStringTable() override { return CD.CVStringTable; }
+  StringTableRef getStringTable() override { return CD.CVStringTable; }
 
 private:
   COFFDumper &CD;
@@ -725,30 +730,35 @@ void COFFDumper::printCodeViewDebugInfo(
   }
 }
 
-void COFFDumper::initializeFileAndStringTables(StringRef Data) {
-  while (!Data.empty() && (CVFileChecksumTable.data() == nullptr ||
-                           CVStringTable.data() == nullptr)) {
+void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) {
+  while (Reader.bytesRemaining() > 0 &&
+         (!CVFileChecksumTable.valid() || !CVStringTable.valid())) {
     // The section consists of a number of subsection in the following format:
     // |SubSectionType|SubSectionSize|Contents...|
     uint32_t SubType, SubSectionSize;
-    error(consume(Data, SubType));
-    error(consume(Data, SubSectionSize));
-    if (SubSectionSize > Data.size())
-      return error(object_error::parse_failed);
+    error(Reader.readInteger(SubType));
+    error(Reader.readInteger(SubSectionSize));
+
+    StringRef Contents;
+    error(Reader.readFixedString(Contents, SubSectionSize));
+
     switch (ModuleDebugFragmentKind(SubType)) {
-    case ModuleDebugFragmentKind::FileChecksums:
-      CVFileChecksumTable = Data.substr(0, SubSectionSize);
-      break;
-    case ModuleDebugFragmentKind::StringTable:
-      CVStringTable = Data.substr(0, SubSectionSize);
+    case ModuleDebugFragmentKind::FileChecksums: {
+      ChecksumContents = BinaryByteStream(Contents, support::little);
+      BinaryStreamReader CSR(ChecksumContents);
+      error(CSR.readArray(CVFileChecksumTable, CSR.getLength()));
       break;
+    }
+    case ModuleDebugFragmentKind::StringTable: {
+      StringTableContents = BinaryByteStream(Contents, support::little);
+      error(CVStringTable.initialize(StringTableContents));
+    } break;
     default:
       break;
     }
+
     uint32_t PaddedSize = alignTo(SubSectionSize, 4);
-    if (PaddedSize > Data.size())
-      error(object_error::parse_failed);
-    Data = Data.drop_front(PaddedSize);
+    error(Reader.skip(PaddedSize - SubSectionSize));
   }
 }
 
@@ -771,7 +781,9 @@ void COFFDumper::printCodeViewSymbolSect
   if (Magic != COFF::DEBUG_SECTION_MAGIC)
     return error(object_error::parse_failed);
 
-  initializeFileAndStringTables(Data);
+  BinaryByteStream FileAndStrings(Data, support::little);
+  BinaryStreamReader FSReader(FileAndStrings);
+  initializeFileAndStringTables(FSReader);
 
   // TODO: Convert this over to using ModuleSubstreamVisitor.
   while (!Data.empty()) {
@@ -861,11 +873,7 @@ void COFFDumper::printCodeViewSymbolSect
         const FrameData *FD;
         error(SR.readObject(FD));
 
-        if (FD->FrameFunc >= CVStringTable.size())
-          error(object_error::parse_failed);
-
-        StringRef FrameFunc =
-            CVStringTable.drop_front(FD->FrameFunc).split('\0').first;
+        StringRef FrameFunc = error(CVStringTable.getString(FD->FrameFunc));
 
         DictScope S(W, "FrameData");
         W.printHex("RvaStart", FD->RvaStart);
@@ -971,10 +979,7 @@ void COFFDumper::printCodeViewFileChecks
   for (auto &FC : Checksums) {
     DictScope S(W, "FileChecksum");
 
-    if (FC.FileNameOffset >= CVStringTable.size())
-      error(object_error::parse_failed);
-    StringRef Filename =
-        CVStringTable.drop_front(FC.FileNameOffset).split('\0').first;
+    StringRef Filename = error(CVStringTable.getString(FC.FileNameOffset));
     W.printHex("Filename", Filename, FC.FileNameOffset);
     W.printHex("ChecksumSize", FC.Checksum.size());
     W.printEnum("ChecksumKind", uint8_t(FC.Kind),
@@ -1008,23 +1013,16 @@ void COFFDumper::printCodeViewInlineeLin
 
 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())
+  if (!CVFileChecksumTable.valid() || !CVStringTable.valid())
     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(consume(Data, StringOffset));
+  auto Iter = CVFileChecksumTable.at(FileOffset);
 
-  // Check if the string table offset is valid.
-  if (StringOffset >= CVStringTable.size())
+  // Check if the file checksum table offset is valid.
+  if (Iter == CVFileChecksumTable.end())
     error(object_error::parse_failed);
 
-  // Return the null-terminated string.
-  return CVStringTable.drop_front(StringOffset).split('\0').first;
+  return error(CVStringTable.getString(Iter->FileNameOffset));
 }
 
 void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Wed May  3 12:11:11 2017
@@ -25,6 +25,11 @@ namespace llvm {
   LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
   void error(std::error_code EC);
   void error(llvm::Error EC);
+  template <typename T> T error(llvm::Expected<T> &&E) {
+    error(E.takeError());
+    return std::move(*E);
+  }
+
   template <class T> T unwrapOrError(ErrorOr<T> EO) {
     if (EO)
       return *EO;

Modified: llvm/trunk/unittests/DebugInfo/PDB/ErrorChecking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/ErrorChecking.h?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/ErrorChecking.h (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/ErrorChecking.h Wed May  3 12:11:11 2017
@@ -36,6 +36,18 @@
     }                                                                          \
   }
 
+#define EXPECT_EXPECTED_EQ(Val, Exp)                                           \
+  {                                                                            \
+    auto Result = Exp;                                                         \
+    auto E = Result.takeError();                                               \
+    EXPECT_FALSE(static_cast<bool>(E));                                        \
+    if (E) {                                                                   \
+      consumeError(std::move(E));                                              \
+      return;                                                                  \
+    }                                                                          \
+    EXPECT_EQ(Val, *Result);                                                   \
+  }
+
 #define EXPECT_UNEXPECTED(Exp)                                                 \
   {                                                                            \
     auto E = Exp.takeError();                                                  \

Modified: llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp?rev=302052&r1=302051&r2=302052&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp Wed May  3 12:11:11 2017
@@ -25,6 +25,12 @@ namespace {
 class StringTableBuilderTest : public ::testing::Test {};
 }
 
+template <typename T>
+static void ExpectExpected(Expected<T> &&E, const T &Value) {
+  EXPECT_EXPECTED(E);
+  EXPECT_EQ(Value, *E);
+}
+
 TEST_F(StringTableBuilderTest, Simple) {
   // Create /names table contents.
   PDBStringTableBuilder Builder;
@@ -46,10 +52,11 @@ TEST_F(StringTableBuilderTest, Simple) {
 
   EXPECT_EQ(3U, Table.getNameCount());
   EXPECT_EQ(1U, Table.getHashVersion());
-  EXPECT_EQ("foo", Table.getStringForID(1));
-  EXPECT_EQ("bar", Table.getStringForID(5));
-  EXPECT_EQ("baz", Table.getStringForID(9));
-  EXPECT_EQ(1U, Table.getIDForString("foo"));
-  EXPECT_EQ(5U, Table.getIDForString("bar"));
-  EXPECT_EQ(9U, Table.getIDForString("baz"));
+
+  EXPECT_EXPECTED_EQ("foo", Table.getStringForID(1));
+  EXPECT_EXPECTED_EQ("bar", Table.getStringForID(5));
+  EXPECT_EXPECTED_EQ("baz", Table.getStringForID(9));
+  EXPECT_EXPECTED_EQ(1U, Table.getIDForString("foo"));
+  EXPECT_EXPECTED_EQ(5U, Table.getIDForString("bar"));
+  EXPECT_EXPECTED_EQ(9U, Table.getIDForString("baz"));
 }




More information about the llvm-commits mailing list