Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,116 +0,0 @@
macro(add_pdb_impl_folder group)
list(APPEND PDB_IMPL_SOURCES ${ARGN})
source_group(${group} FILES ${ARGN})
endmacro()
if(LLVM_ENABLE_DIA_SDK)
include_directories(${MSVC_DIA_SDK_DIR}/include)
set(LIBPDB_LINK_FOLDERS "${MSVC_DIA_SDK_DIR}\\lib")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LIBPDB_LINK_FOLDERS "${LIBPDB_LINK_FOLDERS}\\amd64")
endif()
file(TO_CMAKE_PATH "${LIBPDB_LINK_FOLDERS}\\diaguids.lib" LIBPDB_ADDITIONAL_LIBRARIES)
add_pdb_impl_folder(DIA
DIA/DIADataStream.cpp
DIA/DIAEnumDebugStreams.cpp
DIA/DIAEnumLineNumbers.cpp
DIA/DIAEnumSourceFiles.cpp
DIA/DIAEnumSymbols.cpp
DIA/DIAEnumTables.cpp
DIA/DIAError.cpp
DIA/DIALineNumber.cpp
DIA/DIARawSymbol.cpp
DIA/DIASession.cpp
DIA/DIASourceFile.cpp
DIA/DIATable.cpp
)
set(LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/DIA")
endif()
add_pdb_impl_folder(Native
Native/DbiModuleDescriptor.cpp
Native/DbiModuleDescriptorBuilder.cpp
Native/DbiModuleList.cpp
Native/DbiStream.cpp
Native/DbiStreamBuilder.cpp
Native/EnumTables.cpp
Native/GlobalsStream.cpp
Native/Hash.cpp
Native/HashTable.cpp
Native/InfoStream.cpp
Native/InfoStreamBuilder.cpp
Native/ModuleDebugStream.cpp
Native/NativeBuiltinSymbol.cpp
Native/NativeCompilandSymbol.cpp
Native/NativeEnumModules.cpp
Native/NativeEnumSymbol.cpp
Native/NativeEnumTypes.cpp
Native/NativeExeSymbol.cpp
Native/NativeRawSymbol.cpp
Native/NamedStreamMap.cpp
Native/NativeSession.cpp
Native/PDBFile.cpp
Native/PDBFileBuilder.cpp
Native/PDBStringTable.cpp
Native/PDBStringTableBuilder.cpp
Native/PublicsStream.cpp
Native/GSIStreamBuilder.cpp
Native/RawError.cpp
Native/SymbolStream.cpp
Native/TpiHashing.cpp
Native/TpiStream.cpp
Native/TpiStreamBuilder.cpp)
list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/Native")
list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")
add_llvm_library(LLVMDebugInfoPDB
GenericError.cpp
IPDBSourceFile.cpp
PDB.cpp
PDBContext.cpp
PDBExtras.cpp
PDBInterfaceAnchors.cpp
PDBSymbol.cpp
PDBSymbolAnnotation.cpp
PDBSymbolBlock.cpp
PDBSymbolCompiland.cpp
PDBSymbolCompilandDetails.cpp
PDBSymbolCompilandEnv.cpp
PDBSymbolCustom.cpp
PDBSymbolData.cpp
PDBSymbolExe.cpp
PDBSymbolFunc.cpp
PDBSymbolFuncDebugEnd.cpp
PDBSymbolFuncDebugStart.cpp
PDBSymbolLabel.cpp
PDBSymbolPublicSymbol.cpp
PDBSymbolThunk.cpp
PDBSymbolTypeArray.cpp
PDBSymbolTypeBaseClass.cpp
PDBSymbolTypeBuiltin.cpp
PDBSymbolTypeCustom.cpp
PDBSymbolTypeDimension.cpp
PDBSymbolTypeEnum.cpp
PDBSymbolTypeFriend.cpp
PDBSymbolTypeFunctionArg.cpp
PDBSymbolTypeFunctionSig.cpp
PDBSymbolTypeManaged.cpp
PDBSymbolTypePointer.cpp
PDBSymbolTypeTypedef.cpp
PDBSymbolTypeUDT.cpp
PDBSymbolTypeVTable.cpp
PDBSymbolTypeVTableShape.cpp
PDBSymbolUnknown.cpp
PDBSymbolUsingNamespace.cpp
PDBSymDumper.cpp
UDTLayout.cpp
${PDB_IMPL_SOURCES}
ADDITIONAL_HEADER_DIRS
${LIBPDB_ADDITIONAL_HEADER_DIRS}
)
target_link_libraries(LLVMDebugInfoPDB INTERFACE "${LIBPDB_ADDITIONAL_LIBRARIES}")

View File

@ -1,75 +0,0 @@
//===- DIADataStream.cpp - DIA implementation of IPDBDataStream -*- 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/DIA/DIADataStream.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ConvertUTF.h"
using namespace llvm;
using namespace llvm::pdb;
DIADataStream::DIADataStream(CComPtr<IDiaEnumDebugStreamData> DiaStreamData)
: StreamData(DiaStreamData) {}
uint32_t DIADataStream::getRecordCount() const {
LONG Count = 0;
return (S_OK == StreamData->get_Count(&Count)) ? Count : 0;
}
std::string DIADataStream::getName() const {
CComBSTR Name16;
if (S_OK != StreamData->get_name(&Name16))
return std::string();
std::string Name8;
llvm::ArrayRef<char> Name16Bytes(reinterpret_cast<char *>(Name16.m_str),
Name16.ByteLength());
if (!llvm::convertUTF16ToUTF8String(Name16Bytes, Name8))
return std::string();
return Name8;
}
llvm::Optional<DIADataStream::RecordType>
DIADataStream::getItemAtIndex(uint32_t Index) const {
RecordType Record;
DWORD RecordSize = 0;
StreamData->Item(Index, 0, &RecordSize, nullptr);
if (RecordSize == 0)
return llvm::Optional<RecordType>();
Record.resize(RecordSize);
if (S_OK != StreamData->Item(Index, RecordSize, &RecordSize, &Record[0]))
return llvm::Optional<RecordType>();
return Record;
}
bool DIADataStream::getNext(RecordType &Record) {
Record.clear();
DWORD RecordSize = 0;
ULONG CountFetched = 0;
StreamData->Next(1, 0, &RecordSize, nullptr, &CountFetched);
if (RecordSize == 0)
return false;
Record.resize(RecordSize);
if (S_OK ==
StreamData->Next(1, RecordSize, &RecordSize, &Record[0], &CountFetched))
return false;
return true;
}
void DIADataStream::reset() { StreamData->Reset(); }
DIADataStream *DIADataStream::clone() const {
CComPtr<IDiaEnumDebugStreamData> EnumeratorClone;
if (S_OK != StreamData->Clone(&EnumeratorClone))
return nullptr;
return new DIADataStream(EnumeratorClone);
}

View File

@ -1,54 +0,0 @@
//==- DIAEnumDebugStreams.cpp - DIA Debug Stream 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/DIA/DIAEnumDebugStreams.h"
#include "llvm/DebugInfo/PDB/DIA/DIADataStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
DIAEnumDebugStreams::DIAEnumDebugStreams(
CComPtr<IDiaEnumDebugStreams> DiaEnumerator)
: Enumerator(DiaEnumerator) {}
uint32_t DIAEnumDebugStreams::getChildCount() const {
LONG Count = 0;
return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
}
std::unique_ptr<IPDBDataStream>
DIAEnumDebugStreams::getChildAtIndex(uint32_t Index) const {
CComPtr<IDiaEnumDebugStreamData> Item;
VARIANT VarIndex;
VarIndex.vt = VT_I4;
VarIndex.lVal = Index;
if (S_OK != Enumerator->Item(VarIndex, &Item))
return nullptr;
return std::unique_ptr<IPDBDataStream>(new DIADataStream(Item));
}
std::unique_ptr<IPDBDataStream> DIAEnumDebugStreams::getNext() {
CComPtr<IDiaEnumDebugStreamData> Item;
ULONG NumFetched = 0;
if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
return nullptr;
return std::unique_ptr<IPDBDataStream>(new DIADataStream(Item));
}
void DIAEnumDebugStreams::reset() { Enumerator->Reset(); }
DIAEnumDebugStreams *DIAEnumDebugStreams::clone() const {
CComPtr<IDiaEnumDebugStreams> EnumeratorClone;
if (S_OK != Enumerator->Clone(&EnumeratorClone))
return nullptr;
return new DIAEnumDebugStreams(EnumeratorClone);
}

View File

@ -1,51 +0,0 @@
//==- DIAEnumLineNumbers.cpp - DIA Line Number 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/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIALineNumber.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
DIAEnumLineNumbers::DIAEnumLineNumbers(
CComPtr<IDiaEnumLineNumbers> DiaEnumerator)
: Enumerator(DiaEnumerator) {}
uint32_t DIAEnumLineNumbers::getChildCount() const {
LONG Count = 0;
return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
}
std::unique_ptr<IPDBLineNumber>
DIAEnumLineNumbers::getChildAtIndex(uint32_t Index) const {
CComPtr<IDiaLineNumber> Item;
if (S_OK != Enumerator->Item(Index, &Item))
return nullptr;
return std::unique_ptr<IPDBLineNumber>(new DIALineNumber(Item));
}
std::unique_ptr<IPDBLineNumber> DIAEnumLineNumbers::getNext() {
CComPtr<IDiaLineNumber> Item;
ULONG NumFetched = 0;
if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
return nullptr;
return std::unique_ptr<IPDBLineNumber>(new DIALineNumber(Item));
}
void DIAEnumLineNumbers::reset() { Enumerator->Reset(); }
DIAEnumLineNumbers *DIAEnumLineNumbers::clone() const {
CComPtr<IDiaEnumLineNumbers> EnumeratorClone;
if (S_OK != Enumerator->Clone(&EnumeratorClone))
return nullptr;
return new DIAEnumLineNumbers(EnumeratorClone);
}

View File

@ -1,51 +0,0 @@
//==- DIAEnumSourceFiles.cpp - DIA Source File 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/DIA/DIAEnumSourceFiles.h"
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
using namespace llvm;
using namespace llvm::pdb;
DIAEnumSourceFiles::DIAEnumSourceFiles(
const DIASession &PDBSession, CComPtr<IDiaEnumSourceFiles> DiaEnumerator)
: Session(PDBSession), Enumerator(DiaEnumerator) {}
uint32_t DIAEnumSourceFiles::getChildCount() const {
LONG Count = 0;
return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
}
std::unique_ptr<IPDBSourceFile>
DIAEnumSourceFiles::getChildAtIndex(uint32_t Index) const {
CComPtr<IDiaSourceFile> Item;
if (S_OK != Enumerator->Item(Index, &Item))
return nullptr;
return std::unique_ptr<IPDBSourceFile>(new DIASourceFile(Session, Item));
}
std::unique_ptr<IPDBSourceFile> DIAEnumSourceFiles::getNext() {
CComPtr<IDiaSourceFile> Item;
ULONG NumFetched = 0;
if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
return nullptr;
return std::unique_ptr<IPDBSourceFile>(new DIASourceFile(Session, Item));
}
void DIAEnumSourceFiles::reset() { Enumerator->Reset(); }
DIAEnumSourceFiles *DIAEnumSourceFiles::clone() const {
CComPtr<IDiaEnumSourceFiles> EnumeratorClone;
if (S_OK != Enumerator->Clone(&EnumeratorClone))
return nullptr;
return new DIAEnumSourceFiles(Session, EnumeratorClone);
}

View File

@ -1,55 +0,0 @@
//==- DIAEnumSymbols.cpp - DIA 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/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;
DIAEnumSymbols::DIAEnumSymbols(const DIASession &PDBSession,
CComPtr<IDiaEnumSymbols> DiaEnumerator)
: Session(PDBSession), Enumerator(DiaEnumerator) {}
uint32_t DIAEnumSymbols::getChildCount() const {
LONG Count = 0;
return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
}
std::unique_ptr<PDBSymbol>
DIAEnumSymbols::getChildAtIndex(uint32_t Index) const {
CComPtr<IDiaSymbol> Item;
if (S_OK != Enumerator->Item(Index, &Item))
return nullptr;
std::unique_ptr<DIARawSymbol> RawSymbol(new DIARawSymbol(Session, Item));
return std::unique_ptr<PDBSymbol>(PDBSymbol::create(Session, std::move(RawSymbol)));
}
std::unique_ptr<PDBSymbol> DIAEnumSymbols::getNext() {
CComPtr<IDiaSymbol> Item;
ULONG NumFetched = 0;
if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
return nullptr;
std::unique_ptr<DIARawSymbol> RawSymbol(new DIARawSymbol(Session, Item));
return std::unique_ptr<PDBSymbol>(
PDBSymbol::create(Session, std::move(RawSymbol)));
}
void DIAEnumSymbols::reset() { Enumerator->Reset(); }
DIAEnumSymbols *DIAEnumSymbols::clone() const {
CComPtr<IDiaEnumSymbols> EnumeratorClone;
if (S_OK != Enumerator->Clone(&EnumeratorClone))
return nullptr;
return new DIAEnumSymbols(Session, EnumeratorClone);
}

View File

@ -1,53 +0,0 @@
//===- DIAEnumTables.cpp - DIA Table 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/DIA/DIAEnumTables.h"
#include "llvm/DebugInfo/PDB/DIA/DIATable.h"
using namespace llvm;
using namespace llvm::pdb;
DIAEnumTables::DIAEnumTables(
CComPtr<IDiaEnumTables> DiaEnumerator)
: Enumerator(DiaEnumerator) {}
uint32_t DIAEnumTables::getChildCount() const {
LONG Count = 0;
return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
}
std::unique_ptr<IPDBTable>
DIAEnumTables::getChildAtIndex(uint32_t Index) const {
CComPtr<IDiaTable> Item;
VARIANT Var;
Var.vt = VT_UINT;
Var.uintVal = Index;
if (S_OK != Enumerator->Item(Var, &Item))
return nullptr;
return std::unique_ptr<IPDBTable>(new DIATable(Item));
}
std::unique_ptr<IPDBTable> DIAEnumTables::getNext() {
CComPtr<IDiaTable> Item;
ULONG CeltFetched = 0;
if (S_OK != Enumerator->Next(1, &Item, &CeltFetched))
return nullptr;
return std::unique_ptr<IPDBTable>(new DIATable(Item));
}
void DIAEnumTables::reset() { Enumerator->Reset(); }
DIAEnumTables *DIAEnumTables::clone() const {
CComPtr<IDiaEnumTables> EnumeratorClone;
if (S_OK != Enumerator->Clone(&EnumeratorClone))
return nullptr;
return new DIAEnumTables(EnumeratorClone);
}

View File

@ -1,58 +0,0 @@
#include "llvm/DebugInfo/PDB/DIA/DIAError.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
using namespace llvm;
using namespace llvm::pdb;
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class DIAErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.pdb.dia"; }
std::string message(int Condition) const override {
switch (static_cast<dia_error_code>(Condition)) {
case dia_error_code::could_not_create_impl:
return "Failed to connect to DIA at runtime. Verify that Visual Studio "
"is properly installed, or that msdiaXX.dll is in your PATH.";
case dia_error_code::invalid_file_format:
return "Unable to load PDB. The file has an unrecognized format.";
case dia_error_code::invalid_parameter:
return "The parameter is incorrect.";
case dia_error_code::already_loaded:
return "Unable to load the PDB or EXE, because it is already loaded.";
case dia_error_code::debug_info_mismatch:
return "The PDB file and the EXE file do not match.";
case dia_error_code::unspecified:
return "An unknown error has occurred.";
}
llvm_unreachable("Unrecognized DIAErrorCode");
}
};
static ManagedStatic<DIAErrorCategory> Category;
char DIAError::ID = 0;
DIAError::DIAError(dia_error_code C) : DIAError(C, "") {}
DIAError::DIAError(StringRef Context)
: DIAError(dia_error_code::unspecified, Context) {}
DIAError::DIAError(dia_error_code C, StringRef Context) : Code(C) {
ErrMsg = "DIA Error: ";
std::error_code EC = convertToErrorCode();
ErrMsg += EC.message() + " ";
if (!Context.empty())
ErrMsg += Context;
}
void DIAError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
StringRef DIAError::getErrorMessage() const { return ErrMsg; }
std::error_code DIAError::convertToErrorCode() const {
return std::error_code(static_cast<int>(Code), *Category);
}

