diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-19 07:02:10 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-19 07:02:10 +0000 | 
| commit | 93c91e39b29142dec1d03a30df9f6e757f56c193 (patch) | |
| tree | 33a9b014a327e64450b3c9ed46d8c5bdb78ad345 /lib/DebugInfo/PDB | |
| parent | ca089b24d48ef6fa8da2d0bb8c25bb802c4a95c0 (diff) | |
Notes
Diffstat (limited to 'lib/DebugInfo/PDB')
| -rw-r--r-- | lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp | 12 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/GenericError.cpp | 2 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/InfoStream.cpp | 2 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp | 2 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp | 4 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp | 4 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp | 126 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/TpiHashing.cpp | 128 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/Native/TpiStream.cpp | 1 | ||||
| -rw-r--r-- | lib/DebugInfo/PDB/PDBExtras.cpp | 6 | 
11 files changed, 66 insertions, 222 deletions
| diff --git a/lib/DebugInfo/PDB/CMakeLists.txt b/lib/DebugInfo/PDB/CMakeLists.txt index ff01c948e0997..9b1f37943e678 100644 --- a/lib/DebugInfo/PDB/CMakeLists.txt +++ b/lib/DebugInfo/PDB/CMakeLists.txt @@ -52,7 +52,6 @@ add_pdb_impl_folder(Native    Native/PDBFileBuilder.cpp    Native/PDBStringTable.cpp    Native/PDBStringTableBuilder.cpp -  Native/PDBTypeServerHandler.cpp    Native/PublicsStream.cpp    Native/PublicsStreamBuilder.cpp    Native/RawError.cpp diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp index 0b48a366bd243..4c59d2f2a9d95 100644 --- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp +++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp @@ -125,16 +125,16 @@ PrivateGetDIAValue(IDiaSymbol *Symbol,    return Result8;  } -PDB_UniqueId +codeview::GUID  PrivateGetDIAValue(IDiaSymbol *Symbol,                     HRESULT (__stdcall IDiaSymbol::*Method)(GUID *)) {    GUID Result;    if (S_OK != (Symbol->*Method)(&Result)) -    return PDB_UniqueId(); +    return codeview::GUID(); -  static_assert(sizeof(PDB_UniqueId) == sizeof(GUID), -                "PDB_UniqueId is the wrong size!"); -  PDB_UniqueId IdResult; +  static_assert(sizeof(codeview::GUID) == sizeof(GUID), +                "GUID is the wrong size!"); +  codeview::GUID IdResult;    ::memcpy(&IdResult, &Result, sizeof(GUID));    return IdResult;  } @@ -746,7 +746,7 @@ PDB_SymType DIARawSymbol::getSymTag() const {                                                  &IDiaSymbol::get_symTag);  } -PDB_UniqueId DIARawSymbol::getGuid() const { +codeview::GUID DIARawSymbol::getGuid() const {    return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_guid);  } diff --git a/lib/DebugInfo/PDB/GenericError.cpp b/lib/DebugInfo/PDB/GenericError.cpp index 789f3b813170d..4fcecb92fd154 100644 --- a/lib/DebugInfo/PDB/GenericError.cpp +++ b/lib/DebugInfo/PDB/GenericError.cpp @@ -26,6 +26,8 @@ public:      switch (static_cast<generic_error_code>(Condition)) {      case generic_error_code::unspecified:        return "An unknown error has occurred."; +    case generic_error_code::type_server_not_found: +      return "Type server PDB was not found.";      case generic_error_code::dia_sdk_not_present:        return "LLVM was not compiled with support for DIA.  This usually means "               "that you are are not using MSVC, or your Visual Studio " diff --git a/lib/DebugInfo/PDB/Native/InfoStream.cpp b/lib/DebugInfo/PDB/Native/InfoStream.cpp index 21b66b3e7bcff..829879060c33c 100644 --- a/lib/DebugInfo/PDB/Native/InfoStream.cpp +++ b/lib/DebugInfo/PDB/Native/InfoStream.cpp @@ -118,7 +118,7 @@ uint32_t InfoStream::getSignature() const { return Signature; }  uint32_t InfoStream::getAge() const { return Age; } -PDB_UniqueId InfoStream::getGuid() const { return Guid; } +GUID InfoStream::getGuid() const { return Guid; }  uint32_t InfoStream::getNamedStreamMapByteSize() const {    return NamedStreamMapByteSize; diff --git a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp index 707128f7efd45..6450ae752f965 100644 --- a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp @@ -34,7 +34,7 @@ void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; }  void InfoStreamBuilder::setAge(uint32_t A) { Age = A; } -void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; } +void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }  void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {    Features.push_back(Sig); diff --git a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index cb0830f453c8c..3241000b06db0 100644 --- a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -56,12 +56,12 @@ std::string NativeExeSymbol::getSymbolsFileName() const {    return File.getFilePath();  } -PDB_UniqueId NativeExeSymbol::getGuid() const { +codeview::GUID NativeExeSymbol::getGuid() const {    auto IS = File.getPDBInfoStream();    if (IS)      return IS->getGuid();    consumeError(IS.takeError()); -  return PDB_UniqueId{{0}}; +  return codeview::GUID{{0}};  }  bool NativeExeSymbol::hasCTypes() const { diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp index 92612bcea4ac4..df3f418052a9d 100644 --- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp @@ -323,9 +323,7 @@ PDB_SymType NativeRawSymbol::getSymTag() const {    return PDB_SymType::None;  } -PDB_UniqueId NativeRawSymbol::getGuid() const { -  return PDB_UniqueId{{0}}; -} +codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }  int32_t NativeRawSymbol::getOffset() const {    return 0; diff --git a/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp b/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp deleted file mode 100644 index 9fd90102f72cf..0000000000000 --- a/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//===- PDBTypeServerHandler.cpp ---------------------------------*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Handles CodeView LF_TYPESERVER2 records by attempting to locate a matching -// PDB file, then loading the PDB file and visiting all types from the -// referenced PDB using the original supplied visitor. -// -// The net effect of this is that when visiting a PDB containing a TypeServer -// record, the TypeServer record is "replaced" with all of the records in -// the referenced PDB file.  If a single instance of PDBTypeServerHandler -// encounters the same TypeServer multiple times (for example reusing one -// PDBTypeServerHandler across multiple visitations of distinct object files or -// PDB files), PDBTypeServerHandler will optionally revisit all the records -// again, or simply consume the record and do nothing. -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" - -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/PDB/GenericError.h" -#include "llvm/DebugInfo/PDB/Native/InfoStream.h" -#include "llvm/DebugInfo/PDB/Native/NativeSession.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/TpiStream.h" -#include "llvm/DebugInfo/PDB/PDB.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::pdb; - -static void ignoreErrors(Error EC) { -  llvm::handleAllErrors(std::move(EC), [&](ErrorInfoBase &EIB) {}); -} - -PDBTypeServerHandler::PDBTypeServerHandler(bool RevisitAlways) -    : RevisitAlways(RevisitAlways) {} - -void PDBTypeServerHandler::addSearchPath(StringRef Path) { -  if (Path.empty() || !sys::fs::is_directory(Path)) -    return; - -  SearchPaths.insert(Path); -} - -Expected<bool> -PDBTypeServerHandler::handleInternal(PDBFile &File, -                                     TypeVisitorCallbacks &Callbacks) { -  auto ExpectedTpi = File.getPDBTpiStream(); -  if (!ExpectedTpi) -    return ExpectedTpi.takeError(); - -  // For handling a type server, we should be using whatever the callback array -  // was -  // that is being used for the original file.  We shouldn't allow the visitor -  // to -  // arbitrarily stick a deserializer in there. -  if (auto EC = codeview::visitTypeStream(ExpectedTpi->typeArray(), Callbacks, -                                          VDS_BytesExternal)) -    return std::move(EC); - -  return true; -} - -Expected<bool> PDBTypeServerHandler::handle(TypeServer2Record &TS, -                                            TypeVisitorCallbacks &Callbacks) { -  if (Session) { -    // If we've already handled this TypeServer and we only want to handle each -    // TypeServer once, consume the record without doing anything. -    if (!RevisitAlways) -      return true; - -    return handleInternal(Session->getPDBFile(), Callbacks); -  } - -  StringRef File = sys::path::filename(TS.Name); -  if (File.empty()) -    return make_error<CodeViewError>( -        cv_error_code::corrupt_record, -        "TypeServer2Record does not contain filename!"); - -  for (auto &Path : SearchPaths) { -    SmallString<64> PathStr = Path.getKey(); -    sys::path::append(PathStr, File); -    if (!sys::fs::exists(PathStr)) -      continue; - -    std::unique_ptr<IPDBSession> ThisSession; -    if (auto EC = loadDataForPDB(PDB_ReaderType::Native, PathStr, ThisSession)) { -      // It is not an error if this PDB fails to load, it just means that it -      // doesn't match and we should continue searching. -      ignoreErrors(std::move(EC)); -      continue; -    } - -    std::unique_ptr<NativeSession> NS( -        static_cast<NativeSession *>(ThisSession.release())); -    PDBFile &File = NS->getPDBFile(); -    auto ExpectedInfo = File.getPDBInfoStream(); -    // All PDB Files should have an Info stream. -    if (!ExpectedInfo) -      return ExpectedInfo.takeError(); - -    // Just because a file with a matching name was found and it was an actual -    // PDB file doesn't mean it matches.  For it to match the InfoStream's GUID -    // must match the GUID specified in the TypeServer2 record. -    ArrayRef<uint8_t> GuidBytes(ExpectedInfo->getGuid().Guid); -    StringRef GuidStr(reinterpret_cast<const char *>(GuidBytes.begin()), -                      GuidBytes.size()); -    if (GuidStr != TS.Guid) -      continue; - -    Session = std::move(NS); -    return handleInternal(File, Callbacks); -  } - -  // We couldn't find a matching PDB, so let it be handled by someone else. -  return false; -} diff --git a/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/lib/DebugInfo/PDB/Native/TpiHashing.cpp index 91b8d648fcf9d..77a2d57a83698 100644 --- a/lib/DebugInfo/PDB/Native/TpiHashing.cpp +++ b/lib/DebugInfo/PDB/Native/TpiHashing.cpp @@ -11,101 +11,79 @@  #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"  #include "llvm/DebugInfo/PDB/Native/Hash.h" -#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/Support/JamCRC.h"  using namespace llvm;  using namespace llvm::codeview;  using namespace llvm::pdb;  // Corresponds to `fUDTAnon`. -template <typename T> static bool isAnonymous(T &Rec) { -  StringRef Name = Rec.getName(); +static bool isAnonymous(StringRef Name) {    return Name == "<unnamed-tag>" || Name == "__unnamed" ||           Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");  } -// Computes a hash for a given TPI record. -template <typename T> -static uint32_t getTpiHash(T &Rec, ArrayRef<uint8_t> FullRecord) { -  auto Opts = static_cast<uint16_t>(Rec.getOptions()); - -  bool ForwardRef = -      Opts & static_cast<uint16_t>(ClassOptions::ForwardReference); -  bool Scoped = Opts & static_cast<uint16_t>(ClassOptions::Scoped); -  bool UniqueName = Opts & static_cast<uint16_t>(ClassOptions::HasUniqueName); -  bool IsAnon = UniqueName && isAnonymous(Rec); +// Computes the hash for a user-defined type record. This could be a struct, +// class, union, or enum. +static uint32_t getHashForUdt(const TagRecord &Rec, +                              ArrayRef<uint8_t> FullRecord) { +  ClassOptions Opts = Rec.getOptions(); +  bool ForwardRef = bool(Opts & ClassOptions::ForwardReference); +  bool Scoped = bool(Opts & ClassOptions::Scoped); +  bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName); +  bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());    if (!ForwardRef && !Scoped && !IsAnon)      return hashStringV1(Rec.getName()); -  if (!ForwardRef && UniqueName && !IsAnon) +  if (!ForwardRef && HasUniqueName && !IsAnon)      return hashStringV1(Rec.getUniqueName());    return hashBufferV8(FullRecord);  } -template <typename T> static uint32_t getSourceLineHash(T &Rec) { -  char Buf[4]; -  support::endian::write32le(Buf, Rec.getUDT().getIndex()); -  return hashStringV1(StringRef(Buf, 4)); -} - -void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, -                                          UdtSourceLineRecord &Rec) { -  CVR.Hash = getSourceLineHash(Rec); -} - -void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, -                                          UdtModSourceLineRecord &Rec) { -  CVR.Hash = getSourceLineHash(Rec); -} - -void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, ClassRecord &Rec) { -  CVR.Hash = getTpiHash(Rec, CVR.data()); -} - -void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, EnumRecord &Rec) { -  CVR.Hash = getTpiHash(Rec, CVR.data()); -} - -void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, UnionRecord &Rec) { -  CVR.Hash = getTpiHash(Rec, CVR.data()); -} - -Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UdtSourceLineRecord &Rec) { -  return verifySourceLine(Rec.getUDT()); -} - -Error TpiHashVerifier::visitKnownRecord(CVType &CVR, -                                        UdtModSourceLineRecord &Rec) { -  return verifySourceLine(Rec.getUDT()); -} - -Error TpiHashVerifier::visitKnownRecord(CVType &CVR, ClassRecord &Rec) { -  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index]) -    return errorInvalidHash(); -  return Error::success(); -} -Error TpiHashVerifier::visitKnownRecord(CVType &CVR, EnumRecord &Rec) { -  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index]) -    return errorInvalidHash(); -  return Error::success(); -} -Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UnionRecord &Rec) { -  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index]) -    return errorInvalidHash(); -  return Error::success(); +template <typename T> +static Expected<uint32_t> getHashForUdt(const CVType &Rec) { +  T Deserialized; +  if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec), +                                               Deserialized)) +    return std::move(E); +  return getHashForUdt(Deserialized, Rec.data());  } -Error TpiHashVerifier::verifySourceLine(codeview::TypeIndex TI) { +template <typename T> +static Expected<uint32_t> getSourceLineHash(const CVType &Rec) { +  T Deserialized; +  if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec), +                                               Deserialized)) +    return std::move(E);    char Buf[4]; -  support::endian::write32le(Buf, TI.getIndex()); -  uint32_t Hash = hashStringV1(StringRef(Buf, 4)); -  if (Hash % NumHashBuckets != HashValues[Index]) -    return errorInvalidHash(); -  return Error::success(); +  support::endian::write32le(Buf, Deserialized.getUDT().getIndex()); +  return hashStringV1(StringRef(Buf, 4));  } -Error TpiHashVerifier::visitTypeBegin(CVType &Rec) { -  ++Index; -  RawRecord = Rec; -  return Error::success(); +Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) { +  switch (Rec.kind()) { +  case LF_CLASS: +  case LF_STRUCTURE: +  case LF_INTERFACE: +    return getHashForUdt<ClassRecord>(Rec); +  case LF_UNION: +    return getHashForUdt<UnionRecord>(Rec); +  case LF_ENUM: +    return getHashForUdt<EnumRecord>(Rec); + +  case LF_UDT_SRC_LINE: +    return getSourceLineHash<UdtSourceLineRecord>(Rec); +  case LF_UDT_MOD_SRC_LINE: +    return getSourceLineHash<UdtModSourceLineRecord>(Rec); + +  default: +    break; +  } + +  // Run CRC32 over the bytes. This corresponds to `hashBufv8`. +  JamCRC JC(/*Init=*/0U); +  ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()), +                       Rec.data().size()); +  JC.update(Bytes); +  return JC.getCRC();  } diff --git a/lib/DebugInfo/PDB/Native/TpiStream.cpp b/lib/DebugInfo/PDB/Native/TpiStream.cpp index f917ef91f6396..d3ef87d9009de 100644 --- a/lib/DebugInfo/PDB/Native/TpiStream.cpp +++ b/lib/DebugInfo/PDB/Native/TpiStream.cpp @@ -14,7 +14,6 @@  #include "llvm/DebugInfo/CodeView/TypeRecord.h"  #include "llvm/DebugInfo/MSF/MappedBlockStream.h"  #include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"  #include "llvm/DebugInfo/PDB/Native/RawConstants.h"  #include "llvm/DebugInfo/PDB/Native/RawError.h"  #include "llvm/DebugInfo/PDB/Native/RawTypes.h" diff --git a/lib/DebugInfo/PDB/PDBExtras.cpp b/lib/DebugInfo/PDB/PDBExtras.cpp index faf1142ddf17a..c291185bc67a6 100644 --- a/lib/DebugInfo/PDB/PDBExtras.cpp +++ b/lib/DebugInfo/PDB/PDBExtras.cpp @@ -260,12 +260,6 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,    return OS;  } -raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UniqueId &Guid) { -  codeview::detail::GuidAdapter A(Guid.Guid); -  A.format(OS, ""); -  return OS; -} -  raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {    switch (Type) {      CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Class, "class", OS) | 
