diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/DIA')
18 files changed, 2566 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIADataStream.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIADataStream.cpp new file mode 100644 index 0000000000000..8a806f298d0fb --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIADataStream.cpp @@ -0,0 +1,56 @@ +//===- DIADataStream.cpp - DIA implementation of IPDBDataStream -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIADataStream.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.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 { + return invokeBstrMethod(*StreamData, &IDiaEnumDebugStreamData::get_name); +} + +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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp new file mode 100644 index 0000000000000..e4cb4daf94b14 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp @@ -0,0 +1,46 @@ +//==- DIAEnumDebugStreams.cpp - DIA Debug Stream Enumerator impl -*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp new file mode 100644 index 0000000000000..8a181b448a270 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp @@ -0,0 +1,41 @@ +//==- DIAEnumFrameData.cpp ---------------------------------------*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h" +#include "llvm/DebugInfo/PDB/DIA/DIAFrameData.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" + +using namespace llvm::pdb; + +DIAEnumFrameData::DIAEnumFrameData(CComPtr<IDiaEnumFrameData> DiaEnumerator) + : Enumerator(DiaEnumerator) {} + +uint32_t DIAEnumFrameData::getChildCount() const { + LONG Count = 0; + return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0; +} + +std::unique_ptr<IPDBFrameData> +DIAEnumFrameData::getChildAtIndex(uint32_t Index) const { + CComPtr<IDiaFrameData> Item; + if (S_OK != Enumerator->Item(Index, &Item)) + return nullptr; + + return std::unique_ptr<IPDBFrameData>(new DIAFrameData(Item)); +} + +std::unique_ptr<IPDBFrameData> DIAEnumFrameData::getNext() { + CComPtr<IDiaFrameData> Item; + ULONG NumFetched = 0; + if (S_OK != Enumerator->Next(1, &Item, &NumFetched)) + return nullptr; + + return std::unique_ptr<IPDBFrameData>(new DIAFrameData(Item)); +} + +void DIAEnumFrameData::reset() { Enumerator->Reset(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp new file mode 100644 index 0000000000000..7226ab2ba0a04 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp @@ -0,0 +1,43 @@ +//==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h" +#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIAEnumInjectedSources::DIAEnumInjectedSources( + CComPtr<IDiaEnumInjectedSources> DiaEnumerator) + : Enumerator(DiaEnumerator) {} + +uint32_t DIAEnumInjectedSources::getChildCount() const { + LONG Count = 0; + return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0; +} + +std::unique_ptr<IPDBInjectedSource> +DIAEnumInjectedSources::getChildAtIndex(uint32_t Index) const { + CComPtr<IDiaInjectedSource> Item; + if (S_OK != Enumerator->Item(Index, &Item)) + return nullptr; + + return std::unique_ptr<IPDBInjectedSource>(new DIAInjectedSource(Item)); +} + +std::unique_ptr<IPDBInjectedSource> DIAEnumInjectedSources::getNext() { + CComPtr<IDiaInjectedSource> Item; + ULONG NumFetched = 0; + if (S_OK != Enumerator->Next(1, &Item, &NumFetched)) + return nullptr; + + return std::unique_ptr<IPDBInjectedSource>(new DIAInjectedSource(Item)); +} + +void DIAEnumInjectedSources::reset() { Enumerator->Reset(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp new file mode 100644 index 0000000000000..6f1d7733fb2de --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp @@ -0,0 +1,43 @@ +//==- DIAEnumLineNumbers.cpp - DIA Line Number Enumerator impl ---*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp new file mode 100644 index 0000000000000..4f9b232a024aa --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp @@ -0,0 +1,46 @@ +//==- DIAEnumSectionContribs.cpp ---------------------------------*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h" +#include "llvm/DebugInfo/PDB/DIA/DIASectionContrib.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIAEnumSectionContribs::DIAEnumSectionContribs( + const DIASession &PDBSession, + CComPtr<IDiaEnumSectionContribs> DiaEnumerator) + : Session(PDBSession), Enumerator(DiaEnumerator) {} + +uint32_t DIAEnumSectionContribs::getChildCount() const { + LONG Count = 0; + return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0; +} + +std::unique_ptr<IPDBSectionContrib> +DIAEnumSectionContribs::getChildAtIndex(uint32_t Index) const { + CComPtr<IDiaSectionContrib> Item; + if (S_OK != Enumerator->Item(Index, &Item)) + return nullptr; + + return std::unique_ptr<IPDBSectionContrib>( + new DIASectionContrib(Session, Item)); +} + +std::unique_ptr<IPDBSectionContrib> DIAEnumSectionContribs::getNext() { + CComPtr<IDiaSectionContrib> Item; + ULONG NumFetched = 0; + if (S_OK != Enumerator->Next(1, &Item, &NumFetched)) + return nullptr; + + return std::unique_ptr<IPDBSectionContrib>( + new DIASectionContrib(Session, Item)); +} + +void DIAEnumSectionContribs::reset() { Enumerator->Reset(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp new file mode 100644 index 0000000000000..943e9e1b4d580 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp @@ -0,0 +1,43 @@ +//==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp new file mode 100644 index 0000000000000..5153596d52ae0 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp @@ -0,0 +1,47 @@ +//==- DIAEnumSymbols.cpp - DIA Symbol Enumerator impl ------------*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp new file mode 100644 index 0000000000000..335b575d65423 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp @@ -0,0 +1,44 @@ +//===- DIAEnumTables.cpp - DIA Table Enumerator Impl ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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(); } diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp new file mode 100644 index 0000000000000..819651f777878 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp @@ -0,0 +1,37 @@ +#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 llvm::ManagedStatic<DIAErrorCategory> DIACategory; +const std::error_category &llvm::pdb::DIAErrCategory() { return *DIACategory; } + +char DIAError::ID; diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp new file mode 100644 index 0000000000000..7975156b1abde --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp @@ -0,0 +1,52 @@ +//===- DIAFrameData.cpp - DIA impl. of IPDBFrameData -------------- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAFrameData.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h" + +using namespace llvm::pdb; + +DIAFrameData::DIAFrameData(CComPtr<IDiaFrameData> DiaFrameData) + : FrameData(DiaFrameData) {} + +template <typename ArgType> +ArgType +PrivateGetDIAValue(IDiaFrameData *FrameData, + HRESULT (__stdcall IDiaFrameData::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (FrameData->*Method)(&Value)) + return static_cast<ArgType>(Value); + + return ArgType(); +} + +uint32_t DIAFrameData::getAddressOffset() const { + return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_addressOffset); +} + +uint32_t DIAFrameData::getAddressSection() const { + return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_addressSection); +} + +uint32_t DIAFrameData::getLengthBlock() const { + return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_lengthBlock); +} + +std::string DIAFrameData::getProgram() const { + return invokeBstrMethod(*FrameData, &IDiaFrameData::get_program); +} + +uint32_t DIAFrameData::getRelativeVirtualAddress() const { + return PrivateGetDIAValue(FrameData, + &IDiaFrameData::get_relativeVirtualAddress); +} + +uint64_t DIAFrameData::getVirtualAddress() const { + return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_virtualAddress); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp new file mode 100644 index 0000000000000..032b230b5faa0 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp @@ -0,0 +1,62 @@ +//===- DIAInjectedSource.cpp - DIA impl for IPDBInjectedSource --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIAInjectedSource::DIAInjectedSource(CComPtr<IDiaInjectedSource> DiaSourceFile) + : SourceFile(DiaSourceFile) {} + +uint32_t DIAInjectedSource::getCrc32() const { + DWORD Crc; + return (S_OK == SourceFile->get_crc(&Crc)) ? Crc : 0; +} + +uint64_t DIAInjectedSource::getCodeByteSize() const { + ULONGLONG Size; + return (S_OK == SourceFile->get_length(&Size)) ? Size : 0; +} + +std::string DIAInjectedSource::getFileName() const { + return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_filename); +} + +std::string DIAInjectedSource::getObjectFileName() const { + return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_objectFilename); +} + +std::string DIAInjectedSource::getVirtualFileName() const { + return invokeBstrMethod(*SourceFile, + &IDiaInjectedSource::get_virtualFilename); +} + +uint32_t DIAInjectedSource::getCompression() const { + DWORD Compression = 0; + if (S_OK != SourceFile->get_sourceCompression(&Compression)) + return PDB_SourceCompression::None; + return static_cast<uint32_t>(Compression); +} + +std::string DIAInjectedSource::getCode() const { + DWORD DataSize; + if (S_OK != SourceFile->get_source(0, &DataSize, nullptr)) + return ""; + + std::vector<uint8_t> Buffer(DataSize); + if (S_OK != SourceFile->get_source(DataSize, &DataSize, Buffer.data())) + return ""; + assert(Buffer.size() == DataSize); + return std::string(reinterpret_cast<const char *>(Buffer.data()), + Buffer.size()); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp new file mode 100644 index 0000000000000..3af02ea36c7ba --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp @@ -0,0 +1,75 @@ +//===- DIALineNumber.cpp - DIA implementation of IPDBLineNumber -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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; +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp new file mode 100644 index 0000000000000..c2552f55703ce --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp @@ -0,0 +1,1270 @@ +//===- DIARawSymbol.cpp - DIA implementation of IPDBRawSymbol ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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/DIAEnumLineNumbers.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h" +#include "llvm/DebugInfo/PDB/DIA/DIALineNumber.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.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" + +using namespace llvm; +using namespace llvm::pdb; + +namespace { +Variant VariantFromVARIANT(const VARIANT &V) { + Variant Result; + switch (V.vt) { + case VT_I1: + Result.Value.Int8 = V.cVal; + Result.Type = PDB_VariantType::Int8; + break; + case VT_I2: + Result.Value.Int16 = V.iVal; + Result.Type = PDB_VariantType::Int16; + break; + case VT_I4: + Result.Value.Int32 = V.intVal; + Result.Type = PDB_VariantType::Int32; + break; + case VT_I8: + Result.Value.Int64 = V.llVal; + Result.Type = PDB_VariantType::Int64; + break; + case VT_UI1: + Result.Value.UInt8 = V.bVal; + Result.Type = PDB_VariantType::UInt8; + break; + case VT_UI2: + Result.Value.UInt16 = V.uiVal; + Result.Type = PDB_VariantType::UInt16; + break; + case VT_UI4: + Result.Value.UInt32 = V.uintVal; + Result.Type = PDB_VariantType::UInt32; + break; + case VT_UI8: + Result.Value.UInt64 = V.ullVal; + Result.Type = PDB_VariantType::UInt64; + break; + case VT_BOOL: + Result.Value.Bool = (V.boolVal == VARIANT_TRUE) ? true : false; + Result.Type = PDB_VariantType::Bool; + break; + case VT_R4: + Result.Value.Single = V.fltVal; + Result.Type = PDB_VariantType::Single; + break; + case VT_R8: + Result.Value.Double = V.dblVal; + Result.Type = PDB_VariantType::Double; + break; + case VT_BSTR: { + const char *SrcBytes = reinterpret_cast<const char *>(V.bstrVal); + llvm::ArrayRef<char> SrcByteArray(SrcBytes, SysStringByteLen(V.bstrVal)); + std::string Result8; + if (!llvm::convertUTF16ToUTF8String(SrcByteArray, Result8)) + Result.Value.String = nullptr; + Result.Value.String = new char[Result8.length() + 1]; + ::strcpy(Result.Value.String, Result8.c_str()); + Result.Type = PDB_VariantType::String; + break; + } + default: + Result.Type = PDB_VariantType::Unknown; + break; + } + return Result; +} + +template <typename ArgType> +ArgType PrivateGetDIAValue(IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (Symbol->*Method)(&Value)) + return static_cast<ArgType>(Value); + + return ArgType(); +} + +template <typename ArgType, typename RetType> +RetType PrivateGetDIAValue(IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (Symbol->*Method)(&Value)) + return static_cast<RetType>(Value); + + return RetType(); +} + +std::string +PrivateGetDIAValue(IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(BSTR *)) { + return invokeBstrMethod(*Symbol, Method); +} + +codeview::GUID +PrivateGetDIAValue(IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(GUID *)) { + GUID Result; + if (S_OK != (Symbol->*Method)(&Result)) + return codeview::GUID(); + + static_assert(sizeof(codeview::GUID) == sizeof(GUID), + "GUID is the wrong size!"); + codeview::GUID IdResult; + ::memcpy(&IdResult, &Result, sizeof(GUID)); + return IdResult; +} + +template <typename PrintType, typename ArgType> +void DumpDIAValueAs(llvm::raw_ostream &OS, int Indent, StringRef Name, + IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (Symbol->*Method)(&Value)) + dumpSymbolField(OS, Name, static_cast<PrintType>(Value), Indent); +} + +void DumpDIAIdValue(llvm::raw_ostream &OS, int Indent, StringRef Name, + IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(DWORD *), + const IPDBSession &Session, PdbSymbolIdField FieldId, + PdbSymbolIdField ShowFlags, PdbSymbolIdField RecurseFlags) { + DWORD Value; + if (S_OK == (Symbol->*Method)(&Value)) + dumpSymbolIdField(OS, Name, Value, Indent, Session, FieldId, ShowFlags, + RecurseFlags); +} + +template <typename ArgType> +void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name, + IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (Symbol->*Method)(&Value)) + dumpSymbolField(OS, Name, Value, Indent); +} + +void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name, + IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(BSTR *)) { + BSTR Value = nullptr; + if (S_OK != (Symbol->*Method)(&Value)) + return; + const char *Bytes = reinterpret_cast<const char *>(Value); + ArrayRef<char> ByteArray(Bytes, ::SysStringByteLen(Value)); + std::string Result; + if (llvm::convertUTF16ToUTF8String(ByteArray, Result)) + dumpSymbolField(OS, Name, Result, Indent); + ::SysFreeString(Value); +} + +void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name, + IDiaSymbol *Symbol, + HRESULT (__stdcall IDiaSymbol::*Method)(VARIANT *)) { + VARIANT Value; + Value.vt = VT_EMPTY; + if (S_OK != (Symbol->*Method)(&Value)) + return; + Variant V = VariantFromVARIANT(Value); + + dumpSymbolField(OS, Name, V, Indent); +} +} // namespace + +namespace llvm { +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; +} +} // namespace llvm + +DIARawSymbol::DIARawSymbol(const DIASession &PDBSession, + CComPtr<IDiaSymbol> DiaSymbol) + : Session(PDBSession), Symbol(DiaSymbol) {} + +#define RAW_ID_METHOD_DUMP(Stream, Method, Session, FieldId, ShowFlags, \ + RecurseFlags) \ + DumpDIAIdValue(Stream, Indent, StringRef{#Method}, Symbol, \ + &IDiaSymbol::get_##Method, Session, FieldId, ShowFlags, \ + RecurseFlags); + +#define RAW_METHOD_DUMP(Stream, Method) \ + DumpDIAValue(Stream, Indent, StringRef{#Method}, Symbol, \ + &IDiaSymbol::get_##Method); + +#define RAW_METHOD_DUMP_AS(Stream, Method, Type) \ + DumpDIAValueAs<Type>(Stream, Indent, StringRef{#Method}, Symbol, \ + &IDiaSymbol::get_##Method); + +void DIARawSymbol::dump(raw_ostream &OS, int Indent, + PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const { + RAW_ID_METHOD_DUMP(OS, symIndexId, Session, PdbSymbolIdField::SymIndexId, + ShowIdFields, RecurseIdFields); + RAW_METHOD_DUMP_AS(OS, symTag, PDB_SymType); + + RAW_METHOD_DUMP(OS, access); + RAW_METHOD_DUMP(OS, addressOffset); + RAW_METHOD_DUMP(OS, addressSection); + RAW_METHOD_DUMP(OS, age); + RAW_METHOD_DUMP(OS, arrayIndexTypeId); + RAW_METHOD_DUMP(OS, backEndMajor); + RAW_METHOD_DUMP(OS, backEndMinor); + RAW_METHOD_DUMP(OS, backEndBuild); + RAW_METHOD_DUMP(OS, backEndQFE); + RAW_METHOD_DUMP(OS, baseDataOffset); + RAW_METHOD_DUMP(OS, baseDataSlot); + RAW_METHOD_DUMP(OS, baseSymbolId); + RAW_METHOD_DUMP_AS(OS, baseType, PDB_BuiltinType); + RAW_METHOD_DUMP(OS, bitPosition); + RAW_METHOD_DUMP_AS(OS, callingConvention, PDB_CallingConv); + RAW_ID_METHOD_DUMP(OS, classParentId, Session, PdbSymbolIdField::ClassParent, + ShowIdFields, RecurseIdFields); + RAW_METHOD_DUMP(OS, compilerName); + RAW_METHOD_DUMP(OS, count); + RAW_METHOD_DUMP(OS, countLiveRanges); + RAW_METHOD_DUMP(OS, frontEndMajor); + RAW_METHOD_DUMP(OS, frontEndMinor); + RAW_METHOD_DUMP(OS, frontEndBuild); + RAW_METHOD_DUMP(OS, frontEndQFE); + RAW_ID_METHOD_DUMP(OS, lexicalParentId, Session, + PdbSymbolIdField::LexicalParent, ShowIdFields, + RecurseIdFields); + RAW_METHOD_DUMP(OS, libraryName); + RAW_METHOD_DUMP(OS, liveRangeStartAddressOffset); + RAW_METHOD_DUMP(OS, liveRangeStartAddressSection); + RAW_METHOD_DUMP(OS, liveRangeStartRelativeVirtualAddress); + RAW_METHOD_DUMP(OS, localBasePointerRegisterId); + RAW_METHOD_DUMP(OS, lowerBoundId); + RAW_METHOD_DUMP(OS, memorySpaceKind); + RAW_METHOD_DUMP(OS, name); + RAW_METHOD_DUMP(OS, numberOfAcceleratorPointerTags); + RAW_METHOD_DUMP(OS, numberOfColumns); + RAW_METHOD_DUMP(OS, numberOfModifiers); + RAW_METHOD_DUMP(OS, numberOfRegisterIndices); + RAW_METHOD_DUMP(OS, numberOfRows); + RAW_METHOD_DUMP(OS, objectFileName); + RAW_METHOD_DUMP(OS, oemId); + RAW_METHOD_DUMP(OS, oemSymbolId); + RAW_METHOD_DUMP(OS, offsetInUdt); + RAW_METHOD_DUMP(OS, platform); + RAW_METHOD_DUMP(OS, rank); + RAW_METHOD_DUMP(OS, registerId); + RAW_METHOD_DUMP(OS, registerType); + RAW_METHOD_DUMP(OS, relativeVirtualAddress); + RAW_METHOD_DUMP(OS, samplerSlot); + RAW_METHOD_DUMP(OS, signature); + RAW_METHOD_DUMP(OS, sizeInUdt); + RAW_METHOD_DUMP(OS, slot); + RAW_METHOD_DUMP(OS, sourceFileName); + RAW_METHOD_DUMP(OS, stride); + RAW_METHOD_DUMP(OS, subTypeId); + RAW_METHOD_DUMP(OS, symbolsFileName); + RAW_METHOD_DUMP(OS, targetOffset); + RAW_METHOD_DUMP(OS, targetRelativeVirtualAddress); + RAW_METHOD_DUMP(OS, targetVirtualAddress); + RAW_METHOD_DUMP(OS, targetSection); + RAW_METHOD_DUMP(OS, textureSlot); + RAW_METHOD_DUMP(OS, timeStamp); + RAW_METHOD_DUMP(OS, token); + RAW_ID_METHOD_DUMP(OS, typeId, Session, PdbSymbolIdField::Type, ShowIdFields, + RecurseIdFields); + RAW_METHOD_DUMP(OS, uavSlot); + RAW_METHOD_DUMP(OS, undecoratedName); + RAW_ID_METHOD_DUMP(OS, unmodifiedTypeId, Session, + PdbSymbolIdField::UnmodifiedType, ShowIdFields, + RecurseIdFields); + RAW_METHOD_DUMP(OS, upperBoundId); + RAW_METHOD_DUMP(OS, virtualBaseDispIndex); + RAW_METHOD_DUMP(OS, virtualBaseOffset); + RAW_METHOD_DUMP(OS, virtualTableShapeId); + RAW_METHOD_DUMP_AS(OS, dataKind, PDB_DataKind); + RAW_METHOD_DUMP(OS, guid); + RAW_METHOD_DUMP(OS, offset); + RAW_METHOD_DUMP(OS, thisAdjust); + RAW_METHOD_DUMP(OS, virtualBasePointerOffset); + RAW_METHOD_DUMP_AS(OS, locationType, PDB_LocType); + RAW_METHOD_DUMP(OS, machineType); + RAW_METHOD_DUMP(OS, thunkOrdinal); + RAW_METHOD_DUMP(OS, length); + RAW_METHOD_DUMP(OS, liveRangeLength); + RAW_METHOD_DUMP(OS, virtualAddress); + RAW_METHOD_DUMP_AS(OS, udtKind, PDB_UdtType); + RAW_METHOD_DUMP(OS, constructor); + RAW_METHOD_DUMP(OS, customCallingConvention); + RAW_METHOD_DUMP(OS, farReturn); + RAW_METHOD_DUMP(OS, code); + RAW_METHOD_DUMP(OS, compilerGenerated); + RAW_METHOD_DUMP(OS, constType); + RAW_METHOD_DUMP(OS, editAndContinueEnabled); + RAW_METHOD_DUMP(OS, function); + RAW_METHOD_DUMP(OS, stride); + RAW_METHOD_DUMP(OS, noStackOrdering); + RAW_METHOD_DUMP(OS, hasAlloca); + RAW_METHOD_DUMP(OS, hasAssignmentOperator); + RAW_METHOD_DUMP(OS, isCTypes); + RAW_METHOD_DUMP(OS, hasCastOperator); + RAW_METHOD_DUMP(OS, hasDebugInfo); + RAW_METHOD_DUMP(OS, hasEH); + RAW_METHOD_DUMP(OS, hasEHa); + RAW_METHOD_DUMP(OS, hasInlAsm); + RAW_METHOD_DUMP(OS, framePointerPresent); + RAW_METHOD_DUMP(OS, inlSpec); + RAW_METHOD_DUMP(OS, interruptReturn); + RAW_METHOD_DUMP(OS, hasLongJump); + RAW_METHOD_DUMP(OS, hasManagedCode); + RAW_METHOD_DUMP(OS, hasNestedTypes); + RAW_METHOD_DUMP(OS, noInline); + RAW_METHOD_DUMP(OS, noReturn); + RAW_METHOD_DUMP(OS, optimizedCodeDebugInfo); + RAW_METHOD_DUMP(OS, overloadedOperator); + RAW_METHOD_DUMP(OS, hasSEH); + RAW_METHOD_DUMP(OS, hasSecurityChecks); + RAW_METHOD_DUMP(OS, hasSetJump); + RAW_METHOD_DUMP(OS, strictGSCheck); + RAW_METHOD_DUMP(OS, isAcceleratorGroupSharedLocal); + RAW_METHOD_DUMP(OS, isAcceleratorPointerTagLiveRange); + RAW_METHOD_DUMP(OS, isAcceleratorStubFunction); + RAW_METHOD_DUMP(OS, isAggregated); + RAW_METHOD_DUMP(OS, intro); + RAW_METHOD_DUMP(OS, isCVTCIL); + RAW_METHOD_DUMP(OS, isConstructorVirtualBase); + RAW_METHOD_DUMP(OS, isCxxReturnUdt); + RAW_METHOD_DUMP(OS, isDataAligned); + RAW_METHOD_DUMP(OS, isHLSLData); + RAW_METHOD_DUMP(OS, isHotpatchable); + RAW_METHOD_DUMP(OS, indirectVirtualBaseClass); + RAW_METHOD_DUMP(OS, isInterfaceUdt); + RAW_METHOD_DUMP(OS, intrinsic); + RAW_METHOD_DUMP(OS, isLTCG); + RAW_METHOD_DUMP(OS, isLocationControlFlowDependent); + RAW_METHOD_DUMP(OS, isMSILNetmodule); + RAW_METHOD_DUMP(OS, isMatrixRowMajor); + RAW_METHOD_DUMP(OS, managed); + RAW_METHOD_DUMP(OS, msil); + RAW_METHOD_DUMP(OS, isMultipleInheritance); + RAW_METHOD_DUMP(OS, isNaked); + RAW_METHOD_DUMP(OS, nested); + RAW_METHOD_DUMP(OS, isOptimizedAway); + RAW_METHOD_DUMP(OS, packed); + RAW_METHOD_DUMP(OS, isPointerBasedOnSymbolValue); + RAW_METHOD_DUMP(OS, isPointerToDataMember); + RAW_METHOD_DUMP(OS, isPointerToMemberFunction); + RAW_METHOD_DUMP(OS, pure); + RAW_METHOD_DUMP(OS, RValueReference); + RAW_METHOD_DUMP(OS, isRefUdt); + RAW_METHOD_DUMP(OS, reference); + RAW_METHOD_DUMP(OS, restrictedType); + RAW_METHOD_DUMP(OS, isReturnValue); + RAW_METHOD_DUMP(OS, isSafeBuffers); + RAW_METHOD_DUMP(OS, scoped); + RAW_METHOD_DUMP(OS, isSdl); + RAW_METHOD_DUMP(OS, isSingleInheritance); + RAW_METHOD_DUMP(OS, isSplitted); + RAW_METHOD_DUMP(OS, isStatic); + RAW_METHOD_DUMP(OS, isStripped); + RAW_METHOD_DUMP(OS, unalignedType); + RAW_METHOD_DUMP(OS, notReached); + RAW_METHOD_DUMP(OS, isValueUdt); + RAW_METHOD_DUMP(OS, virtual); + RAW_METHOD_DUMP(OS, virtualBaseClass); + RAW_METHOD_DUMP(OS, isVirtualInheritance); + RAW_METHOD_DUMP(OS, volatileType); + RAW_METHOD_DUMP(OS, wasInlined); + RAW_METHOD_DUMP(OS, unused); + RAW_METHOD_DUMP(OS, value); +} + +std::unique_ptr<IPDBEnumSymbols> +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)) { + if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator)) + return nullptr; + } + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findChildren(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags) const { + llvm::SmallVector<UTF16, 32> Name16; + llvm::convertUTF8ToUTF16String(Name, Name16); + + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + DWORD CompareFlags = static_cast<DWORD>(Flags); + wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data()); + + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != + Symbol->findChildrenEx(EnumVal, Name16Str, CompareFlags, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, uint32_t Section, + uint32_t Offset) const { + llvm::SmallVector<UTF16, 32> Name16; + llvm::convertUTF8ToUTF16String(Name, Name16); + + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + + DWORD CompareFlags = static_cast<DWORD>(Flags); + wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data()); + + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findChildrenExByAddr(EnumVal, Name16Str, CompareFlags, + Section, Offset, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, uint64_t VA) const { + llvm::SmallVector<UTF16, 32> Name16; + llvm::convertUTF8ToUTF16String(Name, Name16); + + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + + DWORD CompareFlags = static_cast<DWORD>(Flags); + wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data()); + + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findChildrenExByVA(EnumVal, Name16Str, CompareFlags, VA, + &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, uint32_t RVA) const { + llvm::SmallVector<UTF16, 32> Name16; + llvm::convertUTF8ToUTF16String(Name, Name16); + + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + DWORD CompareFlags = static_cast<DWORD>(Flags); + wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data()); + + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findChildrenExByRVA(EnumVal, Name16Str, CompareFlags, RVA, + &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const { + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findInlineFramesByAddr(Section, Offset, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findInlineFramesByRVA(uint32_t RVA) const { + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findInlineFramesByRVA(RVA, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumSymbols> +DIARawSymbol::findInlineFramesByVA(uint64_t VA) const { + CComPtr<IDiaEnumSymbols> DiaEnumerator; + if (S_OK != Symbol->findInlineFramesByVA(VA, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); +} + +std::unique_ptr<IPDBEnumLineNumbers> DIARawSymbol::findInlineeLines() const { + CComPtr<IDiaEnumLineNumbers> DiaEnumerator; + if (S_OK != Symbol->findInlineeLines(&DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIARawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset, + uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> DiaEnumerator; + if (S_OK != + Symbol->findInlineeLinesByAddr(Section, Offset, Length, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIARawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> DiaEnumerator; + if (S_OK != Symbol->findInlineeLinesByRVA(RVA, Length, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIARawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> DiaEnumerator; + if (S_OK != Symbol->findInlineeLinesByVA(VA, Length, &DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator); +} + +void DIARawSymbol::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const { + bytes.clear(); + + DWORD DataSize = 0; + Symbol->get_dataBytes(0, &DataSize, nullptr); + if (DataSize == 0) + return; + + bytes.resize(DataSize); + Symbol->get_dataBytes(DataSize, &DataSize, bytes.data()); +} + +std::string DIARawSymbol::getUndecoratedNameEx(PDB_UndnameFlags Flags) const { + CComBSTR Result16; + if (S_OK != Symbol->get_undecoratedNameEx((DWORD)Flags, &Result16)) + return std::string(); + + const char *SrcBytes = reinterpret_cast<const char *>(Result16.m_str); + llvm::ArrayRef<char> SrcByteArray(SrcBytes, Result16.ByteLength()); + std::string Result8; + if (!llvm::convertUTF16ToUTF8String(SrcByteArray, Result8)) + return std::string(); + return Result8; +} + +PDB_MemberAccess DIARawSymbol::getAccess() const { + return PrivateGetDIAValue<DWORD, PDB_MemberAccess>(Symbol, + &IDiaSymbol::get_access); +} + +uint32_t DIARawSymbol::getAddressOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_addressOffset); +} + +uint32_t DIARawSymbol::getAddressSection() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_addressSection); +} + +uint32_t DIARawSymbol::getAge() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_age); +} + +SymIndexId DIARawSymbol::getArrayIndexTypeId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_arrayIndexTypeId); +} + +void DIARawSymbol::getBackEndVersion(VersionInfo &Version) const { + Version.Major = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_backEndMajor); + Version.Minor = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_backEndMinor); + Version.Build = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_backEndBuild); + Version.QFE = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_backEndQFE); +} + +uint32_t DIARawSymbol::getBaseDataOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_baseDataOffset); +} + +uint32_t DIARawSymbol::getBaseDataSlot() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_baseDataSlot); +} + +SymIndexId DIARawSymbol::getBaseSymbolId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_baseSymbolId); +} + +PDB_BuiltinType DIARawSymbol::getBuiltinType() const { + return PrivateGetDIAValue<DWORD, PDB_BuiltinType>(Symbol, + &IDiaSymbol::get_baseType); +} + +uint32_t DIARawSymbol::getBitPosition() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_bitPosition); +} + +PDB_CallingConv DIARawSymbol::getCallingConvention() const { + return PrivateGetDIAValue<DWORD, PDB_CallingConv>( + Symbol, &IDiaSymbol::get_callingConvention); +} + +SymIndexId DIARawSymbol::getClassParentId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_classParentId); +} + +std::string DIARawSymbol::getCompilerName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_compilerName); +} + +uint32_t DIARawSymbol::getCount() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_count); +} + +uint32_t DIARawSymbol::getCountLiveRanges() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_countLiveRanges); +} + +void DIARawSymbol::getFrontEndVersion(VersionInfo &Version) const { + Version.Major = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_frontEndMajor); + Version.Minor = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_frontEndMinor); + Version.Build = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_frontEndBuild); + Version.QFE = PrivateGetDIAValue(Symbol, &IDiaSymbol::get_frontEndQFE); +} + +PDB_Lang DIARawSymbol::getLanguage() const { + return PrivateGetDIAValue<DWORD, PDB_Lang>(Symbol, &IDiaSymbol::get_language); +} + +SymIndexId DIARawSymbol::getLexicalParentId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_lexicalParentId); +} + +std::string DIARawSymbol::getLibraryName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_libraryName); +} + +uint32_t DIARawSymbol::getLiveRangeStartAddressOffset() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_liveRangeStartAddressOffset); +} + +uint32_t DIARawSymbol::getLiveRangeStartAddressSection() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_liveRangeStartAddressSection); +} + +uint32_t DIARawSymbol::getLiveRangeStartRelativeVirtualAddress() const { + return PrivateGetDIAValue( + Symbol, &IDiaSymbol::get_liveRangeStartRelativeVirtualAddress); +} + +codeview::RegisterId DIARawSymbol::getLocalBasePointerRegisterId() const { + return PrivateGetDIAValue<DWORD, codeview::RegisterId>( + Symbol, &IDiaSymbol::get_localBasePointerRegisterId); +} + +SymIndexId DIARawSymbol::getLowerBoundId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_lowerBoundId); +} + +uint32_t DIARawSymbol::getMemorySpaceKind() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_memorySpaceKind); +} + +std::string DIARawSymbol::getName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_name); +} + +uint32_t DIARawSymbol::getNumberOfAcceleratorPointerTags() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_numberOfAcceleratorPointerTags); +} + +uint32_t DIARawSymbol::getNumberOfColumns() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_numberOfColumns); +} + +uint32_t DIARawSymbol::getNumberOfModifiers() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_numberOfModifiers); +} + +uint32_t DIARawSymbol::getNumberOfRegisterIndices() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_numberOfRegisterIndices); +} + +uint32_t DIARawSymbol::getNumberOfRows() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_numberOfRows); +} + +std::string DIARawSymbol::getObjectFileName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_objectFileName); +} + +uint32_t DIARawSymbol::getOemId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_oemId); +} + +SymIndexId DIARawSymbol::getOemSymbolId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_oemSymbolId); +} + +uint32_t DIARawSymbol::getOffsetInUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_offsetInUdt); +} + +PDB_Cpu DIARawSymbol::getPlatform() const { + return PrivateGetDIAValue<DWORD, PDB_Cpu>(Symbol, &IDiaSymbol::get_platform); +} + +uint32_t DIARawSymbol::getRank() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_rank); +} + +codeview::RegisterId DIARawSymbol::getRegisterId() const { + return PrivateGetDIAValue<DWORD, codeview::RegisterId>( + Symbol, &IDiaSymbol::get_registerId); +} + +uint32_t DIARawSymbol::getRegisterType() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_registerType); +} + +uint32_t DIARawSymbol::getRelativeVirtualAddress() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_relativeVirtualAddress); +} + +uint32_t DIARawSymbol::getSamplerSlot() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_samplerSlot); +} + +uint32_t DIARawSymbol::getSignature() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_signature); +} + +uint32_t DIARawSymbol::getSizeInUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_sizeInUdt); +} + +uint32_t DIARawSymbol::getSlot() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_slot); +} + +std::string DIARawSymbol::getSourceFileName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_sourceFileName); +} + +std::unique_ptr<IPDBLineNumber> DIARawSymbol::getSrcLineOnTypeDefn() const { + CComPtr<IDiaLineNumber> LineNumber; + if (FAILED(Symbol->getSrcLineOnTypeDefn(&LineNumber)) || !LineNumber) + return nullptr; + + return std::make_unique<DIALineNumber>(LineNumber); +} + +uint32_t DIARawSymbol::getStride() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_stride); +} + +SymIndexId DIARawSymbol::getSubTypeId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_subTypeId); +} + +std::string DIARawSymbol::getSymbolsFileName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_symbolsFileName); +} + +SymIndexId DIARawSymbol::getSymIndexId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_symIndexId); +} + +uint32_t DIARawSymbol::getTargetOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_targetOffset); +} + +uint32_t DIARawSymbol::getTargetRelativeVirtualAddress() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_targetRelativeVirtualAddress); +} + +uint64_t DIARawSymbol::getTargetVirtualAddress() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_targetVirtualAddress); +} + +uint32_t DIARawSymbol::getTargetSection() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_targetSection); +} + +uint32_t DIARawSymbol::getTextureSlot() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_textureSlot); +} + +uint32_t DIARawSymbol::getTimeStamp() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_timeStamp); +} + +uint32_t DIARawSymbol::getToken() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_token); +} + +SymIndexId DIARawSymbol::getTypeId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_typeId); +} + +uint32_t DIARawSymbol::getUavSlot() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_uavSlot); +} + +std::string DIARawSymbol::getUndecoratedName() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_undecoratedName); +} + +SymIndexId DIARawSymbol::getUnmodifiedTypeId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_unmodifiedTypeId); +} + +SymIndexId DIARawSymbol::getUpperBoundId() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_upperBoundId); +} + +Variant DIARawSymbol::getValue() const { + VARIANT Value; + Value.vt = VT_EMPTY; + if (S_OK != Symbol->get_value(&Value)) + return Variant(); + + return VariantFromVARIANT(Value); +} + +uint32_t DIARawSymbol::getVirtualBaseDispIndex() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualBaseDispIndex); +} + +uint32_t DIARawSymbol::getVirtualBaseOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualBaseOffset); +} + +SymIndexId 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 = std::make_unique<DIARawSymbol>(Session, TableType); + auto Pointer = + PDBSymbol::createAs<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); +} + +PDB_SymType DIARawSymbol::getSymTag() const { + return PrivateGetDIAValue<DWORD, PDB_SymType>(Symbol, + &IDiaSymbol::get_symTag); +} + +codeview::GUID DIARawSymbol::getGuid() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_guid); +} + +int32_t DIARawSymbol::getOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_offset); +} + +int32_t DIARawSymbol::getThisAdjust() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_thisAdjust); +} + +int32_t DIARawSymbol::getVirtualBasePointerOffset() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualBasePointerOffset); +} + +PDB_LocType DIARawSymbol::getLocationType() const { + return PrivateGetDIAValue<DWORD, PDB_LocType>(Symbol, + &IDiaSymbol::get_locationType); +} + +PDB_Machine DIARawSymbol::getMachineType() const { + return PrivateGetDIAValue<DWORD, PDB_Machine>(Symbol, + &IDiaSymbol::get_machineType); +} + +codeview::ThunkOrdinal DIARawSymbol::getThunkOrdinal() const { + return PrivateGetDIAValue<DWORD, codeview::ThunkOrdinal>( + Symbol, &IDiaSymbol::get_thunkOrdinal); +} + +uint64_t DIARawSymbol::getLength() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_length); +} + +uint64_t DIARawSymbol::getLiveRangeLength() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_liveRangeLength); +} + +uint64_t DIARawSymbol::getVirtualAddress() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualAddress); +} + +PDB_UdtType DIARawSymbol::getUdtKind() const { + return PrivateGetDIAValue<DWORD, PDB_UdtType>(Symbol, + &IDiaSymbol::get_udtKind); +} + +bool DIARawSymbol::hasConstructor() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_constructor); +} + +bool DIARawSymbol::hasCustomCallingConvention() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_customCallingConvention); +} + +bool DIARawSymbol::hasFarReturn() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_farReturn); +} + +bool DIARawSymbol::isCode() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_code); +} + +bool DIARawSymbol::isCompilerGenerated() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_compilerGenerated); +} + +bool DIARawSymbol::isConstType() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_constType); +} + +bool DIARawSymbol::isEditAndContinueEnabled() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_editAndContinueEnabled); +} + +bool DIARawSymbol::isFunction() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_function); +} + +bool DIARawSymbol::getAddressTaken() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_addressTaken); +} + +bool DIARawSymbol::getNoStackOrdering() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_noStackOrdering); +} + +bool DIARawSymbol::hasAlloca() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasAlloca); +} + +bool DIARawSymbol::hasAssignmentOperator() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasAssignmentOperator); +} + +bool DIARawSymbol::hasCTypes() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isCTypes); +} + +bool DIARawSymbol::hasCastOperator() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasCastOperator); +} + +bool DIARawSymbol::hasDebugInfo() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasDebugInfo); +} + +bool DIARawSymbol::hasEH() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasEH); +} + +bool DIARawSymbol::hasEHa() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasEHa); +} + +bool DIARawSymbol::hasInlAsm() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasInlAsm); +} + +bool DIARawSymbol::hasInlineAttribute() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_inlSpec); +} + +bool DIARawSymbol::hasInterruptReturn() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_interruptReturn); +} + +bool DIARawSymbol::hasFramePointer() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_framePointerPresent); +} + +bool DIARawSymbol::hasLongJump() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasLongJump); +} + +bool DIARawSymbol::hasManagedCode() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasManagedCode); +} + +bool DIARawSymbol::hasNestedTypes() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasNestedTypes); +} + +bool DIARawSymbol::hasNoInlineAttribute() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_noInline); +} + +bool DIARawSymbol::hasNoReturnAttribute() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_noReturn); +} + +bool DIARawSymbol::hasOptimizedCodeDebugInfo() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_optimizedCodeDebugInfo); +} + +bool DIARawSymbol::hasOverloadedOperator() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_overloadedOperator); +} + +bool DIARawSymbol::hasSEH() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasSEH); +} + +bool DIARawSymbol::hasSecurityChecks() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasSecurityChecks); +} + +bool DIARawSymbol::hasSetJump() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_hasSetJump); +} + +bool DIARawSymbol::hasStrictGSCheck() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_strictGSCheck); +} + +bool DIARawSymbol::isAcceleratorGroupSharedLocal() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_isAcceleratorGroupSharedLocal); +} + +bool DIARawSymbol::isAcceleratorPointerTagLiveRange() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_isAcceleratorPointerTagLiveRange); +} + +bool DIARawSymbol::isAcceleratorStubFunction() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isAcceleratorStubFunction); +} + +bool DIARawSymbol::isAggregated() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isAggregated); +} + +bool DIARawSymbol::isIntroVirtualFunction() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_intro); +} + +bool DIARawSymbol::isCVTCIL() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isCVTCIL); +} + +bool DIARawSymbol::isConstructorVirtualBase() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isConstructorVirtualBase); +} + +bool DIARawSymbol::isCxxReturnUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isCxxReturnUdt); +} + +bool DIARawSymbol::isDataAligned() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isDataAligned); +} + +bool DIARawSymbol::isHLSLData() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isHLSLData); +} + +bool DIARawSymbol::isHotpatchable() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isHotpatchable); +} + +bool DIARawSymbol::isIndirectVirtualBaseClass() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_indirectVirtualBaseClass); +} + +bool DIARawSymbol::isInterfaceUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isInterfaceUdt); +} + +bool DIARawSymbol::isIntrinsic() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_intrinsic); +} + +bool DIARawSymbol::isLTCG() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isLTCG); +} + +bool DIARawSymbol::isLocationControlFlowDependent() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_isLocationControlFlowDependent); +} + +bool DIARawSymbol::isMSILNetmodule() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isMSILNetmodule); +} + +bool DIARawSymbol::isMatrixRowMajor() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isMatrixRowMajor); +} + +bool DIARawSymbol::isManagedCode() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_managed); +} + +bool DIARawSymbol::isMSILCode() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_msil); +} + +bool DIARawSymbol::isMultipleInheritance() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isMultipleInheritance); +} + +bool DIARawSymbol::isNaked() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isNaked); +} + +bool DIARawSymbol::isNested() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_nested); +} + +bool DIARawSymbol::isOptimizedAway() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isOptimizedAway); +} + +bool DIARawSymbol::isPacked() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_packed); +} + +bool DIARawSymbol::isPointerBasedOnSymbolValue() const { + return PrivateGetDIAValue(Symbol, + &IDiaSymbol::get_isPointerBasedOnSymbolValue); +} + +bool DIARawSymbol::isPointerToDataMember() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isPointerToDataMember); +} + +bool DIARawSymbol::isPointerToMemberFunction() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isPointerToMemberFunction); +} + +bool DIARawSymbol::isPureVirtual() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_pure); +} + +bool DIARawSymbol::isRValueReference() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_RValueReference); +} + +bool DIARawSymbol::isRefUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isRefUdt); +} + +bool DIARawSymbol::isReference() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_reference); +} + +bool DIARawSymbol::isRestrictedType() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_restrictedType); +} + +bool DIARawSymbol::isReturnValue() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isReturnValue); +} + +bool DIARawSymbol::isSafeBuffers() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isSafeBuffers); +} + +bool DIARawSymbol::isScoped() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_scoped); +} + +bool DIARawSymbol::isSdl() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isSdl); +} + +bool DIARawSymbol::isSingleInheritance() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isSingleInheritance); +} + +bool DIARawSymbol::isSplitted() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isSplitted); +} + +bool DIARawSymbol::isStatic() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isStatic); +} + +bool DIARawSymbol::hasPrivateSymbols() const { + // hasPrivateSymbols is the opposite of isStripped, but we expose + // hasPrivateSymbols as a more intuitive interface. + return !PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isStripped); +} + +bool DIARawSymbol::isUnalignedType() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_unalignedType); +} + +bool DIARawSymbol::isUnreached() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_notReached); +} + +bool DIARawSymbol::isValueUdt() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isValueUdt); +} + +bool DIARawSymbol::isVirtual() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtual); +} + +bool DIARawSymbol::isVirtualBaseClass() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualBaseClass); +} + +bool DIARawSymbol::isVirtualInheritance() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_isVirtualInheritance); +} + +bool DIARawSymbol::isVolatileType() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_volatileType); +} + +bool DIARawSymbol::wasInlined() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_wasInlined); +} + +std::string DIARawSymbol::getUnused() const { + return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_unused); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp new file mode 100644 index 0000000000000..4f0e078e6712c --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp @@ -0,0 +1,125 @@ +//===- DIASectionContrib.cpp - DIA impl. of IPDBSectionContrib ---- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIASectionContrib.h" +#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIASectionContrib::DIASectionContrib(const DIASession &PDBSession, + CComPtr<IDiaSectionContrib> DiaSection) + : Session(PDBSession), Section(DiaSection) {} + +std::unique_ptr<PDBSymbolCompiland> DIASectionContrib::getCompiland() const { + CComPtr<IDiaSymbol> Symbol; + if (FAILED(Section->get_compiland(&Symbol))) + return nullptr; + + auto RawSymbol = std::make_unique<DIARawSymbol>(Session, Symbol); + return PDBSymbol::createAs<PDBSymbolCompiland>(Session, std::move(RawSymbol)); +} + +template <typename ArgType> +ArgType +PrivateGetDIAValue(IDiaSectionContrib *Section, + HRESULT (__stdcall IDiaSectionContrib::*Method)(ArgType *)) { + ArgType Value; + if (S_OK == (Section->*Method)(&Value)) + return static_cast<ArgType>(Value); + + return ArgType(); +} + +uint32_t DIASectionContrib::getAddressSection() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_addressSection); +} + +uint32_t DIASectionContrib::getAddressOffset() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_addressOffset); +} + +uint64_t DIASectionContrib::getVirtualAddress() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_virtualAddress); +} + +uint32_t DIASectionContrib::getRelativeVirtualAddress() const { + return PrivateGetDIAValue(Section, + &IDiaSectionContrib::get_relativeVirtualAddress); +} + +uint32_t DIASectionContrib::getLength() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_length); +} + +bool DIASectionContrib::isNotPaged() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_notPaged); +} + +bool DIASectionContrib::hasCode() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_code); +} + +bool DIASectionContrib::hasCode16Bit() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_code16bit); +} + +bool DIASectionContrib::hasInitializedData() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_initializedData); +} + +bool DIASectionContrib::hasUninitializedData() const { + return PrivateGetDIAValue(Section, + &IDiaSectionContrib::get_uninitializedData); +} + +bool DIASectionContrib::isRemoved() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_remove); +} + +bool DIASectionContrib::hasComdat() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_comdat); +} + +bool DIASectionContrib::isDiscardable() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_discardable); +} + +bool DIASectionContrib::isNotCached() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_notCached); +} + +bool DIASectionContrib::isShared() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_share); +} + +bool DIASectionContrib::isExecutable() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_execute); +} + +bool DIASectionContrib::isReadable() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_read); +} + +bool DIASectionContrib::isWritable() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_write); +} + +uint32_t DIASectionContrib::getDataCrc32() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_dataCrc); +} + +uint32_t DIASectionContrib::getRelocationsCrc32() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_relocationsCrc); +} + +uint32_t DIASectionContrib::getCompilandId() const { + return PrivateGetDIAValue(Section, &IDiaSectionContrib::get_compilandId); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp new file mode 100644 index 0000000000000..64ffa776bbd6f --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -0,0 +1,423 @@ +//===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.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 errorCodeToError(std::error_code(ENOENT, std::generic_category())); + 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<PDBError>(pdb_error_code::dia_failed_loading); +#else + const wchar_t *msdia_dll = L"msdia140.dll"; + 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<PDBError>(pdb_error_code::invalid_utf8_path, 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<PDBError>(pdb_error_code::invalid_utf8_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; +} + +bool DIASession::setLoadAddress(uint64_t Address) { + return (S_OK == Session->put_loadAddress(Address)); +} + +std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() { + CComPtr<IDiaSymbol> GlobalScope; + if (S_OK != Session->get_globalScope(&GlobalScope)) + return nullptr; + + auto RawSymbol = std::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; +} + +bool DIASession::addressForVA(uint64_t VA, uint32_t &Section, + uint32_t &Offset) const { + DWORD ArgSection, ArgOffset = 0; + if (S_OK == Session->addressForVA(VA, &ArgSection, &ArgOffset)) { + Section = static_cast<uint32_t>(ArgSection); + Offset = static_cast<uint32_t>(ArgOffset); + return true; + } + return false; +} + +bool DIASession::addressForRVA(uint32_t RVA, uint32_t &Section, + uint32_t &Offset) const { + DWORD ArgSection, ArgOffset = 0; + if (S_OK == Session->addressForRVA(RVA, &ArgSection, &ArgOffset)) { + Section = static_cast<uint32_t>(ArgSection); + Offset = static_cast<uint32_t>(ArgOffset); + return true; + } + return false; +} + +std::unique_ptr<PDBSymbol> +DIASession::getSymbolById(SymIndexId SymbolId) const { + CComPtr<IDiaSymbol> LocatedSymbol; + if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol)) + return nullptr; + + auto RawSymbol = std::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 = std::make_unique<DIARawSymbol>(*this, Symbol); + return PDBSymbol::create(*this, std::move(RawSymbol)); +} + +std::unique_ptr<PDBSymbol> DIASession::findSymbolByRVA(uint32_t RVA, + PDB_SymType Type) const { + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + + CComPtr<IDiaSymbol> Symbol; + if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol)) + return nullptr; + + auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol); + return PDBSymbol::create(*this, std::move(RawSymbol)); +} + +std::unique_ptr<PDBSymbol> +DIASession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) const { + enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); + + CComPtr<IDiaSymbol> Symbol; + if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol)) + return nullptr; + + auto RawSymbol = std::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 std::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)) { + ULONGLONG LoadAddr = 0; + if (S_OK != Session->get_loadAddress(&LoadAddr)) + return nullptr; + DWORD RVA = static_cast<DWORD>(Address - LoadAddr); + if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers)) + return nullptr; + } + return std::make_unique<DIAEnumLineNumbers>(LineNumbers); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIASession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> LineNumbers; + if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers)) + return nullptr; + + return std::make_unique<DIAEnumLineNumbers>(LineNumbers); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIASession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, + uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> LineNumbers; + if (S_OK != Session->findLinesByAddr(Section, Offset, Length, &LineNumbers)) + return nullptr; + + return std::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 std::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 std::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 std::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 std::make_unique<DIASourceFile>(*this, LocatedFile); +} + +std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const { + CComPtr<IDiaEnumDebugStreams> DiaEnumerator; + if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumDebugStreams>(DiaEnumerator); +} + +std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const { + CComPtr<IDiaEnumTables> DiaEnumerator; + if (S_OK != Session->getEnumTables(&DiaEnumerator)) + return nullptr; + + return std::make_unique<DIAEnumTables>(DiaEnumerator); +} + +template <class T> static CComPtr<T> getTableEnumerator(IDiaSession &Session) { + CComPtr<T> Enumerator; + CComPtr<IDiaEnumTables> ET; + CComPtr<IDiaTable> Table; + ULONG Count = 0; + + if (Session.getEnumTables(&ET) != S_OK) + return nullptr; + + while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) { + // There is only one table that matches the given iid + if (S_OK == Table->QueryInterface(__uuidof(T), (void **)&Enumerator)) + break; + Table.Release(); + } + return Enumerator; +} +std::unique_ptr<IPDBEnumInjectedSources> +DIASession::getInjectedSources() const { + CComPtr<IDiaEnumInjectedSources> Files = + getTableEnumerator<IDiaEnumInjectedSources>(*Session); + if (!Files) + return nullptr; + + return std::make_unique<DIAEnumInjectedSources>(Files); +} + +std::unique_ptr<IPDBEnumSectionContribs> +DIASession::getSectionContribs() const { + CComPtr<IDiaEnumSectionContribs> Sections = + getTableEnumerator<IDiaEnumSectionContribs>(*Session); + if (!Sections) + return nullptr; + + return std::make_unique<DIAEnumSectionContribs>(*this, Sections); +} + +std::unique_ptr<IPDBEnumFrameData> +DIASession::getFrameData() const { + CComPtr<IDiaEnumFrameData> FD = + getTableEnumerator<IDiaEnumFrameData>(*Session); + if (!FD) + return nullptr; + + return std::make_unique<DIAEnumFrameData>(FD); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp new file mode 100644 index 0000000000000..21e757c3a0604 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp @@ -0,0 +1,63 @@ +//===- DIASourceFile.cpp - DIA implementation of IPDBSourceFile -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.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/DIA/DIAUtils.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.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 { + return invokeBstrMethod(*SourceFile, &IDiaSourceFile::get_fileName); +} + +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))); +} diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp new file mode 100644 index 0000000000000..33d74abd740e0 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/DIA/DIATable.cpp @@ -0,0 +1,50 @@ +//===- DIATable.cpp - DIA implementation of IPDBTable -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIATable.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.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 { + return invokeBstrMethod(*Table, &IDiaTable::get_name); +} + +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; +} |
