[PATCH] D21361: [pdbdump] Verify LF_{CLASS, ENUM, INTERFACE, STRUCTURE, UNION} records.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 14 16:29:40 PDT 2016


ruiu created this revision.
ruiu added a reviewer: zturner.
ruiu added a subscriber: llvm-commits.

This patch is to verify more patterns.

http://reviews.llvm.org/D21361

Files:
  lib/DebugInfo/PDB/Raw/TpiStream.cpp

Index: lib/DebugInfo/PDB/Raw/TpiStream.cpp
===================================================================
--- lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -69,6 +69,38 @@
 
 TpiStream::~TpiStream() {}
 
+// Computes a hash for a given TPI record.
+template <typename T, codeview::TypeRecordKind K>
+static Error getTpiHash(const codeview::CVType &Rec, uint32_t &Hash) {
+  ArrayRef<uint8_t> Data = Rec.Data;
+  ErrorOr<T> Obj = T::deserialize(K, Data);
+  if (Obj.getError())
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "Corrupt TPI hash table.");
+
+  auto Opts = static_cast<uint16_t>(Obj->getOptions());
+  if (Opts & static_cast<uint16_t>(codeview::ClassOptions::ForwardReference)) {
+    // We don't know how to calculate a hash value for this yet.
+    // Currently we just skip it.
+    Hash = 0;
+    return Error::success();
+  }
+
+  if (!(Opts & static_cast<uint16_t>(codeview::ClassOptions::Scoped))) {
+    Hash = hashStringV1(Obj->getName());
+    return Error::success();
+  }
+
+  if (Opts & static_cast<uint16_t>(codeview::ClassOptions::HasUniqueName)) {
+    Hash = hashStringV1(Obj->getUniqueName());
+    return Error::success();
+  }
+
+  // This case is not implemented yet.
+  Hash = 0;
+  return Error::success();
+}
+
 // Verifies that a given type record matches with a given hash value.
 // Currently we only verify SRC_LINE records.
 static Error verifyTIHash(const codeview::CVType &Rec, uint32_t Expected,
@@ -83,19 +115,32 @@
   case LF_UDT_MOD_SRC_LINE:
     Hash = hashStringV1(StringRef((const char *)D.data(), 4));
     break;
-  case LF_ENUM: {
-    ErrorOr<EnumRecord> Enum = EnumRecord::deserialize(TypeRecordKind::Enum, D);
-    if (Enum.getError())
-      return make_error<RawError>(raw_error_code::corrupt_file,
-                                  "Corrupt TPI hash table.");
-    Hash = hashStringV1(Enum->getName());
+  case LF_CLASS:
+    if (auto EC = getTpiHash<ClassRecord, TypeRecordKind::Class>(Rec, Hash))
+      return EC;
+    break;
+  case LF_ENUM:
+    if (auto EC = getTpiHash<EnumRecord, TypeRecordKind::Enum>(Rec, Hash))
+      return EC;
+    break;
+  case LF_INTERFACE:
+    if (auto EC = getTpiHash<ClassRecord, TypeRecordKind::Interface>(Rec, Hash))
+      return EC;
+    break;
+  case LF_STRUCTURE:
+    if (auto EC = getTpiHash<ClassRecord, TypeRecordKind::Struct>(Rec, Hash))
+      return EC;
+    break;
+  case LF_UNION:
+    if (auto EC = getTpiHash<UnionRecord, TypeRecordKind::Union>(Rec, Hash))
+      return EC;
     break;
-  }
   default:
+    // This pattern is not implemented yet.
     return Error::success();
   }
 
-  if ((Hash % NumHashBuckets) != Expected)
+  if (Hash && (Hash % NumHashBuckets) != Expected)
     return make_error<RawError>(raw_error_code::corrupt_file,
                                 "Corrupt TPI hash table.");
   return Error::success();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21361.60779.patch
Type: text/x-patch
Size: 2938 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160614/e4d61feb/attachment.bin>


More information about the llvm-commits mailing list