View File

@ -1,76 +0,0 @@
//===- DIALineNumber.cpp - DIA implementation of IPDBLineNumber -*- 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/DIA/DIALineNumber.h"
using namespace llvm;
using namespace llvm::pdb;
DIALineNumber::DIALineNumber(CComPtr<IDiaLineNumber> DiaLineNumber)
: LineNumber(DiaLineNumber) {}
uint32_t DIALineNumber::getLineNumber() const {
DWORD Line = 0;
return (S_OK == LineNumber->get_lineNumber(&Line)) ? Line : 0;
}
uint32_t DIALineNumber::getLineNumberEnd() const {
DWORD LineEnd = 0;
return (S_OK == LineNumber->get_lineNumberEnd(&LineEnd)) ? LineEnd : 0;
}
uint32_t DIALineNumber::getColumnNumber() const {
DWORD Column = 0;
return (S_OK == LineNumber->get_columnNumber(&Column)) ? Column : 0;
}
uint32_t DIALineNumber::getColumnNumberEnd() const {
DWORD ColumnEnd = 0;
return (S_OK == LineNumber->get_columnNumberEnd(&ColumnEnd)) ? ColumnEnd : 0;
}
uint32_t DIALineNumber::getAddressSection() const {
DWORD Section = 0;
return (S_OK == LineNumber->get_addressSection(&Section)) ? Section : 0;
}
uint32_t DIALineNumber::getAddressOffset() const {
DWORD Offset = 0;
return (S_OK == LineNumber->get_addressOffset(&Offset)) ? Offset : 0;
}
uint32_t DIALineNumber::getRelativeVirtualAddress() const {
DWORD RVA = 0;
return (S_OK == LineNumber->get_relativeVirtualAddress(&RVA)) ? RVA : 0;
}
uint64_t DIALineNumber::getVirtualAddress() const {
ULONGLONG Addr = 0;
return (S_OK == LineNumber->get_virtualAddress(&Addr)) ? Addr : 0;
}
uint32_t DIALineNumber::getLength() const {
DWORD Length = 0;
return (S_OK == LineNumber->get_length(&Length)) ? Length : 0;
}
uint32_t DIALineNumber::getSourceFileId() const {
DWORD Id = 0;
return (S_OK == LineNumber->get_sourceFileId(&Id)) ? Id : 0;
}
uint32_t DIALineNumber::getCompilandId() const {
DWORD Id = 0;
return (S_OK == LineNumber->get_compilandId(&Id)) ? Id : 0;
}
bool DIALineNumber::isStatement() const {
BOOL Statement = 0;
return (S_OK == LineNumber->get_statement(&Statement)) ? Statement : false;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,312 +0,0 @@
//===- DIASession.cpp - DIA 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/DIA/DIASession.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumTables.h"
#include "llvm/DebugInfo/PDB/DIA/DIAError.h"
#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
#include "llvm/DebugInfo/PDB/DIA/DIASupport.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#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;
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);
case E_PDB_FORMAT:
return make_error<DIAError>(dia_error_code::invalid_file_format, Context);
case E_INVALIDARG:
return make_error<DIAError>(dia_error_code::invalid_parameter, Context);
case E_UNEXPECTED:
return make_error<DIAError>(dia_error_code::already_loaded, Context);
case E_PDB_INVALID_SIG:
case E_PDB_INVALID_AGE:
return make_error<DIAError>(dia_error_code::debug_info_mismatch, Context);
default: {
std::string S;
raw_string_ostream OS(S);
OS << "HRESULT: " << format_hex(static_cast<DWORD>(Result), 10, true)
<< ": " << Context;
return make_error<DIAError>(dia_error_code::unspecified, OS.str());
}
}
}
static Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) {
if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER,
IID_IDiaDataSource,
reinterpret_cast<LPVOID *>(&DiaDataSource))))
return Error::success();
// If the CoCreateInstance call above failed, msdia*.dll is not registered.
// Try loading the DLL corresponding to the #included DIA SDK.
#if !defined(_MSC_VER)
return llvm::make_error<GenericError>(
"DIA is only supported when using MSVC.");
#else
const wchar_t *msdia_dll = nullptr;
#if _MSC_VER >= 1900 && _MSC_VER < 2000
msdia_dll = L"msdia140.dll"; // VS2015
#elif _MSC_VER >= 1800
msdia_dll = L"msdia120.dll"; // VS2013
#else
#error "Unknown Visual Studio version."
#endif
HRESULT HR;
if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
reinterpret_cast<LPVOID *>(&DiaDataSource))))
return ErrorFromHResult(HR, "Calling NoRegCoCreate");
return Error::success();
#endif
}
DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
Error DIASession::createFromPdb(StringRef Path,
std::unique_ptr<IPDBSession> &Session) {
CComPtr<IDiaDataSource> DiaDataSource;
CComPtr<IDiaSession> DiaSession;
// We assume that CoInitializeEx has already been called by the executable.
if (auto E = LoadDIA(DiaDataSource))
return E;
llvm::SmallVector<UTF16, 128> Path16;
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
return make_error<GenericError>(generic_error_code::invalid_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 {0}", Path);
}
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR, "Calling openSession");
Session.reset(new DIASession(DiaSession));
return Error::success();
}
Error DIASession::createFromExe(StringRef Path,
std::unique_ptr<IPDBSession> &Session) {
CComPtr<IDiaDataSource> DiaDataSource;
CComPtr<IDiaSession> DiaSession;
// We assume that CoInitializeEx has already been called by the executable.
if (auto EC = LoadDIA(DiaDataSource))
return EC;
llvm::SmallVector<UTF16, 128> Path16;
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
return make_error<GenericError>(generic_error_code::invalid_path, Path);
const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
HRESULT HR;
if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr)))
return ErrorFromHResult(HR, "Calling loadDataForExe");
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR, "Calling openSession");
Session.reset(new DIASession(DiaSession));
return Error::success();
}
uint64_t DIASession::getLoadAddress() const {
uint64_t LoadAddress;
bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
return (success) ? LoadAddress : 0;
}
void DIASession::setLoadAddress(uint64_t Address) {
Session->put_loadAddress(Address);
}
std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() {
CComPtr<IDiaSymbol> GlobalScope;
if (S_OK != Session->get_globalScope(&GlobalScope))
return nullptr;
auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
std::unique_ptr<PDBSymbolExe> ExeSymbol(
static_cast<PDBSymbolExe *>(PdbSymbol.release()));
return ExeSymbol;
}
std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
CComPtr<IDiaSymbol> LocatedSymbol;
if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
return nullptr;
auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
std::unique_ptr<PDBSymbol>
DIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
CComPtr<IDiaSymbol> Symbol;
if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) {
ULONGLONG LoadAddr = 0;
if (S_OK != Session->get_loadAddress(&LoadAddr))
return nullptr;
DWORD RVA = static_cast<DWORD>(Address - LoadAddr);
if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
return nullptr;
}
auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
std::unique_ptr<IPDBEnumLineNumbers>
DIASession::findLineNumbers(const PDBSymbolCompiland &Compiland,
const IPDBSourceFile &File) const {
const DIARawSymbol &RawCompiland =
static_cast<const DIARawSymbol &>(Compiland.getRawSymbol());
const DIASourceFile &RawFile = static_cast<const DIASourceFile &>(File);
CComPtr<IDiaEnumLineNumbers> LineNumbers;
if (S_OK !=
Session->findLines(RawCompiland.getDiaSymbol(), RawFile.getDiaFile(),
&LineNumbers))
return nullptr;
return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumLineNumbers>
DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
CComPtr<IDiaEnumLineNumbers> LineNumbers;
if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers))
return nullptr;
return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumSourceFiles>
DIASession::findSourceFiles(const PDBSymbolCompiland *Compiland,
llvm::StringRef Pattern,
PDB_NameSearchFlags Flags) const {
IDiaSymbol *DiaCompiland = nullptr;
CComBSTR Utf16Pattern;
if (!Pattern.empty())
Utf16Pattern = CComBSTR(Pattern.data());
if (Compiland)
DiaCompiland = static_cast<const DIARawSymbol &>(Compiland->getRawSymbol())
.getDiaSymbol();
Flags = static_cast<PDB_NameSearchFlags>(
Flags | PDB_NameSearchFlags::NS_FileNameExtMatch);
CComPtr<IDiaEnumSourceFiles> SourceFiles;
if (S_OK !=
Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles))
return nullptr;
return llvm::make_unique<DIAEnumSourceFiles>(*this, SourceFiles);
}
std::unique_ptr<IPDBSourceFile>
DIASession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
llvm::StringRef Pattern,
PDB_NameSearchFlags Flags) const {
auto SourceFiles = findSourceFiles(Compiland, Pattern, Flags);
if (!SourceFiles || SourceFiles->getChildCount() == 0)
return nullptr;
return SourceFiles->getNext();
}
std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
DIASession::findCompilandsForSourceFile(llvm::StringRef Pattern,
PDB_NameSearchFlags Flags) const {
auto File = findOneSourceFile(nullptr, Pattern, Flags);
if (!File)
return nullptr;
return File->getCompilands();
}
std::unique_ptr<PDBSymbolCompiland>
DIASession::findOneCompilandForSourceFile(llvm::StringRef Pattern,
PDB_NameSearchFlags Flags) const {
auto Compilands = findCompilandsForSourceFile(Pattern, Flags);
if (!Compilands || Compilands->getChildCount() == 0)
return nullptr;
return Compilands->getNext();
}
std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
CComPtr<IDiaEnumSourceFiles> Files;
if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
return nullptr;
return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
}
std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
const PDBSymbolCompiland &Compiland) const {
CComPtr<IDiaEnumSourceFiles> Files;
const DIARawSymbol &RawSymbol =
static_cast<const DIARawSymbol &>(Compiland.getRawSymbol());
if (S_OK !=
Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
return nullptr;
return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
}
std::unique_ptr<IPDBSourceFile>
DIASession::getSourceFileById(uint32_t FileId) const {
CComPtr<IDiaSourceFile> LocatedFile;
if (S_OK != Session->findFileById(FileId, &LocatedFile))
return nullptr;
return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
}
std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
}
std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const {
CComPtr<IDiaEnumTables> DiaEnumerator;
if (S_OK != Session->getEnumTables(&DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
}

View File

@ -1,74 +0,0 @@
//===- DIASourceFile.cpp - DIA implementation of IPDBSourceFile -*- 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/DIA/DIASourceFile.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/Support/ConvertUTF.h"
using namespace llvm;
using namespace llvm::pdb;
DIASourceFile::DIASourceFile(const DIASession &PDBSession,
CComPtr<IDiaSourceFile> DiaSourceFile)
: Session(PDBSession), SourceFile(DiaSourceFile) {}
std::string DIASourceFile::getFileName() const {
CComBSTR FileName16;
HRESULT Result = SourceFile->get_fileName(&FileName16);
if (S_OK != Result)
return std::string();
std::string FileName8;
llvm::ArrayRef<char> FileNameBytes(reinterpret_cast<char *>(FileName16.m_str),
FileName16.ByteLength());
llvm::convertUTF16ToUTF8String(FileNameBytes, FileName8);
return FileName8;
}
uint32_t DIASourceFile::getUniqueId() const {
DWORD Id;
return (S_OK == SourceFile->get_uniqueId(&Id)) ? Id : 0;
}
std::string DIASourceFile::getChecksum() const {
DWORD ByteSize = 0;
HRESULT Result = SourceFile->get_checksum(0, &ByteSize, nullptr);
if (ByteSize == 0)
return std::string();
std::vector<BYTE> ChecksumBytes(ByteSize);
Result = SourceFile->get_checksum(ByteSize, &ByteSize, &ChecksumBytes[0]);
if (S_OK != Result)
return std::string();
return std::string(ChecksumBytes.begin(), ChecksumBytes.end());
}
PDB_Checksum DIASourceFile::getChecksumType() const {
DWORD Type;
HRESULT Result = SourceFile->get_checksumType(&Type);
if (S_OK != Result)
return PDB_Checksum::None;
return static_cast<PDB_Checksum>(Type);
}
std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
DIASourceFile::getCompilands() const {
CComPtr<IDiaEnumSymbols> DiaEnumerator;
HRESULT Result = SourceFile->get_compilands(&DiaEnumerator);
if (S_OK != Result)
return nullptr;
auto Enumerator = std::unique_ptr<IPDBEnumSymbols>(
new DIAEnumSymbols(Session, DiaEnumerator));
return std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>(
new ConcreteSymbolEnumerator<PDBSymbolCompiland>(std::move(Enumerator)));
}

View File

@ -1,62 +0,0 @@
//===- DIATable.cpp - DIA implementation of IPDBTable -----------*- 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/DIA/DIATable.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ConvertUTF.h"
using namespace llvm;
using namespace llvm::pdb;
DIATable::DIATable(CComPtr<IDiaTable> DiaTable)
: Table(DiaTable) {}
uint32_t DIATable::getItemCount() const {
LONG Count = 0;
return (S_OK == Table->get_Count(&Count)) ? Count : 0;
}
std::string DIATable::getName() const {
CComBSTR Name16;
if (S_OK != Table->get_name(&Name16))
return std::string();
std::string Name8;
llvm::ArrayRef<char> Name16Bytes(reinterpret_cast<char *>(Name16.m_str),
Name16.ByteLength());
if (!llvm::convertUTF16ToUTF8String(Name16Bytes, Name8))
return std::string();
return Name8;
}
PDB_TableType DIATable::getTableType() const {
CComBSTR Name16;
if (S_OK != Table->get_name(&Name16))
return PDB_TableType::TableInvalid;
if (Name16 == DiaTable_Symbols)
return PDB_TableType::Symbols;
if (Name16 == DiaTable_SrcFiles)
return PDB_TableType::SourceFiles;
if (Name16 == DiaTable_Sections)
return PDB_TableType::SectionContribs;
if (Name16 == DiaTable_LineNums)
return PDB_TableType::LineNumbers;
if (Name16 == DiaTable_SegMap)
return PDB_TableType::Segments;
if (Name16 == DiaTable_InjSrc)
return PDB_TableType::InjectedSources;
if (Name16 == DiaTable_FrameData)
return PDB_TableType::FrameData;
if (Name16 == DiaTable_InputAssemblyFiles)
return PDB_TableType::InputAssemblyFiles;
if (Name16 == DiaTable_Dbg)
return PDB_TableType::Dbg;
return PDB_TableType::TableInvalid;
}

View File

@ -1,68 +0,0 @@
//===- Error.cpp - system_error extensions for PDB --------------*- 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/GenericError.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
using namespace llvm;
using namespace llvm::pdb;
namespace {
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class GenericErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.pdb"; }
std::string message(int Condition) const override {
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 "
"installation "
"is corrupt.";
case generic_error_code::invalid_path:
return "Unable to load PDB. Make sure the file exists and is readable.";
}
llvm_unreachable("Unrecognized generic_error_code");
}
};
} // end anonymous namespace
static ManagedStatic<GenericErrorCategory> Category;
char GenericError::ID = 0;
GenericError::GenericError(generic_error_code C) : GenericError(C, "") {}
GenericError::GenericError(StringRef Context)
: GenericError(generic_error_code::unspecified, Context) {}
GenericError::GenericError(generic_error_code C, StringRef Context) : Code(C) {
ErrMsg = "PDB Error: ";
std::error_code EC = convertToErrorCode();
if (Code != generic_error_code::unspecified)
ErrMsg += EC.message() + " ";
if (!Context.empty())
ErrMsg += Context;
}
void GenericError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
StringRef GenericError::getErrorMessage() const { return ErrMsg; }
std::error_code GenericError::convertToErrorCode() const {
return std::error_code(static_cast<int>(Code), *Category);
}

