summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/DebugInfo/PDB
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/PDB')
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp43
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp19
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/GenericError.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp90
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp196
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp280
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp)220
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp)234
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp)4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/GSI.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp)20
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/GSI.h (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.h)20
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp)6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/Hash.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/Hash.cpp)4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp308
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp139
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp74
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp123
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp152
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp48
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp50
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp51
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp84
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp694
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp218
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp)144
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp221
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp139
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp138
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp)47
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp89
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/RawError.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp)4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp)13
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp89
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp (renamed from contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp)96
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp177
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDB.cpp22
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp5
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBExtras.cpp24
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp36
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp15
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp23
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp10
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp11
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp19
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp10
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp12
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp6
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp77
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp65
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp81
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp85
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp104
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp163
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp108
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp148
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp136
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/TpiHashing.cpp110
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp145
-rw-r--r--contrib/llvm/lib/DebugInfo/PDB/UDTLayout.cpp303
86 files changed, 4290 insertions, 1792 deletions
diff --git a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
index cae817c..f62c499 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/DIA/DIADataStream.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
+#include "llvm/DebugInfo/PDB/DIA/DIADataStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
index 4741d9c..796ce21 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIALineNumber.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
index ccf8c4e..b9311d0 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
index 3c211b5..2666385 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index bba5b0f..4c59d2f 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -10,9 +10,14 @@
#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/raw_ostream.h"
@@ -120,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;
}
@@ -178,9 +183,10 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
}
namespace llvm {
-raw_ostream &operator<<(raw_ostream &OS, const GUID &Guid) {
- const PDB_UniqueId *Id = reinterpret_cast<const PDB_UniqueId *>(&Guid);
- OS << *Id;
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const GUID &G) {
+ StringRef GuidBytes(reinterpret_cast<const char *>(&G), sizeof(G));
+ codeview::detail::GuidAdapter A(GuidBytes);
+ A.format(OS, "");
return OS;
}
}
@@ -366,8 +372,11 @@ DIARawSymbol::findChildren(PDB_SymType Type) const {
enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
CComPtr<IDiaEnumSymbols> DiaEnumerator;
- if (S_OK != Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator))
- return nullptr;
+ if (S_OK !=
+ Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator)) {
+ if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator))
+ return nullptr;
+ }
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
@@ -715,6 +724,18 @@ uint32_t DIARawSymbol::getVirtualTableShapeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualTableShapeId);
}
+std::unique_ptr<PDBSymbolTypeBuiltin>
+DIARawSymbol::getVirtualBaseTableType() const {
+ CComPtr<IDiaSymbol> TableType;
+ if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType)
+ return nullptr;
+
+ auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
+ auto Pointer =
+ llvm::make_unique<PDBSymbolTypePointer>(Session, std::move(RawVT));
+ return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
+}
+
PDB_DataKind DIARawSymbol::getDataKind() const {
return PrivateGetDIAValue<DWORD, PDB_DataKind>(Symbol,
&IDiaSymbol::get_dataKind);
@@ -725,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/contrib/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
index 6ecf335..ef9390c 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -21,12 +21,22 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::pdb;
-static Error ErrorFromHResult(HRESULT Result, StringRef Context) {
+template <typename... Ts>
+static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args) {
+ SmallString<64> MessageStorage;
+ StringRef Context;
+ if (sizeof...(Args) > 0) {
+ MessageStorage = formatv(Str, std::forward<Ts>(Args)...).str();
+ Context = MessageStorage;
+ } else
+ Context = Str;
+
switch (Result) {
case E_PDB_NOT_FOUND:
return make_error<GenericError>(generic_error_code::invalid_path, Context);
@@ -95,8 +105,9 @@ Error DIASession::createFromPdb(StringRef Path,
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
HRESULT HR;
- if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str)))
- return ErrorFromHResult(HR, "Calling loadDataFromPdb");
+ if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {
+ return ErrorFromHResult(HR, "Calling loadDataFromPdb {0}", Path);
+ }
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR, "Calling openSession");
@@ -140,7 +151,7 @@ void DIASession::setLoadAddress(uint64_t Address) {
Session->put_loadAddress(Address);
}
-std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
+std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() {
CComPtr<IDiaSymbol> GlobalScope;
if (S_OK != Session->get_globalScope(&GlobalScope))
return nullptr;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/GenericError.cpp b/contrib/llvm/lib/DebugInfo/PDB/GenericError.cpp
index 789f3b8..4fcecb9 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/GenericError.cpp
+++ b/contrib/llvm/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/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
new file mode 100644
index 0000000..dabcc34
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
@@ -0,0 +1,90 @@
+//===- DbiModuleDescriptor.cpp - PDB module information -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+DbiModuleDescriptor::DbiModuleDescriptor() = default;
+
+DbiModuleDescriptor::DbiModuleDescriptor(const DbiModuleDescriptor &Info) =
+ default;
+
+DbiModuleDescriptor::~DbiModuleDescriptor() = default;
+
+Error DbiModuleDescriptor::initialize(BinaryStreamRef Stream,
+ DbiModuleDescriptor &Info) {
+ BinaryStreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(Info.Layout))
+ return EC;
+
+ if (auto EC = Reader.readCString(Info.ModuleName))
+ return EC;
+
+ if (auto EC = Reader.readCString(Info.ObjFileName))
+ return EC;
+ return Error::success();
+}
+
+bool DbiModuleDescriptor::hasECInfo() const {
+ return (Layout->Flags & ModInfoFlags::HasECFlagMask) != 0;
+}
+
+uint16_t DbiModuleDescriptor::getTypeServerIndex() const {
+ return (Layout->Flags & ModInfoFlags::TypeServerIndexMask) >>
+ ModInfoFlags::TypeServerIndexShift;
+}
+
+uint16_t DbiModuleDescriptor::getModuleStreamIndex() const {
+ return Layout->ModDiStream;
+}
+
+uint32_t DbiModuleDescriptor::getSymbolDebugInfoByteSize() const {
+ return Layout->SymBytes;
+}
+
+uint32_t DbiModuleDescriptor::getC11LineInfoByteSize() const {
+ return Layout->C11Bytes;
+}
+
+uint32_t DbiModuleDescriptor::getC13LineInfoByteSize() const {
+ return Layout->C13Bytes;
+}
+
+uint32_t DbiModuleDescriptor::getNumberOfFiles() const {
+ return Layout->NumFiles;
+}
+
+uint32_t DbiModuleDescriptor::getSourceFileNameIndex() const {
+ return Layout->SrcFileNameNI;
+}
+
+uint32_t DbiModuleDescriptor::getPdbFilePathNameIndex() const {
+ return Layout->PdbFilePathNI;
+}
+
+StringRef DbiModuleDescriptor::getModuleName() const { return ModuleName; }
+
+StringRef DbiModuleDescriptor::getObjFileName() const { return ObjFileName; }
+
+uint32_t DbiModuleDescriptor::getRecordLength() const {
+ uint32_t M = ModuleName.str().size() + 1;
+ uint32_t O = ObjFileName.str().size() + 1;
+ uint32_t Size = sizeof(ModuleInfoHeader) + M + O;
+ Size = alignTo(Size, 4);
+ return Size;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
new file mode 100644
index 0000000..897f78c
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -0,0 +1,196 @@
+//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryItemStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+namespace llvm {
+template <> struct BinaryItemTraits<CVSymbol> {
+ static size_t length(const CVSymbol &Item) { return Item.RecordData.size(); }
+
+ static ArrayRef<uint8_t> bytes(const CVSymbol &Item) {
+ return Item.RecordData;
+ }
+};
+}
+
+static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
+ uint32_t C13Size) {
+ uint32_t Size = sizeof(uint32_t); // Signature
+ Size += alignTo(SymbolByteSize, 4); // Symbol Data
+ Size += 0; // TODO: Layout.C11Bytes
+ Size += C13Size; // C13 Debug Info Size
+ Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
+ Size += 0; // GlobalRefs substream bytes
+ return Size;
+}
+
+DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
+ uint32_t ModIndex,
+ msf::MSFBuilder &Msf)
+ : MSF(Msf), ModuleName(ModuleName) {
+ ::memset(&Layout, 0, sizeof(Layout));
+ Layout.Mod = ModIndex;
+}
+
+DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
+
+uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
+ return Layout.ModDiStream;
+}
+
+void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) {
+ ObjFileName = Name;
+}
+
+void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
+ PdbFilePathNI = NI;
+}
+
+void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
+ Symbols.push_back(Symbol);
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // is not true of object files.
+ assert(Symbol.length() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid Symbol alignment!");
+ SymbolByteSize += Symbol.length();
+}
+
+void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
+ SourceFiles.push_back(Path);
+}
+
+uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
+ uint32_t Result = 0;
+ for (const auto &Builder : C13Builders) {
+ assert(Builder && "Empty C13 Fragment Builder!");
+ Result += Builder->calculateSerializedLength();
+ }
+ return Result;
+}
+
+uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
+ uint32_t L = sizeof(Layout);
+ uint32_t M = ModuleName.size() + 1;
+ uint32_t O = ObjFileName.size() + 1;
+ return alignTo(L + M + O, sizeof(uint32_t));
+}
+
+template <typename T> struct Foo {
+ explicit Foo(T &&Answer) : Answer(Answer) {}
+
+ T Answer;
+};
+
+template <typename T> Foo<T> makeFoo(T &&t) { return Foo<T>(std::move(t)); }
+
+void DbiModuleDescriptorBuilder::finalize() {
+ Layout.SC.ModuleIndex = Layout.Mod;
+ Layout.FileNameOffs = 0; // TODO: Fix this
+ Layout.Flags = 0; // TODO: Fix this
+ Layout.C11Bytes = 0;
+ Layout.C13Bytes = calculateC13DebugInfoSize();
+ (void)Layout.Mod; // Set in constructor
+ (void)Layout.ModDiStream; // Set in finalizeMsfLayout
+ Layout.NumFiles = SourceFiles.size();
+ Layout.PdbFilePathNI = PdbFilePathNI;
+ Layout.SrcFileNameNI = 0;
+
+ // This value includes both the signature field as well as the record bytes
+ // from the symbol stream.
+ Layout.SymBytes = SymbolByteSize + sizeof(uint32_t);
+}
+
+Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
+ this->Layout.ModDiStream = kInvalidStreamIndex;
+ uint32_t C13Size = calculateC13DebugInfoSize();
+ auto ExpectedSN =
+ MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size));
+ if (!ExpectedSN)
+ return ExpectedSN.takeError();
+ Layout.ModDiStream = *ExpectedSN;
+ return Error::success();
+}
+
+Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
+ const msf::MSFLayout &MsfLayout,
+ WritableBinaryStreamRef MsfBuffer) {
+ // We write the Modi record to the `ModiWriter`, but we additionally write its
+ // symbol stream to a brand new stream.
+ if (auto EC = ModiWriter.writeObject(Layout))
+ return EC;
+ if (auto EC = ModiWriter.writeCString(ModuleName))
+ return EC;
+ if (auto EC = ModiWriter.writeCString(ObjFileName))
+ return EC;
+ if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
+ return EC;
+
+ if (Layout.ModDiStream != kInvalidStreamIndex) {
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
+ WritableBinaryStreamRef Ref(*NS);
+ BinaryStreamWriter SymbolWriter(Ref);
+ // Write the symbols.
+ if (auto EC =
+ SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
+ return EC;
+ BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
+ Records.setItems(Symbols);
+ BinaryStreamRef RecordsRef(Records);
+ if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
+ return EC;
+ if (auto EC = SymbolWriter.padToAlignment(4))
+ return EC;
+ // TODO: Write C11 Line data
+ assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid debug section alignment!");
+ for (const auto &Builder : C13Builders) {
+ assert(Builder && "Empty C13 Fragment Builder!");
+ if (auto EC = Builder->commit(SymbolWriter))
+ return EC;
+ }
+
+ // TODO: Figure out what GlobalRefs substream actually is and populate it.
+ if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
+ return EC;
+ if (SymbolWriter.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::stream_too_long);
+ }
+ return Error::success();
+}
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+ std::shared_ptr<DebugSubsection> Subsection) {
+ assert(Subsection);
+ C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+ std::move(Subsection), CodeViewContainer::Pdb));
+}
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+ const DebugSubsectionRecord &SubsectionContents) {
+ C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+ SubsectionContents, CodeViewContainer::Pdb));
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
new file mode 100644
index 0000000..eea70b2
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
@@ -0,0 +1,280 @@
+//===- DbiModuleList.cpp - PDB module information list --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DbiModuleSourceFilesIterator::DbiModuleSourceFilesIterator(
+ const DbiModuleList &Modules, uint32_t Modi, uint16_t Filei)
+ : Modules(&Modules), Modi(Modi), Filei(Filei) {
+ setValue();
+}
+
+bool DbiModuleSourceFilesIterator::
+operator==(const DbiModuleSourceFilesIterator &R) const {
+ // incompatible iterators are never equal
+ if (!isCompatible(R))
+ return false;
+
+ // If they're compatible, and they're both ends, then they're equal.
+ if (isEnd() && R.isEnd())
+ return true;
+
+ // If one is an end and the other is not, they're not equal.
+ if (isEnd() != R.isEnd())
+ return false;
+
+ // Now we know:
+ // - They're compatible
+ // - They're not *both* end iterators
+ // - Their endness is the same.
+ // Thus, they're compatible iterators pointing to a valid file on the same
+ // module. All we need to check are the file indices.
+ assert(Modules == R.Modules);
+ assert(Modi == R.Modi);
+ assert(!isEnd());
+ assert(!R.isEnd());
+
+ return (Filei == R.Filei);
+}
+
+bool DbiModuleSourceFilesIterator::
+operator<(const DbiModuleSourceFilesIterator &R) const {
+ assert(isCompatible(R));
+
+ // It's not sufficient to compare the file indices, because default
+ // constructed iterators could be equal to iterators with valid indices. To
+ // account for this, early-out if they're equal.
+ if (*this == R)
+ return false;
+
+ return Filei < R.Filei;
+}
+
+std::ptrdiff_t DbiModuleSourceFilesIterator::
+operator-(const DbiModuleSourceFilesIterator &R) const {
+ assert(isCompatible(R));
+ assert(!(*this < R));
+
+ // If they're both end iterators, the distance is 0.
+ if (isEnd() && R.isEnd())
+ return 0;
+
+ assert(!R.isEnd());
+
+ // At this point, R cannot be end, but *this can, which means that *this
+ // might be a universal end iterator with none of its fields set. So in that
+ // case have to rely on R as the authority to figure out how many files there
+ // are to compute the distance.
+ uint32_t Thisi = Filei;
+ if (isEnd()) {
+ uint32_t RealModi = R.Modi;
+ Thisi = R.Modules->getSourceFileCount(RealModi);
+ }
+
+ assert(Thisi >= R.Filei);
+ return Thisi - R.Filei;
+}
+
+DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
+operator+=(std::ptrdiff_t N) {
+ assert(!isEnd());
+
+ Filei += N;
+ assert(Filei <= Modules->getSourceFileCount(Modi));
+ setValue();
+ return *this;
+}
+
+DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
+operator-=(std::ptrdiff_t N) {
+ // Note that we can subtract from an end iterator, but not a universal end
+ // iterator.
+ assert(!isUniversalEnd());
+
+ assert(N <= Filei);
+
+ Filei -= N;
+ return *this;
+}
+
+void DbiModuleSourceFilesIterator::setValue() {
+ if (isEnd()) {
+ ThisValue = "";
+ return;
+ }
+
+ uint32_t Off = Modules->ModuleInitialFileIndex[Modi] + Filei;
+ auto ExpectedValue = Modules->getFileName(Off);
+ if (!ExpectedValue) {
+ consumeError(ExpectedValue.takeError());
+ Filei = Modules->getSourceFileCount(Modi);
+ } else
+ ThisValue = *ExpectedValue;
+}
+
+bool DbiModuleSourceFilesIterator::isEnd() const {
+ if (isUniversalEnd())
+ return true;
+
+ assert(Modules);
+ assert(Modi <= Modules->getModuleCount());
+ assert(Filei <= Modules->getSourceFileCount(Modi));
+
+ if (Modi == Modules->getModuleCount())
+ return true;
+ if (Filei == Modules->getSourceFileCount(Modi))
+ return true;
+ return false;
+}
+
+bool DbiModuleSourceFilesIterator::isUniversalEnd() const { return !Modules; }
+
+bool DbiModuleSourceFilesIterator::isCompatible(
+ const DbiModuleSourceFilesIterator &R) const {
+ // Universal iterators are compatible with any other iterator.
+ if (isUniversalEnd() || R.isUniversalEnd())
+ return true;
+
+ // At this point, neither iterator is a universal end iterator, although one
+ // or both might be non-universal end iterators. Regardless, the module index
+ // is valid, so they are compatible if and only if they refer to the same
+ // module.
+ return Modi == R.Modi;
+}
+
+Error DbiModuleList::initialize(BinaryStreamRef ModInfo,
+ BinaryStreamRef FileInfo) {
+ if (auto EC = initializeModInfo(ModInfo))
+ return EC;
+ if (auto EC = initializeFileInfo(FileInfo))
+ return EC;
+
+ return Error::success();
+}
+
+Error DbiModuleList::initializeModInfo(BinaryStreamRef ModInfo) {
+ ModInfoSubstream = ModInfo;
+
+ if (ModInfo.getLength() == 0)
+ return Error::success();
+
+ BinaryStreamReader Reader(ModInfo);
+
+ if (auto EC = Reader.readArray(Descriptors, ModInfo.getLength()))
+ return EC;
+
+ return Error::success();
+}
+
+Error DbiModuleList::initializeFileInfo(BinaryStreamRef FileInfo) {
+ FileInfoSubstream = FileInfo;
+
+ if (FileInfo.getLength() == 0)
+ return Error::success();
+
+ BinaryStreamReader FISR(FileInfo);
+ if (auto EC = FISR.readObject(FileInfoHeader))
+ return EC;
+
+ // First is an array of `NumModules` module indices. This does not seem to be
+ // used for anything meaningful, so we ignore it.
+ FixedStreamArray<support::ulittle16_t> ModuleIndices;
+ if (auto EC = FISR.readArray(ModuleIndices, FileInfoHeader->NumModules))
+ return EC;
+ if (auto EC = FISR.readArray(ModFileCountArray, FileInfoHeader->NumModules))
+ return EC;
+
+ // Compute the real number of source files. We can't trust the value in
+ // `FileInfoHeader->NumSourceFiles` because it is a unit16, and the sum of all
+ // source file counts might be larger than a unit16. So we compute the real
+ // count by summing up the individual counts.
+ uint32_t NumSourceFiles = 0;
+ for (auto Count : ModFileCountArray)
+ NumSourceFiles += Count;
+
+ // In the reference implementation, this array is where the pointer documented
+ // at the definition of ModuleInfoHeader::FileNameOffs points to. Note that
+ // although the field in ModuleInfoHeader is ignored this array is not, as it
+ // is the authority on where each filename begins in the names buffer.
+ if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
+ return EC;
+
+ if (auto EC = FISR.readStreamRef(NamesBuffer))
+ return EC;
+
+ auto DescriptorIter = Descriptors.begin();
+ uint32_t NextFileIndex = 0;
+ ModuleInitialFileIndex.resize(FileInfoHeader->NumModules);
+ ModuleDescriptorOffsets.resize(FileInfoHeader->NumModules);
+ for (size_t I = 0; I < FileInfoHeader->NumModules; ++I) {
+ assert(DescriptorIter != Descriptors.end());
+ ModuleInitialFileIndex[I] = NextFileIndex;
+ ModuleDescriptorOffsets[I] = DescriptorIter.offset();
+
+ NextFileIndex += ModFileCountArray[I];
+ ++DescriptorIter;
+ }
+
+ assert(DescriptorIter == Descriptors.end());
+ assert(NextFileIndex == NumSourceFiles);
+
+ return Error::success();
+}
+
+uint32_t DbiModuleList::getModuleCount() const {
+ return FileInfoHeader->NumModules;
+}
+
+uint32_t DbiModuleList::getSourceFileCount() const {
+ return FileNameOffsets.size();
+}
+
+uint16_t DbiModuleList::getSourceFileCount(uint32_t Modi) const {
+ return ModFileCountArray[Modi];
+}
+
+DbiModuleDescriptor DbiModuleList::getModuleDescriptor(uint32_t Modi) const {
+ assert(Modi < getModuleCount());
+ uint32_t Offset = ModuleDescriptorOffsets[Modi];
+ auto Iter = Descriptors.at(Offset);
+ assert(Iter != Descriptors.end());
+ return *Iter;
+}
+
+iterator_range<DbiModuleSourceFilesIterator>
+DbiModuleList::source_files(uint32_t Modi) const {
+ return make_range<DbiModuleSourceFilesIterator>(
+ DbiModuleSourceFilesIterator(*this, Modi, 0),
+ DbiModuleSourceFilesIterator());
+}
+
+Expected<StringRef> DbiModuleList::getFileName(uint32_t Index) const {
+ BinaryStreamReader Names(NamesBuffer);
+ if (Index >= getSourceFileCount())
+ return make_error<RawError>(raw_error_code::index_out_of_bounds);
+
+ uint32_t FileOffset = FileNameOffsets[Index];
+ Names.setOffset(FileOffset);
+ StringRef Name;
+ if (auto EC = Names.readCString(Name))
+ return std::move(EC);
+ return Name;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
index 4f4a0cf..0eeac7e 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -7,21 +7,20 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
-#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
-#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstddef>
@@ -35,7 +34,7 @@ using namespace llvm::support;
template <typename ContribType>
static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
- StreamReader &Reader) {
+ BinaryStreamReader &Reader) {
if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
return make_error<RawError>(
raw_error_code::corrupt_file,
@@ -48,13 +47,12 @@ static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
}
DbiStream::DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
- : Pdb(File), Stream(std::move(Stream)), Header(nullptr) {
-}
+ : Pdb(File), Stream(std::move(Stream)), Header(nullptr) {}
DbiStream::~DbiStream() = default;
Error DbiStream::reload() {
- StreamReader Reader(*Stream);
+ BinaryStreamReader Reader(*Stream);
if (Stream->getLength() < sizeof(DbiStreamHeader))
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -74,14 +72,6 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::feature_unsupported,
"Unsupported DBI version.");
- auto IS = Pdb.getPDBInfoStream();
- if (!IS)
- return IS.takeError();
-
- if (Header->Age != IS->getAge())
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI Age does not match PDB Age.");
-
if (Stream->getLength() !=
sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
Header->SecContrSubstreamSize + Header->SectionMapSize +
@@ -109,26 +99,27 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI type server substream not aligned.");
- if (auto EC =
- Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
- return EC;
- if (auto EC = initializeModInfoArray())
+ if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
return EC;
- if (auto EC = Reader.readStreamRef(SecContrSubstream,
+ if (auto EC = Reader.readSubstream(SecContrSubstream,
Header->SecContrSubstreamSize))
return EC;
- if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize))
+ if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
return EC;
- if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize))
+ if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
return EC;
if (auto EC =
- Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize))
+ Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
return EC;
- if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize))
+ if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
return EC;
- if (auto EC = Reader.readArray(DbgStreams, Header->OptionalDbgHdrSize /
- sizeof(ulittle16_t)))
+ if (auto EC = Reader.readArray(
+ DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
+ return EC;
+
+ if (auto EC = Modules.initialize(ModiSubstream.StreamData,
+ FileInfoSubstream.StreamData))
return EC;
if (auto EC = initializeSectionContributionData())
@@ -137,8 +128,6 @@ Error DbiStream::reload() {
return EC;
if (auto EC = initializeSectionMapData())
return EC;
- if (auto EC = initializeFileInfo())
- return EC;
if (auto EC = initializeFpoRecords())
return EC;
@@ -146,9 +135,9 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
- if (ECSubstream.getLength() > 0) {
- StreamReader ECReader(ECSubstream);
- if (auto EC = ECNames.load(ECReader))
+ if (!ECSubstream.empty()) {
+ BinaryStreamReader ECReader(ECSubstream.StreamData);
+ if (auto EC = ECNames.reload(ECReader))
return EC;
}
@@ -209,35 +198,42 @@ PDB_Machine DbiStream::getMachineType() const {
return static_cast<PDB_Machine>(Machine);
}
-msf::FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
+FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
return SectionHeaders;
}
-msf::FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
+FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
return FpoRecords;
}
-ArrayRef<ModuleInfoEx> DbiStream::modules() const { return ModuleInfos; }
-msf::FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
+const DbiModuleList &DbiStream::modules() const { return Modules; }
+
+FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
return SectionMap;
}
void DbiStream::visitSectionContributions(
ISectionContribVisitor &Visitor) const {
- if (SectionContribVersion == DbiSecContribVer60) {
+ if (!SectionContribs.empty()) {
+ assert(SectionContribVersion == DbiSecContribVer60);
for (auto &SC : SectionContribs)
Visitor.visit(SC);
- } else if (SectionContribVersion == DbiSecContribV2) {
+ } else if (!SectionContribs2.empty()) {
+ assert(SectionContribVersion == DbiSecContribV2);
for (auto &SC : SectionContribs2)
Visitor.visit(SC);
}
}
+Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
+ return ECNames.getStringForID(NI);
+}
+
Error DbiStream::initializeSectionContributionData() {
- if (SecContrSubstream.getLength() == 0)
+ if (SecContrSubstream.empty())
return Error::success();
- StreamReader SCReader(SecContrSubstream);
+ BinaryStreamReader SCReader(SecContrSubstream.StreamData);
if (auto EC = SCReader.readEnum(SectionContribVersion))
return EC;
@@ -250,35 +246,20 @@ Error DbiStream::initializeSectionContributionData() {
"Unsupported DBI Section Contribution version");
}
-Error DbiStream::initializeModInfoArray() {
- if (ModInfoSubstream.getLength() == 0)
- return Error::success();
-
- // Since each ModInfo in the stream is a variable length, we have to iterate
- // them to know how many there actually are.
- StreamReader Reader(ModInfoSubstream);
-
- VarStreamArray<ModInfo> ModInfoArray;
- if (auto EC = Reader.readArray(ModInfoArray, ModInfoSubstream.getLength()))
- return EC;
- for (auto &Info : ModInfoArray) {
- ModuleInfos.emplace_back(Info);
- }
-
- return Error::success();
-}
-
// Initializes this->SectionHeaders.
Error DbiStream::initializeSectionHeadersData() {
if (DbgStreams.size() == 0)
return Error::success();
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
+ if (StreamNum == kInvalidStreamIndex)
+ return Error::success();
+
if (StreamNum >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
auto SHS = MappedBlockStream::createIndexedStream(
- Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum, Pdb.getAllocator());
size_t StreamLen = SHS->getLength();
if (StreamLen % sizeof(object::coff_section))
@@ -286,7 +267,7 @@ Error DbiStream::initializeSectionHeadersData() {
"Corrupted section header stream.");
size_t NumSections = StreamLen / sizeof(object::coff_section);
- msf::StreamReader Reader(*SHS);
+ BinaryStreamReader Reader(*SHS);
if (auto EC = Reader.readArray(SectionHeaders, NumSections))
return make_error<RawError>(raw_error_code::corrupt_file,
"Could not read a bitmap.");
@@ -310,7 +291,7 @@ Error DbiStream::initializeFpoRecords() {
return make_error<RawError>(raw_error_code::no_stream);
auto FS = MappedBlockStream::createIndexedStream(
- Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum, Pdb.getAllocator());
size_t StreamLen = FS->getLength();
if (StreamLen % sizeof(object::FpoData))
@@ -318,7 +299,7 @@ Error DbiStream::initializeFpoRecords() {
"Corrupted New FPO stream.");
size_t NumRecords = StreamLen / sizeof(object::FpoData);
- msf::StreamReader Reader(*FS);
+ BinaryStreamReader Reader(*FS);
if (auto EC = Reader.readArray(FpoRecords, NumRecords))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted New FPO stream.");
@@ -326,82 +307,38 @@ Error DbiStream::initializeFpoRecords() {
return Error::success();
}
-Error DbiStream::initializeSectionMapData() {
- if (SecMapSubstream.getLength() == 0)
- return Error::success();
+BinarySubstreamRef DbiStream::getSectionContributionData() const {
+ return SecContrSubstream;
+}
- StreamReader SMReader(SecMapSubstream);
- const SecMapHeader *Header;
- if (auto EC = SMReader.readObject(Header))
- return EC;
- if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
- return EC;
- return Error::success();
+BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
+ return SecMapSubstream;
}
-Error DbiStream::initializeFileInfo() {
- if (FileInfoSubstream.getLength() == 0)
- return Error::success();
+BinarySubstreamRef DbiStream::getModiSubstreamData() const {
+ return ModiSubstream;
+}
- const FileInfoSubstreamHeader *FH;
- StreamReader FISR(FileInfoSubstream);
- if (auto EC = FISR.readObject(FH))
- return EC;
+BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
+ return FileInfoSubstream;
+}
- // The number of modules in the stream should be the same as reported by
- // the FileInfoSubstreamHeader.
- if (FH->NumModules != ModuleInfos.size())
- return make_error<RawError>(raw_error_code::corrupt_file,
- "FileInfo substream count doesn't match DBI.");
+BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
+ return TypeServerMapSubstream;
+}
- FixedStreamArray<ulittle16_t> ModIndexArray;
- FixedStreamArray<ulittle16_t> ModFileCountArray;
+BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
- // First is an array of `NumModules` module indices. This is not used for the
- // same reason that `NumSourceFiles` is not used. It's an array of uint16's,
- // but it's possible there are more than 64k source files, which would imply
- // more than 64k modules (e.g. object files) as well. So we ignore this
- // field.
- if (auto EC = FISR.readArray(ModIndexArray, ModuleInfos.size()))
- return EC;
- if (auto EC = FISR.readArray(ModFileCountArray, ModuleInfos.size()))
- return EC;
+Error DbiStream::initializeSectionMapData() {
+ if (SecMapSubstream.empty())
+ return Error::success();
- // Compute the real number of source files.
- uint32_t NumSourceFiles = 0;
- for (auto Count : ModFileCountArray)
- NumSourceFiles += Count;
-
- // This is the array that in the reference implementation corresponds to
- // `ModInfo::FileLayout::FileNameOffs`, which is commented there as being a
- // pointer. Due to the mentioned problems of pointers causing difficulty
- // when reading from the file on 64-bit systems, we continue to ignore that
- // field in `ModInfo`, and instead build a vector of StringRefs and stores
- // them in `ModuleInfoEx`. The value written to and read from the file is
- // not used anyway, it is only there as a way to store the offsets for the
- // purposes of later accessing the names at runtime.
- if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
+ BinaryStreamReader SMReader(SecMapSubstream.StreamData);
+ const SecMapHeader *Header;
+ if (auto EC = SMReader.readObject(Header))
return EC;
-
- if (auto EC = FISR.readStreamRef(NamesBuffer))
+ if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
return EC;
-
- // We go through each ModuleInfo, determine the number N of source files for
- // that module, and then get the next N offsets from the Offsets array, using
- // them to get the corresponding N names from the Names buffer and associating
- // each one with the corresponding module.
- uint32_t NextFileIndex = 0;
- for (size_t I = 0; I < ModuleInfos.size(); ++I) {
- uint32_t NumFiles = ModFileCountArray[I];
- ModuleInfos[I].SourceFiles.resize(NumFiles);
- for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) {
- auto ThisName = getFileNameForIndex(NextFileIndex);
- if (!ThisName)
- return ThisName.takeError();
- ModuleInfos[I].SourceFiles[J] = *ThisName;
- }
- }
-
return Error::success();
}
@@ -411,16 +348,3 @@ uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
return kInvalidStreamIndex;
return DbgStreams[T];
}
-
-Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
- StreamReader Names(NamesBuffer);
- if (Index >= FileNameOffsets.size())
- return make_error<RawError>(raw_error_code::index_out_of_bounds);
-
- uint32_t FileOffset = FileNameOffsets[Index];
- Names.setOffset(FileOffset);
- StringRef Name;
- if (auto EC = Names.readZeroString(Name))
- return std::move(EC);
- return Name;
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 1d5b8d6..25076e4 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -7,31 +7,30 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Object/COFF.h"
-#include "llvm/Support/COFF.h"
+#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
-namespace {
-class ModiSubstreamBuilder {};
-}
-
DbiStreamBuilder::DbiStreamBuilder(msf::MSFBuilder &Msf)
: Msf(Msf), Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),
PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),
Header(nullptr), DbgStreams((int)DbgHeaderType::Max) {}
+DbiStreamBuilder::~DbiStreamBuilder() {}
+
void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
void DbiStreamBuilder::setAge(uint32_t A) { Age = A; }
@@ -46,17 +45,21 @@ void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
-void DbiStreamBuilder::setSectionContribs(ArrayRef<SectionContrib> Arr) {
- SectionContribs = Arr;
-}
-
void DbiStreamBuilder::setSectionMap(ArrayRef<SecMapEntry> SecMap) {
SectionMap = SecMap;
}
+void DbiStreamBuilder::setSymbolRecordStreamIndex(uint32_t Index) {
+ SymRecordStreamIndex = Index;
+}
+
+void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
+ PublicsStreamIndex = Index;
+}
+
Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
ArrayRef<uint8_t> Data) {
- if (DbgStreams[(int)Type].StreamNumber)
+ if (DbgStreams[(int)Type].StreamNumber != kInvalidStreamIndex)
return make_error<RawError>(raw_error_code::duplicate_entry,
"The specified stream type already exists");
auto ExpectedIndex = Msf.addStream(Data.size());
@@ -68,46 +71,62 @@ Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
return Error::success();
}
+uint32_t DbiStreamBuilder::addECName(StringRef Name) {
+ return ECNamesBuilder.insert(Name);
+}
+
uint32_t DbiStreamBuilder::calculateSerializedLength() const {
// For now we only support serializing the header.
return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +
- calculateSectionMapStreamSize() + calculateDbgStreamsSize();
+ calculateSectionMapStreamSize() + calculateDbgStreamsSize() +
+ ECNamesBuilder.calculateSerializedSize();
}
-Error DbiStreamBuilder::addModuleInfo(StringRef ObjFile, StringRef Module) {
- auto Entry = llvm::make_unique<ModuleInfo>();
- ModuleInfo *M = Entry.get();
- Entry->Mod = Module;
- Entry->Obj = ObjFile;
- auto Result = ModuleInfos.insert(std::make_pair(Module, std::move(Entry)));
+Expected<DbiModuleDescriptorBuilder &>
+DbiStreamBuilder::addModuleInfo(StringRef ModuleName) {
+ uint32_t Index = ModiList.size();
+ auto MIB =
+ llvm::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf);
+ auto M = MIB.get();
+ auto Result = ModiMap.insert(std::make_pair(ModuleName, std::move(MIB)));
+
if (!Result.second)
return make_error<RawError>(raw_error_code::duplicate_entry,
"The specified module already exists");
- ModuleInfoList.push_back(M);
- return Error::success();
+ ModiList.push_back(M);
+ return *M;
}
Error DbiStreamBuilder::addModuleSourceFile(StringRef Module, StringRef File) {
- auto ModIter = ModuleInfos.find(Module);
- if (ModIter == ModuleInfos.end())
+ auto ModIter = ModiMap.find(Module);
+ if (ModIter == ModiMap.end())
return make_error<RawError>(raw_error_code::no_entry,
"The specified module was not found");
+ return addModuleSourceFile(*ModIter->second, File);
+}
+
+Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
+ StringRef File) {
uint32_t Index = SourceFileNames.size();
SourceFileNames.insert(std::make_pair(File, Index));
- auto &ModEntry = *ModIter;
- ModEntry.second->SourceFiles.push_back(File);
+ Module.addSourceFile(File);
return Error::success();
}
+Expected<uint32_t> DbiStreamBuilder::getSourceFileNameIndex(StringRef File) {
+ auto NameIter = SourceFileNames.find(File);
+ if (NameIter == SourceFileNames.end())
+ return make_error<RawError>(raw_error_code::no_entry,
+ "The specified source file was not found");
+ return NameIter->getValue();
+}
+
uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {
uint32_t Size = 0;
- for (const auto &M : ModuleInfoList) {
- Size += sizeof(ModuleInfoHeader);
- Size += M->Mod.size() + 1;
- Size += M->Obj.size() + 1;
- }
- return alignTo(Size, sizeof(uint32_t));
+ for (const auto &M : ModiList)
+ Size += M->calculateSerializedLength();
+ return Size;
}
uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize() const {
@@ -123,16 +142,21 @@ uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const {
return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size();
}
-uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
- uint32_t Size = 0;
- Size += sizeof(ulittle16_t); // NumModules
- Size += sizeof(ulittle16_t); // NumSourceFiles
- Size += ModuleInfoList.size() * sizeof(ulittle16_t); // ModIndices
- Size += ModuleInfoList.size() * sizeof(ulittle16_t); // ModFileCounts
+uint32_t DbiStreamBuilder::calculateNamesOffset() const {
+ uint32_t Offset = 0;
+ Offset += sizeof(ulittle16_t); // NumModules
+ Offset += sizeof(ulittle16_t); // NumSourceFiles
+ Offset += ModiList.size() * sizeof(ulittle16_t); // ModIndices
+ Offset += ModiList.size() * sizeof(ulittle16_t); // ModFileCounts
uint32_t NumFileInfos = 0;
- for (const auto &M : ModuleInfoList)
- NumFileInfos += M->SourceFiles.size();
- Size += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets
+ for (const auto &M : ModiList)
+ NumFileInfos += M->source_files().size();
+ Offset += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets
+ return Offset;
+}
+
+uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
+ uint32_t Size = calculateNamesOffset();
Size += calculateNamesBufferSize();
return alignTo(Size, sizeof(uint32_t));
}
@@ -149,43 +173,19 @@ uint32_t DbiStreamBuilder::calculateDbgStreamsSize() const {
return DbgStreams.size() * sizeof(uint16_t);
}
-Error DbiStreamBuilder::generateModiSubstream() {
- uint32_t Size = calculateModiSubstreamSize();
- auto Data = Allocator.Allocate<uint8_t>(Size);
-
- ModInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
-
- StreamWriter ModiWriter(ModInfoBuffer);
- for (const auto &M : ModuleInfoList) {
- ModuleInfoHeader Layout = {};
- Layout.ModDiStream = kInvalidStreamIndex;
- Layout.NumFiles = M->SourceFiles.size();
- if (auto EC = ModiWriter.writeObject(Layout))
- return EC;
- if (auto EC = ModiWriter.writeZeroString(M->Mod))
- return EC;
- if (auto EC = ModiWriter.writeZeroString(M->Obj))
- return EC;
- }
- if (ModiWriter.bytesRemaining() > sizeof(uint32_t))
- return make_error<RawError>(raw_error_code::invalid_format,
- "Unexpected bytes in Modi Stream Data");
- return Error::success();
-}
-
Error DbiStreamBuilder::generateFileInfoSubstream() {
uint32_t Size = calculateFileInfoSubstreamSize();
- uint32_t NameSize = calculateNamesBufferSize();
auto Data = Allocator.Allocate<uint8_t>(Size);
- uint32_t NamesOffset = Size - NameSize;
+ uint32_t NamesOffset = calculateNamesOffset();
- FileInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
+ FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),
+ llvm::support::little);
- WritableStreamRef MetadataBuffer =
- WritableStreamRef(FileInfoBuffer).keep_front(NamesOffset);
- StreamWriter MetadataWriter(MetadataBuffer);
+ WritableBinaryStreamRef MetadataBuffer =
+ WritableBinaryStreamRef(FileInfoBuffer).keep_front(NamesOffset);
+ BinaryStreamWriter MetadataWriter(MetadataBuffer);
- uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModuleInfos.size());
+ uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModiList.size());
uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());
if (auto EC = MetadataWriter.writeInteger(ModiCount)) // NumModules
return EC;
@@ -195,8 +195,8 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
if (auto EC = MetadataWriter.writeInteger(I)) // Mod Indices
return EC;
}
- for (const auto MI : ModuleInfoList) {
- FileCount = static_cast<uint16_t>(MI->SourceFiles.size());
+ for (const auto &MI : ModiList) {
+ FileCount = static_cast<uint16_t>(MI->source_files().size());
if (auto EC = MetadataWriter.writeInteger(FileCount)) // Mod File Counts
return EC;
}
@@ -205,16 +205,16 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
// A side effect of this is that this will actually compute the various
// file name offsets, so we can then go back and write the FileNameOffsets
// array to the other substream.
- NamesBuffer = WritableStreamRef(FileInfoBuffer).drop_front(NamesOffset);
- StreamWriter NameBufferWriter(NamesBuffer);
+ NamesBuffer = WritableBinaryStreamRef(FileInfoBuffer).drop_front(NamesOffset);
+ BinaryStreamWriter NameBufferWriter(NamesBuffer);
for (auto &Name : SourceFileNames) {
Name.second = NameBufferWriter.getOffset();
- if (auto EC = NameBufferWriter.writeZeroString(Name.getKey()))
+ if (auto EC = NameBufferWriter.writeCString(Name.getKey()))
return EC;
}
- for (const auto MI : ModuleInfoList) {
- for (StringRef Name : MI->SourceFiles) {
+ for (const auto &MI : ModiList) {
+ for (StringRef Name : MI->source_files()) {
auto Result = SourceFileNames.find(Name);
if (Result == SourceFileNames.end())
return make_error<RawError>(raw_error_code::no_entry,
@@ -224,6 +224,9 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
}
}
+ if (auto EC = NameBufferWriter.padToAlignment(sizeof(uint32_t)))
+ return EC;
+
if (NameBufferWriter.bytesRemaining() > 0)
return make_error<RawError>(raw_error_code::invalid_format,
"The names buffer contained unexpected data.");
@@ -240,13 +243,14 @@ Error DbiStreamBuilder::finalize() {
if (Header)
return Error::success();
- DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
+ for (auto &MI : ModiList)
+ MI->finalize();
- if (auto EC = generateModiSubstream())
- return EC;
if (auto EC = generateFileInfoSubstream())
return EC;
+ DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
+ ::memset(H, 0, sizeof(DbiStreamHeader));
H->VersionHeader = *VerHeader;
H->VersionSignature = -1;
H->Age = Age;
@@ -256,15 +260,15 @@ Error DbiStreamBuilder::finalize() {
H->PdbDllVersion = PdbDllVersion;
H->MachineType = static_cast<uint16_t>(MachineType);
- H->ECSubstreamSize = 0;
+ H->ECSubstreamSize = ECNamesBuilder.calculateSerializedSize();
H->FileInfoSize = FileInfoBuffer.getLength();
- H->ModiSubstreamSize = ModInfoBuffer.getLength();
+ H->ModiSubstreamSize = calculateModiSubstreamSize();
H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
H->SecContrSubstreamSize = calculateSectionContribsStreamSize();
H->SectionMapSize = calculateSectionMapStreamSize();
H->TypeServerSize = 0;
- H->SymRecordStreamIndex = kInvalidStreamIndex;
- H->PublicSymbolStreamIndex = kInvalidStreamIndex;
+ H->SymRecordStreamIndex = SymRecordStreamIndex;
+ H->PublicSymbolStreamIndex = PublicsStreamIndex;
H->MFCTypeServerIndex = kInvalidStreamIndex;
H->GlobalSymbolStreamIndex = kInvalidStreamIndex;
@@ -273,6 +277,11 @@ Error DbiStreamBuilder::finalize() {
}
Error DbiStreamBuilder::finalizeMsfLayout() {
+ for (auto &MI : ModiList) {
+ if (auto EC = MI->finalizeMsfLayout())
+ return EC;
+ }
+
uint32_t Length = calculateSerializedLength();
if (auto EC = Msf.setStreamSize(StreamDBI, Length))
return EC;
@@ -298,23 +307,17 @@ static uint16_t toSecMapFlags(uint32_t Flags) {
return Ret;
}
-// A utility function to create Section Contributions
-// for a given input sections.
-std::vector<SectionContrib> DbiStreamBuilder::createSectionContribs(
- ArrayRef<object::coff_section> SecHdrs) {
- std::vector<SectionContrib> Ret;
-
- // Create a SectionContrib for each input section.
- for (auto &Sec : SecHdrs) {
- Ret.emplace_back();
- auto &Entry = Ret.back();
- memset(&Entry, 0, sizeof(Entry));
-
- Entry.Off = Sec.PointerToRawData;
- Entry.Size = Sec.SizeOfRawData;
- Entry.Characteristics = Sec.Characteristics;
- }
- return Ret;
+void DbiStreamBuilder::addSectionContrib(DbiModuleDescriptorBuilder *ModuleDbi,
+ const object::coff_section *SecHdr) {
+ SectionContrib SC;
+ memset(&SC, 0, sizeof(SC));
+ SC.ISect = (uint16_t)~0U; // This represents nil.
+ SC.Off = SecHdr->PointerToRawData;
+ SC.Size = SecHdr->SizeOfRawData;
+ SC.Characteristics = SecHdr->Characteristics;
+ // Use the module index in the module dbi stream or nil (-1).
+ SC.Imod = ModuleDbi ? ModuleDbi->getModuleIndex() : (uint16_t)~0U;
+ SectionContribs.emplace_back(SC);
}
// A utility function to create a Section Map for a given list of COFF sections.
@@ -358,24 +361,26 @@ std::vector<SecMapEntry> DbiStreamBuilder::createSectionMap(
}
Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
- const msf::WritableStream &Buffer) {
+ WritableBinaryStreamRef MsfBuffer) {
if (auto EC = finalize())
return EC;
- auto InfoS =
- WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamDBI);
+ auto DbiS = WritableMappedBlockStream::createIndexedStream(
+ Layout, MsfBuffer, StreamDBI, Allocator);
- StreamWriter Writer(*InfoS);
+ BinaryStreamWriter Writer(*DbiS);
if (auto EC = Writer.writeObject(*Header))
return EC;
- if (auto EC = Writer.writeStreamRef(ModInfoBuffer))
- return EC;
+ for (auto &M : ModiList) {
+ if (auto EC = M->commit(Writer, Layout, MsfBuffer))
+ return EC;
+ }
if (!SectionContribs.empty()) {
if (auto EC = Writer.writeEnum(DbiSecContribVer60))
return EC;
- if (auto EC = Writer.writeArray(SectionContribs))
+ if (auto EC = Writer.writeArray(makeArrayRef(SectionContribs)))
return EC;
}
@@ -391,6 +396,9 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
return EC;
+ if (auto EC = ECNamesBuilder.commit(Writer))
+ return EC;
+
for (auto &Stream : DbgStreams)
if (auto EC = Writer.writeInteger(Stream.StreamNumber))
return EC;
@@ -399,8 +407,8 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (Stream.StreamNumber == kInvalidStreamIndex)
continue;
auto WritableStream = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, Stream.StreamNumber);
- StreamWriter DbgStreamWriter(*WritableStream);
+ Layout, MsfBuffer, Stream.StreamNumber, Allocator);
+ BinaryStreamWriter DbgStreamWriter(*WritableStream);
if (auto EC = DbgStreamWriter.writeArray(Stream.Data))
return EC;
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
index fc9270c..b3837dc 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/EnumTables.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/EnumTables.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/Raw/EnumTables.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
using namespace llvm;
using namespace llvm::pdb;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/GSI.cpp
index 6ecbb5c..b219fe2 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/GSI.cpp
@@ -9,10 +9,10 @@
#include "GSI.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
@@ -28,9 +28,9 @@ static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
return Error::success();
}
-Error readGSIHashBuckets(
- msf::FixedStreamArray<support::ulittle32_t> &HashBuckets,
- const GSIHashHeader *HashHdr, msf::StreamReader &Reader) {
+Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+ const GSIHashHeader *HashHdr,
+ BinaryStreamReader &Reader) {
if (auto EC = checkHashHdrVersion(HashHdr))
return EC;
@@ -57,7 +57,7 @@ Error readGSIHashBuckets(
}
Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
- msf::StreamReader &Reader) {
+ BinaryStreamReader &Reader) {
if (Reader.readObject(HashHdr))
return make_error<RawError>(raw_error_code::corrupt_file,
"Stream does not contain a GSIHashHeader.");
@@ -70,9 +70,9 @@ Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
return Error::success();
}
-Error readGSIHashRecords(msf::FixedStreamArray<PSHashRecord> &HashRecords,
+Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
const GSIHashHeader *HashHdr,
- msf::StreamReader &Reader) {
+ BinaryStreamReader &Reader) {
if (auto EC = checkHashHdrVersion(HashHdr))
return EC;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.h b/contrib/llvm/lib/DebugInfo/PDB/Native/GSI.h
index 82cebd9..9e63bc8 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/GSI.h
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/GSI.h
@@ -25,17 +25,15 @@
#ifndef LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H
#define LLVM_LIB_DEBUGINFO_PDB_RAW_GSI_H
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
namespace llvm {
-namespace msf {
-class StreamReader;
-}
+class BinaryStreamReader;
namespace pdb {
@@ -56,14 +54,14 @@ struct GSIHashHeader {
support::ulittle32_t NumBuckets;
};
-Error readGSIHashBuckets(
- msf::FixedStreamArray<support::ulittle32_t> &HashBuckets,
- const GSIHashHeader *HashHdr, msf::StreamReader &Reader);
+Error readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+ const GSIHashHeader *HashHdr,
+ BinaryStreamReader &Reader);
Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
- msf::StreamReader &Reader);
-Error readGSIHashRecords(msf::FixedStreamArray<PSHashRecord> &HashRecords,
+ BinaryStreamReader &Reader);
+Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
const GSIHashHeader *HashHdr,
- msf::StreamReader &Reader);
+ BinaryStreamReader &Reader);
}
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
index 31afc92..a2ee0f0 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/GlobalsStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "GSI.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/GlobalsStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -23,7 +23,7 @@ GlobalsStream::GlobalsStream(std::unique_ptr<MappedBlockStream> Stream)
GlobalsStream::~GlobalsStream() = default;
Error GlobalsStream::reload() {
- StreamReader Reader(*Stream);
+ BinaryStreamReader Reader(*Stream);
const GSIHashHeader *HashHdr;
if (auto EC = readGSIHashHeader(HashHdr, Reader))
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/Hash.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/Hash.cpp
index b9f685e..61188ec 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/Hash.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/Hash.cpp
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/Raw/Hash.h"
-
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/JamCRC.h"
+#include <cstdint>
using namespace llvm;
using namespace llvm::support;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp
new file mode 100644
index 0000000..439217f
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/HashTable.cpp
@@ -0,0 +1,308 @@
+//===- HashTable.cpp - PDB Hash Table -------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+HashTable::HashTable() : HashTable(8) {}
+
+HashTable::HashTable(uint32_t Capacity) { Buckets.resize(Capacity); }
+
+Error HashTable::load(BinaryStreamReader &Stream) {
+ const Header *H;
+ if (auto EC = Stream.readObject(H))
+ return EC;
+ if (H->Capacity == 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid Hash Table Capacity");
+ if (H->Size > maxLoad(H->Capacity))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid Hash Table Size");
+
+ Buckets.resize(H->Capacity);
+
+ if (auto EC = readSparseBitVector(Stream, Present))
+ return EC;
+ if (Present.count() != H->Size)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Present bit vector does not match size!");
+
+ if (auto EC = readSparseBitVector(Stream, Deleted))
+ return EC;
+ if (Present.intersects(Deleted))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Present bit vector interesects deleted!");
+
+ for (uint32_t P : Present) {
+ if (auto EC = Stream.readInteger(Buckets[P].first))
+ return EC;
+ if (auto EC = Stream.readInteger(Buckets[P].second))
+ return EC;
+ }
+
+ return Error::success();
+}
+
+uint32_t HashTable::calculateSerializedLength() const {
+ uint32_t Size = sizeof(Header);
+
+ int NumBitsP = Present.find_last() + 1;
+ int NumBitsD = Deleted.find_last() + 1;
+
+ // Present bit set number of words, followed by that many actual words.
+ Size += sizeof(uint32_t);
+ Size += alignTo(NumBitsP, sizeof(uint32_t));
+
+ // Deleted bit set number of words, followed by that many actual words.
+ Size += sizeof(uint32_t);
+ Size += alignTo(NumBitsD, sizeof(uint32_t));
+
+ // One (Key, Value) pair for each entry Present.
+ Size += 2 * sizeof(uint32_t) * size();
+
+ return Size;
+}
+
+Error HashTable::commit(BinaryStreamWriter &Writer) const {
+ Header H;
+ H.Size = size();
+ H.Capacity = capacity();
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+
+ if (auto EC = writeSparseBitVector(Writer, Present))
+ return EC;
+
+ if (auto EC = writeSparseBitVector(Writer, Deleted))
+ return EC;
+
+ for (const auto &Entry : *this) {
+ if (auto EC = Writer.writeInteger(Entry.first))
+ return EC;
+ if (auto EC = Writer.writeInteger(Entry.second))
+ return EC;
+ }
+ return Error::success();
+}
+
+void HashTable::clear() {
+ Buckets.resize(8);
+ Present.clear();
+ Deleted.clear();
+}
+
+uint32_t HashTable::capacity() const { return Buckets.size(); }
+
+uint32_t HashTable::size() const { return Present.count(); }
+
+HashTableIterator HashTable::begin() const { return HashTableIterator(*this); }
+
+HashTableIterator HashTable::end() const {
+ return HashTableIterator(*this, 0, true);
+}
+
+HashTableIterator HashTable::find(uint32_t K) {
+ uint32_t H = K % capacity();
+ uint32_t I = H;
+ Optional<uint32_t> FirstUnused;
+ do {
+ if (isPresent(I)) {
+ if (Buckets[I].first == K)
+ return HashTableIterator(*this, I, false);
+ } else {
+ if (!FirstUnused)
+ FirstUnused = I;
+ // Insertion occurs via linear probing from the slot hint, and will be
+ // inserted at the first empty / deleted location. Therefore, if we are
+ // probing and find a location that is neither present nor deleted, then
+ // nothing must have EVER been inserted at this location, and thus it is
+ // not possible for a matching value to occur later.
+ if (!isDeleted(I))
+ break;
+ }
+ I = (I + 1) % capacity();
+ } while (I != H);
+
+ // The only way FirstUnused would not be set is if every single entry in the
+ // table were Present. But this would violate the load factor constraints
+ // that we impose, so it should never happen.
+ assert(FirstUnused);
+ return HashTableIterator(*this, *FirstUnused, true);
+}
+
+void HashTable::set(uint32_t K, uint32_t V) {
+ auto Entry = find(K);
+ if (Entry != end()) {
+ assert(isPresent(Entry.index()));
+ assert(Buckets[Entry.index()].first == K);
+ // We're updating, no need to do anything special.
+ Buckets[Entry.index()].second = V;
+ return;
+ }
+
+ auto &B = Buckets[Entry.index()];
+ assert(!isPresent(Entry.index()));
+ assert(Entry.isEnd());
+ B.first = K;
+ B.second = V;
+ Present.set(Entry.index());
+ Deleted.reset(Entry.index());
+
+ grow();
+
+ assert(find(K) != end());
+}
+
+void HashTable::remove(uint32_t K) {
+ auto Iter = find(K);
+ // It wasn't here to begin with, just exit.
+ if (Iter == end())
+ return;
+
+ assert(Present.test(Iter.index()));
+ assert(!Deleted.test(Iter.index()));
+ Deleted.set(Iter.index());
+ Present.reset(Iter.index());
+}
+
+uint32_t HashTable::get(uint32_t K) {
+ auto I = find(K);
+ assert(I != end());
+ return (*I).second;
+}
+
+uint32_t HashTable::maxLoad(uint32_t capacity) { return capacity * 2 / 3 + 1; }
+
+void HashTable::grow() {
+ uint32_t S = size();
+ if (S < maxLoad(capacity()))
+ return;
+ assert(capacity() != UINT32_MAX && "Can't grow Hash table!");
+
+ uint32_t NewCapacity =
+ (capacity() <= INT32_MAX) ? capacity() * 2 : UINT32_MAX;
+
+ // Growing requires rebuilding the table and re-hashing every item. Make a
+ // copy with a larger capacity, insert everything into the copy, then swap
+ // it in.
+ HashTable NewMap(NewCapacity);
+ for (auto I : Present) {
+ NewMap.set(Buckets[I].first, Buckets[I].second);
+ }
+
+ Buckets.swap(NewMap.Buckets);
+ std::swap(Present, NewMap.Present);
+ std::swap(Deleted, NewMap.Deleted);
+ assert(capacity() == NewCapacity);
+ assert(size() == S);
+}
+
+Error HashTable::readSparseBitVector(BinaryStreamReader &Stream,
+ SparseBitVector<> &V) {
+ uint32_t NumWords;
+ if (auto EC = Stream.readInteger(NumWords))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected hash table number of words"));
+
+ for (uint32_t I = 0; I != NumWords; ++I) {
+ uint32_t Word;
+ if (auto EC = Stream.readInteger(Word))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected hash table word"));
+ for (unsigned Idx = 0; Idx < 32; ++Idx)
+ if (Word & (1U << Idx))
+ V.set((I * 32) + Idx);
+ }
+ return Error::success();
+}
+
+Error HashTable::writeSparseBitVector(BinaryStreamWriter &Writer,
+ SparseBitVector<> &Vec) {
+ int ReqBits = Vec.find_last() + 1;
+ uint32_t NumWords = alignTo(ReqBits, sizeof(uint32_t)) / sizeof(uint32_t);
+ if (auto EC = Writer.writeInteger(NumWords))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not write linear map number of words"));
+
+ uint32_t Idx = 0;
+ for (uint32_t I = 0; I != NumWords; ++I) {
+ uint32_t Word = 0;
+ for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) {
+ if (Vec.test(Idx))
+ Word |= (1 << WordIdx);
+ }
+ if (auto EC = Writer.writeInteger(Word))
+ return joinErrors(std::move(EC), make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "Could not write linear map word"));
+ }
+ return Error::success();
+}
+
+HashTableIterator::HashTableIterator(const HashTable &Map, uint32_t Index,
+ bool IsEnd)
+ : Map(&Map), Index(Index), IsEnd(IsEnd) {}
+
+HashTableIterator::HashTableIterator(const HashTable &Map) : Map(&Map) {
+ int I = Map.Present.find_first();
+ if (I == -1) {
+ Index = 0;
+ IsEnd = true;
+ } else {
+ Index = static_cast<uint32_t>(I);
+ IsEnd = false;
+ }
+}
+
+HashTableIterator &HashTableIterator::operator=(const HashTableIterator &R) {
+ Map = R.Map;
+ return *this;
+}
+
+bool HashTableIterator::operator==(const HashTableIterator &R) const {
+ if (IsEnd && R.IsEnd)
+ return true;
+ if (IsEnd != R.IsEnd)
+ return false;
+
+ return (Map == R.Map) && (Index == R.Index);
+}
+
+const std::pair<uint32_t, uint32_t> &HashTableIterator::operator*() const {
+ assert(Map->Present.test(Index));
+ return Map->Buckets[Index];
+}
+
+HashTableIterator &HashTableIterator::operator++() {
+ while (Index < Map->Buckets.size()) {
+ ++Index;
+ if (Map->Present.test(Index))
+ return *this;
+ }
+
+ IsEnd = true;
+ return *this;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
new file mode 100644
index 0000000..8298790
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStream.cpp
@@ -0,0 +1,139 @@
+//===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
+ : Stream(std::move(Stream)) {}
+
+Error InfoStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ const InfoStreamHeader *H;
+ if (auto EC = Reader.readObject(H))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "PDB Stream does not contain a header."));
+
+ switch (H->Version) {
+ case PdbImplVC70:
+ case PdbImplVC80:
+ case PdbImplVC110:
+ case PdbImplVC140:
+ break;
+ default:
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unsupported PDB stream version.");
+ }
+
+ Version = H->Version;
+ Signature = H->Signature;
+ Age = H->Age;
+ Guid = H->Guid;
+
+ uint32_t Offset = Reader.getOffset();
+ if (auto EC = NamedStreams.load(Reader))
+ return EC;
+ uint32_t NewOffset = Reader.getOffset();
+ NamedStreamMapByteSize = NewOffset - Offset;
+
+ Reader.setOffset(Offset);
+ if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
+ return EC;
+
+ bool Stop = false;
+ while (!Stop && !Reader.empty()) {
+ PdbRaw_FeatureSig Sig;
+ if (auto EC = Reader.readEnum(Sig))
+ return EC;
+ // Since this value comes from a file, it's possible we have some strange
+ // value which doesn't correspond to any value. We don't want to warn on
+ // -Wcovered-switch-default in this case, so switch on the integral value
+ // instead of the enumeration value.
+ switch (uint32_t(Sig)) {
+ case uint32_t(PdbRaw_FeatureSig::VC110):
+ // No other flags for VC110 PDB.
+ Stop = true;
+ LLVM_FALLTHROUGH;
+ case uint32_t(PdbRaw_FeatureSig::VC140):
+ Features |= PdbFeatureContainsIdStream;
+ break;
+ case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
+ Features |= PdbFeatureNoTypeMerging;
+ break;
+ case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
+ Features |= PdbFeatureMinimalDebugInfo;
+ break;
+ default:
+ continue;
+ }
+ FeatureSignatures.push_back(Sig);
+ }
+ return Error::success();
+}
+
+uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
+
+uint32_t InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
+ uint32_t Result;
+ if (!NamedStreams.get(Name, Result))
+ return 0;
+ return Result;
+}
+
+iterator_range<StringMapConstIterator<uint32_t>>
+InfoStream::named_streams() const {
+ return NamedStreams.entries();
+}
+
+bool InfoStream::containsIdStream() const {
+ return !!(Features & PdbFeatureContainsIdStream);
+}
+
+PdbRaw_ImplVer InfoStream::getVersion() const {
+ return static_cast<PdbRaw_ImplVer>(Version);
+}
+
+uint32_t InfoStream::getSignature() const { return Signature; }
+
+uint32_t InfoStream::getAge() const { return Age; }
+
+GUID InfoStream::getGuid() const { return Guid; }
+
+uint32_t InfoStream::getNamedStreamMapByteSize() const {
+ return NamedStreamMapByteSize;
+}
+
+PdbRaw_Features InfoStream::getFeatures() const { return Features; }
+
+ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
+ return FeatureSignatures;
+}
+
+const NamedStreamMap &InfoStream::getNamedStreams() const {
+ return NamedStreams;
+}
+
+BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
+ return SubNamedStreams;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
new file mode 100644
index 0000000..6450ae7
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
@@ -0,0 +1,74 @@
+//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
+ NamedStreamMap &NamedStreams)
+ : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0),
+ NamedStreams(NamedStreams) {}
+
+void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
+
+void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; }
+
+void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
+
+void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
+
+void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
+ Features.push_back(Sig);
+}
+
+Error InfoStreamBuilder::finalizeMsfLayout() {
+ uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize() +
+ (Features.size() + 1) * sizeof(uint32_t);
+ if (auto EC = Msf.setStreamSize(StreamPDB, Length))
+ return EC;
+ return Error::success();
+}
+
+Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef Buffer) const {
+ auto InfoS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, StreamPDB, Msf.getAllocator());
+ BinaryStreamWriter Writer(*InfoS);
+
+ InfoStreamHeader H;
+ H.Age = Age;
+ H.Signature = Sig;
+ H.Version = Ver;
+ H.Guid = Guid;
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+
+ if (auto EC = NamedStreams.commit(Writer))
+ return EC;
+ if (auto EC = Writer.writeInteger(0))
+ return EC;
+ for (auto E : Features) {
+ if (auto EC = Writer.writeEnum(E))
+ return EC;
+ }
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
new file mode 100644
index 0000000..2e1f61c
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -0,0 +1,123 @@
+//===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+ModuleDebugStreamRef::ModuleDebugStreamRef(
+ const DbiModuleDescriptor &Module,
+ std::unique_ptr<MappedBlockStream> Stream)
+ : Mod(Module), Stream(std::move(Stream)) {}
+
+ModuleDebugStreamRef::~ModuleDebugStreamRef() = default;
+
+Error ModuleDebugStreamRef::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
+ uint32_t C11Size = Mod.getC11LineInfoByteSize();
+ uint32_t C13Size = Mod.getC13LineInfoByteSize();
+
+ if (C11Size > 0 && C13Size > 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Module has both C11 and C13 line info");
+
+ BinaryStreamRef S;
+
+ if (auto EC = Reader.readInteger(Signature))
+ return EC;
+ if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4))
+ return EC;
+ if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
+ return EC;
+ if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
+ return EC;
+
+ BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
+ if (auto EC =
+ SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining()))
+ return EC;
+
+ BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
+ if (auto EC = SubsectionsReader.readArray(Subsections,
+ SubsectionsReader.bytesRemaining()))
+ return EC;
+
+ uint32_t GlobalRefsSize;
+ if (auto EC = Reader.readInteger(GlobalRefsSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
+ return EC;
+ if (Reader.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unexpected bytes in module stream.");
+
+ return Error::success();
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
+ return SymbolsSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
+ return C11LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
+ return C13LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
+ return GlobalRefsSubstream;
+}
+
+iterator_range<codeview::CVSymbolArray::Iterator>
+ModuleDebugStreamRef::symbols(bool *HadError) const {
+ return make_range(SymbolArray.begin(HadError), SymbolArray.end());
+}
+
+iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
+ModuleDebugStreamRef::subsections() const {
+ return make_range(Subsections.begin(), Subsections.end());
+}
+
+bool ModuleDebugStreamRef::hasDebugSubsections() const {
+ return !C13LinesSubstream.empty();
+}
+
+Error ModuleDebugStreamRef::commit() { return Error::success(); }
+
+Expected<codeview::DebugChecksumsSubsectionRef>
+ModuleDebugStreamRef::findChecksumsSubsection() const {
+ codeview::DebugChecksumsSubsectionRef Result;
+ for (const auto &SS : subsections()) {
+ if (SS.kind() != DebugSubsectionKind::FileChecksums)
+ continue;
+
+ if (auto EC = Result.initialize(SS.getRecordData()))
+ return std::move(EC);
+ return Result;
+ }
+ return Result;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
new file mode 100644
index 0000000..6cdf6dd
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -0,0 +1,152 @@
+//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <tuple>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+// FIXME: This shouldn't be necessary, but if we insert the strings in any
+// other order, cvdump cannot read the generated name map. This suggests that
+// we may be using the wrong hash function. A closer inspection of the cvdump
+// source code may reveal something, but for now this at least makes us work,
+// even if only by accident.
+static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
+ "/src/headerblock"};
+
+NamedStreamMap::NamedStreamMap() = default;
+
+Error NamedStreamMap::load(BinaryStreamReader &Stream) {
+ Mapping.clear();
+ FinalizedHashTable.clear();
+ FinalizedInfo.reset();
+
+ uint32_t StringBufferSize;
+ if (auto EC = Stream.readInteger(StringBufferSize))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected string buffer size"));
+
+ BinaryStreamRef StringsBuffer;
+ if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
+ return EC;
+
+ HashTable OffsetIndexMap;
+ if (auto EC = OffsetIndexMap.load(Stream))
+ return EC;
+
+ uint32_t NameOffset;
+ uint32_t NameIndex;
+ for (const auto &Entry : OffsetIndexMap) {
+ std::tie(NameOffset, NameIndex) = Entry;
+
+ // Compute the offset of the start of the string relative to the stream.
+ BinaryStreamReader NameReader(StringsBuffer);
+ NameReader.setOffset(NameOffset);
+ // Pump out our c-string from the stream.
+ StringRef Str;
+ if (auto EC = NameReader.readCString(Str))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected name map name"));
+
+ // Add this to a string-map from name to stream number.
+ Mapping.insert({Str, NameIndex});
+ }
+
+ return Error::success();
+}
+
+Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
+ assert(FinalizedInfo.hasValue());
+
+ // The first field is the number of bytes of string data.
+ if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
+ return EC;
+
+ for (const auto &Name : OrderedStreamNames) {
+ auto Item = Mapping.find(Name);
+ if (Item == Mapping.end())
+ continue;
+ if (auto EC = Writer.writeCString(Item->getKey()))
+ return EC;
+ }
+
+ // And finally the Offset Index map.
+ if (auto EC = FinalizedHashTable.commit(Writer))
+ return EC;
+
+ return Error::success();
+}
+
+uint32_t NamedStreamMap::finalize() {
+ if (FinalizedInfo.hasValue())
+ return FinalizedInfo->SerializedLength;
+
+ // Build the finalized hash table.
+ FinalizedHashTable.clear();
+ FinalizedInfo.emplace();
+
+ for (const auto &Name : OrderedStreamNames) {
+ auto Item = Mapping.find(Name);
+ if (Item == Mapping.end())
+ continue;
+ FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
+ FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
+ }
+
+ // Number of bytes of string data.
+ FinalizedInfo->SerializedLength += sizeof(support::ulittle32_t);
+ // Followed by that many actual bytes of string data.
+ FinalizedInfo->SerializedLength += FinalizedInfo->StringDataBytes;
+ // Followed by the mapping from Offset to Index.
+ FinalizedInfo->SerializedLength +=
+ FinalizedHashTable.calculateSerializedLength();
+ return FinalizedInfo->SerializedLength;
+}
+
+iterator_range<StringMapConstIterator<uint32_t>>
+NamedStreamMap::entries() const {
+ return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
+ Mapping.end());
+}
+
+uint32_t NamedStreamMap::size() const { return Mapping.size(); }
+
+bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
+ auto Iter = Mapping.find(Stream);
+ if (Iter == Mapping.end())
+ return false;
+ StreamNo = Iter->second;
+ return true;
+}
+
+void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
+ FinalizedInfo.reset();
+ Mapping[Stream] = StreamNo;
+}
+
+void NamedStreamMap::remove(StringRef Stream) {
+ FinalizedInfo.reset();
+ Mapping.erase(Stream);
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp
new file mode 100644
index 0000000..60416f6
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp
@@ -0,0 +1,48 @@
+//===- NativeBuiltinSymbol.cpp ------------------------------------ C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
+
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeBuiltinSymbol::NativeBuiltinSymbol(NativeSession &PDBSession,
+ SymIndexId Id, PDB_BuiltinType T,
+ uint64_t L)
+ : NativeRawSymbol(PDBSession, Id), Session(PDBSession), Type(T), Length(L) {
+}
+
+NativeBuiltinSymbol::~NativeBuiltinSymbol() {}
+
+std::unique_ptr<NativeRawSymbol> NativeBuiltinSymbol::clone() const {
+ return llvm::make_unique<NativeBuiltinSymbol>(Session, SymbolId, Type, Length);
+}
+
+void NativeBuiltinSymbol::dump(raw_ostream &OS, int Indent) const {
+ // TODO: Apparently nothing needs this yet.
+}
+
+PDB_SymType NativeBuiltinSymbol::getSymTag() const {
+ return PDB_SymType::BuiltinType;
+}
+
+PDB_BuiltinType NativeBuiltinSymbol::getBuiltinType() const { return Type; }
+
+bool NativeBuiltinSymbol::isConstType() const { return false; }
+
+uint64_t NativeBuiltinSymbol::getLength() const { return Length; }
+
+bool NativeBuiltinSymbol::isUnalignedType() const { return false; }
+
+bool NativeBuiltinSymbol::isVolatileType() const { return false; }
+
+} // namespace pdb
+} // namespace llvm
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
new file mode 100644
index 0000000..7132a99
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -0,0 +1,50 @@
+//===- NativeCompilandSymbol.cpp - Native impl for compilands ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
+ SymIndexId SymbolId,
+ DbiModuleDescriptor MI)
+ : NativeRawSymbol(Session, SymbolId), Module(MI) {}
+
+PDB_SymType NativeCompilandSymbol::getSymTag() const {
+ return PDB_SymType::Compiland;
+}
+
+std::unique_ptr<NativeRawSymbol> NativeCompilandSymbol::clone() const {
+ return llvm::make_unique<NativeCompilandSymbol>(Session, SymbolId, Module);
+}
+
+bool NativeCompilandSymbol::isEditAndContinueEnabled() const {
+ return Module.hasECInfo();
+}
+
+uint32_t NativeCompilandSymbol::getLexicalParentId() const { return 0; }
+
+// The usage of getObjFileName for getLibraryName and getModuleName for getName
+// may seem backwards, but it is consistent with DIA, which is what this API
+// was modeled after. We may rename these methods later to try to eliminate
+// this potential confusion.
+
+std::string NativeCompilandSymbol::getLibraryName() const {
+ return Module.getObjFileName();
+}
+
+std::string NativeCompilandSymbol::getName() const {
+ return Module.getModuleName();
+}
+
+} // namespace pdb
+} // namespace llvm
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
new file mode 100644
index 0000000..a65782e
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
@@ -0,0 +1,51 @@
+//==- NativeEnumModules.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeEnumModules::NativeEnumModules(NativeSession &PDBSession,
+ const DbiModuleList &Modules,
+ uint32_t Index)
+ : Session(PDBSession), Modules(Modules), Index(Index) {}
+
+uint32_t NativeEnumModules::getChildCount() const {
+ return static_cast<uint32_t>(Modules.getModuleCount());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumModules::getChildAtIndex(uint32_t Index) const {
+ if (Index >= Modules.getModuleCount())
+ return nullptr;
+ return Session.createCompilandSymbol(Modules.getModuleDescriptor(Index));
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() {
+ if (Index >= Modules.getModuleCount())
+ return nullptr;
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumModules::reset() { Index = 0; }
+
+NativeEnumModules *NativeEnumModules::clone() const {
+ return new NativeEnumModules(Session, Modules, Index);
+}
+
+}
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
new file mode 100644
index 0000000..3241000
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -0,0 +1,84 @@
+//===- NativeExeSymbol.cpp - native impl for PDBSymbolExe -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
+ : NativeRawSymbol(Session, SymbolId), File(Session.getPDBFile()) {}
+
+std::unique_ptr<NativeRawSymbol> NativeExeSymbol::clone() const {
+ return llvm::make_unique<NativeExeSymbol>(Session, SymbolId);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeExeSymbol::findChildren(PDB_SymType Type) const {
+ switch (Type) {
+ case PDB_SymType::Compiland: {
+ auto Dbi = File.getPDBDbiStream();
+ if (Dbi) {
+ const DbiModuleList &Modules = Dbi->modules();
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumModules(Session, Modules));
+ }
+ consumeError(Dbi.takeError());
+ break;
+ }
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+uint32_t NativeExeSymbol::getAge() const {
+ auto IS = File.getPDBInfoStream();
+ if (IS)
+ return IS->getAge();
+ consumeError(IS.takeError());
+ return 0;
+}
+
+std::string NativeExeSymbol::getSymbolsFileName() const {
+ return File.getFilePath();
+}
+
+codeview::GUID NativeExeSymbol::getGuid() const {
+ auto IS = File.getPDBInfoStream();
+ if (IS)
+ return IS->getGuid();
+ consumeError(IS.takeError());
+ return codeview::GUID{{0}};
+}
+
+bool NativeExeSymbol::hasCTypes() const {
+ auto Dbi = File.getPDBDbiStream();
+ if (Dbi)
+ return Dbi->hasCTypes();
+ consumeError(Dbi.takeError());
+ return false;
+}
+
+bool NativeExeSymbol::hasPrivateSymbols() const {
+ auto Dbi = File.getPDBDbiStream();
+ if (Dbi)
+ return !Dbi->isStripped();
+ consumeError(Dbi.takeError());
+ return false;
+}
+
+} // namespace pdb
+} // namespace llvm
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
new file mode 100644
index 0000000..df3f418
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -0,0 +1,694 @@
+//===- NativeRawSymbol.cpp - Native implementation of IPDBRawSymbol -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId)
+ : Session(PDBSession), SymbolId(SymbolId) {}
+
+void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildren(PDB_SymType Type) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags, uint32_t RVA) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
+ return nullptr;
+}
+
+void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
+ bytes.clear();
+}
+
+PDB_MemberAccess NativeRawSymbol::getAccess() const {
+ return PDB_MemberAccess::Private;
+}
+
+uint32_t NativeRawSymbol::getAddressOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getAddressSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getAge() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getArrayIndexTypeId() const {
+ return 0;
+}
+
+void NativeRawSymbol::getBackEndVersion(VersionInfo &Version) const {
+ Version.Major = 0;
+ Version.Minor = 0;
+ Version.Build = 0;
+ Version.QFE = 0;
+}
+
+uint32_t NativeRawSymbol::getBaseDataOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getBaseDataSlot() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getBaseSymbolId() const {
+ return 0;
+}
+
+PDB_BuiltinType NativeRawSymbol::getBuiltinType() const {
+ return PDB_BuiltinType::None;
+}
+
+uint32_t NativeRawSymbol::getBitPosition() const {
+ return 0;
+}
+
+PDB_CallingConv NativeRawSymbol::getCallingConvention() const {
+ return PDB_CallingConv::FarStdCall;
+}
+
+uint32_t NativeRawSymbol::getClassParentId() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getCompilerName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getCount() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getCountLiveRanges() const {
+ return 0;
+}
+
+void NativeRawSymbol::getFrontEndVersion(VersionInfo &Version) const {
+ Version.Major = 0;
+ Version.Minor = 0;
+ Version.Build = 0;
+ Version.QFE = 0;
+}
+
+PDB_Lang NativeRawSymbol::getLanguage() const {
+ return PDB_Lang::Cobol;
+}
+
+uint32_t NativeRawSymbol::getLexicalParentId() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getLibraryName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartAddressOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartAddressSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartRelativeVirtualAddress() const {
+ return 0;
+}
+
+codeview::RegisterId NativeRawSymbol::getLocalBasePointerRegisterId() const {
+ return codeview::RegisterId::EAX;
+}
+
+uint32_t NativeRawSymbol::getLowerBoundId() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getMemorySpaceKind() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getNumberOfAcceleratorPointerTags() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfColumns() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfModifiers() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfRegisterIndices() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfRows() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getObjectFileName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getOemId() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getOemSymbolId() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getOffsetInUdt() const {
+ return 0;
+}
+
+PDB_Cpu NativeRawSymbol::getPlatform() const {
+ return PDB_Cpu::Intel8080;
+}
+
+uint32_t NativeRawSymbol::getRank() const {
+ return 0;
+}
+
+codeview::RegisterId NativeRawSymbol::getRegisterId() const {
+ return codeview::RegisterId::EAX;
+}
+
+uint32_t NativeRawSymbol::getRegisterType() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getRelativeVirtualAddress() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSamplerSlot() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSignature() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSizeInUdt() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSlot() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getSourceFileName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getStride() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSubTypeId() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getSymbolsFileName() const { return {}; }
+
+uint32_t NativeRawSymbol::getSymIndexId() const { return SymbolId; }
+
+uint32_t NativeRawSymbol::getTargetOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTargetRelativeVirtualAddress() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getTargetVirtualAddress() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTargetSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTextureSlot() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTimeStamp() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getToken() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTypeId() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getUavSlot() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getUndecoratedName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getUnmodifiedTypeId() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getUpperBoundId() const {
+ return 0;
+}
+
+Variant NativeRawSymbol::getValue() const {
+ return Variant();
+}
+
+uint32_t NativeRawSymbol::getVirtualBaseDispIndex() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getVirtualBaseOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getVirtualTableShapeId() const {
+ return 0;
+}
+
+std::unique_ptr<PDBSymbolTypeBuiltin>
+NativeRawSymbol::getVirtualBaseTableType() const {
+ return nullptr;
+}
+
+PDB_DataKind NativeRawSymbol::getDataKind() const {
+ return PDB_DataKind::Unknown;
+}
+
+PDB_SymType NativeRawSymbol::getSymTag() const {
+ return PDB_SymType::None;
+}
+
+codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }
+
+int32_t NativeRawSymbol::getOffset() const {
+ return 0;
+}
+
+int32_t NativeRawSymbol::getThisAdjust() const {
+ return 0;
+}
+
+int32_t NativeRawSymbol::getVirtualBasePointerOffset() const {
+ return 0;
+}
+
+PDB_LocType NativeRawSymbol::getLocationType() const {
+ return PDB_LocType::Null;
+}
+
+PDB_Machine NativeRawSymbol::getMachineType() const {
+ return PDB_Machine::Invalid;
+}
+
+codeview::ThunkOrdinal NativeRawSymbol::getThunkOrdinal() const {
+ return codeview::ThunkOrdinal::Standard;
+}
+
+uint64_t NativeRawSymbol::getLength() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getLiveRangeLength() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getVirtualAddress() const {
+ return 0;
+}
+
+PDB_UdtType NativeRawSymbol::getUdtKind() const {
+ return PDB_UdtType::Struct;
+}
+
+bool NativeRawSymbol::hasConstructor() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCustomCallingConvention() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasFarReturn() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCompilerGenerated() const {
+ return false;
+}
+
+bool NativeRawSymbol::isConstType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isEditAndContinueEnabled() const {
+ return false;
+}
+
+bool NativeRawSymbol::isFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::getAddressTaken() const {
+ return false;
+}
+
+bool NativeRawSymbol::getNoStackOrdering() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasAlloca() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasAssignmentOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCTypes() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCastOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasDebugInfo() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasEH() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasEHa() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInlAsm() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInlineAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInterruptReturn() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasFramePointer() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasLongJump() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasManagedCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNestedTypes() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNoInlineAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNoReturnAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasOptimizedCodeDebugInfo() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasOverloadedOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSEH() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSecurityChecks() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSetJump() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasStrictGSCheck() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorGroupSharedLocal() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorPointerTagLiveRange() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorStubFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAggregated() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIntroVirtualFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCVTCIL() const {
+ return false;
+}
+
+bool NativeRawSymbol::isConstructorVirtualBase() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCxxReturnUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isDataAligned() const {
+ return false;
+}
+
+bool NativeRawSymbol::isHLSLData() const {
+ return false;
+}
+
+bool NativeRawSymbol::isHotpatchable() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIndirectVirtualBaseClass() const {
+ return false;
+}
+
+bool NativeRawSymbol::isInterfaceUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIntrinsic() const {
+ return false;
+}
+
+bool NativeRawSymbol::isLTCG() const {
+ return false;
+}
+
+bool NativeRawSymbol::isLocationControlFlowDependent() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMSILNetmodule() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMatrixRowMajor() const {
+ return false;
+}
+
+bool NativeRawSymbol::isManagedCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMSILCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMultipleInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isNaked() const {
+ return false;
+}
+
+bool NativeRawSymbol::isNested() const {
+ return false;
+}
+
+bool NativeRawSymbol::isOptimizedAway() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPacked() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerBasedOnSymbolValue() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerToDataMember() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerToMemberFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPureVirtual() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRValueReference() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRefUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isReference() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRestrictedType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isReturnValue() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSafeBuffers() const {
+ return false;
+}
+
+bool NativeRawSymbol::isScoped() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSdl() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSingleInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSplitted() const {
+ return false;
+}
+
+bool NativeRawSymbol::isStatic() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasPrivateSymbols() const {
+ return false;
+}
+
+bool NativeRawSymbol::isUnalignedType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isUnreached() const {
+ return false;
+}
+
+bool NativeRawSymbol::isValueUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtual() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtualBaseClass() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtualInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVolatileType() const {
+ return false;
+}
+
+bool NativeRawSymbol::wasInlined() const {
+ return false;
+}
+
+std::string NativeRawSymbol::getUnused() const {
+ return {};
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
new file mode 100644
index 0000000..76de0d8
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -0,0 +1,218 @@
+//===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+namespace {
+// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
+// to instantiate a NativeBuiltinSymbol for that type.
+static const struct BuiltinTypeEntry {
+ codeview::SimpleTypeKind Kind;
+ PDB_BuiltinType Type;
+ uint32_t Size;
+} BuiltinTypes[] = {
+ {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
+ {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
+ {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
+ {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
+ {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
+ // This table can be grown as necessary, but these are the only types we've
+ // needed so far.
+};
+} // namespace
+
+NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
+ std::unique_ptr<BumpPtrAllocator> Allocator)
+ : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
+
+NativeSession::~NativeSession() = default;
+
+Error NativeSession::createFromPdb(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
+ MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
+ /*RequiresNullTerminator=*/false);
+ if (!ErrorOrBuffer)
+ return make_error<GenericError>(generic_error_code::invalid_path);
+
+ std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
+ auto Stream = llvm::make_unique<MemoryBufferByteStream>(
+ std::move(Buffer), llvm::support::little);
+
+ auto Allocator = llvm::make_unique<BumpPtrAllocator>();
+ auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
+ if (auto EC = File->parseFileHeaders())
+ return EC;
+ if (auto EC = File->parseStreamData())
+ return EC;
+
+ Session =
+ llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
+
+ return Error::success();
+}
+
+Error NativeSession::createFromExe(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session) {
+ return make_error<RawError>(raw_error_code::feature_unsupported);
+}
+
+std::unique_ptr<PDBSymbolCompiland>
+NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
+ const auto Id = static_cast<SymIndexId>(SymbolCache.size());
+ SymbolCache.push_back(
+ llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
+ return llvm::make_unique<PDBSymbolCompiland>(
+ *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
+}
+
+SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) {
+ // First see if it's already in our cache.
+ const auto Entry = TypeIndexToSymbolId.find(Index);
+ if (Entry != TypeIndexToSymbolId.end())
+ return Entry->second;
+
+ // Symbols for built-in types are created on the fly.
+ if (Index.isSimple()) {
+ // FIXME: We will eventually need to handle pointers to other simple types,
+ // which are still simple types in the world of CodeView TypeIndexes.
+ if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
+ return 0;
+ const auto Kind = Index.getSimpleKind();
+ const auto It =
+ std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes),
+ [Kind](const BuiltinTypeEntry &Builtin) {
+ return Builtin.Kind == Kind;
+ });
+ if (It == std::end(BuiltinTypes))
+ return 0;
+ SymIndexId Id = SymbolCache.size();
+ SymbolCache.emplace_back(
+ llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
+ TypeIndexToSymbolId[Index] = Id;
+ return Id;
+ }
+
+ // TODO: Look up PDB type by type index
+
+ return 0;
+}
+
+uint64_t NativeSession::getLoadAddress() const { return 0; }
+
+void NativeSession::setLoadAddress(uint64_t Address) {}
+
+std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
+ const auto Id = static_cast<SymIndexId>(SymbolCache.size());
+ SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
+ auto RawSymbol = SymbolCache[Id]->clone();
+ auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
+ std::unique_ptr<PDBSymbolExe> ExeSymbol(
+ static_cast<PDBSymbolExe *>(PdbSymbol.release()));
+ return ExeSymbol;
+}
+
+std::unique_ptr<PDBSymbol>
+NativeSession::getSymbolById(uint32_t SymbolId) const {
+ // If the caller has a SymbolId, it'd better be in our SymbolCache.
+ return SymbolId < SymbolCache.size()
+ ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
+ : nullptr;
+}
+
+std::unique_ptr<PDBSymbol>
+NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbersByAddress(uint64_t Address,
+ uint32_t Length) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSourceFiles>
+NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
+ StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBSourceFile>
+NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+NativeSession::findCompilandsForSourceFile(StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbolCompiland>
+NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
+ const PDBSymbolCompiland &Compiland) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBSourceFile>
+NativeSession::getSourceFileById(uint32_t FileId) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
+ return nullptr;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 5349151..0b6492e 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -7,24 +7,25 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/GlobalsStream.h"
-#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/Path.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -38,12 +39,18 @@ namespace {
typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
} // end anonymous namespace
-PDBFile::PDBFile(std::unique_ptr<ReadableStream> PdbFileBuffer,
+PDBFile::PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
BumpPtrAllocator &Allocator)
- : Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
+ : FilePath(Path), Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
PDBFile::~PDBFile() = default;
+StringRef PDBFile::getFilePath() const { return FilePath; }
+
+StringRef PDBFile::getFileDirectory() const {
+ return sys::path::parent_path(FilePath);
+}
+
uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }
uint32_t PDBFile::getFreeBlockMapBlock() const {
@@ -106,7 +113,7 @@ Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
}
Error PDBFile::parseFileHeaders() {
- StreamReader Reader(*Buffer);
+ BinaryStreamReader Reader(*Buffer);
// Initialize SB.
const msf::SuperBlock *SB = nullptr;
@@ -139,8 +146,9 @@ Error PDBFile::parseFileHeaders() {
// at getBlockSize() intervals, so we have to be compatible.
// See the function fpmPn() for more information:
// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
- auto FpmStream = MappedBlockStream::createFpmStream(ContainerLayout, *Buffer);
- StreamReader FpmReader(*FpmStream);
+ auto FpmStream =
+ MappedBlockStream::createFpmStream(ContainerLayout, *Buffer, Allocator);
+ BinaryStreamReader FpmReader(*FpmStream);
ArrayRef<uint8_t> FpmBytes;
if (auto EC = FpmReader.readBytes(FpmBytes,
msf::getFullFpmByteSize(ContainerLayout)))
@@ -177,8 +185,9 @@ Error PDBFile::parseStreamData() {
// is exactly what we are attempting to parse. By specifying a custom
// subclass of IPDBStreamData which only accesses the fields that have already
// been parsed, we can avoid this and reuse MappedBlockStream.
- auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer);
- StreamReader Reader(*DS);
+ auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer,
+ Allocator);
+ BinaryStreamReader Reader(*DS);
if (auto EC = Reader.readInteger(NumStreams))
return EC;
@@ -221,6 +230,14 @@ ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
return ContainerLayout.DirectoryBlocks;
}
+MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
+ MSFStreamLayout Result;
+ auto Blocks = getStreamBlockList(StreamIdx);
+ Result.Blocks.assign(Blocks.begin(), Blocks.end());
+ Result.Length = getStreamByteSize(StreamIdx);
+ return Result;
+}
+
Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
if (!Globals) {
auto DbiS = getPDBDbiStream();
@@ -229,7 +246,8 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
auto GlobalS = safelyCreateIndexedStream(
ContainerLayout, *Buffer, DbiS->getGlobalSymbolStreamIndex());
- if (!GlobalS) return GlobalS.takeError();
+ if (!GlobalS)
+ return GlobalS.takeError();
auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS));
if (auto EC = TempGlobals->reload())
return std::move(EC);
@@ -241,7 +259,8 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
if (!Info) {
auto InfoS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamPDB);
- if (!InfoS) return InfoS.takeError();
+ if (!InfoS)
+ return InfoS.takeError();
auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
if (auto EC = TempInfo->reload())
return std::move(EC);
@@ -253,7 +272,8 @@ Expected<InfoStream &> PDBFile::getPDBInfoStream() {
Expected<DbiStream &> PDBFile::getPDBDbiStream() {
if (!Dbi) {
auto DbiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamDBI);
- if (!DbiS) return DbiS.takeError();
+ if (!DbiS)
+ return DbiS.takeError();
auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS));
if (auto EC = TempDbi->reload())
return std::move(EC);
@@ -265,7 +285,8 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() {
Expected<TpiStream &> PDBFile::getPDBTpiStream() {
if (!Tpi) {
auto TpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamTPI);
- if (!TpiS) return TpiS.takeError();
+ if (!TpiS)
+ return TpiS.takeError();
auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
if (auto EC = TempTpi->reload())
return std::move(EC);
@@ -277,7 +298,8 @@ Expected<TpiStream &> PDBFile::getPDBTpiStream() {
Expected<TpiStream &> PDBFile::getPDBIpiStream() {
if (!Ipi) {
auto IpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamIPI);
- if (!IpiS) return IpiS.takeError();
+ if (!IpiS)
+ return IpiS.takeError();
auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
if (auto EC = TempIpi->reload())
return std::move(EC);
@@ -294,7 +316,8 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
auto PublicS = safelyCreateIndexedStream(
ContainerLayout, *Buffer, DbiS->getPublicSymbolStreamIndex());
- if (!PublicS) return PublicS.takeError();
+ if (!PublicS)
+ return PublicS.takeError();
auto TempPublics =
llvm::make_unique<PublicsStream>(*this, std::move(*PublicS));
if (auto EC = TempPublics->reload())
@@ -313,7 +336,8 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
auto SymbolS =
safelyCreateIndexedStream(ContainerLayout, *Buffer, SymbolStreamNum);
- if (!SymbolS) return SymbolS.takeError();
+ if (!SymbolS)
+ return SymbolS.takeError();
auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
if (auto EC = TempSymbols->reload())
@@ -323,8 +347,8 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
return *Symbols;
}
-Expected<NameHashTable &> PDBFile::getStringTable() {
- if (!StringTable || !StringTableStream) {
+Expected<PDBStringTable &> PDBFile::getStringTable() {
+ if (!Strings) {
auto IS = getPDBInfoStream();
if (!IS)
return IS.takeError();
@@ -333,23 +357,39 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
auto NS =
safelyCreateIndexedStream(ContainerLayout, *Buffer, NameStreamIndex);
- if (!NS) return NS.takeError();
+ if (!NS)
+ return NS.takeError();
- StreamReader Reader(**NS);
- auto N = llvm::make_unique<NameHashTable>();
- if (auto EC = N->load(Reader))
+ auto N = llvm::make_unique<PDBStringTable>();
+ BinaryStreamReader Reader(**NS);
+ if (auto EC = N->reload(Reader))
return std::move(EC);
- StringTable = std::move(N);
+ assert(Reader.bytesRemaining() == 0);
StringTableStream = std::move(*NS);
+ Strings = std::move(N);
}
- return *StringTable;
+ return *Strings;
+}
+
+uint32_t PDBFile::getPointerSize() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS)
+ return 0;
+ PDB_Machine Machine = DbiS->getMachineType();
+ if (Machine == PDB_Machine::Amd64)
+ return 8;
+ return 4;
}
bool PDBFile::hasPDBDbiStream() const { return StreamDBI < getNumStreams(); }
bool PDBFile::hasPDBGlobalsStream() {
auto DbiS = getPDBDbiStream();
- if (!DbiS) return false;
+ if (!DbiS) {
+ consumeError(DbiS.takeError());
+ return false;
+ }
+
return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
}
@@ -359,33 +399,39 @@ bool PDBFile::hasPDBIpiStream() const { return StreamIPI < getNumStreams(); }
bool PDBFile::hasPDBPublicsStream() {
auto DbiS = getPDBDbiStream();
- if (!DbiS) return false;
+ if (!DbiS) {
+ consumeError(DbiS.takeError());
+ return false;
+ }
return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
}
bool PDBFile::hasPDBSymbolStream() {
auto DbiS = getPDBDbiStream();
- if (!DbiS) return false;
+ if (!DbiS)
+ return false;
return DbiS->getSymRecordStreamIndex() < getNumStreams();
}
bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
-bool PDBFile::hasStringTable() {
+bool PDBFile::hasPDBStringTable() {
auto IS = getPDBInfoStream();
- if (!IS) return false;
+ if (!IS)
+ return false;
return IS->getNamedStreamIndex("/names") < getNumStreams();
}
-/// Wrapper around MappedBlockStream::createIndexedStream()
-/// that checks if a stream with that index actually exists.
-/// If it does not, the return value will have an MSFError with
-/// code msf_error_code::no_stream. Else, the return value will
-/// contain the stream returned by createIndexedStream().
-Expected<std::unique_ptr<MappedBlockStream>> PDBFile::safelyCreateIndexedStream(
- const MSFLayout &Layout, const ReadableStream &MsfData,
- uint32_t StreamIndex) const {
+/// Wrapper around MappedBlockStream::createIndexedStream() that checks if a
+/// stream with that index actually exists. If it does not, the return value
+/// will have an MSFError with code msf_error_code::no_stream. Else, the return
+/// value will contain the stream returned by createIndexedStream().
+Expected<std::unique_ptr<MappedBlockStream>>
+PDBFile::safelyCreateIndexedStream(const MSFLayout &Layout,
+ BinaryStreamRef MsfData,
+ uint32_t StreamIndex) const {
if (StreamIndex >= getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
- return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex);
+ return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex,
+ Allocator);
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
new file mode 100644
index 0000000..9f35fd7
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -0,0 +1,221 @@
+//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+
+#include "llvm/ADT/BitVector.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
+ : Allocator(Allocator) {}
+
+PDBFileBuilder::~PDBFileBuilder() {}
+
+Error PDBFileBuilder::initialize(uint32_t BlockSize) {
+ auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
+ if (!ExpectedMsf)
+ return ExpectedMsf.takeError();
+ Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
+ return Error::success();
+}
+
+MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
+
+InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
+ if (!Info)
+ Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
+ return *Info;
+}
+
+DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
+ if (!Dbi)
+ Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
+ return *Dbi;
+}
+
+TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
+ if (!Tpi)
+ Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
+ return *Tpi;
+}
+
+TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
+ if (!Ipi)
+ Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
+ return *Ipi;
+}
+
+PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
+ return Strings;
+}
+
+PublicsStreamBuilder &PDBFileBuilder::getPublicsBuilder() {
+ if (!Publics)
+ Publics = llvm::make_unique<PublicsStreamBuilder>(*Msf);
+ return *Publics;
+}
+
+Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
+ auto ExpectedStream = Msf->addStream(Size);
+ if (!ExpectedStream)
+ return ExpectedStream.takeError();
+ NamedStreams.set(Name, *ExpectedStream);
+ return Error::success();
+}
+
+Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
+
+ if (Ipi && Ipi->getRecordCount() > 0) {
+ // In theory newer PDBs always have an ID stream, but by saying that we're
+ // only going to *really* have an ID stream if there is at least one ID
+ // record, we leave open the opportunity to test older PDBs such as those
+ // that don't have an ID stream.
+ auto &Info = getInfoBuilder();
+ Info.addFeature(PdbRaw_FeatureSig::VC140);
+ }
+
+ uint32_t StringsLen = Strings.calculateSerializedSize();
+
+ if (auto EC = addNamedStream("/names", StringsLen))
+ return std::move(EC);
+ if (auto EC = addNamedStream("/LinkInfo", 0))
+ return std::move(EC);
+
+ if (Info) {
+ if (auto EC = Info->finalizeMsfLayout())
+ return std::move(EC);
+ }
+ if (Dbi) {
+ if (auto EC = Dbi->finalizeMsfLayout())
+ return std::move(EC);
+ }
+ if (Tpi) {
+ if (auto EC = Tpi->finalizeMsfLayout())
+ return std::move(EC);
+ }
+ if (Ipi) {
+ if (auto EC = Ipi->finalizeMsfLayout())
+ return std::move(EC);
+ }
+ if (Publics) {
+ if (auto EC = Publics->finalizeMsfLayout())
+ return std::move(EC);
+ if (Dbi) {
+ Dbi->setPublicsStreamIndex(Publics->getStreamIndex());
+ Dbi->setSymbolRecordStreamIndex(Publics->getRecordStreamIdx());
+ }
+ }
+
+ return Msf->build();
+}
+
+Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const {
+ uint32_t SN = 0;
+ if (!NamedStreams.get(Name, SN))
+ return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
+ return SN;
+}
+
+Error PDBFileBuilder::commit(StringRef Filename) {
+ assert(!Filename.empty());
+ auto ExpectedLayout = finalizeMsfLayout();
+ if (!ExpectedLayout)
+ return ExpectedLayout.takeError();
+ auto &Layout = *ExpectedLayout;
+
+ uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
+ auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
+ if (OutFileOrError.getError())
+ return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
+ Filename);
+ FileBufferByteStream Buffer(std::move(*OutFileOrError),
+ llvm::support::little);
+ BinaryStreamWriter Writer(Buffer);
+
+ if (auto EC = Writer.writeObject(*Layout.SB))
+ return EC;
+ uint32_t BlockMapOffset =
+ msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
+ Writer.setOffset(BlockMapOffset);
+ if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
+ return EC;
+
+ auto DirStream = WritableMappedBlockStream::createDirectoryStream(
+ Layout, Buffer, Allocator);
+ BinaryStreamWriter DW(*DirStream);
+ if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
+ return EC;
+
+ if (auto EC = DW.writeArray(Layout.StreamSizes))
+ return EC;
+
+ for (const auto &Blocks : Layout.StreamMap) {
+ if (auto EC = DW.writeArray(Blocks))
+ return EC;
+ }
+
+ auto ExpectedSN = getNamedStreamIndex("/names");
+ if (!ExpectedSN)
+ return ExpectedSN.takeError();
+
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, *ExpectedSN, Allocator);
+ BinaryStreamWriter NSWriter(*NS);
+ if (auto EC = Strings.commit(NSWriter))
+ return EC;
+
+ if (Info) {
+ if (auto EC = Info->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Dbi) {
+ if (auto EC = Dbi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Tpi) {
+ if (auto EC = Tpi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Ipi) {
+ if (auto EC = Ipi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Publics) {
+ auto PS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, Publics->getStreamIndex(), Allocator);
+ BinaryStreamWriter PSWriter(*PS);
+ if (auto EC = Publics->commit(PSWriter))
+ return EC;
+ }
+
+ return Buffer.commit();
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
new file mode 100644
index 0000000..acd45f7
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
@@ -0,0 +1,139 @@
+//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
+uint32_t PDBStringTable::getNameCount() const { return NameCount; }
+uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
+uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
+
+Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ if (Header->Signature != PDBStringTableSignature)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid hash table signature");
+ if (Header->HashVersion != 1 && Header->HashVersion != 2)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unsupported hash version");
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTable::readStrings(BinaryStreamReader &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"));
+ }
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+const codeview::DebugStringTableSubsectionRef &
+PDBStringTable::getStringTable() const {
+ return Strings;
+}
+
+Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
+ const support::ulittle32_t *HashCount;
+ if (auto EC = Reader.readObject(HashCount))
+ return EC;
+
+ if (auto EC = Reader.readArray(IDs, *HashCount)) {
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read bucket array"));
+ }
+
+ return Error::success();
+}
+
+Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
+ if (auto EC = Reader.readInteger(NameCount))
+ return EC;
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTable::reload(BinaryStreamReader &Reader) {
+
+ BinaryStreamReader SectionReader;
+
+ std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
+ if (auto EC = readHeader(SectionReader))
+ return EC;
+
+ std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
+ if (auto EC = readStrings(SectionReader))
+ return EC;
+
+ // We don't know how long the hash table is until we parse it, so let the
+ // function responsible for doing that figure it out.
+ if (auto EC = readHashTable(Reader))
+ return EC;
+
+ std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
+ if (auto EC = readEpilogue(SectionReader))
+ return EC;
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
+ return Strings.getString(ID);
+}
+
+Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
+ uint32_t Hash =
+ (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
+ size_t Count = IDs.size();
+ uint32_t Start = Hash % Count;
+ for (size_t I = 0; I < Count; ++I) {
+ // The hash is just a starting point for the search, but if it
+ // doesn't work we should find the string no matter what, because
+ // we iterate the entire array.
+ uint32_t Index = (Start + I) % Count;
+
+ uint32_t ID = IDs[Index];
+ auto ExpectedStr = getStringForID(ID);
+ if (!ExpectedStr)
+ return ExpectedStr.takeError();
+
+ if (*ExpectedStr == Str)
+ return ID;
+ }
+ return make_error<RawError>(raw_error_code::no_entry);
+}
+
+FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
+ return IDs;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
new file mode 100644
index 0000000..90acfad
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
@@ -0,0 +1,138 @@
+//===- PDBStringTableBuilder.cpp - PDB String Table -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::support;
+using namespace llvm::support::endian;
+using namespace llvm::pdb;
+
+uint32_t PDBStringTableBuilder::insert(StringRef S) {
+ return Strings.insert(S);
+}
+
+static uint32_t computeBucketCount(uint32_t NumStrings) {
+ // The /names stream is basically an on-disk open-addressing hash table.
+ // Hash collisions are resolved by linear probing. We cannot make
+ // utilization 100% because it will make the linear probing extremely
+ // slow. But lower utilization wastes disk space. As a reasonable
+ // load factor, we choose 80%. We need +1 because slot 0 is reserved.
+ return (NumStrings + 1) * 1.25;
+}
+
+uint32_t PDBStringTableBuilder::calculateHashTableSize() const {
+ uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field.
+ Size += sizeof(uint32_t) * computeBucketCount(Strings.size());
+
+ return Size;
+}
+
+uint32_t PDBStringTableBuilder::calculateSerializedSize() const {
+ uint32_t Size = 0;
+ Size += sizeof(PDBStringTableHeader);
+ Size += Strings.calculateSerializedSize();
+ Size += calculateHashTableSize();
+ Size += sizeof(uint32_t); // The /names stream ends with the string count.
+ return Size;
+}
+
+void PDBStringTableBuilder::setStrings(
+ const codeview::DebugStringTableSubsection &Strings) {
+ this->Strings = Strings;
+}
+
+Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
+ // Write a header
+ PDBStringTableHeader H;
+ H.Signature = PDBStringTableSignature;
+ H.HashVersion = 1;
+ H.ByteSize = Strings.calculateSerializedSize();
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const {
+ if (auto EC = Strings.commit(Writer))
+ return EC;
+
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const {
+ // Write a hash table.
+ uint32_t BucketCount = computeBucketCount(Strings.size());
+ if (auto EC = Writer.writeInteger(BucketCount))
+ return EC;
+ std::vector<ulittle32_t> Buckets(BucketCount);
+
+ for (auto &Pair : Strings) {
+ StringRef S = Pair.getKey();
+ uint32_t Offset = Pair.getValue();
+ uint32_t Hash = hashStringV1(S);
+
+ for (uint32_t I = 0; I != BucketCount; ++I) {
+ uint32_t Slot = (Hash + I) % BucketCount;
+ if (Slot == 0)
+ continue; // Skip reserved slot
+ if (Buckets[Slot] != 0)
+ continue;
+ Buckets[Slot] = Offset;
+ break;
+ }
+ }
+
+ if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets)))
+ return EC;
+
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const {
+ if (auto EC = Writer.writeInteger<uint32_t>(Strings.size()))
+ return EC;
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
+ BinaryStreamWriter SectionWriter;
+
+ std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader));
+ if (auto EC = writeHeader(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) =
+ Writer.split(Strings.calculateSerializedSize());
+ if (auto EC = writeStrings(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize());
+ if (auto EC = writeHashTable(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t));
+ if (auto EC = writeEpilogue(SectionWriter))
+ return EC;
+
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp
index b31f605..9c3e654 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStream.cpp
@@ -22,15 +22,15 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "GSI.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -41,19 +41,6 @@ using namespace llvm::msf;
using namespace llvm::support;
using namespace llvm::pdb;
-// This is PSGSIHDR struct defined in
-// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
-struct PublicsStream::HeaderInfo {
- ulittle32_t SymHash;
- ulittle32_t AddrMap;
- ulittle32_t NumThunks;
- ulittle32_t SizeOfThunk;
- ulittle16_t ISectThunkTable;
- char Padding[2];
- ulittle32_t OffThunkTable;
- ulittle32_t NumSections;
-};
-
PublicsStream::PublicsStream(PDBFile &File,
std::unique_ptr<MappedBlockStream> Stream)
: Pdb(File), Stream(std::move(Stream)) {}
@@ -69,10 +56,11 @@ uint32_t PublicsStream::getAddrMap() const { return Header->AddrMap; }
// we skip over the hash table which we believe contains information about
// public symbols.
Error PublicsStream::reload() {
- StreamReader Reader(*Stream);
+ BinaryStreamReader Reader(*Stream);
// Check stream size.
- if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader))
+ if (Reader.bytesRemaining() <
+ sizeof(PublicsStreamHeader) + sizeof(GSIHashHeader))
return make_error<RawError>(raw_error_code::corrupt_file,
"Publics Stream does not contain a header.");
@@ -105,10 +93,12 @@ Error PublicsStream::reload() {
"Could not read a thunk map."));
// Something called "section map" follows.
- if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read a section map."));
+ if (Reader.bytesRemaining() > 0) {
+ if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a section map."));
+ }
if (Reader.bytesRemaining() > 0)
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -128,4 +118,13 @@ PublicsStream::getSymbols(bool *HadError) const {
return SS.getSymbols(HadError);
}
+Expected<const codeview::CVSymbolArray &>
+PublicsStream::getSymbolArray() const {
+ auto SymbolS = Pdb.getPDBSymbolStream();
+ if (!SymbolS)
+ return SymbolS.takeError();
+
+ return SymbolS->getSymbolArray();
+}
+
Error PublicsStream::commit() { return Error::success(); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp
new file mode 100644
index 0000000..28c4a8f
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/PublicsStreamBuilder.cpp
@@ -0,0 +1,89 @@
+//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+
+#include "GSI.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+PublicsStreamBuilder::PublicsStreamBuilder(msf::MSFBuilder &Msf) : Msf(Msf) {}
+
+PublicsStreamBuilder::~PublicsStreamBuilder() {}
+
+uint32_t PublicsStreamBuilder::calculateSerializedLength() const {
+ uint32_t Size = 0;
+ Size += sizeof(PublicsStreamHeader);
+ Size += sizeof(GSIHashHeader);
+ Size += HashRecords.size() * sizeof(PSHashRecord);
+ size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+ uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
+ Size += NumBitmapEntries;
+
+ // FIXME: Account for hash buckets. For now since we we write a zero-bitmap
+ // indicating that no hash buckets are valid, we also write zero byets of hash
+ // bucket data.
+ Size += 0;
+ return Size;
+}
+
+Error PublicsStreamBuilder::finalizeMsfLayout() {
+ Expected<uint32_t> Idx = Msf.addStream(calculateSerializedLength());
+ if (!Idx)
+ return Idx.takeError();
+ StreamIdx = *Idx;
+
+ Expected<uint32_t> RecordIdx = Msf.addStream(0);
+ if (!RecordIdx)
+ return RecordIdx.takeError();
+ RecordStreamIdx = *RecordIdx;
+ return Error::success();
+}
+
+Error PublicsStreamBuilder::commit(BinaryStreamWriter &PublicsWriter) {
+ PublicsStreamHeader PSH;
+ GSIHashHeader GSH;
+
+ // FIXME: Figure out what to put for these values.
+ PSH.AddrMap = 0;
+ PSH.ISectThunkTable = 0;
+ PSH.NumSections = 0;
+ PSH.NumThunks = 0;
+ PSH.OffThunkTable = 0;
+ PSH.SizeOfThunk = 0;
+ PSH.SymHash = 0;
+
+ GSH.VerSignature = GSIHashHeader::HdrSignature;
+ GSH.VerHdr = GSIHashHeader::HdrVersion;
+ GSH.HrSize = 0;
+ GSH.NumBuckets = 0;
+
+ if (auto EC = PublicsWriter.writeObject(PSH))
+ return EC;
+ if (auto EC = PublicsWriter.writeObject(GSH))
+ return EC;
+ if (auto EC = PublicsWriter.writeArray(makeArrayRef(HashRecords)))
+ return EC;
+
+ size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+ uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
+ std::vector<uint8_t> BitmapData(NumBitmapEntries);
+ // FIXME: Build an actual bitmap
+ if (auto EC = PublicsWriter.writeBytes(makeArrayRef(BitmapData)))
+ return EC;
+
+ // FIXME: Write actual hash buckets.
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/RawError.cpp
index f4a5057..548289f 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/RawError.cpp
@@ -1,4 +1,4 @@
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
@@ -38,6 +38,8 @@ public:
return "The entry does not exist.";
case raw_error_code::not_writable:
return "The PDB does not support writing.";
+ case raw_error_code::stream_too_long:
+ return "The stream was longer than expected.";
case raw_error_code::invalid_tpi_hash:
return "The Type record has an invalid hash value.";
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp
index 2f3ac34..9e9ebd1 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/SymbolStream.cpp
@@ -7,16 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
@@ -30,7 +29,7 @@ SymbolStream::SymbolStream(std::unique_ptr<MappedBlockStream> Stream)
SymbolStream::~SymbolStream() {}
Error SymbolStream::reload() {
- StreamReader Reader(*Stream);
+ BinaryStreamReader Reader(*Stream);
if (auto EC = Reader.readArray(SymbolRecords, Stream->getLength()))
return EC;
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp
new file mode 100644
index 0000000..77a2d57
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp
@@ -0,0 +1,89 @@
+//===- TpiHashing.cpp -----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/Support/JamCRC.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+// Corresponds to `fUDTAnon`.
+static bool isAnonymous(StringRef Name) {
+ return Name == "<unnamed-tag>" || Name == "__unnamed" ||
+ Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
+}
+
+// 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 && HasUniqueName && !IsAnon)
+ return hashStringV1(Rec.getUniqueName());
+ return hashBufferV8(FullRecord);
+}
+
+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());
+}
+
+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, Deserialized.getUDT().getIndex());
+ return hashStringV1(StringRef(Buf, 4));
+}
+
+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/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp
index a1167cd..d3ef87d 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -7,19 +7,18 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiHashing.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -32,28 +31,13 @@ using namespace llvm::support;
using namespace llvm::msf;
using namespace llvm::pdb;
-TpiStream::TpiStream(const PDBFile &File,
- std::unique_ptr<MappedBlockStream> Stream)
+TpiStream::TpiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
: Pdb(File), Stream(std::move(Stream)) {}
TpiStream::~TpiStream() = default;
-// Verifies that a given type record matches with a given hash value.
-// Currently we only verify SRC_LINE records.
-Error TpiStream::verifyHashValues() {
- TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
- TypeDeserializer Deserializer;
-
- TypeVisitorCallbackPipeline Pipeline;
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Verifier);
-
- CVTypeVisitor Visitor(Pipeline);
- return Visitor.visitTypeStream(TypeRecords);
-}
-
Error TpiStream::reload() {
- StreamReader Reader(*Stream);
+ BinaryStreamReader Reader(*Stream);
if (Reader.bytesRemaining() < sizeof(TpiStreamHeader))
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -81,7 +65,13 @@ Error TpiStream::reload() {
"TPI Stream Invalid number of hash buckets.");
// The actual type records themselves come from this stream
- if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
+ if (auto EC =
+ Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
+ return EC;
+
+ BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
+ if (auto EC =
+ RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
return EC;
// Hash indices, hash values, etc come from the hash stream.
@@ -91,21 +81,20 @@ Error TpiStream::reload() {
"Invalid TPI hash stream index.");
auto HS = MappedBlockStream::createIndexedStream(
- Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex);
- StreamReader HSR(*HS);
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex,
+ Pdb.getAllocator());
+ BinaryStreamReader HSR(*HS);
+ // There should be a hash value for every type record, or no hashes at all.
uint32_t NumHashValues =
Header->HashValueBuffer.Length / sizeof(ulittle32_t);
- if (NumHashValues != NumTypeRecords())
+ if (NumHashValues != getNumTypeRecords() && NumHashValues != 0)
return make_error<RawError>(
raw_error_code::corrupt_file,
"TPI hash count does not match with the number of type records.");
HSR.setOffset(Header->HashValueBuffer.Off);
if (auto EC = HSR.readArray(HashValues, NumHashValues))
return EC;
- std::vector<ulittle32_t> HashValueList;
- for (auto I : HashValues)
- HashValueList.push_back(I);
HSR.setOffset(Header->IndexOffsetBuffer.Off);
uint32_t NumTypeIndexOffsets =
@@ -113,20 +102,17 @@ Error TpiStream::reload() {
if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
return EC;
- HSR.setOffset(Header->HashAdjBuffer.Off);
- uint32_t NumHashAdjustments =
- Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
- if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
- return EC;
+ if (Header->HashAdjBuffer.Length > 0) {
+ HSR.setOffset(Header->HashAdjBuffer.Off);
+ if (auto EC = HashAdjusters.load(HSR))
+ return EC;
+ }
HashStream = std::move(HS);
-
- // TPI hash table is a parallel array for the type records.
- // Verify that the hash values match with type records.
- if (auto EC = verifyHashValues())
- return EC;
}
+ Types = llvm::make_unique<LazyRandomTypeCollection>(
+ TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
return Error::success();
}
@@ -139,7 +125,7 @@ uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }
uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }
-uint32_t TpiStream::NumTypeRecords() const {
+uint32_t TpiStream::getNumTypeRecords() const {
return TypeIndexEnd() - TypeIndexBegin();
}
@@ -151,26 +137,24 @@ uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
return Header->HashAuxStreamIndex;
}
-uint32_t TpiStream::NumHashBuckets() const { return Header->NumHashBuckets; }
+uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
-FixedStreamArray<support::ulittle32_t>
-TpiStream::getHashValues() const {
+BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
+ return TypeRecordsSubstream;
+}
+
+FixedStreamArray<support::ulittle32_t> TpiStream::getHashValues() const {
return HashValues;
}
-FixedStreamArray<TypeIndexOffset>
-TpiStream::getTypeIndexOffsets() const {
+FixedStreamArray<TypeIndexOffset> TpiStream::getTypeIndexOffsets() const {
return TypeIndexOffsets;
}
-FixedStreamArray<TypeIndexOffset>
-TpiStream::getHashAdjustments() const {
- return HashAdjustments;
-}
+HashTable &TpiStream::getHashAdjusters() { return HashAdjusters; }
-iterator_range<CVTypeArray::Iterator>
-TpiStream::types(bool *HadError) const {
+CVTypeRange TpiStream::types(bool *HadError) const {
return make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
new file mode 100644
index 0000000..9e943c7
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -0,0 +1,177 @@
+//===- TpiStreamBuilder.cpp - -------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
+ : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
+}
+
+TpiStreamBuilder::~TpiStreamBuilder() = default;
+
+void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
+ VerHeader = Version;
+}
+
+void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
+ Optional<uint32_t> Hash) {
+ // If we just crossed an 8KB threshold, add a type index offset.
+ size_t NewSize = TypeRecordBytes + Record.size();
+ constexpr size_t EightKB = 8 * 1024;
+ if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) {
+ TypeIndexOffsets.push_back(
+ {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
+ TypeRecords.size()),
+ ulittle32_t(TypeRecordBytes)});
+ }
+ TypeRecordBytes = NewSize;
+
+ TypeRecords.push_back(Record);
+ if (Hash)
+ TypeHashes.push_back(*Hash);
+}
+
+Error TpiStreamBuilder::finalize() {
+ if (Header)
+ return Error::success();
+
+ TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
+
+ uint32_t Count = TypeRecords.size();
+
+ H->Version = VerHeader;
+ H->HeaderSize = sizeof(TpiStreamHeader);
+ H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
+ H->TypeIndexEnd = H->TypeIndexBegin + Count;
+ H->TypeRecordBytes = TypeRecordBytes;
+
+ H->HashStreamIndex = HashStreamIndex;
+ H->HashAuxStreamIndex = kInvalidStreamIndex;
+ H->HashKeySize = sizeof(ulittle32_t);
+ H->NumHashBuckets = MinTpiHashBuckets;
+
+ // Recall that hash values go into a completely different stream identified by
+ // the `HashStreamIndex` field of the `TpiStreamHeader`. Therefore, the data
+ // begins at offset 0 of this independent stream.
+ H->HashValueBuffer.Off = 0;
+ H->HashValueBuffer.Length = calculateHashBufferSize();
+
+ // We never write any adjustments into our PDBs, so this is usually some
+ // offset with zero length.
+ H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length;
+ H->HashAdjBuffer.Length = 0;
+
+ H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length;
+ H->IndexOffsetBuffer.Length = calculateIndexOffsetSize();
+
+ Header = H;
+ return Error::success();
+}
+
+uint32_t TpiStreamBuilder::calculateSerializedLength() {
+ return sizeof(TpiStreamHeader) + TypeRecordBytes;
+}
+
+uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
+ assert((TypeRecords.size() == TypeHashes.size() || TypeHashes.empty()) &&
+ "either all or no type records should have hashes");
+ return TypeHashes.size() * sizeof(ulittle32_t);
+}
+
+uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {
+ return TypeIndexOffsets.size() * sizeof(codeview::TypeIndexOffset);
+}
+
+Error TpiStreamBuilder::finalizeMsfLayout() {
+ uint32_t Length = calculateSerializedLength();
+ if (auto EC = Msf.setStreamSize(Idx, Length))
+ return EC;
+
+ uint32_t HashStreamSize =
+ calculateHashBufferSize() + calculateIndexOffsetSize();
+
+ if (HashStreamSize == 0)
+ return Error::success();
+
+ auto ExpectedIndex = Msf.addStream(HashStreamSize);
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ HashStreamIndex = *ExpectedIndex;
+ if (!TypeHashes.empty()) {
+ ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeHashes.size());
+ MutableArrayRef<ulittle32_t> HashBuffer(H, TypeHashes.size());
+ for (uint32_t I = 0; I < TypeHashes.size(); ++I) {
+ HashBuffer[I] = TypeHashes[I] % MinTpiHashBuckets;
+ }
+ ArrayRef<uint8_t> Bytes(
+ reinterpret_cast<const uint8_t *>(HashBuffer.data()),
+ calculateHashBufferSize());
+ HashValueStream =
+ llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
+ }
+ return Error::success();
+}
+
+Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef Buffer) {
+ if (auto EC = finalize())
+ return EC;
+
+ auto InfoS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
+ Idx, Allocator);
+
+ BinaryStreamWriter Writer(*InfoS);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
+ for (auto Rec : TypeRecords)
+ if (auto EC = Writer.writeBytes(Rec))
+ return EC;
+
+ if (HashStreamIndex != kInvalidStreamIndex) {
+ auto HVS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, HashStreamIndex, Allocator);
+ BinaryStreamWriter HW(*HVS);
+ if (HashValueStream) {
+ if (auto EC = HW.writeStreamRef(*HashValueStream))
+ return EC;
+ }
+
+ for (auto &IndexOffset : TypeIndexOffsets) {
+ if (auto EC = HW.writeObject(IndexOffset))
+ return EC;
+ }
+ }
+
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDB.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDB.cpp
index 0d72059..501d4f5 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDB.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDB.cpp
@@ -1,4 +1,4 @@
-//===- PDB.cpp - base header file for creating a PDB reader -----*- C++ -*-===//
+//===- PDB.cpp - base header file for creating a PDB reader ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,18 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/PDB.h"
-
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDB.h"
#if LLVM_ENABLE_DIA_SDK
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#endif
-#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/Support/Error.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -27,25 +23,25 @@ using namespace llvm::pdb;
Error llvm::pdb::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
std::unique_ptr<IPDBSession> &Session) {
// Create the correct concrete instance type based on the value of Type.
- if (Type == PDB_ReaderType::Raw)
- return RawSession::createFromPdb(Path, Session);
+ if (Type == PDB_ReaderType::Native)
+ return NativeSession::createFromPdb(Path, Session);
#if LLVM_ENABLE_DIA_SDK
return DIASession::createFromPdb(Path, Session);
#else
- return llvm::make_error<GenericError>("DIA is not installed on the system");
+ return make_error<GenericError>("DIA is not installed on the system");
#endif
}
Error llvm::pdb::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
std::unique_ptr<IPDBSession> &Session) {
// Create the correct concrete instance type based on the value of Type.
- if (Type == PDB_ReaderType::Raw)
- return RawSession::createFromExe(Path, Session);
+ if (Type == PDB_ReaderType::Native)
+ return NativeSession::createFromExe(Path, Session);
#if LLVM_ENABLE_DIA_SDK
return DIASession::createFromExe(Path, Session);
#else
- return llvm::make_error<GenericError>("DIA is not installed on the system");
+ return make_error<GenericError>("DIA is not installed on the system");
#endif
}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index 94b81ec..df0feac 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -12,8 +12,8 @@
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
#include "llvm/Object/COFF.h"
@@ -29,8 +29,7 @@ PDBContext::PDBContext(const COFFObjectFile &Object,
Session->setLoadAddress(ImageBase.get());
}
-void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
- bool SummarizeTypes) {}
+void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier) {
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBExtras.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
index b7eee6e..c291185 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -1,4 +1,4 @@
-//===- PDBExtras.cpp - helper functions and classes for PDBs -----*- C++-*-===//
+//===- PDBExtras.cpp - helper functions and classes for PDBs --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,8 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/PDBExtras.h"
-
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -269,25 +270,6 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {
return OS;
}
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UniqueId &Id) {
- static const char *Lookup = "0123456789ABCDEF";
-
- static_assert(sizeof(PDB_UniqueId) == 16, "Expected 16-byte GUID");
- ArrayRef<uint8_t> GuidBytes(reinterpret_cast<const uint8_t*>(&Id), 16);
- OS << "{";
- for (int i=0; i < 16;) {
- uint8_t Byte = GuidBytes[i];
- uint8_t HighNibble = (Byte >> 4) & 0xF;
- uint8_t LowNibble = Byte & 0xF;
- OS << Lookup[HighNibble] << Lookup[LowNibble];
- ++i;
- if (i>=4 && i<=10 && i%2==0)
- OS << "-";
- }
- OS << "}";
- return OS;
-}
-
raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
const PDB_Machine &Machine) {
switch (Machine) {
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
index 633e11a..74010c2 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
@@ -53,6 +54,9 @@ PDBSymbol::PDBSymbol(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
: Session(PDBSession), RawSymbol(std::move(Symbol)) {}
+PDBSymbol::PDBSymbol(PDBSymbol &Symbol)
+ : Session(Symbol.Session), RawSymbol(std::move(Symbol.RawSymbol)) {}
+
PDBSymbol::~PDBSymbol() = default;
#define FACTORY_SYMTAG_CASE(Tag, Type) \
@@ -99,16 +103,30 @@ PDBSymbol::create(const IPDBSession &PDBSession,
}
}
-#define TRY_DUMP_TYPE(Type) \
- if (const Type *DerivedThis = dyn_cast<Type>(this)) \
- Dumper.dump(OS, Indent, *DerivedThis);
-
-#define ELSE_TRY_DUMP_TYPE(Type, Dumper) else TRY_DUMP_TYPE(Type, Dumper)
-
void PDBSymbol::defaultDump(raw_ostream &OS, int Indent) const {
RawSymbol->dump(OS, Indent);
}
+void PDBSymbol::dumpProperties() const {
+ outs() << "\n";
+ defaultDump(outs(), 0);
+ outs().flush();
+}
+
+void PDBSymbol::dumpChildStats() const {
+ TagStats Stats;
+ getChildStats(Stats);
+ outs() << "\n";
+ for (auto &Stat : Stats) {
+ outs() << Stat.first << ": " << Stat.second << "\n";
+ }
+ outs().flush();
+}
+
+std::unique_ptr<PDBSymbol> PDBSymbol::clone() const {
+ return Session.getSymbolById(getSymIndexId());
+}
+
PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
@@ -141,6 +159,8 @@ PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::getChildStats(TagStats &Stats) const {
std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
+ if (!Result)
+ return nullptr;
Stats.clear();
while (auto Child = Result->getNext()) {
++Stats[Child->getSymTag()];
@@ -148,3 +168,7 @@ PDBSymbol::getChildStats(TagStats &Stats) const {
Result->reset();
return Result;
}
+
+std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
+ return Session.getSymbolById(Id);
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
index cdb167b..3648272 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
@@ -18,7 +18,9 @@ using namespace llvm::pdb;
PDBSymbolAnnotation::PDBSymbolAnnotation(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Annotation);
+}
void PDBSymbolAnnotation::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
index fd5dc94..7076b4a 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,6 +19,8 @@ using namespace llvm::pdb;
PDBSymbolBlock::PDBSymbolBlock(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Block);
+}
void PDBSymbolBlock::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
index ebff088..854cf42 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolCompiland::PDBSymbolCompiland(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Compiland);
+}
void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
index 6dbd522..f73cd36 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolCompilandDetails::PDBSymbolCompilandDetails(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::CompilandDetails);
+}
void PDBSymbolCompilandDetails::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
index 9c7f0b1..df696fa 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
@@ -10,8 +10,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -20,7 +20,9 @@ using namespace llvm::pdb;
PDBSymbolCompilandEnv::PDBSymbolCompilandEnv(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::CompilandEnv);
+}
std::string PDBSymbolCompilandEnv::getValue() const {
Variant Value = RawSymbol->getValue();
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
index 0ea387a..a7b69a7 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
@@ -10,8 +10,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -20,7 +20,9 @@ using namespace llvm::pdb;
PDBSymbolCustom::PDBSymbolCustom(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> CustomSymbol)
- : PDBSymbol(PDBSession, std::move(CustomSymbol)) {}
+ : PDBSymbol(PDBSession, std::move(CustomSymbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Custom);
+}
void PDBSymbolCustom::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) {
RawSymbol->getDataBytes(bytes);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
index 62bb6f3..6002668 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp
@@ -19,10 +19,8 @@ using namespace llvm::pdb;
PDBSymbolData::PDBSymbolData(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> DataSymbol)
- : PDBSymbol(PDBSession, std::move(DataSymbol)) {}
-
-std::unique_ptr<PDBSymbol> PDBSymbolData::getType() const {
- return Session.getSymbolById(getTypeId());
+ : PDBSymbol(PDBSession, std::move(DataSymbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Data);
}
void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
index 60101c1..7417167 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include <utility>
@@ -18,6 +19,18 @@ using namespace llvm::pdb;
PDBSymbolExe::PDBSymbolExe(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Exe);
+}
void PDBSymbolExe::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+
+uint32_t PDBSymbolExe::getPointerByteSize() const {
+ auto Pointer = findOneChild<PDBSymbolTypePointer>();
+ if (Pointer)
+ return Pointer->getLength();
+
+ if (getMachineType() == PDB_Machine::x86)
+ return 4;
+ return 8;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index 35251c0..5a5cb4c 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -12,10 +12,10 @@
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include <unordered_set>
@@ -85,10 +85,8 @@ private:
PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
-std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const {
- return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId());
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Function);
}
std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
@@ -96,8 +94,15 @@ PDBSymbolFunc::getArguments() const {
return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
}
-std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const {
- return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
-}
-
void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+
+bool PDBSymbolFunc::isDestructor() const {
+ std::string Name = getName();
+ if (Name.empty())
+ return false;
+ if (Name[0] == '~')
+ return true;
+ if (Name == "__vecDelDtor")
+ return true;
+ return false;
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
index 77e996f..4a4195b 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolFuncDebugEnd::PDBSymbolFuncDebugEnd(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::FuncDebugEnd);
+}
void PDBSymbolFuncDebugEnd::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
index 9c65387..a448a40 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolFuncDebugStart::PDBSymbolFuncDebugStart(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::FuncDebugStart);
+}
void PDBSymbolFuncDebugStart::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
index d2cfd11..a67a20d 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
@@ -18,6 +18,8 @@ using namespace llvm::pdb;
PDBSymbolLabel::PDBSymbolLabel(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Label);
+}
void PDBSymbolLabel::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
index 97d6687..dbec16f 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolPublicSymbol::PDBSymbolPublicSymbol(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::PublicSymbol);
+}
void PDBSymbolPublicSymbol::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
index ef8897d..b264819 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
@@ -18,6 +18,8 @@ using namespace llvm::pdb;
PDBSymbolThunk::PDBSymbolThunk(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Thunk);
+}
void PDBSymbolThunk::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
index c010cc5..a8054a4 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
@@ -19,12 +19,14 @@ using namespace llvm::pdb;
PDBSymbolTypeArray::PDBSymbolTypeArray(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
-std::unique_ptr<PDBSymbol> PDBSymbolTypeArray::getElementType() const {
- return Session.getSymbolById(getTypeId());
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::ArrayType);
}
void PDBSymbolTypeArray::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
+
+void PDBSymbolTypeArray::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
index 382c397..0fdf8b6 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolTypeBaseClass::PDBSymbolTypeBaseClass(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::BaseClass);
+}
void PDBSymbolTypeBaseClass::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
index e5d65bf..0bf563a 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
@@ -18,7 +18,9 @@ using namespace llvm::pdb;
PDBSymbolTypeBuiltin::PDBSymbolTypeBuiltin(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::BuiltinType);
+}
void PDBSymbolTypeBuiltin::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
index 1d80c97..726e7e1 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolTypeCustom::PDBSymbolTypeCustom(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::CustomType);
+}
void PDBSymbolTypeCustom::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
index 535d97d..6c84b98 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
@@ -10,8 +10,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -20,7 +20,9 @@ using namespace llvm::pdb;
PDBSymbolTypeDimension::PDBSymbolTypeDimension(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Dimension);
+}
void PDBSymbolTypeDimension::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
index 788f2b7..2addea0 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
@@ -21,15 +21,8 @@ using namespace llvm::pdb;
PDBSymbolTypeEnum::PDBSymbolTypeEnum(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
-std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolTypeEnum::getClassParent() const {
- return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
-}
-
-std::unique_ptr<PDBSymbolTypeBuiltin>
-PDBSymbolTypeEnum::getUnderlyingType() const {
- return Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(getTypeId());
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Enum);
}
void PDBSymbolTypeEnum::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
index 5831bae..c018772 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolTypeFriend::PDBSymbolTypeFriend(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Friend);
+}
void PDBSymbolTypeFriend::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
index c6f586d..4d5cd63 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
@@ -18,7 +18,9 @@ using namespace llvm::pdb;
PDBSymbolTypeFunctionArg::PDBSymbolTypeFunctionArg(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::FunctionArg);
+}
void PDBSymbolTypeFunctionArg::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
index 057ae26..0304c62 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
@@ -12,9 +12,9 @@
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include <utility>
@@ -68,10 +68,8 @@ private:
PDBSymbolTypeFunctionSig::PDBSymbolTypeFunctionSig(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
-std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getReturnType() const {
- return Session.getSymbolById(getTypeId());
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::FunctionSig);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -79,13 +77,10 @@ PDBSymbolTypeFunctionSig::getArguments() const {
return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
}
-std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getClassParent() const {
- uint32_t ClassId = getClassParentId();
- if (ClassId == 0)
- return nullptr;
- return Session.getSymbolById(ClassId);
-}
-
void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
+
+void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
index 072d2cf..7cfba82 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolTypeManaged::PDBSymbolTypeManaged(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::ManagedType);
+}
void PDBSymbolTypeManaged::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
index 6997714..6981981 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
@@ -19,12 +19,14 @@ using namespace llvm::pdb;
PDBSymbolTypePointer::PDBSymbolTypePointer(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
-std::unique_ptr<PDBSymbol> PDBSymbolTypePointer::getPointeeType() const {
- return Session.getSymbolById(getTypeId());
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::PointerType);
}
void PDBSymbolTypePointer::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
+
+void PDBSymbolTypePointer::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
index 0f283b9..102b540 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
@@ -18,7 +18,9 @@ using namespace llvm::pdb;
PDBSymbolTypeTypedef::PDBSymbolTypeTypedef(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::Typedef);
+}
void PDBSymbolTypeTypedef::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
index c71838c..15dc153 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
@@ -9,7 +9,15 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
#include <utility>
@@ -18,6 +26,8 @@ using namespace llvm::pdb;
PDBSymbolTypeUDT::PDBSymbolTypeUDT(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::UDT);
+}
void PDBSymbolTypeUDT::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
index 6b76db5..9a21855 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
@@ -18,7 +18,9 @@ using namespace llvm::pdb;
PDBSymbolTypeVTable::PDBSymbolTypeVTable(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::VTable);
+}
void PDBSymbolTypeVTable::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
index ef509d6..ddc0574 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolTypeVTableShape::PDBSymbolTypeVTableShape(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::VTableShape);
+}
void PDBSymbolTypeVTableShape::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
index dbbea9c..fdbe845 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
diff --git a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
index 6a62d55..f40578f 100644
--- a/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
+++ b/contrib/llvm/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
@@ -9,8 +9,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include <utility>
@@ -19,7 +19,9 @@ using namespace llvm::pdb;
PDBSymbolUsingNamespace::PDBSymbolUsingNamespace(
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
+ : PDBSymbol(PDBSession, std::move(Symbol)) {
+ assert(RawSymbol->getSymTag() == PDB_SymType::UsingNamespace);
+}
void PDBSymbolUsingNamespace::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
deleted file mode 100644
index f19535d..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
- : Stream(std::move(Stream)) {}
-
-Error InfoStream::reload() {
- StreamReader Reader(*Stream);
-
- const InfoStreamHeader *H;
- if (auto EC = Reader.readObject(H))
- return joinErrors(
- std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "PDB Stream does not contain a header."));
-
- switch (H->Version) {
- case PdbImplVC70:
- case PdbImplVC80:
- case PdbImplVC110:
- case PdbImplVC140:
- break;
- default:
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported PDB stream version.");
- }
-
- Version = H->Version;
- Signature = H->Signature;
- Age = H->Age;
- Guid = H->Guid;
-
- return NamedStreams.load(Reader);
-}
-
-uint32_t InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
- uint32_t Result;
- if (!NamedStreams.tryGetValue(Name, Result))
- return 0;
- return Result;
-}
-
-iterator_range<StringMapConstIterator<uint32_t>>
-InfoStream::named_streams() const {
- return NamedStreams.entries();
-}
-
-PdbRaw_ImplVer InfoStream::getVersion() const {
- return static_cast<PdbRaw_ImplVer>(Version);
-}
-
-uint32_t InfoStream::getSignature() const { return Signature; }
-
-uint32_t InfoStream::getAge() const { return Age; }
-
-PDB_UniqueId InfoStream::getGuid() const { return Guid; }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
deleted file mode 100644
index 73fbf85..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
-
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf)
- : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
-
-void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
-
-void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; }
-
-void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
-
-void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
-
-NameMapBuilder &InfoStreamBuilder::getNamedStreamsBuilder() {
- return NamedStreams;
-}
-
-uint32_t InfoStreamBuilder::calculateSerializedLength() const {
- return sizeof(InfoStreamHeader) + NamedStreams.calculateSerializedLength();
-}
-
-Error InfoStreamBuilder::finalizeMsfLayout() {
- uint32_t Length = calculateSerializedLength();
- if (auto EC = Msf.setStreamSize(StreamPDB, Length))
- return EC;
- return Error::success();
-}
-
-Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
- const msf::WritableStream &Buffer) const {
- auto InfoS =
- WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamPDB);
- StreamWriter Writer(*InfoS);
-
- InfoStreamHeader H;
- H.Age = Age;
- H.Signature = Sig;
- H.Version = Ver;
- H.Guid = Guid;
- if (auto EC = Writer.writeObject(H))
- return EC;
-
- return NamedStreams.commit(Writer);
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
deleted file mode 100644
index b34d770..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-//===- ModInfo.cpp - PDB module information -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-ModInfo::ModInfo() = default;
-
-ModInfo::ModInfo(const ModInfo &Info) = default;
-
-ModInfo::~ModInfo() = default;
-
-Error ModInfo::initialize(ReadableStreamRef Stream, ModInfo &Info) {
- StreamReader Reader(Stream);
- if (auto EC = Reader.readObject(Info.Layout))
- return EC;
-
- if (auto EC = Reader.readZeroString(Info.ModuleName))
- return EC;
-
- if (auto EC = Reader.readZeroString(Info.ObjFileName))
- return EC;
- return Error::success();
-}
-
-bool ModInfo::hasECInfo() const {
- return (Layout->Flags & ModInfoFlags::HasECFlagMask) != 0;
-}
-
-uint16_t ModInfo::getTypeServerIndex() const {
- return (Layout->Flags & ModInfoFlags::TypeServerIndexMask) >>
- ModInfoFlags::TypeServerIndexShift;
-}
-
-uint16_t ModInfo::getModuleStreamIndex() const { return Layout->ModDiStream; }
-
-uint32_t ModInfo::getSymbolDebugInfoByteSize() const {
- return Layout->SymBytes;
-}
-
-uint32_t ModInfo::getLineInfoByteSize() const { return Layout->LineBytes; }
-
-uint32_t ModInfo::getC13LineInfoByteSize() const { return Layout->C13Bytes; }
-
-uint32_t ModInfo::getNumberOfFiles() const { return Layout->NumFiles; }
-
-uint32_t ModInfo::getSourceFileNameIndex() const {
- return Layout->SrcFileNameNI;
-}
-
-uint32_t ModInfo::getPdbFilePathNameIndex() const {
- return Layout->PdbFilePathNI;
-}
-
-StringRef ModInfo::getModuleName() const { return ModuleName; }
-
-StringRef ModInfo::getObjFileName() const { return ObjFileName; }
-
-uint32_t ModInfo::getRecordLength() const {
- uint32_t M = ModuleName.str().size() + 1;
- uint32_t O = ObjFileName.str().size() + 1;
- uint32_t Size = sizeof(ModuleInfoHeader) + M + O;
- Size = alignTo(Size, 4);
- return Size;
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
deleted file mode 100644
index 0ffc5b7..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//===- ModStream.cpp - PDB Module Info Stream Access ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamRef.h"
-#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
-#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-ModStream::ModStream(const ModInfo &Module,
- std::unique_ptr<MappedBlockStream> Stream)
- : Mod(Module), Stream(std::move(Stream)) {}
-
-ModStream::~ModStream() = default;
-
-Error ModStream::reload() {
- StreamReader Reader(*Stream);
-
- uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
- uint32_t C11Size = Mod.getLineInfoByteSize();
- uint32_t C13Size = Mod.getC13LineInfoByteSize();
-
- if (C11Size > 0 && C13Size > 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Module has both C11 and C13 line info");
-
- ReadableStreamRef S;
-
- if (auto EC = Reader.readInteger(Signature))
- return EC;
- if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
- return EC;
-
- if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
- return EC;
- if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
- return EC;
-
- StreamReader LineReader(C13LinesSubstream);
- if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining()))
- return EC;
-
- uint32_t GlobalRefsSize;
- if (auto EC = Reader.readInteger(GlobalRefsSize))
- return EC;
- if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
- return EC;
- if (Reader.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unexpected bytes in module stream.");
-
- return Error::success();
-}
-
-iterator_range<codeview::CVSymbolArray::Iterator>
-ModStream::symbols(bool *HadError) const {
- // It's OK if the stream is empty.
- if (SymbolsSubstream.getUnderlyingStream().getLength() == 0)
- return make_range(SymbolsSubstream.end(), SymbolsSubstream.end());
- return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
-}
-
-iterator_range<codeview::ModuleSubstreamArray::Iterator>
-ModStream::lines(bool *HadError) const {
- return make_range(LineInfo.begin(HadError), LineInfo.end());
-}
-
-Error ModStream::commit() { return Error::success(); }
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp
deleted file mode 100644
index 84cccb35..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- NameHashTable.cpp - PDB Name Hash Table ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/Hash.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/Support/Endian.h"
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::support;
-using namespace llvm::pdb;
-
-NameHashTable::NameHashTable() : Signature(0), HashVersion(0), NameCount(0) {}
-
-Error NameHashTable::load(StreamReader &Stream) {
- struct Header {
- support::ulittle32_t Signature;
- support::ulittle32_t HashVersion;
- support::ulittle32_t ByteSize;
- };
-
- const Header *H;
- if (auto EC = Stream.readObject(H))
- return EC;
-
- if (H->Signature != 0xEFFEEFFE)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid hash table signature");
- if (H->HashVersion != 1 && H->HashVersion != 2)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported hash version");
-
- Signature = H->Signature;
- HashVersion = H->HashVersion;
- if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid hash table byte length"));
-
- const support::ulittle32_t *HashCount;
- if (auto EC = Stream.readObject(HashCount))
- return EC;
-
- if (auto EC = Stream.readArray(IDs, *HashCount))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read bucket array"));
-
- if (Stream.bytesRemaining() < sizeof(support::ulittle32_t))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Missing name count");
-
- if (auto EC = Stream.readInteger(NameCount))
- return EC;
- return Error::success();
-}
-
-StringRef NameHashTable::getStringForID(uint32_t ID) const {
- if (ID == IDs[0])
- return StringRef();
-
- // NamesBuffer is a buffer of null terminated strings back to back. ID is
- // the starting offset of the string we're looking for. So just seek into
- // the desired offset and a read a null terminated stream from that offset.
- StringRef Result;
- StreamReader NameReader(NamesBuffer);
- NameReader.setOffset(ID);
- if (auto EC = NameReader.readZeroString(Result))
- consumeError(std::move(EC));
- return Result;
-}
-
-uint32_t NameHashTable::getIDForString(StringRef Str) const {
- uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
- size_t Count = IDs.size();
- uint32_t Start = Hash % Count;
- for (size_t I = 0; I < Count; ++I) {
- // The hash is just a starting point for the search, but if it
- // doesn't work we should find the string no matter what, because
- // we iterate the entire array.
- uint32_t Index = (Start + I) % Count;
-
- uint32_t ID = IDs[Index];
- StringRef S = getStringForID(ID);
- if (S == Str)
- return ID;
- }
- // IDs[0] contains the ID of the "invalid" entry.
- return IDs[0];
-}
-
-FixedStreamArray<support::ulittle32_t> NameHashTable::name_ids() const {
- return IDs;
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
deleted file mode 100644
index 0f55f58..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-//===- NameMap.cpp - PDB Name Map -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SparseBitVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-NameMap::NameMap() = default;
-
-Error NameMap::load(StreamReader &Stream) {
- // This is some sort of weird string-set/hash table encoded in the stream.
- // It starts with the number of bytes in the table.
- uint32_t NumberOfBytes;
- if (auto EC = Stream.readInteger(NumberOfBytes))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map length"));
- if (Stream.bytesRemaining() < NumberOfBytes)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid name map length");
-
- // Following that field is the starting offset of strings in the name table.
- uint32_t StringsOffset = Stream.getOffset();
- Stream.setOffset(StringsOffset + NumberOfBytes);
-
- // This appears to be equivalent to the total number of strings *actually*
- // in the name table.
- uint32_t HashSize;
- if (auto EC = Stream.readInteger(HashSize))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map hash size"));
-
- // This appears to be an upper bound on the number of strings in the name
- // table.
- uint32_t MaxNumberOfStrings;
- if (auto EC = Stream.readInteger(MaxNumberOfStrings))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map max strings"));
-
- if (MaxNumberOfStrings > (UINT32_MAX / sizeof(uint32_t)))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Implausible number of strings");
-
- const uint32_t MaxNumberOfWords = UINT32_MAX / (sizeof(uint32_t) * 8);
-
- // This appears to be a hash table which uses bitfields to determine whether
- // or not a bucket is 'present'.
- uint32_t NumPresentWords;
- if (auto EC = Stream.readInteger(NumPresentWords))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map num words"));
-
- if (NumPresentWords > MaxNumberOfWords)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Number of present words is too large");
-
- SparseBitVector<> Present;
- for (uint32_t I = 0; I != NumPresentWords; ++I) {
- uint32_t Word;
- if (auto EC = Stream.readInteger(Word))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map word"));
- for (unsigned Idx = 0; Idx < 32; ++Idx)
- if (Word & (1U << Idx))
- Present.set((I * 32) + Idx);
- }
-
- // This appears to be a hash table which uses bitfields to determine whether
- // or not a bucket is 'deleted'.
- uint32_t NumDeletedWords;
- if (auto EC = Stream.readInteger(NumDeletedWords))
- return joinErrors(
- std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map num deleted words"));
-
- if (NumDeletedWords > MaxNumberOfWords)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Number of deleted words is too large");
-
- SparseBitVector<> Deleted;
- for (uint32_t I = 0; I != NumDeletedWords; ++I) {
- uint32_t Word;
- if (auto EC = Stream.readInteger(Word))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map word"));
- for (unsigned Idx = 0; Idx < 32; ++Idx)
- if (Word & (1U << Idx))
- Deleted.set((I * 32) + Idx);
- }
-
- for (unsigned I : Present) {
- // For all present entries, dump out their mapping.
- (void)I;
-
- // This appears to be an offset relative to the start of the strings.
- // It tells us where the null-terminated string begins.
- uint32_t NameOffset;
- if (auto EC = Stream.readInteger(NameOffset))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map name offset"));
-
- // This appears to be a stream number into the stream directory.
- uint32_t NameIndex;
- if (auto EC = Stream.readInteger(NameIndex))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map name index"));
-
- // Compute the offset of the start of the string relative to the stream.
- uint32_t StringOffset = StringsOffset + NameOffset;
- uint32_t OldOffset = Stream.getOffset();
- // Pump out our c-string from the stream.
- StringRef Str;
- Stream.setOffset(StringOffset);
- if (auto EC = Stream.readZeroString(Str))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected name map name"));
-
- Stream.setOffset(OldOffset);
- // Add this to a string-map from name to stream number.
- Mapping.insert({Str, NameIndex});
- }
-
- return Error::success();
-}
-
-iterator_range<StringMapConstIterator<uint32_t>> NameMap::entries() const {
- return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
- Mapping.end());
-}
-
-bool NameMap::tryGetValue(StringRef Name, uint32_t &Value) const {
- auto Iter = Mapping.find(Name);
- if (Iter == Mapping.end())
- return false;
- Value = Iter->second;
- return true;
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
deleted file mode 100644
index f570d59..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- NameMapBuilder.cpp - PDB Name Map Builder ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
-#include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NameMapBuilder::NameMapBuilder() = default;
-
-void NameMapBuilder::addMapping(StringRef Name, uint32_t Mapping) {
- StringDataBytes += Name.size() + 1;
- Map.insert({Name, Mapping});
-}
-
-Expected<std::unique_ptr<NameMap>> NameMapBuilder::build() {
- auto Result = llvm::make_unique<NameMap>();
- Result->Mapping = Map;
- return std::move(Result);
-}
-
-uint32_t NameMapBuilder::calculateSerializedLength() const {
- uint32_t TotalLength = 0;
-
- TotalLength += sizeof(support::ulittle32_t); // StringDataBytes value
- TotalLength += StringDataBytes; // actual string data
-
- TotalLength += sizeof(support::ulittle32_t); // Hash Size
- TotalLength += sizeof(support::ulittle32_t); // Max Number of Strings
- TotalLength += sizeof(support::ulittle32_t); // Num Present Words
- // One bitmask word for each present entry
- TotalLength += Map.size() * sizeof(support::ulittle32_t);
- TotalLength += sizeof(support::ulittle32_t); // Num Deleted Words
-
- // For each present word, which we are treating as equivalent to the number of
- // entries in the table, we have a pair of integers. An offset into the
- // string data, and a corresponding stream number.
- TotalLength += Map.size() * 2 * sizeof(support::ulittle32_t);
-
- return TotalLength;
-}
-
-Error NameMapBuilder::commit(msf::StreamWriter &Writer) const {
- // The first field is the number of bytes of string data. So add
- // up the length of all strings plus a null terminator for each
- // one.
- uint32_t NumBytes = 0;
- for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
- NumBytes += B->getKeyLength() + 1;
- }
-
- if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data
- return EC;
- // Now all of the string data itself.
- for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
- if (auto EC = Writer.writeZeroString(B->getKey()))
- return EC;
- }
-
- if (auto EC = Writer.writeInteger(Map.size())) // Hash Size
- return EC;
-
- if (auto EC = Writer.writeInteger(Map.size())) // Max Number of Strings
- return EC;
-
- if (auto EC = Writer.writeInteger(Map.size())) // Num Present Words
- return EC;
-
- // For each entry in the mapping, write a bit mask which represents a bucket
- // to store it in. We don't use this, so the value we write isn't important
- // to us, it just has to be there.
- for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
- if (auto EC = Writer.writeInteger(1U))
- return EC;
- }
-
- if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
- return EC;
-
- // Mappings of each word.
- uint32_t OffsetSoFar = 0;
- for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
- // This is a list of key value pairs where the key is the offset into the
- // strings buffer, and the value is a stream number. Write each pair.
- if (auto EC = Writer.writeInteger(OffsetSoFar))
- return EC;
-
- if (auto EC = Writer.writeInteger(B->second))
- return EC;
-
- OffsetSoFar += B->getKeyLength() + 1;
- }
-
- return Error::success();
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
deleted file mode 100644
index 6fec0e3..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
-
-#include "llvm/ADT/BitVector.h"
-
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/StreamInterface.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/GenericError.h"
-#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator) {}
-
-Error PDBFileBuilder::initialize(uint32_t BlockSize) {
- auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
- if (!ExpectedMsf)
- return ExpectedMsf.takeError();
- Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
- return Error::success();
-}
-
-MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
-
-InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
- if (!Info)
- Info = llvm::make_unique<InfoStreamBuilder>(*Msf);
- return *Info;
-}
-
-DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
- if (!Dbi)
- Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
- return *Dbi;
-}
-
-TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
- if (!Tpi)
- Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
- return *Tpi;
-}
-
-TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
- if (!Ipi)
- Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
- return *Ipi;
-}
-
-Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
- if (Info) {
- if (auto EC = Info->finalizeMsfLayout())
- return std::move(EC);
- }
- if (Dbi) {
- if (auto EC = Dbi->finalizeMsfLayout())
- return std::move(EC);
- }
- if (Tpi) {
- if (auto EC = Tpi->finalizeMsfLayout())
- return std::move(EC);
- }
- if (Ipi) {
- if (auto EC = Ipi->finalizeMsfLayout())
- return std::move(EC);
- }
-
- return Msf->build();
-}
-
-Error PDBFileBuilder::commit(StringRef Filename) {
- auto ExpectedLayout = finalizeMsfLayout();
- if (!ExpectedLayout)
- return ExpectedLayout.takeError();
- auto &Layout = *ExpectedLayout;
-
- uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
- auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
- if (OutFileOrError.getError())
- return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path,
- Filename);
- FileBufferByteStream Buffer(std::move(*OutFileOrError));
- StreamWriter Writer(Buffer);
-
- if (auto EC = Writer.writeObject(*Layout.SB))
- return EC;
- uint32_t BlockMapOffset =
- msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
- Writer.setOffset(BlockMapOffset);
- if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
- return EC;
-
- auto DirStream =
- WritableMappedBlockStream::createDirectoryStream(Layout, Buffer);
- StreamWriter DW(*DirStream);
- if (auto EC =
- DW.writeInteger(static_cast<uint32_t>(Layout.StreamSizes.size())))
- return EC;
-
- if (auto EC = DW.writeArray(Layout.StreamSizes))
- return EC;
-
- for (const auto &Blocks : Layout.StreamMap) {
- if (auto EC = DW.writeArray(Blocks))
- return EC;
- }
-
- if (Info) {
- if (auto EC = Info->commit(Layout, Buffer))
- return EC;
- }
-
- if (Dbi) {
- if (auto EC = Dbi->commit(Layout, Buffer))
- return EC;
- }
-
- if (Tpi) {
- if (auto EC = Tpi->commit(Layout, Buffer))
- return EC;
- }
-
- if (Ipi) {
- if (auto EC = Ipi->commit(Layout, Buffer))
- return EC;
- }
-
- return Buffer.commit();
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp
deleted file mode 100644
index cd3a206..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-//===- RawSession.cpp - Raw implementation of IPDBSession -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/PDB/GenericError.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
-#include <memory>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-RawSession::RawSession(std::unique_ptr<PDBFile> PdbFile,
- std::unique_ptr<BumpPtrAllocator> Allocator)
- : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
-
-RawSession::~RawSession() = default;
-
-Error RawSession::createFromPdb(StringRef Path,
- std::unique_ptr<IPDBSession> &Session) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
- MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
- /*RequiresNullTerminator=*/false);
- if (!ErrorOrBuffer)
- return make_error<GenericError>(generic_error_code::invalid_path);
-
- std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
- auto Stream = llvm::make_unique<MemoryBufferByteStream>(std::move(Buffer));
-
- auto Allocator = llvm::make_unique<BumpPtrAllocator>();
- auto File = llvm::make_unique<PDBFile>(std::move(Stream), *Allocator);
- if (auto EC = File->parseFileHeaders())
- return EC;
- if (auto EC = File->parseStreamData())
- return EC;
-
- Session =
- llvm::make_unique<RawSession>(std::move(File), std::move(Allocator));
-
- return Error::success();
-}
-
-Error RawSession::createFromExe(StringRef Path,
- std::unique_ptr<IPDBSession> &Session) {
- return make_error<RawError>(raw_error_code::feature_unsupported);
-}
-
-uint64_t RawSession::getLoadAddress() const { return 0; }
-
-void RawSession::setLoadAddress(uint64_t Address) {}
-
-std::unique_ptr<PDBSymbolExe> RawSession::getGlobalScope() const {
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbol> RawSession::getSymbolById(uint32_t SymbolId) const {
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbol>
-RawSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-RawSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
- const IPDBSourceFile &File) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-RawSession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumSourceFiles>
-RawSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
- StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBSourceFile>
-RawSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
- StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
-RawSession::findCompilandsForSourceFile(StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbolCompiland>
-RawSession::findOneCompilandForSourceFile(StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumSourceFiles> RawSession::getAllSourceFiles() const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumSourceFiles> RawSession::getSourceFilesForCompiland(
- const PDBSymbolCompiland &Compiland) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBSourceFile>
-RawSession::getSourceFileById(uint32_t FileId) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumDataStreams> RawSession::getDebugStreams() const {
- return nullptr;
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiHashing.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiHashing.cpp
deleted file mode 100644
index 6c3ddb3..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiHashing.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//===- TpiHashing.cpp -----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Raw/TpiHashing.h"
-
-#include "llvm/DebugInfo/PDB/Raw/Hash.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.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();
- 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);
-
- if (!ForwardRef && !Scoped && !IsAnon)
- return hashStringV1(Rec.getName());
- if (!ForwardRef && UniqueName && !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();
-}
-
-Error TpiHashVerifier::verifySourceLine(codeview::TypeIndex TI) {
- 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();
-}
-
-Error TpiHashVerifier::visitTypeBegin(CVType &Rec) {
- ++Index;
- RawRecord = Rec;
- return Error::success();
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
deleted file mode 100644
index c769321..0000000
--- a/contrib/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//===- TpiStreamBuilder.cpp - -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/ByteStream.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/MSF/StreamArray.h"
-#include "llvm/DebugInfo/MSF/StreamReader.h"
-#include "llvm/DebugInfo/MSF/StreamWriter.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Raw/RawError.h"
-#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
-#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
- : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
-}
-
-TpiStreamBuilder::~TpiStreamBuilder() = default;
-
-void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
- VerHeader = Version;
-}
-
-void TpiStreamBuilder::addTypeRecord(const codeview::CVType &Record) {
- TypeRecords.push_back(Record);
- TypeRecordStream.setItems(TypeRecords);
-}
-
-Error TpiStreamBuilder::finalize() {
- if (Header)
- return Error::success();
-
- TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
-
- uint32_t Count = TypeRecords.size();
- uint32_t HashBufferSize = calculateHashBufferSize();
-
- H->Version = *VerHeader;
- H->HeaderSize = sizeof(TpiStreamHeader);
- H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
- H->TypeIndexEnd = H->TypeIndexBegin + Count;
- H->TypeRecordBytes = TypeRecordStream.getLength();
-
- H->HashStreamIndex = HashStreamIndex;
- H->HashAuxStreamIndex = kInvalidStreamIndex;
- H->HashKeySize = sizeof(ulittle32_t);
- H->NumHashBuckets = MinTpiHashBuckets;
-
- // Recall that hash values go into a completely different stream identified by
- // the `HashStreamIndex` field of the `TpiStreamHeader`. Therefore, the data
- // begins at offset 0 of this independent stream.
- H->HashValueBuffer.Off = 0;
- H->HashValueBuffer.Length = HashBufferSize;
- H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length;
- H->HashAdjBuffer.Length = 0;
- H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length;
- H->IndexOffsetBuffer.Length = 0;
-
- Header = H;
- return Error::success();
-}
-
-uint32_t TpiStreamBuilder::calculateSerializedLength() const {
- return sizeof(TpiStreamHeader) + TypeRecordStream.getLength();
-}
-
-uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
- if (TypeRecords.empty() || !TypeRecords[0].Hash.hasValue())
- return 0;
- return TypeRecords.size() * sizeof(ulittle32_t);
-}
-
-Error TpiStreamBuilder::finalizeMsfLayout() {
- uint32_t Length = calculateSerializedLength();
- if (auto EC = Msf.setStreamSize(Idx, Length))
- return EC;
-
- uint32_t HashBufferSize = calculateHashBufferSize();
-
- if (HashBufferSize == 0)
- return Error::success();
-
- auto ExpectedIndex = Msf.addStream(HashBufferSize);
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- HashStreamIndex = *ExpectedIndex;
- ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeRecords.size());
- MutableArrayRef<ulittle32_t> HashBuffer(H, TypeRecords.size());
- for (uint32_t I = 0; I < TypeRecords.size(); ++I) {
- HashBuffer[I] = *TypeRecords[I].Hash % MinTpiHashBuckets;
- }
- ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(HashBuffer.data()),
- HashBufferSize);
- HashValueStream = llvm::make_unique<ByteStream>(Bytes);
- return Error::success();
-}
-
-Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
- const msf::WritableStream &Buffer) {
- if (auto EC = finalize())
- return EC;
-
- auto InfoS =
- WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Idx);
-
- StreamWriter Writer(*InfoS);
- if (auto EC = Writer.writeObject(*Header))
- return EC;
-
- auto RecordArray = VarStreamArray<codeview::CVType>(TypeRecordStream);
- if (auto EC = Writer.writeArray(RecordArray))
- return EC;
-
- if (HashStreamIndex != kInvalidStreamIndex) {
- auto HVS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
- HashStreamIndex);
- StreamWriter HW(*HVS);
- if (auto EC = HW.writeStreamRef(*HashValueStream))
- return EC;
- }
-
- return Error::success();
-}
diff --git a/contrib/llvm/lib/DebugInfo/PDB/UDTLayout.cpp b/contrib/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
new file mode 100644
index 0000000..5f4390b
--- /dev/null
+++ b/contrib/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -0,0 +1,303 @@
+//===- UDTLayout.cpp ------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Support/Casting.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) {
+ const IPDBSession &Session = Symbol.getSession();
+ const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol();
+ uint32_t TypeId = RawSymbol.getTypeId();
+ return Session.getSymbolById(TypeId);
+}
+
+static uint32_t getTypeLength(const PDBSymbol &Symbol) {
+ auto SymbolType = getSymbolType(Symbol);
+ const IPDBRawSymbol &RawType = SymbolType->getRawSymbol();
+
+ return RawType.getLength();
+}
+
+LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
+ const PDBSymbol *Symbol, const std::string &Name,
+ uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided)
+ : Symbol(Symbol), Parent(Parent), Name(Name),
+ OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
+ IsElided(IsElided) {
+ UsedBytes.resize(SizeOf, true);
+}
+
+uint32_t LayoutItemBase::deepPaddingSize() const {
+ return UsedBytes.size() - UsedBytes.count();
+}
+
+uint32_t LayoutItemBase::tailPadding() const {
+ int Last = UsedBytes.find_last();
+
+ return UsedBytes.size() - (Last + 1);
+}
+
+DataMemberLayoutItem::DataMemberLayoutItem(
+ const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
+ : LayoutItemBase(&Parent, Member.get(), Member->getName(),
+ Member->getOffset(), getTypeLength(*Member), false),
+ DataMember(std::move(Member)) {
+ auto Type = DataMember->getType();
+ if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
+ UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
+ UsedBytes = UdtLayout->usedBytes();
+ }
+}
+
+VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
+ uint32_t Offset, uint32_t Size)
+ : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
+ Type(std::move(Sym)) {
+}
+
+const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
+ return *dyn_cast<PDBSymbolData>(Symbol);
+}
+
+bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
+
+const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
+ return *UdtLayout;
+}
+
+VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeVTable> VT)
+ : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
+ VTable(std::move(VT)) {
+ auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
+ ElementSize = VTableType->getLength();
+}
+
+UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided)
+ : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
+ // UDT storage comes from a union of all the children's storage, so start out
+ // uninitialized.
+ UsedBytes.reset(0, Size);
+
+ initializeChildren(Sym);
+ if (LayoutSize < Size)
+ UsedBytes.resize(LayoutSize);
+}
+
+uint32_t UDTLayoutBase::tailPadding() const {
+ uint32_t Abs = LayoutItemBase::tailPadding();
+ if (!LayoutItems.empty()) {
+ const LayoutItemBase *Back = LayoutItems.back();
+ uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
+ if (Abs < ChildPadding)
+ Abs = 0;
+ else
+ Abs -= ChildPadding;
+ }
+ return Abs;
+}
+
+ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
+ : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
+ UDT(UDT) {
+ ImmediateUsedBytes.resize(SizeOf, false);
+ for (auto &LI : LayoutItems) {
+ uint32_t Begin = LI->getOffsetInParent();
+ uint32_t End = Begin + LI->getLayoutSize();
+ End = std::min(SizeOf, End);
+ ImmediateUsedBytes.set(Begin, End);
+ }
+}
+
+ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
+ : ClassLayout(*UDT) {
+ OwnedStorage = std::move(UDT);
+}
+
+uint32_t ClassLayout::immediatePadding() const {
+ return SizeOf - ImmediateUsedBytes.count();
+}
+
+BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
+ uint32_t OffsetInParent, bool Elide,
+ std::unique_ptr<PDBSymbolTypeBaseClass> B)
+ : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
+ Elide),
+ Base(std::move(B)) {
+ if (isEmptyBase()) {
+ // Special case an empty base so that it doesn't get treated as padding.
+ UsedBytes.resize(1);
+ UsedBytes.set(0);
+ }
+ IsVirtualBase = Base->isVirtualBaseClass();
+}
+
+void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
+ // Handled bases first, followed by VTables, followed by data members,
+ // followed by functions, followed by other. This ordering is necessary
+ // so that bases and vtables get initialized before any functions which
+ // may override them.
+ UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
+ UniquePtrVector<PDBSymbolTypeVTable> VTables;
+ UniquePtrVector<PDBSymbolData> Members;
+ UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
+
+ auto Children = Sym.findAllChildren();
+ while (auto Child = Children->getNext()) {
+ if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
+ if (Base->isVirtualBaseClass())
+ VirtualBaseSyms.push_back(std::move(Base));
+ else
+ Bases.push_back(std::move(Base));
+ }
+ else if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) {
+ if (Data->getDataKind() == PDB_DataKind::Member)
+ Members.push_back(std::move(Data));
+ else
+ Other.push_back(std::move(Data));
+ } else if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child))
+ VTables.push_back(std::move(VT));
+ else if (auto Func = unique_dyn_cast<PDBSymbolFunc>(Child))
+ Funcs.push_back(std::move(Func));
+ else {
+ Other.push_back(std::move(Child));
+ }
+ }
+
+ // We don't want to have any re-allocations in the list of bases, so make
+ // sure to reserve enough space so that our ArrayRefs don't get invalidated.
+ AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
+
+ // Only add non-virtual bases to the class first. Only at the end of the
+ // class, after all non-virtual bases and data members have been added do we
+ // add virtual bases. This way the offsets are correctly aligned when we go
+ // to lay out virtual bases.
+ for (auto &Base : Bases) {
+ uint32_t Offset = Base->getOffset();
+ // Non-virtual bases never get elided.
+ auto BL = llvm::make_unique<BaseClassLayout>(*this, Offset, false,
+ std::move(Base));
+
+ AllBases.push_back(BL.get());
+ addChildToLayout(std::move(BL));
+ }
+ NonVirtualBases = AllBases;
+
+ assert(VTables.size() <= 1);
+ if (!VTables.empty()) {
+ auto VTLayout =
+ llvm::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
+
+ VTable = VTLayout.get();
+
+ addChildToLayout(std::move(VTLayout));
+ }
+
+ for (auto &Data : Members) {
+ auto DM = llvm::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
+
+ addChildToLayout(std::move(DM));
+ }
+
+ // Make sure add virtual bases before adding functions, since functions may be
+ // overrides of virtual functions declared in a virtual base, so the VTables
+ // and virtual intros need to be correctly initialized.
+ for (auto &VB : VirtualBaseSyms) {
+ int VBPO = VB->getVirtualBasePointerOffset();
+ if (!hasVBPtrAtOffset(VBPO)) {
+ if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
+ auto VBPL = llvm::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+ VBPO, VBP->getLength());
+ VBPtr = VBPL.get();
+ addChildToLayout(std::move(VBPL));
+ }
+ }
+
+ // Virtual bases always go at the end. So just look for the last place we
+ // ended when writing something, and put our virtual base there.
+ // Note that virtual bases get elided unless this is a top-most derived
+ // class.
+ uint32_t Offset = UsedBytes.find_last() + 1;
+ bool Elide = (Parent != nullptr);
+ auto BL =
+ llvm::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+ AllBases.push_back(BL.get());
+
+ // Only lay this virtual base out directly inside of *this* class if this
+ // is a top-most derived class. Keep track of it regardless, but only
+ // physically lay it out if it's a topmost derived class.
+ addChildToLayout(std::move(BL));
+ }
+ VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
+
+ if (Parent != nullptr)
+ LayoutSize = UsedBytes.find_last() + 1;
+}
+
+bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
+ if (VBPtr && VBPtr->getOffsetInParent() == Off)
+ return true;
+ for (BaseClassLayout *BL : AllBases) {
+ if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
+ return true;
+ }
+ return false;
+}
+
+void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
+ uint32_t Begin = Child->getOffsetInParent();
+
+ if (!Child->isElided()) {
+ BitVector ChildBytes = Child->usedBytes();
+
+ // Suppose the child occupies 4 bytes starting at offset 12 in a 32 byte
+ // class. When we call ChildBytes.resize(32), the Child's storage will
+ // still begin at offset 0, so we need to shift it left by offset bytes
+ // to get it into the right position.
+ ChildBytes.resize(UsedBytes.size());
+ ChildBytes <<= Child->getOffsetInParent();
+ UsedBytes |= ChildBytes;
+
+ if (ChildBytes.count() > 0) {
+ auto Loc = std::upper_bound(LayoutItems.begin(), LayoutItems.end(), Begin,
+ [](uint32_t Off, const LayoutItemBase *Item) {
+ return (Off < Item->getOffsetInParent());
+ });
+
+ LayoutItems.insert(Loc, Child.get());
+ }
+ }
+
+ ChildStorage.push_back(std::move(Child));
+}
OpenPOWER on IntegriCloud