View File

@ -1,35 +0,0 @@
//===- IPDBSourceFile.cpp - base interface for a PDB source file ----------===//
//
// 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/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
#include <string>
using namespace llvm;
using namespace llvm::pdb;
IPDBSourceFile::~IPDBSourceFile() = default;
void IPDBSourceFile::dump(raw_ostream &OS, int Indent) const {
OS.indent(Indent);
PDB_Checksum ChecksumType = getChecksumType();
OS << "[";
if (ChecksumType != PDB_Checksum::None) {
OS << ChecksumType << ": ";
std::string Checksum = getChecksum();
for (uint8_t c : Checksum)
OS << format_hex_no_prefix(c, 2, true);
} else
OS << "No checksum";
OS << "] " << getFileName() << "\n";
}

View File

@ -1,23 +0,0 @@
;===- ./lib/DebugInfo/PDB/LLVMBuild.txt ------------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = DebugInfoPDB
parent = DebugInfo
required_libraries = Object Support DebugInfoCodeView DebugInfoMSF

View File

@ -1,90 +0,0 @@
//===- 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;
}

View File

@ -1,179 +0,0 @@
//===- 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/GSIStreamBuilder.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;
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));
}
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));
}

View File

@ -1,280 +0,0 @@
//===- 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;
}

View File

@ -1,349 +0,0 @@
//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) 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/DbiStream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.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/Object/COFF.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
using namespace llvm::support;
template <typename ContribType>
static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
BinaryStreamReader &Reader) {
if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
return make_error<RawError>(
raw_error_code::corrupt_file,
"Invalid number of bytes of section contributions");
uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
if (auto EC = Reader.readArray(Output, Count))
return EC;
return Error::success();
}
DbiStream::DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
: Pdb(File), Stream(std::move(Stream)), Header(nullptr) {}
DbiStream::~DbiStream() = default;
Error DbiStream::reload() {
BinaryStreamReader Reader(*Stream);
if (Stream->getLength() < sizeof(DbiStreamHeader))
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI Stream does not contain a header.");
if (auto EC = Reader.readObject(Header))
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI Stream does not contain a header.");
if (Header->VersionSignature != -1)
return make_error<RawError>(raw_error_code::corrupt_file,
"Invalid DBI version signature.");
// Require at least version 7, which should be present in all PDBs
// produced in the last decade and allows us to avoid having to
// special case all kinds of complicated arcane formats.
if (Header->VersionHeader < PdbDbiV70)
return make_error<RawError>(raw_error_code::feature_unsupported,
"Unsupported DBI version.");
if (Stream->getLength() !=
sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
Header->SecContrSubstreamSize + Header->SectionMapSize +
Header->FileInfoSize + Header->TypeServerSize +
Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI Length does not equal sum of substreams.");
// Only certain substreams are guaranteed to be aligned. Validate
// them here.
if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI MODI substream not aligned.");
if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0)
return make_error<RawError>(
raw_error_code::corrupt_file,
"DBI section contribution substream not aligned.");
if (Header->SectionMapSize % sizeof(uint32_t) != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI section map substream not aligned.");
if (Header->FileInfoSize % sizeof(uint32_t) != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI file info substream not aligned.");
if (Header->TypeServerSize % sizeof(uint32_t) != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI type server substream not aligned.");
if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
return EC;
if (auto EC = Reader.readSubstream(SecContrSubstream,
Header->SecContrSubstreamSize))
return EC;
if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
return EC;
if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
return EC;
if (auto EC =
Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
return EC;
if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
return EC;
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())
return EC;
if (auto EC = initializeSectionHeadersData())
return EC;
if (auto EC = initializeSectionMapData())
return EC;
if (auto EC = initializeFpoRecords())
return EC;
if (Reader.bytesRemaining() > 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
if (!ECSubstream.empty()) {
BinaryStreamReader ECReader(ECSubstream.StreamData);
if (auto EC = ECNames.reload(ECReader))
return EC;
}
return Error::success();
}
PdbRaw_DbiVer DbiStream::getDbiVersion() const {
uint32_t Value = Header->VersionHeader;
return static_cast<PdbRaw_DbiVer>(Value);
}
uint32_t DbiStream::getAge() const { return Header->Age; }
uint16_t DbiStream::getPublicSymbolStreamIndex() const {
return Header->PublicSymbolStreamIndex;
}
uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
return Header->GlobalSymbolStreamIndex;
}
uint16_t DbiStream::getFlags() const { return Header->Flags; }
bool DbiStream::isIncrementallyLinked() const {
return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0;
}
bool DbiStream::hasCTypes() const {
return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0;
}
bool DbiStream::isStripped() const {
return (Header->Flags & DbiFlags::FlagStrippedMask) != 0;
}
uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }
uint16_t DbiStream::getBuildMajorVersion() const {
return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >>
DbiBuildNo::BuildMajorShift;
}
uint16_t DbiStream::getBuildMinorVersion() const {
return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >>
DbiBuildNo::BuildMinorShift;
}
uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }
uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }
uint32_t DbiStream::getSymRecordStreamIndex() const {
return Header->SymRecordStreamIndex;
}
PDB_Machine DbiStream::getMachineType() const {
uint16_t Machine = Header->MachineType;
return static_cast<PDB_Machine>(Machine);
}
FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
return SectionHeaders;
}
FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() {
return FpoRecords;
}
const DbiModuleList &DbiStream::modules() const { return Modules; }
FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
return SectionMap;
}
void DbiStream::visitSectionContributions(
ISectionContribVisitor &Visitor) const {
if (!SectionContribs.empty()) {
assert(SectionContribVersion == DbiSecContribVer60);
for (auto &SC : SectionContribs)
Visitor.visit(SC);
} 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.empty())
return Error::success();
BinaryStreamReader SCReader(SecContrSubstream.StreamData);
if (auto EC = SCReader.readEnum(SectionContribVersion))
return EC;
if (SectionContribVersion == DbiSecContribVer60)
return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
if (SectionContribVersion == DbiSecContribV2)
return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);
return make_error<RawError>(raw_error_code::feature_unsupported,
"Unsupported DBI Section Contribution version");
}
// 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.getAllocator());
size_t StreamLen = SHS->getLength();
if (StreamLen % sizeof(object::coff_section))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted section header stream.");
size_t NumSections = StreamLen / sizeof(object::coff_section);
BinaryStreamReader Reader(*SHS);
if (auto EC = Reader.readArray(SectionHeaders, NumSections))
return make_error<RawError>(raw_error_code::corrupt_file,
"Could not read a bitmap.");
SectionHeaderStream = std::move(SHS);
return Error::success();
}
// Initializes this->Fpos.
Error DbiStream::initializeFpoRecords() {
if (DbgStreams.size() == 0)
return Error::success();
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
// This means there is no FPO data.
if (StreamNum == kInvalidStreamIndex)
return Error::success();
if (StreamNum >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
auto FS = MappedBlockStream::createIndexedStream(
Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum, Pdb.getAllocator());
size_t StreamLen = FS->getLength();
if (StreamLen % sizeof(object::FpoData))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted New FPO stream.");
size_t NumRecords = StreamLen / sizeof(object::FpoData);
BinaryStreamReader Reader(*FS);
if (auto EC = Reader.readArray(FpoRecords, NumRecords))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted New FPO stream.");
FpoStream = std::move(FS);
return Error::success();
}
BinarySubstreamRef DbiStream::getSectionContributionData() const {
return SecContrSubstream;
}
BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
return SecMapSubstream;
}
BinarySubstreamRef DbiStream::getModiSubstreamData() const {
return ModiSubstream;
}
BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
return FileInfoSubstream;
}
BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
return TypeServerMapSubstream;
}
BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
Error DbiStream::initializeSectionMapData() {
if (SecMapSubstream.empty())
return Error::success();
BinaryStreamReader SMReader(SecMapSubstream.StreamData);
const SecMapHeader *Header;
if (auto EC = SMReader.readObject(Header))
return EC;
if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
return EC;
return Error::success();
}
uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
uint16_t T = static_cast<uint16_t>(Type);
if (T >= DbgStreams.size())
return kInvalidStreamIndex;
return DbgStreams[T];
}

Some files were not shown because too many files have changed in this diff Show More