-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/raw_pdb/README.md b/third_party/raw_pdb/README.md
deleted file mode 100644
index d275d5e..0000000
--- a/third_party/raw_pdb/README.md
+++ /dev/null
@@ -1,190 +0,0 @@
-# RawPDB
-
-**RawPDB** is a C++11 library that directly reads Microsoft Program DataBase PDB files. The code is extracted almost directly from Live++ 2, a battle-tested hot-reload tool for C++.
-
-## Design
-
-**RawPDB** gives you direct access to the stream data contained in a PDB file. It does not attempt to offer abstractions for iterating symbols, translation units, contributions, etc.
-
-Building a high-level abstraction over the provided low-level data is an ill-fated attempt that can never really be performant for everybody, because different tools like debuggers, hot-reload tools (e.g. Live++), profilers (e.g. Superluminal), need to perform different queries against the stored data.
-
-We therefore believe the best solution is to offer direct access to the underlying data, with applications bringing that data into their own structures.
-
-## Goal
-
-Eventually, we want **RawPDB** to become the de-facto replacement of Microsoft's DIA SDK that most C++ developers (have to) use.
-
-## Features
-
-* Fast - **RawPDB** works directly with memory-mapped data, so only the data from the streams you touch affect performance. It is orders of magnitudes faster than the DIA SDK, and faster than comparable LLVM code
-* Scalable - **RawPDB's** API gives you access to individual streams that can all be read concurrently in a trivial fashion, since all returned data structures are immutable. There are no locks or waits anywhere inside the library
-* Lightweight - **RawPDB** is small and compiles in roughly 1 second
-* Allocation-friendly - **RawPDB** performs only a few allocations, and those can be overridden easily by changing the underlying macro
-* No STL - **RawPDB** does not need any STL containers or algorithms
-* No exceptions - **RawPDB** does not use exceptions
-* No RTTI - **RawPDB** does not need RTTI or use class hierarchies
-* High-quality code - **RawPDB** compiles clean under -Wall
-
-## Building
-
-The code compiles clean under Visual Studio 2015, 2017, 2019, or 2022. A solution for Visual Studio 2019 is included.
-
-## Performance
-
-Running the **Symbols** and **Contributions** examples on a 1GiB PDB yields the following output:
-
-
-Opening PDB file C:\Development\llvm-project\build\tools\clang\unittests\Tooling\RelWithDebInfo\ToolingTests.pdb
-
-Running example "Symbols"
-| Reading image section stream
-| ---> done in 0.066ms
-| Reading module info stream
-| ---> done in 0.562ms
-| Reading symbol record stream
-| ---> done in 25.185ms
-| Reading public symbol stream
-| ---> done in 1.133ms
-| Storing public symbols
-| ---> done in 46.171ms (212023 elements)
-| Reading global symbol stream
-| ---> done in 1.381ms
-| Storing global symbols
-| ---> done in 12.769ms (448957 elements)
-| Storing symbols from modules
-| ---> done in 145.849ms (2243 elements)
----> done in 233.694ms (539611 elements)
-
-
-
-Opening PDB file C:\Development\llvm-project\build\tools\clang\unittests\Tooling\RelWithDebInfo\ToolingTests.pdb
-
-Running example "Contributions"
-| Reading image section stream
-| ---> done in 0.066ms
-| Reading module info stream
-| ---> done in 0.594ms
-| Reading section contribution stream
-| ---> done in 9.839ms
-| Storing contributions
-| ---> done in 67.346ms (630924 elements)
-| std::sort contributions
-| ---> done in 19.218ms
----> done in 97.283ms
-20 largest contributions:
-1: 1896496 bytes from LLVMAMDGPUCodeGen.dir\RelWithDebInfo\AMDGPUInstructionSelector.obj
-2: 1700720 bytes from LLVMHexagonCodeGen.dir\RelWithDebInfo\HexagonInstrInfo.obj
-3: 1536470 bytes from LLVMRISCVCodeGen.dir\RelWithDebInfo\RISCVISelDAGToDAG.obj
-4: 1441408 bytes from LLVMAArch64CodeGen.dir\RelWithDebInfo\AArch64InstructionSelector.obj
-5: 1187048 bytes from LLVMRISCVCodeGen.dir\RelWithDebInfo\RISCVInstructionSelector.obj
-6: 1026504 bytes from LLVMARMCodeGen.dir\RelWithDebInfo\ARMInstructionSelector.obj
-7: 952080 bytes from LLVMAMDGPUDesc.dir\RelWithDebInfo\AMDGPUMCTargetDesc.obj
-8: 849888 bytes from LLVMX86Desc.dir\RelWithDebInfo\X86MCTargetDesc.obj
-9: 712176 bytes from LLVMHexagonCodeGen.dir\RelWithDebInfo\HexagonInstrInfo.obj
-10: 679035 bytes from LLVMX86CodeGen.dir\RelWithDebInfo\X86ISelDAGToDAG.obj
-11: 525174 bytes from LLVMAMDGPUDesc.dir\RelWithDebInfo\AMDGPUMCTargetDesc.obj
-12: 523035 bytes from * Linker *
-13: 519312 bytes from LLVMRISCVDesc.dir\RelWithDebInfo\RISCVMCTargetDesc.obj
-14: 512496 bytes from LLVMVEDesc.dir\RelWithDebInfo\VEMCTargetDesc.obj
-15: 498768 bytes from LLVMX86CodeGen.dir\RelWithDebInfo\X86InstructionSelector.obj
-16: 483528 bytes from LLVMMipsCodeGen.dir\RelWithDebInfo\MipsInstructionSelector.obj
-17: 449472 bytes from LLVMAMDGPUCodeGen.dir\RelWithDebInfo\AMDGPUISelDAGToDAG.obj
-18: 444246 bytes from C:\Development\llvm-project\build\tools\clang\lib\Basic\obj.clangBasic.dir\RelWithDebInfo\DiagnosticIDs.obj
-19: 371584 bytes from LLVMAArch64CodeGen.dir\RelWithDebInfo\AArch64ISelDAGToDAG.obj
-20: 370272 bytes from LLVMNVPTXDesc.dir\RelWithDebInfo\NVPTXMCTargetDesc.obj
-
-
-This is at least an order of magnitude faster than DIA, even though the example code is completely serial and uses std::vector, std::string, and std::sort, which are used for illustration purposes only.
-
-When reading streams in a concurrent fashion, you will most likely be limited by the speed at which the OS can bring the data into your process.
-
-Running the **Lines** example on a 1.37 GiB PDB yields the following output:
-
-
-
-Opening PDB file C:\pdb-test-files\clang-debug.pdb
-Version 20000404, signature 1658696914, age 1, GUID 563dd8f1-f32b-459b-8c2beae0e70bc19b
-
-Running example "Lines"
-| Reading image section stream
-| ---> done in 0.313ms
-| Reading module info stream
-| ---> done in 0.403ms
-| Reading names stream
-| ---> done in 0.126ms
-| Storing lines from modules
-| ---> done in 306.720ms (1847 elements)
-| std::sort sections
-| ---> done in 103.090ms (4023680 elements)
-
-
-
-## Supported streams
-
-**RawPDB** gives you access to the following PDB stream data:
-
-* DBI stream data
- * Public symbols
- * Global symbols
- * Modules
- * Module symbols
- * Module lines (C13 line information)
- * Image sections
- * Info stream
- * "/names" stream
- * Section contributions
- * Source files
-
-* IPI stream data
-
-* TPI stream data
-
-Furthermore, PDBs linked using /DEBUG:FASTLINK are not supported. These PDBs do not contain much information, since private symbol information is distributed among object files and library files.
-
-## Documentation
-
-If you are unfamiliar with the basic structure of a PDB file, the LLVM documentation serves as a good introduction.
-
-Consult the example code to see how to read and parse the PDB streams.
-
-## Directory structure
-
-* bin: contains final binary output files (.exe and .pdb)
-* build: contains Visual Studio 2019 solution and project files
-* lib: contains the RawPDB library output files (.lib and .pdb)
-* src: contains the RawPDB source code, as well as example code
-* temp: contains intermediate build artefacts
-
-## Examples
-
-### Symbols (ExampleSymbols.cpp)
-
-A basic example that shows how to load symbols from public, global, and module streams.
-
-### Contributions (ExampleContributions.cpp)
-
-A basic example that shows how to load contributions, sort them by size, and output the 20 largest ones along with the object file they originated from.
-
-### Function symbols (ExampleFunctionSymbols.cpp)
-
-An example intended for profiler developers that shows how to enumerate all function symbols and retrieve or compute their code size.
-
-### Function variables (ExampleFunctionVariables.cpp)
-
-An example intended for debugger developers that shows how to enumerate all function records needed for displaying function variables.
-
-### Lines (ExampleLines.cpp)
-
-An example that shows to how to load line information for all modules.
-
-### Types (ExampleTypes.cpp)
-
-An example that prints all type records.
-
-### PDBSize (ExamplePDBSize.cpp)
-
-An example that could serve as a starting point for people wanting to investigate and optimize the size of their PDBs.
-
-## Sponsoring or supporting RawPDB
-
-We have chosen a very liberal license to let **RawPDB** be used in as many scenarios as possible, including commercial applications. If you would like to support its development, consider licensing Live++ instead. Not only do you give something back, but get a great productivity enhancement on top!
diff --git a/third_party/raw_pdb/raw_pdb.natvis b/third_party/raw_pdb/raw_pdb.natvis
deleted file mode 100644
index e285ad0..0000000
--- a/third_party/raw_pdb/raw_pdb.natvis
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- {{ size={m_length} }}
-
-
- m_length
- m_data
-
-
-
-
diff --git a/third_party/raw_pdb/src/CMakeLists.txt b/third_party/raw_pdb/src/CMakeLists.txt
deleted file mode 100644
index fdbe1e0..0000000
--- a/third_party/raw_pdb/src/CMakeLists.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-set(SOURCES
- Foundation/PDB_ArrayView.h
- Foundation/PDB_Assert.h
- Foundation/PDB_BitOperators.h
- Foundation/PDB_BitUtil.h
- Foundation/PDB_CRT.h
- Foundation/PDB_Forward.h
- Foundation/PDB_Log.h
- Foundation/PDB_Macros.h
- Foundation/PDB_Memory.h
- Foundation/PDB_Move.h
- Foundation/PDB_Platform.h
- Foundation/PDB_PointerUtil.h
- Foundation/PDB_TypeTraits.h
- Foundation/PDB_Warnings.h
-
- PDB.cpp
- PDB.h
- PDB_CoalescedMSFStream.cpp
- PDB_CoalescedMSFStream.h
- PDB_DBIStream.cpp
- PDB_DBIStream.h
- PDB_DBITypes.cpp
- PDB_DBITypes.h
- PDB_DirectMSFStream.cpp
- PDB_DirectMSFStream.h
- PDB_ErrorCodes.h
- PDB_GlobalSymbolStream.cpp
- PDB_GlobalSymbolStream.h
- PDB_ImageSectionStream.cpp
- PDB_ImageSectionStream.h
- PDB_InfoStream.cpp
- PDB_InfoStream.h
- PDB_IPIStream.cpp
- PDB_IPIStream.h
- PDB_IPITypes.h
- PDB_ModuleInfoStream.cpp
- PDB_ModuleInfoStream.h
- PDB_ModuleLineStream.cpp
- PDB_ModuleLineStream.h
- PDB_ModuleSymbolStream.cpp
- PDB_ModuleSymbolStream.h
- PDB_NamesStream.cpp
- PDB_NamesStream.h
- PDB_PCH.cpp
- PDB_PCH.h
- PDB_PublicSymbolStream.cpp
- PDB_PublicSymbolStream.h
- PDB_RawFile.cpp
- PDB_RawFile.h
- PDB_SectionContributionStream.cpp
- PDB_SectionContributionStream.h
- PDB_SourceFileStream.cpp
- PDB_SourceFileStream.h
- PDB_TPIStream.cpp
- PDB_TPIStream.h
- PDB_TPITypes.h
- PDB_Types.cpp
- PDB_Types.h
- PDB_Util.h
-)
-
-source_group(src FILES
- ${SOURCES}
-)
-
-add_library(raw_pdb
- ${SOURCES}
-)
-
-target_include_directories(raw_pdb
- PUBLIC
- .
-)
-
-target_precompile_headers(raw_pdb
- PRIVATE
- PDB_PCH.h
-)
-
-option(RAWPDB_BUILD_EXAMPLES "Build Examples" ON)
-
-if (RAWPDB_BUILD_EXAMPLES)
- add_subdirectory(Examples)
-endif()
-
-if (UNIX)
- include(GNUInstallDirs)
-
- install(
- TARGETS raw_pdb
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- )
-
- file(GLOB_RECURSE HEADER_FILES
- "${CMAKE_CURRENT_SOURCE_DIR}/*.h"
- )
-
- file(GLOB_RECURSE HEADER_FILES_FOUNDATION
- "${CMAKE_CURRENT_SOURCE_DIR}/Foundation/*.h"
- )
-
- install(
- FILES ${HEADER_FILES}
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/raw_pdb/"
- )
-
- install(
- FILES ${HEADER_FILES_FOUNDATION}
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/raw_pdb/Foundation"
- )
-endif (UNIX)
diff --git a/third_party/raw_pdb/src/Examples/CMakeLists.txt b/third_party/raw_pdb/src/Examples/CMakeLists.txt
deleted file mode 100644
index 6e59c1a..0000000
--- a/third_party/raw_pdb/src/Examples/CMakeLists.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-project(Examples)
-
-set(SOURCES
- ExampleContributions.cpp
- ExampleFunctionSymbols.cpp
- ExampleFunctionVariables.cpp
- ExampleIPI.cpp
- ExampleLines.cpp
- ExampleMain.cpp
- ExampleMemoryMappedFile.cpp
- ExampleMemoryMappedFile.h
- ExamplePDBSize.cpp
- Examples_PCH.cpp
- Examples_PCH.h
- ExampleSymbols.cpp
- ExampleTimedScope.cpp
- ExampleTimedScope.h
- ExampleTypes.cpp
- ExampleTypeTable.cpp
- ExampleTypeTable.h
-)
-
-source_group(src FILES
- ${SOURCES}
-)
-
-add_executable(Examples
- ${SOURCES}
-)
-
-target_link_libraries(Examples
- PUBLIC
- raw_pdb
-)
-
-target_precompile_headers(Examples
- PUBLIC
- Examples_PCH.h
-)
\ No newline at end of file
diff --git a/third_party/raw_pdb/src/Examples/ExampleContributions.cpp b/third_party/raw_pdb/src/Examples/ExampleContributions.cpp
deleted file mode 100644
index 93c5091..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleContributions.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-
-
-namespace
-{
- // we don't have to store std::string in the contributions, since all the data is memory-mapped anyway.
- // we do it in this example to ensure that we don't "cheat" when reading the PDB file. memory-mapped data will only
- // be faulted into the process once it's touched, so actually copying the string data makes us touch the needed data,
- // giving us a real performance measurement.
- struct Contribution
- {
- std::string objectFile;
- uint32_t rva;
- uint32_t size;
- };
-}
-
-
-void ExampleContributions(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream);
-void ExampleContributions(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream)
-{
- TimedScope total("\nRunning example \"Contributions\"");
-
- // in order to keep the example easy to understand, we load the PDB data serially.
- // note that this can be improved a lot by reading streams concurrently.
-
- // prepare the image section stream first. it is needed for converting section + offset into an RVA
- TimedScope sectionScope("Reading image section stream");
- const PDB::ImageSectionStream imageSectionStream = dbiStream.CreateImageSectionStream(rawPdbFile);
- sectionScope.Done();
-
-
- // prepare the module info stream for matching contributions against files
- TimedScope moduleScope("Reading module info stream");
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- moduleScope.Done();
-
-
- // read contribution stream
- TimedScope contributionScope("Reading section contribution stream");
- const PDB::SectionContributionStream sectionContributionStream = dbiStream.CreateSectionContributionStream(rawPdbFile);
- contributionScope.Done();
-
- std::vector contributions;
- {
- TimedScope scope("Storing contributions");
-
- const PDB::ArrayView sectionContributions = sectionContributionStream.GetContributions();
- const size_t count = sectionContributions.GetLength();
-
- contributions.reserve(count);
-
- for (const PDB::DBI::SectionContribution& contribution : sectionContributions)
- {
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(contribution.section, contribution.offset);
- if (rva == 0u)
- {
- printf("Contribution has invalid RVA\n");
- continue;
- }
-
- const PDB::ModuleInfoStream::Module& module = moduleInfoStream.GetModule(contribution.moduleIndex);
-
- contributions.push_back(Contribution { module.GetName().Decay(), rva, contribution.size });
- }
-
- scope.Done(count);
- }
-
- TimedScope sortScope("std::sort contributions");
- std::sort(contributions.begin(), contributions.end(), [](const Contribution& lhs, const Contribution& rhs)
- {
- return lhs.size > rhs.size;
- });
- sortScope.Done();
-
- total.Done();
-
- // log the 20 largest contributions
- {
- printf("20 largest contributions:\n");
-
- const size_t countToShow = std::min(20ul, contributions.size());
- for (size_t i = 0u; i < countToShow; ++i)
- {
- const Contribution& contribution = contributions[i];
- printf("%zu: %u bytes from %s\n", i + 1u, contribution.size, contribution.objectFile.c_str());
- }
- }
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleFunctionSymbols.cpp b/third_party/raw_pdb/src/Examples/ExampleFunctionSymbols.cpp
deleted file mode 100644
index fee212e..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleFunctionSymbols.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-
-namespace
-{
- // in this example, we are only interested in function symbols: function name, RVA, and size.
- // this is what most profilers need, they aren't interested in any other data.
- struct FunctionSymbol
- {
- std::string name;
- uint32_t rva;
- uint32_t size;
- const PDB::CodeView::DBI::Record* frameProc;
- };
-}
-
-
-void ExampleFunctionSymbols(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream);
-void ExampleFunctionSymbols(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream)
-{
- TimedScope total("\nRunning example \"Function symbols\"");
-
- // in order to keep the example easy to understand, we load the PDB data serially.
- // note that this can be improved a lot by reading streams concurrently.
-
- // prepare the image section stream first. it is needed for converting section + offset into an RVA
- TimedScope sectionScope("Reading image section stream");
- const PDB::ImageSectionStream imageSectionStream = dbiStream.CreateImageSectionStream(rawPdbFile);
- sectionScope.Done();
-
-
- // prepare the module info stream for grabbing function symbols from modules
- TimedScope moduleScope("Reading module info stream");
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- moduleScope.Done();
-
-
- // prepare symbol record stream needed by the public stream
- TimedScope symbolStreamScope("Reading symbol record stream");
- const PDB::CoalescedMSFStream symbolRecordStream = dbiStream.CreateSymbolRecordStream(rawPdbFile);
- symbolStreamScope.Done();
-
-
- // note that we only use unordered_set in order to keep the example code easy to understand.
- // using other hash set implementations like e.g. abseil's Swiss Tables (https://abseil.io/about/design/swisstables) is *much* faster.
- std::vector functionSymbols;
- std::unordered_set seenFunctionRVAs;
-
- // start by reading the module stream, grabbing every function symbol we can find.
- // in most cases, this gives us ~90% of all function symbols already, along with their size.
- {
- TimedScope scope("Storing function symbols from modules");
-
- const PDB::ArrayView modules = moduleInfoStream.GetModules();
-
- for (const PDB::ModuleInfoStream::Module& module : modules)
- {
- if (!module.HasSymbolStream())
- {
- continue;
- }
-
- const PDB::ModuleSymbolStream moduleSymbolStream = module.CreateSymbolStream(rawPdbFile);
- moduleSymbolStream.ForEachSymbol([&functionSymbols, &seenFunctionRVAs, &imageSectionStream](const PDB::CodeView::DBI::Record* record)
- {
- // only grab function symbols from the module streams
- const char* name = nullptr;
- uint32_t rva = 0u;
- uint32_t size = 0u;
- if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_FRAMEPROC)
- {
- functionSymbols[functionSymbols.size() - 1].frameProc = record;
- return;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_THUNK32)
- {
- if (record->data.S_THUNK32.thunk == PDB::CodeView::DBI::ThunkOrdinal::TrampolineIncremental)
- {
- // we have never seen incremental linking thunks stored inside a S_THUNK32 symbol, but better safe than sorry
- name = "ILT";
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_THUNK32.section, record->data.S_THUNK32.offset);
- size = 5u;
- }
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_TRAMPOLINE)
- {
- // incremental linking thunks are stored in the linker module
- name = "ILT";
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_TRAMPOLINE.thunkSection, record->data.S_TRAMPOLINE.thunkOffset);
- size = 5u;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LPROC32)
- {
- name = record->data.S_LPROC32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LPROC32.section, record->data.S_LPROC32.offset);
- size = record->data.S_LPROC32.codeSize;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GPROC32)
- {
- name = record->data.S_GPROC32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GPROC32.section, record->data.S_GPROC32.offset);
- size = record->data.S_GPROC32.codeSize;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LPROC32_ID)
- {
- name = record->data.S_LPROC32_ID.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LPROC32_ID.section, record->data.S_LPROC32_ID.offset);
- size = record->data.S_LPROC32_ID.codeSize;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GPROC32_ID)
- {
- name = record->data.S_GPROC32_ID.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GPROC32_ID.section, record->data.S_GPROC32_ID.offset);
- size = record->data.S_GPROC32_ID.codeSize;
- }
-
- if (rva == 0u)
- {
- return;
- }
-
- functionSymbols.push_back(FunctionSymbol { name, rva, size, nullptr });
- seenFunctionRVAs.emplace(rva);
- });
- }
-
- scope.Done(modules.GetLength());
- }
-
- // we don't need to touch global symbols in this case.
- // most of the data we need can be obtained from the module symbol streams, and the global symbol stream only offers data symbols on top of that, which we are not interested in.
- // however, there can still be public function symbols we haven't seen yet in any of the modules, especially for PDBs that don't provide module-specific information.
-
- // read public symbols
- TimedScope publicScope("Reading public symbol stream");
- const PDB::PublicSymbolStream publicSymbolStream = dbiStream.CreatePublicSymbolStream(rawPdbFile);
- publicScope.Done();
- {
- TimedScope scope("Storing public function symbols");
-
- const PDB::ArrayView hashRecords = publicSymbolStream.GetRecords();
- const size_t count = hashRecords.GetLength();
-
- for (const PDB::HashRecord& hashRecord : hashRecords)
- {
- const PDB::CodeView::DBI::Record* record = publicSymbolStream.GetRecord(symbolRecordStream, hashRecord);
- if (record->header.kind != PDB::CodeView::DBI::SymbolRecordKind::S_PUB32)
- {
- // normally, a PDB only contains S_PUB32 symbols in the public symbol stream, but we have seen PDBs that also store S_CONSTANT as public symbols.
- // ignore these.
- continue;
- }
-
- if ((PDB_AS_UNDERLYING(record->data.S_PUB32.flags) & PDB_AS_UNDERLYING(PDB::CodeView::DBI::PublicSymbolFlags::Function)) == 0u)
- {
- // ignore everything that is not a function
- continue;
- }
-
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_PUB32.section, record->data.S_PUB32.offset);
- if (rva == 0u)
- {
- // certain symbols (e.g. control-flow guard symbols) don't have a valid RVA, ignore those
- continue;
- }
-
- // check whether we already know this symbol from one of the module streams
- const auto it = seenFunctionRVAs.find(rva);
- if (it != seenFunctionRVAs.end())
- {
- // we know this symbol already, ignore it
- continue;
- }
-
- // this is a new function symbol, so store it.
- // note that we don't know its size yet.
- functionSymbols.push_back(FunctionSymbol { record->data.S_PUB32.name, rva, 0u, nullptr });
- }
-
- scope.Done(count);
- }
-
-
- // we still need to find the size of the public function symbols.
- // this can be deduced by sorting the symbols by their RVA, and then computing the distance between the current and the next symbol.
- // this works since functions are always mapped to executable pages, so they aren't interleaved by any data symbols.
- TimedScope sortScope("std::sort function symbols");
- std::sort(functionSymbols.begin(), functionSymbols.end(), [](const FunctionSymbol& lhs, const FunctionSymbol& rhs)
- {
- return lhs.rva < rhs.rva;
- });
- sortScope.Done();
-
- const size_t symbolCount = functionSymbols.size();
- if (symbolCount != 0u)
- {
- TimedScope computeScope("Computing function symbol sizes");
-
- size_t foundCount = 0u;
-
- // we have at least 1 symbol.
- // compute missing symbol sizes by computing the distance from this symbol to the next.
- // note that this includes "int 3" padding after the end of a function. if you don't want that, but the actual number of bytes of
- // the function's code, your best bet is to use a disassembler instead.
- for (size_t i = 0u; i < symbolCount - 1u; ++i)
- {
- FunctionSymbol& currentSymbol = functionSymbols[i];
- if (currentSymbol.size != 0u)
- {
- // the symbol's size is already known
- continue;
- }
-
- const FunctionSymbol& nextSymbol = functionSymbols[i + 1u];
- const size_t size = nextSymbol.rva - currentSymbol.rva;
- (void)size; // unused
- ++foundCount;
- }
-
- // we know have the sizes of all symbols, except the last.
- // this can be found by going through the contributions, if needed.
- FunctionSymbol& lastSymbol = functionSymbols[symbolCount - 1u];
- if (lastSymbol.size == 0u)
- {
- // bad luck, we can't deduce the last symbol's size, so have to consult the contributions instead.
- // we do a linear search in this case to keep the code simple.
- const PDB::SectionContributionStream sectionContributionStream = dbiStream.CreateSectionContributionStream(rawPdbFile);
- const PDB::ArrayView sectionContributions = sectionContributionStream.GetContributions();
- for (const PDB::DBI::SectionContribution& contribution : sectionContributions)
- {
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(contribution.section, contribution.offset);
- if (rva == 0u)
- {
- printf("Contribution has invalid RVA\n");
- continue;
- }
-
- if (rva == lastSymbol.rva)
- {
- lastSymbol.size = contribution.size;
- break;
- }
-
- if (rva > lastSymbol.rva)
- {
- // should have found the contribution by now
- printf("Unknown contribution for symbol %s at RVA 0x%X", lastSymbol.name.c_str(), lastSymbol.rva);
- break;
- }
- }
- }
-
- computeScope.Done(foundCount);
- }
-
- total.Done(functionSymbols.size());
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleFunctionVariables.cpp b/third_party/raw_pdb/src/Examples/ExampleFunctionVariables.cpp
deleted file mode 100644
index 85b5610..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleFunctionVariables.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "ExampleTypeTable.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-#include "PDB_TPIStream.h"
-
-using SymbolRecordKind = PDB::CodeView::DBI::SymbolRecordKind;
-
-static std::string GetVariableTypeName(const TypeTable& typeTable, uint32_t typeIndex)
-{
- // Defined in ExampleTypes.cpp
- extern std::string GetTypeName(const TypeTable & typeTable, uint32_t typeIndex);
-
- std::string typeName = GetTypeName(typeTable, typeIndex);
-
- // Remove any '%s' substring used to insert a variable/field name.
- const uint64_t markerPos = typeName.find("%s");
- if (markerPos != typeName.npos)
- {
- typeName.erase(markerPos, 2);
- }
-
- return typeName;
-}
-
-static void Printf(uint32_t indent, const char* format, ...)
-{
- va_list args;
- va_start(args, format);
-
- printf("%*s", indent * 4, "");
- vprintf(format, args);
-
- va_end(args);
-}
-
-void ExampleFunctionVariables(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::TPIStream& tpiStream);
-void ExampleFunctionVariables(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::TPIStream& tpiStream)
-{
- TimedScope total("\nRunning example \"Function variables\"");
-
- TimedScope typeTableScope("Create TypeTable");
- TypeTable typeTable(tpiStream);
- typeTableScope.Done();
-
- // in order to keep the example easy to understand, we load the PDB data serially.
- // note that this can be improved a lot by reading streams concurrently.
-
- // prepare the image section stream first. it is needed for converting section + offset into an RVA
- TimedScope sectionScope("Reading image section stream");
- const PDB::ImageSectionStream imageSectionStream = dbiStream.CreateImageSectionStream(rawPdbFile);
- sectionScope.Done();
-
- // prepare the module info stream for grabbing function symbols from modules
- TimedScope moduleScope("Reading module info stream");
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- moduleScope.Done();
-
- // prepare symbol record stream needed by the public stream
- TimedScope symbolStreamScope("Reading symbol record stream");
- const PDB::CoalescedMSFStream symbolRecordStream = dbiStream.CreateSymbolRecordStream(rawPdbFile);
- symbolStreamScope.Done();
-
- {
- TimedScope scope("Printing function variable records from modules\n");
-
- const PDB::ArrayView modules = moduleInfoStream.GetModules();
-
- uint32_t blockLevel = 0;
- uint32_t recordCount = 0;
-
- for (const PDB::ModuleInfoStream::Module& module : modules)
- {
- if (!module.HasSymbolStream())
- {
- continue;
- }
-
- const PDB::ModuleSymbolStream moduleSymbolStream = module.CreateSymbolStream(rawPdbFile);
- moduleSymbolStream.ForEachSymbol([&typeTable, &imageSectionStream, &blockLevel, &recordCount](const PDB::CodeView::DBI::Record* record)
- {
- const SymbolRecordKind kind = record->header.kind;
- const PDB::CodeView::DBI::Record::Data& data = record->data;
-
- if (kind == SymbolRecordKind::S_END)
- {
- PDB_ASSERT(blockLevel > 0, "Block level for S_END is 0");
- blockLevel--;
- Printf(blockLevel, "S_END\n");
-
- if (blockLevel == 0)
- {
- Printf(0, "\n");
- }
- }
- else if(kind == SymbolRecordKind::S_SKIP)
- {
- Printf(blockLevel, "S_SKIP\n");
- }
- else if (kind == SymbolRecordKind::S_BLOCK32)
- {
- const uint32_t offset = imageSectionStream.ConvertSectionOffsetToRVA(data.S_BLOCK32.section, data.S_BLOCK32.offset);
-
- Printf(blockLevel, "S_BLOCK32: '%s' | Code Offset 0x%X\n", data.S_BLOCK32.name, offset);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_LABEL32)
- {
- Printf(blockLevel, "S_LABEL32: '%s' | Offset 0x%X\n", data.S_LABEL32.name, data.S_LABEL32.offset);
- }
- else if(kind == SymbolRecordKind::S_CONSTANT)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_CONSTANT.typeIndex);
-
- Printf(blockLevel, "S_CONSTANT: '%s' -> '%s' | Value 0x%X\n", typeName.c_str(), data.S_CONSTANT.name, data.S_CONSTANT.value);
- }
- else if(kind == SymbolRecordKind::S_LOCAL)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_LOCAL.typeIndex);
- Printf(blockLevel, "S_LOCAL: '%s' -> '%s' | Param: %s | Optimized Out: %s\n", typeName.c_str(), data.S_LOCAL.name, data.S_LOCAL.flags.fIsParam ? "True" : "False", data.S_LOCAL.flags.fIsOptimizedOut ? "True" : "False");
- }
- else if (kind == SymbolRecordKind::S_DEFRANGE_REGISTER)
- {
- Printf(blockLevel, "S_DEFRANGE_REGISTER: Register 0x%X\n", data.S_DEFRANGE_REGISTER.reg);
- }
- else if(kind == SymbolRecordKind::S_DEFRANGE_FRAMEPOINTER_REL)
- {
- Printf(blockLevel, "S_DEFRANGE_FRAMEPOINTER_REL: Frame Pointer Offset 0x%X | Range Start 0x%X | Range Section Start 0x%X | Range Length %u\n",
- data.S_DEFRANGE_FRAMEPOINTER_REL.offsetFramePointer,
- data.S_DEFRANGE_FRAMEPOINTER_REL.range.offsetStart,
- data.S_DEFRANGE_FRAMEPOINTER_REL.range.isectionStart,
- data.S_DEFRANGE_FRAMEPOINTER_REL.range.length);
- }
- else if(kind == SymbolRecordKind::S_DEFRANGE_SUBFIELD_REGISTER)
- {
- Printf(blockLevel, "S_DEFRANGE_SUBFIELD_REGISTER: Register %u | Parent offset 0x%X | Range Start 0x%X | Range Section Start 0x%X | Range Length %u\n",
- data.S_DEFRANGE_SUBFIELD_REGISTER.reg,
- data.S_DEFRANGE_SUBFIELD_REGISTER.offsetParent,
- data.S_DEFRANGE_SUBFIELD_REGISTER.range.offsetStart,
- data.S_DEFRANGE_SUBFIELD_REGISTER.range.isectionStart,
- data.S_DEFRANGE_SUBFIELD_REGISTER.range.length);
- }
- else if (kind == SymbolRecordKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE)
- {
- Printf(blockLevel, "S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: Offset 0x%X\n", data.S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE.offsetFramePointer);
- }
- else if (kind == SymbolRecordKind::S_DEFRANGE_REGISTER_REL)
- {
- Printf(blockLevel, "S_DEFRANGE_REGISTER_REL: Base Register %u | Parent offset 0x%X | Base Register Offset 0x%X | Range Start 0x%X | Range Section Start 0x%X | Range Length %u\n",
- data.S_DEFRANGE_REGISTER_REL.baseRegister,
- data.S_DEFRANGE_REGISTER_REL.offsetParent,
- data.S_DEFRANGE_REGISTER_REL.offsetBasePointer,
- data.S_DEFRANGE_REGISTER_REL.offsetParent,
- data.S_DEFRANGE_REGISTER_REL.range.offsetStart,
- data.S_DEFRANGE_REGISTER_REL.range.isectionStart,
- data.S_DEFRANGE_REGISTER_REL.range.length);
- }
- else if(kind == SymbolRecordKind::S_FILESTATIC)
- {
- Printf(blockLevel, "S_FILESTATIC: '%s'\n", data.S_FILESTATIC.name);
- }
- else if (kind == SymbolRecordKind::S_INLINESITE)
- {
- Printf(blockLevel, "S_INLINESITE: Parent 0x%X\n", data.S_INLINESITE.parent);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_INLINESITE_END)
- {
- PDB_ASSERT(blockLevel > 0, "Block level for S_INLINESITE_END is 0");
- blockLevel--;
- Printf(blockLevel, "S_INLINESITE_END:\n");
- }
- else if (kind == SymbolRecordKind::S_CALLEES)
- {
- Printf(blockLevel, "S_CALLEES: Count %u\n", data.S_CALLEES.count);
- }
- else if (kind == SymbolRecordKind::S_CALLERS)
- {
- Printf(blockLevel, "S_CALLERS: Count %u\n", data.S_CALLERS.count);
- }
- else if (kind == SymbolRecordKind::S_INLINEES)
- {
- Printf(blockLevel, "S_INLINEES: Count %u\n", data.S_INLINEES.count);
- }
- else if (kind == SymbolRecordKind::S_LDATA32)
- {
- if (blockLevel > 0)
- {
- // Not sure why some type index 0 (T_NO_TYPE) are included in some PDBs.
- if (data.S_LDATA32.typeIndex != 0) // PDB::CodeView::TPI::TypeIndexKind::T_NOTYPE)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_LDATA32.typeIndex);
- Printf(blockLevel, "S_LDATA32: '%s' -> '%s'\n", data.S_LDATA32.name, typeName.c_str());
- }
- }
- }
- else if (kind == SymbolRecordKind::S_LTHREAD32)
- {
- if (blockLevel > 0)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_LTHREAD32.typeIndex);
- Printf(blockLevel, "S_LTHREAD32: '%s' -> '%s'\n", data.S_LTHREAD32.name, typeName.c_str());
- }
- }
- else if (kind == SymbolRecordKind::S_UDT)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_UDT.typeIndex);
-
- Printf(blockLevel, "S_UDT: '%s' -> '%s'\n", data.S_UDT.name, typeName.c_str());
- }
- else if (kind == PDB::CodeView::DBI::SymbolRecordKind::S_REGISTER)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_REGSYM.typeIndex);
-
- Printf(blockLevel, "S_REGSYM: '%s' -> '%s' | Register %i\n",
- data.S_REGSYM.name, typeName.c_str(),
- data.S_REGSYM.reg);
- }
- else if (kind == PDB::CodeView::DBI::SymbolRecordKind::S_BPREL32)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_BPRELSYM32.typeIndex);
-
- Printf(blockLevel, "S_BPRELSYM32: '%s' -> '%s' | BP register Offset 0x%X\n",
- data.S_BPRELSYM32.name, typeName.c_str(),
- data.S_BPRELSYM32.offset);
- }
- else if (kind == PDB::CodeView::DBI::SymbolRecordKind::S_REGREL32)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_REGREL32.typeIndex);
-
- Printf(blockLevel, "S_REGREL32: '%s' -> '%s' | Register %i | Register Offset 0x%X\n",
- data.S_REGREL32.name, typeName.c_str(),
- data.S_REGREL32.reg,
- data.S_REGREL32.offset);
- }
- else if(kind == SymbolRecordKind::S_FRAMECOOKIE)
- {
- Printf(blockLevel, "S_FRAMECOOKIE: Offset 0x%X | Register %u | Type %u\n",
- data.S_FRAMECOOKIE.offset,
- data.S_FRAMECOOKIE.reg,
- data.S_FRAMECOOKIE.cookietype);
- }
- else if(kind == SymbolRecordKind::S_CALLSITEINFO)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_CALLSITEINFO.typeIndex);
- Printf(blockLevel, "S_CALLSITEINFO: '%s' | Offset 0x%X | Section %u\n", typeName.c_str(), data.S_CALLSITEINFO.offset, data.S_CALLSITEINFO.section);
- }
- else if(kind == SymbolRecordKind::S_HEAPALLOCSITE)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_HEAPALLOCSITE.typeIndex);
- Printf(blockLevel, "S_HEAPALLOCSITE: '%s' | Offset 0x%X | Section %u | Instruction Length %u\n", typeName.c_str(),
- data.S_HEAPALLOCSITE.offset,
- data.S_HEAPALLOCSITE.section,
- data.S_HEAPALLOCSITE.instructionLength);
- }
- else if (kind == SymbolRecordKind::S_FRAMEPROC)
- {
- Printf(blockLevel, "S_FRAMEPROC: Size %u | Padding %u | Padding Offset 0x%X | Callee Registers Size %u\n",
- data.S_FRAMEPROC.cbFrame,
- data.S_FRAMEPROC.cbPad,
- data.S_FRAMEPROC.offPad,
- data.S_FRAMEPROC.cbSaveRegs);
- }
- else if (kind == SymbolRecordKind::S_ANNOTATION)
- {
- Printf(blockLevel, "S_ANNOTATION: Offset 0x%X | Count %u\n", data.S_ANNOTATIONSYM.offset, data.S_ANNOTATIONSYM.annotationsCount);
- // print N null-terminated annotation strings, skipping their null-terminators to get to the next string
- const char* annotation = data.S_ANNOTATIONSYM.annotations;
- for (int i = 0; i < data.S_ANNOTATIONSYM.annotationsCount; ++i, annotation += strlen(annotation) + 1)
- Printf(blockLevel + 1, "S_ANNOTATION.%u: %s\n", i, annotation);
- PDB_ASSERT(annotation <= (const char*)record + record->header.size + sizeof(record->header.size),
- "Annotation strings end beyond the record size %X; annotaions count: %u", record->header.size, data.S_ANNOTATIONSYM.annotationsCount);
- }
- else if (kind == SymbolRecordKind::S_THUNK32)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
-
- if (data.S_THUNK32.thunk == PDB::CodeView::DBI::ThunkOrdinal::TrampolineIncremental)
- {
- // we have never seen incremental linking thunks stored inside a S_THUNK32 symbol, but better safe than sorry
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_THUNK32.section, data.S_THUNK32.offset);
- Printf(blockLevel, "Function: 'ILT/Thunk' | RVA 0x%X\n", rva);
- }
- else
- {
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_THUNK32.section, data.S_THUNK32.offset);
- Printf(blockLevel, "S_THUNK32 Function '%s' | RVA 0x%X\n", data.S_THUNK32.name, rva);
- blockLevel++;
- }
- }
- else if (kind == SymbolRecordKind::S_TRAMPOLINE)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
- // incremental linking thunks are stored in the linker module
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_TRAMPOLINE.thunkSection, data.S_TRAMPOLINE.thunkOffset);
- Printf(blockLevel, "Function 'ILT/Trampoline' | RVA 0x%X\n", rva);
- }
- else if (kind == SymbolRecordKind::S_LPROC32)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_LPROC32.section, data.S_LPROC32.offset);
- Printf(blockLevel, "S_LPROC32 Function '%s' | RVA 0x%X\n", data.S_LPROC32.name, rva);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_GPROC32)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_GPROC32.section, data.S_GPROC32.offset);
- Printf(blockLevel, "S_GPROC32 Function '%s' | RVA 0x%X\n", data.S_GPROC32.name, rva);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_LPROC32_ID)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_LPROC32_ID.section, data.S_LPROC32_ID.offset);
- Printf(blockLevel, "S_LPROC32_ID Function '%s' | RVA 0x%X\n", data.S_LPROC32_ID.name, rva);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_GPROC32_ID)
- {
- PDB_ASSERT(blockLevel == 0, "BlockLevel %u != 0", blockLevel);
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(data.S_GPROC32_ID.section, data.S_GPROC32_ID.offset);
- Printf(blockLevel, "S_GPROC32_ID Function '%s' | RVA 0x%X\n", data.S_GPROC32_ID.name, rva);
- blockLevel++;
- }
- else if (kind == SymbolRecordKind::S_REGREL32_INDIR)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_REGREL32_INDIR.typeIndex);
-
- Printf(blockLevel, "S_REGREL32_INDIR: '%s' -> '%s' | Register %i | Unknown1 0x%X | Unknown2 0x%X\n",
- data.S_REGREL32_INDIR.name, typeName.c_str(),
- data.S_REGREL32_INDIR.unknown1,
- data.S_REGREL32_INDIR.unknown1);
- }
- else if (kind == SymbolRecordKind::S_REGREL32_ENCTMP)
- {
- const std::string typeName = GetVariableTypeName(typeTable, data.S_REGREL32.typeIndex);
-
- Printf(blockLevel, "S_REGREL32_ENCTMP: '%s' -> '%s' | Register %i | Register Offset 0x%X\n",
- data.S_REGREL32.name, typeName.c_str(),
- data.S_REGREL32.reg,
- data.S_REGREL32.offset);
- }
- else if (kind == SymbolRecordKind::S_UNAMESPACE)
- {
- Printf(blockLevel, "S_UNAMESPACE: '%s'\n", data.S_UNAMESPACE.name);
- }
- else if (kind == SymbolRecordKind::S_ARMSWITCHTABLE)
- {
- Printf(blockLevel, "S_ARMSWITCHTABLE: "
- "Switch Type: %u | Num Entries: %u | Base Section: %u | Base Offset: 0x%X | "
- "Branch Section: %u | Branch Offset: 0x%X | Table Section: %u | Table Offset: 0x%X\n",
- data.S_ARMSWITCHTABLE.switchType,
- data.S_ARMSWITCHTABLE.numEntries,
- data.S_ARMSWITCHTABLE.sectionBase,
- data.S_ARMSWITCHTABLE.offsetBase,
- data.S_ARMSWITCHTABLE.sectionBranch,
- data.S_ARMSWITCHTABLE.offsetBranch,
- data.S_ARMSWITCHTABLE.sectionTable,
- data.S_ARMSWITCHTABLE.offsetTable);
- }
- else
- {
- // We only care about records inside functions.
- if (blockLevel > 0)
- {
- PDB_ASSERT(false, "Unhandled record kind 0x%X with block level %u\n", static_cast(kind), blockLevel);
- }
- }
-
- recordCount++;
-
- });
- }
-
- scope.Done(recordCount);
- }
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleIPI.cpp b/third_party/raw_pdb/src/Examples/ExampleIPI.cpp
deleted file mode 100644
index 5286689..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleIPI.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "ExampleTypeTable.h"
-#include "PDB_RawFile.h"
-#include "PDB_InfoStream.h"
-#include "PDB_IPIStream.h"
-#include "PDB_TPIStream.h"
-
-static std::string GetTypeNameIPI(const TypeTable& typeTable, uint32_t typeIndex)
-{
- // Defined in ExampleTypes.cpp
- extern std::string GetTypeName(const TypeTable & typeTable, uint32_t typeIndex);
-
- std::string typeName = GetTypeName(typeTable, typeIndex);
-
- // Remove any '%s' substring used to insert a variable/field name.
- const uint64_t markerPos = typeName.find("%s");
- if (markerPos != typeName.npos)
- {
- typeName.erase(markerPos, 2);
- }
-
- return typeName;
-}
-
-void ExampleIPI(const PDB::RawFile& rawPdbFile, const PDB::InfoStream& infoStream, const PDB::TPIStream& tpiStream, const PDB::IPIStream& ipiStream);
-
-void ExampleIPI(const PDB::RawFile& rawPdbFile, const PDB::InfoStream& infoStream, const PDB::TPIStream& tpiStream, const PDB::IPIStream& ipiStream)
-{
- if (!infoStream.HasIPIStream())
- {
- return;
- }
-
- TimedScope total("\nRunning example \"IPI\"");
-
- TimedScope typeTableScope("Create TypeTable");
- TypeTable typeTable(tpiStream);
- typeTableScope.Done();
-
- // prepare names stream for grabbing file paths from lines
- TimedScope namesScope("Reading names stream");
- const PDB::NamesStream namesStream = infoStream.CreateNamesStream(rawPdbFile);
- namesScope.Done();
-
- const uint32_t firstTypeIndex = ipiStream.GetFirstTypeIndex();
-
- PDB::ArrayView records = ipiStream.GetTypeRecords();
-
- std::vector strings;
-
- strings.resize(records.GetLength(), nullptr);
-
- size_t index = 0;
-
- for (const PDB::CodeView::IPI::Record* record : records)
- {
- const PDB::CodeView::IPI::RecordHeader& header = record->header;
-
- if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_STRING_ID)
- {
- strings[index] = record->data.LF_STRING_ID.name;
- }
-
- index++;
- }
-
- uint32_t identifier = firstTypeIndex;
-
- std::string typeName, parentTypeName;
-
- printf("\n --- IPI Records ---\n\n");
-
- for(const PDB::CodeView::IPI::Record* record : records)
- {
- const PDB::CodeView::IPI::RecordHeader& header = record->header;
-
- if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_FUNC_ID)
- {
- typeName = GetTypeNameIPI(typeTable, record->data.LF_FUNC_ID.typeIndex);
-
- printf("Kind: 'LF_FUNC_ID' Size: %i ID: %u\n", header.size, identifier);
- printf(" Scope ID: %u\n Type: '%s'\n Name: '%s'\n\n",
- record->data.LF_FUNC_ID.scopeId,
- typeName.c_str(),
- record->data.LF_FUNC_ID.name);
-
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_MFUNC_ID)
- {
- typeName = GetTypeNameIPI(typeTable, record->data.LF_MFUNC_ID.typeIndex);
- parentTypeName = GetTypeNameIPI(typeTable, record->data.LF_MFUNC_ID.parentTypeIndex);
-
- printf("Kind: 'LF_MFUNC_ID' Size: %i ID: %u\n", header.size, identifier);
- printf(" Parent Type: '%s'\n Type: '%s'\n Name: '%s'\n\n",
- parentTypeName.c_str(),
- typeName.c_str(),
- record->data.LF_MFUNC_ID.name);
-
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_BUILDINFO)
- {
- printf("Kind: 'LF_BUILDINFO' Size: %u ID: %u\n", header.size, identifier);
-
- if (record->data.LF_BUILDINFO.count == 0)
- {
- continue;
- }
-
- printf("Strings: '%s'", strings[record->data.LF_BUILDINFO.typeIndices[0] - firstTypeIndex]);
-
- for (uint32_t i = 1, size = record->data.LF_BUILDINFO.count; i < size; ++i)
- {
- const uint32_t stringIndex = record->data.LF_BUILDINFO.typeIndices[i];
-
- if (stringIndex == 0)
- {
- printf(", ''");
- }
- else
- {
- printf(", '%s'", strings[stringIndex - firstTypeIndex]);
- }
- }
-
- printf("\n\n");
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_SUBSTR_LIST)
- {
- printf("Kind: 'LF_SUBSTR_LIST' Size: %u ID: %u\n", header.size, identifier);
-
- if (record->data.LF_SUBSTR_LIST.count == 0)
- {
- continue;
- }
-
- printf(" Strings: '%s'", strings[record->data.LF_SUBSTR_LIST.typeIndices[0] - firstTypeIndex]);
-
- for (uint32_t i = 1, size = record->data.LF_SUBSTR_LIST.count; i < size; ++i)
- {
- const uint32_t stringIndex = record->data.LF_SUBSTR_LIST.typeIndices[i];
-
- if (stringIndex == 0)
- {
- printf(", ''");
- }
- else
- {
- printf(", '%s'", strings[stringIndex - firstTypeIndex]);
- }
- }
-
- printf("\n\n");
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_STRING_ID)
- {
- printf("Kind: 'LF_STRING_ID' Size: %u ID: %u\n", header.size, identifier);
-
- printf(" Substring ID: %u\n Name: '%s'\n\n", record->data.LF_STRING_ID.id, record->data.LF_STRING_ID.name);
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_UDT_SRC_LINE)
- {
- typeName = GetTypeNameIPI(typeTable, record->data.LF_UDT_SRC_LINE.typeIndex);
-
- const uint32_t stringIndex = record->data.LF_UDT_SRC_LINE.stringIndex;
-
- printf("Kind: 'LF_UDT_SRC_LINE' Size: %u ID: %u\n", header.size, identifier);
-
- printf(" Type: '%s'\n Source Path: %s\n Line: %u\n\n",
- typeName.c_str(),
- strings[stringIndex - firstTypeIndex],
- record->data.LF_UDT_SRC_LINE.line);
- }
- else if (header.kind == PDB::CodeView::IPI::TypeRecordKind::LF_UDT_MOD_SRC_LINE)
- {
- typeName = GetTypeNameIPI(typeTable, record->data.LF_UDT_MOD_SRC_LINE.typeIndex);
-
- const char* string = namesStream.GetFilename(record->data.LF_UDT_MOD_SRC_LINE.stringIndex);
-
- printf("Kind: 'LF_UDT_SRC_LINE' Size: %u ID: %u\n", header.size, identifier);
-
- printf(" Type: '%s'\n Source Path: %s\n Line: %u\n Module Index: %u\n\n",
- typeName.c_str(),
- string,
- record->data.LF_UDT_MOD_SRC_LINE.line,
- record->data.LF_UDT_MOD_SRC_LINE.moduleIndex);
- }
- else
- {
- printf("Kind: 0x%X Size: %u ID: %u\n\n", static_cast(header.kind), header.size, identifier);
- }
-
- identifier++;
- }
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleLines.cpp b/third_party/raw_pdb/src/Examples/ExampleLines.cpp
deleted file mode 100644
index f055b98..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleLines.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "Foundation/PDB_PointerUtil.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-#include "PDB_InfoStream.h"
-
-#include
-
-namespace
-{
- struct Section
- {
- uint16_t index;
- uint32_t offset;
- size_t lineIndex;
- };
-
- struct Filename
- {
- uint32_t fileChecksumOffset;
- uint32_t namesFilenameOffset;
- PDB::CodeView::DBI::ChecksumKind checksumKind;
- uint8_t checksumSize;
- uint8_t checksum[32];
- };
-
- struct Line
- {
- uint32_t lineNumber;
- uint32_t codeSize;
- size_t filenameIndex;
- };
-}
-
-void ExampleLines(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::InfoStream& infoStream);
-void ExampleLines(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::InfoStream& infoStream)
-{
- if (!infoStream.HasNamesStream())
- {
- printf("PDB has no '/names' stream for looking up filenames for lines, skipping \"Lines\" example.");
- return;
- }
-
- TimedScope total("\nRunning example \"Lines\"");
-
- // prepare the image section stream first. it is needed for converting section + offset into an RVA
- TimedScope sectionScope("Reading image section stream");
- const PDB::ImageSectionStream imageSectionStream = dbiStream.CreateImageSectionStream(rawPdbFile);
- sectionScope.Done();
-
- // prepare the module info stream for grabbing function symbols from modules
- TimedScope moduleScope("Reading module info stream");
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- moduleScope.Done();
-
- // prepare names stream for grabbing file paths from lines
- TimedScope namesScope("Reading names stream");
- const PDB::NamesStream namesStream = infoStream.CreateNamesStream(rawPdbFile);
- namesScope.Done();
-
- // keeping sections and lines separate, as sorting the smaller Section struct is 2x faster in release builds
- // than having all the fields in one big Line struct and sorting those.
- std::vector sections;
- std::vector filenames;
- std::vector lines;
-
- {
- TimedScope scope("Storing lines from modules");
-
- const PDB::ArrayView modules = moduleInfoStream.GetModules();
-
- for (const PDB::ModuleInfoStream::Module& module : modules)
- {
- if (!module.HasLineStream())
- {
- continue;
- }
-
- const PDB::ModuleLineStream moduleLineStream = module.CreateLineStream(rawPdbFile);
-
- const size_t moduleFilenamesStartIndex = filenames.size();
- const PDB::CodeView::DBI::FileChecksumHeader* moduleFileChecksumHeader = nullptr;
-
- moduleLineStream.ForEachSection([&moduleLineStream, &namesStream, &moduleFileChecksumHeader, §ions, &filenames, &lines](const PDB::CodeView::DBI::LineSection* lineSection)
- {
- if (lineSection->header.kind == PDB::CodeView::DBI::DebugSubsectionKind::S_LINES)
- {
- moduleLineStream.ForEachLinesBlock(lineSection,
- [&lineSection, §ions, &filenames, &lines](const PDB::CodeView::DBI::LinesFileBlockHeader* linesBlockHeader, const PDB::CodeView::DBI::Line* blocklines, const PDB::CodeView::DBI::Column* blockColumns)
- {
- if (linesBlockHeader->numLines == 0)
- {
- return;
- }
-
- const PDB::CodeView::DBI::Line& firstLine = blocklines[0];
-
- const uint16_t sectionIndex = lineSection->linesHeader.sectionIndex;
- const uint32_t sectionOffset = lineSection->linesHeader.sectionOffset;
- const uint32_t fileChecksumOffset = linesBlockHeader->fileChecksumOffset;
-
- const size_t filenameIndex = filenames.size();
-
- // there will be duplicate filenames for any real world pdb.
- // ideally the filenames would be stored in a map with the filename or checksum as the key.
- // but that would complicate the logic in this example and therefore just use a vector to make it easier to understand.
- filenames.push_back({ fileChecksumOffset, 0, PDB::CodeView::DBI::ChecksumKind::None, 0, {0} });
-
- sections.push_back({ sectionIndex, sectionOffset, lines.size() });
-
- // initially set code size of first line to 0, will be updated in loop below.
- lines.push_back({ firstLine.linenumStart, 0, filenameIndex });
-
- for(uint32_t i = 1, size = linesBlockHeader->numLines; i < size; ++i)
- {
- const PDB::CodeView::DBI::Line& line = blocklines[i];
-
- // calculate code size of previous line by using the current line offset.
- lines.back().codeSize = line.offset - blocklines[i-1].offset;
-
- sections.push_back({ sectionIndex, sectionOffset + line.offset, lines.size() });
- lines.push_back({ line.linenumStart, 0, filenameIndex });
- }
-
- // calc code size of last line
- lines.back().codeSize = lineSection->linesHeader.codeSize - blocklines[linesBlockHeader->numLines-1].offset;
-
- // columns are optional
- if (blockColumns == nullptr)
- {
- return;
- }
-
- for (uint32_t i = 0, size = linesBlockHeader->numLines; i < size; ++i)
- {
- const PDB::CodeView::DBI::Column& column = blockColumns[i];
- (void)column;
- }
- });
- }
- else if (lineSection->header.kind == PDB::CodeView::DBI::DebugSubsectionKind::S_FILECHECKSUMS)
- {
- // how to read checksums and their filenames from the Names Stream
- moduleLineStream.ForEachFileChecksum(lineSection, [&namesStream](const PDB::CodeView::DBI::FileChecksumHeader* fileChecksumHeader)
- {
- const char* filename = namesStream.GetFilename(fileChecksumHeader->filenameOffset);
- (void)filename;
- });
-
- // store the checksum header for the module, as there might be more lines after the checksums.
- // so lines will get their checksum header values assigned after processing all line sections in the module.
- PDB_ASSERT(moduleFileChecksumHeader == nullptr, "Module File Checksum Header already set");
- moduleFileChecksumHeader = &lineSection->checksumHeader;
- }
- else if (lineSection->header.kind == PDB::CodeView::DBI::DebugSubsectionKind::S_INLINEELINES)
- {
- if (lineSection->inlineeHeader.kind == PDB::CodeView::DBI::InlineeSourceLineKind::Signature)
- {
- moduleLineStream.ForEachInlineeSourceLine(lineSection, [](const PDB::CodeView::DBI::InlineeSourceLine* inlineeSourceLine)
- {
- (void)inlineeSourceLine;
-
- });
- }
- else
- {
- moduleLineStream.ForEachInlineeSourceLineEx(lineSection, [](const PDB::CodeView::DBI::InlineeSourceLineEx* inlineeSourceLineEx)
- {
- for (uint32_t i = 0; i < inlineeSourceLineEx->extraLines; ++i)
- {
- const uint32_t checksumOffset = inlineeSourceLineEx->extrafileChecksumOffsets[i];
- (void)checksumOffset;
- }
- });
- }
- }
- else
- {
- PDB_ASSERT(false, "Line Section kind 0x%X not handled", static_cast(lineSection->header.kind));
- }
- });
-
- // assign checksum values for each filename added in this module
- for (size_t i = moduleFilenamesStartIndex, size = filenames.size(); i < size; ++i)
- {
- Filename& filename = filenames[i];
-
- // look up the filename's checksum header in the module's checksums section
- const PDB::CodeView::DBI::FileChecksumHeader* checksumHeader = PDB::Pointer::Offset(moduleFileChecksumHeader, filename.fileChecksumOffset);
-
- PDB_ASSERT(checksumHeader->checksumKind >= PDB::CodeView::DBI::ChecksumKind::None &&
- checksumHeader->checksumKind <= PDB::CodeView::DBI::ChecksumKind::SHA256,
- "Invalid checksum kind %u", static_cast(checksumHeader->checksumKind));
-
- // store checksum values in filname struct
- filename.namesFilenameOffset = checksumHeader->filenameOffset;
- filename.checksumKind = checksumHeader->checksumKind;
- filename.checksumSize = checksumHeader->checksumSize;
- std::memcpy(filename.checksum, checksumHeader->checksum, checksumHeader->checksumSize);
- }
- }
-
- scope.Done(modules.GetLength());
-
- TimedScope sortScope("std::sort sections");
-
- // sort sections, so we can iterate over lines by address order.
- std::sort(sections.begin(), sections.end(), [](const Section& lhs, const Section& rhs)
- {
- if (lhs.index == rhs.index)
- {
- return lhs.offset < rhs.offset;
- }
-
- return lhs.index < rhs.index;
- });
-
- sortScope.Done(sections.size());
-
-// Disabled by default, as it will print a lot of lines for large PDBs :-)
-#if 0
- // DIA2Dump style lines output
- static const char hexChars[17] = "0123456789ABCDEF";
- char checksumString[128];
-
- printf("*** LINES RAW PDB\n");
-
- const char* prevFilename = nullptr;
-
- for (const Section& section : sections)
- {
- const Line& line = lines[section.lineIndex];
- const Filename& lineFilename = filenames[line.filenameIndex];
-
- const char* filename = namesStream.GetFilename(lineFilename.namesFilenameOffset);
-
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(section.index, section.offset);
-
- // only print filename for a line if it is different from the previous one.
- if (filename != prevFilename)
- {
- for (size_t i = 0, j = 0; i < lineFilename.checksumSize; i++, j+=2)
- {
- checksumString[j] = hexChars[lineFilename.checksum[i] >> 4];
- checksumString[j+1] = hexChars[lineFilename.checksum[i] & 0xF];
- }
-
- checksumString[lineFilename.checksumSize * 2] = '\0';
-
- printf(" line %u at [0x%08X][0x%04X:0x%08X], len = 0x%X %s (0x%02X: %s)\n",
- line.lineNumber, rva, section.index, section.offset, line.codeSize,
- filename, static_cast(lineFilename.checksumKind), checksumString);
-
- prevFilename = filename;
- }
- else
- {
- printf(" line %u at [0x%08X][0x%04X:0x%08X], len = 0x%X\n",
- line.lineNumber, rva, section.index, section.offset, line.codeSize);
- }
- }
-#endif
- }
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleMain.cpp b/third_party/raw_pdb/src/Examples/ExampleMain.cpp
deleted file mode 100644
index b424942..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleMain.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleMemoryMappedFile.h"
-#include "PDB.h"
-#include "PDB_RawFile.h"
-#include "PDB_InfoStream.h"
-#include "PDB_DBIStream.h"
-#include "PDB_TPIStream.h"
-#include "PDB_IPIStream.h"
-#include "PDB_NamesStream.h"
-
-namespace
-{
- PDB_NO_DISCARD static bool IsError(PDB::ErrorCode errorCode)
- {
- switch (errorCode)
- {
- case PDB::ErrorCode::Success:
- return false;
-
- case PDB::ErrorCode::InvalidSuperBlock:
- printf("Invalid Superblock\n");
- return true;
-
- case PDB::ErrorCode::InvalidFreeBlockMap:
- printf("Invalid free block map\n");
- return true;
-
- case PDB::ErrorCode::InvalidStream:
- printf("Invalid stream\n");
- return true;
-
- case PDB::ErrorCode::InvalidSignature:
- printf("Invalid stream signature\n");
- return true;
-
- case PDB::ErrorCode::InvalidStreamIndex:
- printf("Invalid stream index\n");
- return true;
-
- case PDB::ErrorCode::InvalidDataSize:
- printf("Invalid data size\n");
- return true;
-
- case PDB::ErrorCode::UnknownVersion:
- printf("Unknown version\n");
- return true;
- }
-
- // only ErrorCode::Success means there wasn't an error, so all other paths have to assume there was an error
- return true;
- }
-
- PDB_NO_DISCARD static bool HasValidDBIStreams(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream)
- {
- // check whether the DBI stream offers all sub-streams we need
- if (IsError(dbiStream.HasValidSymbolRecordStream(rawPdbFile)))
- {
- return false;
- }
-
- if (IsError(dbiStream.HasValidPublicSymbolStream(rawPdbFile)))
- {
- return false;
- }
-
- if (IsError(dbiStream.HasValidGlobalSymbolStream(rawPdbFile)))
- {
- return false;
- }
-
- if (IsError(dbiStream.HasValidSectionContributionStream(rawPdbFile)))
- {
- return false;
- }
-
- if (IsError(dbiStream.HasValidImageSectionStream(rawPdbFile)))
- {
- return false;
- }
-
- return true;
- }
-}
-
-
-// declare all examples
-extern void ExamplePDBSize(const PDB::RawFile&, const PDB::DBIStream&);
-extern void ExampleTPISize(const PDB::TPIStream& tpiStream, const char* outPath);
-extern void ExampleContributions(const PDB::RawFile&, const PDB::DBIStream&);
-extern void ExampleSymbols(const PDB::RawFile&, const PDB::DBIStream&);
-extern void ExampleFunctionSymbols(const PDB::RawFile&, const PDB::DBIStream&);
-extern void ExampleFunctionVariables(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::TPIStream&);
-extern void ExampleLines(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream, const PDB::InfoStream& infoStream);
-extern void ExampleTypes(const PDB::TPIStream&);
-extern void ExampleIPI(const PDB::RawFile& rawPdbFile, const PDB::InfoStream& infoStream, const PDB::TPIStream& tpiStream, const PDB::IPIStream& ipiStream);
-
-int main(int argc, char** argv)
-{
- if (argc != 2)
- {
- printf("Usage: Examples \nError: Incorrect usage\n");
-
- return 1;
- }
-
- printf("Opening PDB file %s\n", argv[1]);
-
- // try to open the PDB file and check whether all the data we need is available
- MemoryMappedFile::Handle pdbFile = MemoryMappedFile::Open(argv[1]);
- if (!pdbFile.baseAddress)
- {
- printf("Cannot memory-map file %s\n", argv[1]);
-
- return 1;
- }
-
- if (IsError(PDB::ValidateFile(pdbFile.baseAddress, pdbFile.len)))
- {
- MemoryMappedFile::Close(pdbFile);
-
- return 2;
- }
-
- const PDB::RawFile rawPdbFile = PDB::CreateRawFile(pdbFile.baseAddress);
- if (IsError(PDB::HasValidDBIStream(rawPdbFile)))
- {
- MemoryMappedFile::Close(pdbFile);
-
- return 3;
- }
-
- const PDB::InfoStream infoStream(rawPdbFile);
- if (infoStream.UsesDebugFastLink())
- {
- printf("PDB was linked using unsupported option /DEBUG:FASTLINK\n");
-
- MemoryMappedFile::Close(pdbFile);
-
- return 4;
- }
-
- const auto h = infoStream.GetHeader();
- printf("Version %u, signature %u, age %u, GUID %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x\n",
- static_cast(h->version), h->signature, h->age,
- h->guid.Data1, h->guid.Data2, h->guid.Data3,
- h->guid.Data4[0], h->guid.Data4[1], h->guid.Data4[2], h->guid.Data4[3], h->guid.Data4[4], h->guid.Data4[5], h->guid.Data4[6], h->guid.Data4[7]);
-
- const PDB::DBIStream dbiStream = PDB::CreateDBIStream(rawPdbFile);
- if (!HasValidDBIStreams(rawPdbFile, dbiStream))
- {
- MemoryMappedFile::Close(pdbFile);
-
- return 5;
- }
-
- if (IsError(PDB::HasValidTPIStream(rawPdbFile)))
- {
- MemoryMappedFile::Close(pdbFile);
-
- return 5;
- }
- const PDB::TPIStream tpiStream = PDB::CreateTPIStream(rawPdbFile);
-
- PDB::IPIStream ipiStream;
-
- // It's perfectly possible that an old PDB does not have an IPI stream.
- if(infoStream.HasIPIStream())
- {
- PDB::ErrorCode error = PDB::HasValidIPIStream(rawPdbFile);
-
- if (error != PDB::ErrorCode::InvalidStream && IsError(error))
- {
- MemoryMappedFile::Close(pdbFile);
-
- return 5;
- }
-
- ipiStream = PDB::CreateIPIStream(rawPdbFile);
- }
-
-
- // run all examples
- ExamplePDBSize(rawPdbFile, dbiStream);
- ExampleContributions(rawPdbFile, dbiStream);
- ExampleSymbols(rawPdbFile, dbiStream);
- ExampleFunctionSymbols(rawPdbFile, dbiStream);
- ExampleFunctionVariables(rawPdbFile, dbiStream, tpiStream);
- ExampleLines(rawPdbFile, dbiStream, infoStream);
- ExampleTypes(tpiStream);
- ExampleIPI(rawPdbFile, infoStream, tpiStream, ipiStream);
- // uncomment to dump type sizes to a CSV
- // ExampleTPISize(tpiStream, "output.csv");
-
- MemoryMappedFile::Close(pdbFile);
-
- return 0;
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.cpp b/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.cpp
deleted file mode 100644
index 4b46b4b..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleMemoryMappedFile.h"
-
-
-MemoryMappedFile::Handle MemoryMappedFile::Open(const char* path)
-{
-#ifdef _WIN32
- void* file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, nullptr);
-
- if (file == INVALID_HANDLE_VALUE)
- {
- return Handle { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- void* fileMapping = CreateFileMappingW(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
-
- if (fileMapping == nullptr)
- {
- CloseHandle(file);
-
- return Handle { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- void* baseAddress = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
-
- if (baseAddress == nullptr)
- {
- CloseHandle(fileMapping);
- CloseHandle(file);
-
- return Handle { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- BY_HANDLE_FILE_INFORMATION fileInformation;
- const bool getInformationResult = GetFileInformationByHandle(file, &fileInformation);
- if (!getInformationResult)
- {
- UnmapViewOfFile(baseAddress);
- CloseHandle(fileMapping);
- CloseHandle(file);
-
- return Handle { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- const size_t fileSizeHighBytes = static_cast(fileInformation.nFileSizeHigh) << 32;
- const size_t fileSizeLowBytes = fileInformation.nFileSizeLow;
- const size_t fileSize = fileSizeHighBytes | fileSizeLowBytes;
- return Handle { file, fileMapping, baseAddress, fileSize };
-#else
- struct stat fileSb;
-
- int file = open(path, O_RDONLY);
-
- if (file == INVALID_HANDLE_VALUE)
- {
- return Handle { INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- if (fstat(file, &fileSb) == -1)
- {
- close(file);
-
- return Handle { INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- void* baseAddress = mmap(nullptr, fileSb.st_size, PROT_READ, MAP_PRIVATE, file, 0);
-
- if (baseAddress == MAP_FAILED)
- {
- close(file);
-
- return Handle { INVALID_HANDLE_VALUE, nullptr, 0 };
- }
-
- return Handle { file, baseAddress, static_cast(fileSb.st_size) };
-#endif
-}
-
-
-void MemoryMappedFile::Close(Handle& handle)
-{
-#ifdef _WIN32
- UnmapViewOfFile(handle.baseAddress);
- CloseHandle(handle.fileMapping);
- CloseHandle(handle.file);
-
- handle.file = nullptr;
- handle.fileMapping = nullptr;
-#else
- munmap(handle.baseAddress, handle.len);
- close(handle.file);
-
- handle.file = 0;
-#endif
-
- handle.baseAddress = nullptr;
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.h b/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.h
deleted file mode 100644
index c145753..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleMemoryMappedFile.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#ifndef _WIN32
-#include
-#include
-#include
-#include
-
-#define INVALID_HANDLE_VALUE ((long)-1)
-#endif
-
-namespace MemoryMappedFile
-{
- struct Handle
- {
-#ifdef _WIN32
- void* file;
- void* fileMapping;
-#else
- int file;
-#endif
- void* baseAddress;
- size_t len;
- };
-
- Handle Open(const char* path);
- void Close(Handle& handle);
-}
diff --git a/third_party/raw_pdb/src/Examples/ExamplePDBSize.cpp b/third_party/raw_pdb/src/Examples/ExamplePDBSize.cpp
deleted file mode 100644
index c0a4dc6..0000000
--- a/third_party/raw_pdb/src/Examples/ExamplePDBSize.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-
-
-namespace
-{
- struct Stream
- {
- std::string name;
- uint32_t size;
- };
-}
-
-
-void ExamplePDBSize(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream);
-void ExamplePDBSize(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream)
-{
- TimedScope total("\nRunning example \"PDBSize\"");
-
- std::vector streams;
-
- // print show general statistics
- printf("General\n");
- printf("-------\n");
- {
- const PDB::SuperBlock* superBlock = rawPdbFile.GetSuperBlock();
- printf("PDB page size (block size): %u\n", superBlock->blockSize);
- printf("PDB block count: %u\n", superBlock->blockCount);
-
- const size_t rawSize = static_cast(superBlock->blockSize) * static_cast(superBlock->blockCount);
- printf("PDB raw size: %zu MiB (%zu GiB)\n", rawSize >> 20u, rawSize >> 30u);
- }
-
- // print the sizes of all known streams
- printf("\n");
- printf("Sizes of known streams\n");
- printf("----------------------\n");
- {
- const uint32_t streamCount = rawPdbFile.GetStreamCount();
- const uint32_t tpiStreamSize = (streamCount > 2u) ? rawPdbFile.GetStreamSize(2u) : 0u;
- const uint32_t dbiStreamSize = (streamCount > 3u) ? rawPdbFile.GetStreamSize(3u) : 0u;
- const uint32_t ipiStreamSize = (streamCount > 4u) ? rawPdbFile.GetStreamSize(4u) : 0u;
-
- printf("TPI stream size: %u KiB (%u MiB)\n", tpiStreamSize >> 10u, tpiStreamSize >> 20u);
- printf("DBI stream size: %u KiB (%u MiB)\n", dbiStreamSize >> 10u, dbiStreamSize >> 20u);
- printf("IPI stream size: %u KiB (%u MiB)\n", ipiStreamSize >> 10u, ipiStreamSize >> 20u);
-
- streams.push_back(Stream { "TPI", tpiStreamSize });
- streams.push_back(Stream { "DBI", dbiStreamSize });
- streams.push_back(Stream { "IPI", ipiStreamSize });
-
- const uint32_t globalSymbolStreamSize = rawPdbFile.GetStreamSize(dbiStream.GetHeader().globalStreamIndex);
- const uint32_t publicSymbolStreamSize = rawPdbFile.GetStreamSize(dbiStream.GetHeader().publicStreamIndex);
- const uint32_t symbolRecordStreamSize = rawPdbFile.GetStreamSize(dbiStream.GetHeader().symbolRecordStreamIndex);
-
- printf("Global symbol stream size: %u KiB (%u MiB)\n", globalSymbolStreamSize >> 10u, globalSymbolStreamSize >> 20u);
- printf("Public symbol stream size: %u KiB (%u MiB)\n", publicSymbolStreamSize >> 10u, publicSymbolStreamSize >> 20u);
- printf("Symbol record stream size: %u KiB (%u MiB)\n", symbolRecordStreamSize >> 10u, symbolRecordStreamSize >> 20u);
-
- streams.emplace_back(Stream { "Global", globalSymbolStreamSize });
- streams.emplace_back(Stream { "Public", publicSymbolStreamSize });
- streams.emplace_back(Stream { "Symbol", symbolRecordStreamSize });
- }
-
- // print the sizes of all module streams
- printf("\n");
- printf("Sizes of module streams\n");
- printf("-----------------------\n");
- {
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- const PDB::ArrayView modules = moduleInfoStream.GetModules();
-
- for (const PDB::ModuleInfoStream::Module& module : modules)
- {
- const PDB::DBI::ModuleInfo* moduleInfo = module.GetInfo();
- const char* name = module.GetName().Decay();
- const char* objectName = module.GetObjectName().Decay();
-
- const uint16_t streamIndex = module.HasSymbolStream() ? moduleInfo->moduleSymbolStreamIndex : 0u;
- const uint32_t moduleStreamSize = (streamIndex != 0u) ? rawPdbFile.GetStreamSize(streamIndex) : 0u;
-
- printf("Module %s (%s) stream size: %u KiB (%u MiB)\n", name, objectName, moduleStreamSize >> 10u, moduleStreamSize >> 20u);
-
- streams.push_back(Stream { name, moduleStreamSize });
- }
- }
-
- // sort the streams by their size
- std::sort(streams.begin(), streams.end(), [](const Stream& lhs, const Stream& rhs)
- {
- return lhs.size > rhs.size;
- });
-
- // log the 20 largest stream
- {
- printf("\n");
- printf("Sizes of 20 largest streams:\n");
-
- const size_t countToShow = std::min(20ul, streams.size());
- for (size_t i = 0u; i < countToShow; ++i)
- {
- const Stream& stream = streams[i];
- printf("%zu: %u KiB (%u MiB) from stream %s\n", i + 1u, stream.size >> 10u, stream.size >> 20u, stream.name.c_str());
- }
- }
-
- // print the raw stream sizes
- printf("\n");
- printf("Raw sizes of all streams\n");
- printf("------------------------\n");
- {
- const uint32_t streamCount = rawPdbFile.GetStreamCount();
- for (uint32_t i = 0u; i < streamCount; ++i)
- {
- const uint32_t streamSize = rawPdbFile.GetStreamSize(i);
- printf("Stream %u size: %u KiB (%u MiB)\n", i, streamSize >> 10u, streamSize >> 20u);
- }
- }
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleSymbols.cpp b/third_party/raw_pdb/src/Examples/ExampleSymbols.cpp
deleted file mode 100644
index c1b2ef8..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleSymbols.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-
-
-namespace
-{
- // we don't have to store std::string in the symbols, since all the data is memory-mapped anyway.
- // we do it in this example to ensure that we don't "cheat" when reading the PDB file. memory-mapped data will only
- // be faulted into the process once it's touched, so actually copying the string data makes us touch the needed data,
- // giving us a real performance measurement.
- struct Symbol
- {
- std::string name;
- uint32_t rva;
- };
-}
-
-
-void ExampleSymbols(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream);
-void ExampleSymbols(const PDB::RawFile& rawPdbFile, const PDB::DBIStream& dbiStream)
-{
- TimedScope total("\nRunning example \"Symbols\"");
-
- // in order to keep the example easy to understand, we load the PDB data serially.
- // note that this can be improved a lot by reading streams concurrently.
-
- // prepare the image section stream first. it is needed for converting section + offset into an RVA
- TimedScope sectionScope("Reading image section stream");
- const PDB::ImageSectionStream imageSectionStream = dbiStream.CreateImageSectionStream(rawPdbFile);
- sectionScope.Done();
-
-
- // prepare the module info stream for matching contributions against files
- TimedScope moduleScope("Reading module info stream");
- const PDB::ModuleInfoStream moduleInfoStream = dbiStream.CreateModuleInfoStream(rawPdbFile);
- moduleScope.Done();
-
-
- // prepare symbol record stream needed by both public and global streams
- TimedScope symbolStreamScope("Reading symbol record stream");
- const PDB::CoalescedMSFStream symbolRecordStream = dbiStream.CreateSymbolRecordStream(rawPdbFile);
- symbolStreamScope.Done();
-
- std::vector symbols;
-
- // read public symbols
- TimedScope publicScope("Reading public symbol stream");
- const PDB::PublicSymbolStream publicSymbolStream = dbiStream.CreatePublicSymbolStream(rawPdbFile);
- publicScope.Done();
- {
- TimedScope scope("Storing public symbols");
-
- const PDB::ArrayView hashRecords = publicSymbolStream.GetRecords();
- const size_t count = hashRecords.GetLength();
-
- symbols.reserve(count);
-
- for (const PDB::HashRecord& hashRecord : hashRecords)
- {
- const PDB::CodeView::DBI::Record* record = publicSymbolStream.GetRecord(symbolRecordStream, hashRecord);
- if (record->header.kind != PDB::CodeView::DBI::SymbolRecordKind::S_PUB32)
- {
- // normally, a PDB only contains S_PUB32 symbols in the public symbol stream, but we have seen PDBs that also store S_CONSTANT as public symbols.
- // ignore these.
- continue;
- }
-
- const uint32_t rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_PUB32.section, record->data.S_PUB32.offset);
- if (rva == 0u)
- {
- // certain symbols (e.g. control-flow guard symbols) don't have a valid RVA, ignore those
- continue;
- }
-
- symbols.push_back(Symbol { record->data.S_PUB32.name, rva });
- }
-
- scope.Done(count);
- }
-
-
- // read global symbols
- TimedScope globalScope("Reading global symbol stream");
- const PDB::GlobalSymbolStream globalSymbolStream = dbiStream.CreateGlobalSymbolStream(rawPdbFile);
- globalScope.Done();
- {
- TimedScope scope("Storing global symbols");
-
- const PDB::ArrayView hashRecords = globalSymbolStream.GetRecords();
- const size_t count = hashRecords.GetLength();
-
- symbols.reserve(symbols.size() + count);
-
- for (const PDB::HashRecord& hashRecord : hashRecords)
- {
- const PDB::CodeView::DBI::Record* record = globalSymbolStream.GetRecord(symbolRecordStream, hashRecord);
-
- const char* name = nullptr;
- uint32_t rva = 0u;
- if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GDATA32)
- {
- name = record->data.S_GDATA32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GDATA32.section, record->data.S_GDATA32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GTHREAD32)
- {
- name = record->data.S_GTHREAD32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GTHREAD32.section, record->data.S_GTHREAD32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LDATA32)
- {
- name = record->data.S_LDATA32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LDATA32.section, record->data.S_LDATA32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LTHREAD32)
- {
- name = record->data.S_LTHREAD32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LTHREAD32.section, record->data.S_LTHREAD32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_UDT)
- {
- name = record->data.S_UDT.name;
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_UDT_ST)
- {
- name = record->data.S_UDT_ST.name;
- }
-
- if (rva == 0u)
- {
- // certain symbols (e.g. control-flow guard symbols) don't have a valid RVA, ignore those
- continue;
- }
-
- symbols.push_back(Symbol { name, rva });
- }
-
- scope.Done(count);
- }
-
-
- // read module symbols
- {
- TimedScope scope("Storing symbols from modules");
-
- const PDB::ArrayView modules = moduleInfoStream.GetModules();
-
- for (const PDB::ModuleInfoStream::Module& module : modules)
- {
- if (!module.HasSymbolStream())
- {
- continue;
- }
-
- const PDB::ModuleSymbolStream moduleSymbolStream = module.CreateSymbolStream(rawPdbFile);
- moduleSymbolStream.ForEachSymbol([&symbols, &imageSectionStream](const PDB::CodeView::DBI::Record* record)
- {
- const char* name = nullptr;
- uint32_t rva = 0u;
- if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_THUNK32)
- {
- if (record->data.S_THUNK32.thunk == PDB::CodeView::DBI::ThunkOrdinal::TrampolineIncremental)
- {
- // we have never seen incremental linking thunks stored inside a S_THUNK32 symbol, but better be safe than sorry
- name = "ILT";
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_THUNK32.section, record->data.S_THUNK32.offset);
- }
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_TRAMPOLINE)
- {
- // incremental linking thunks are stored in the linker module
- name = "ILT";
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_TRAMPOLINE.thunkSection, record->data.S_TRAMPOLINE.thunkOffset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_BLOCK32)
- {
- // blocks never store a name and are only stored for indicating whether other symbols are children of this block
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LABEL32)
- {
- // labels don't have a name
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LPROC32)
- {
- name = record->data.S_LPROC32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LPROC32.section, record->data.S_LPROC32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GPROC32)
- {
- name = record->data.S_GPROC32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GPROC32.section, record->data.S_GPROC32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LPROC32_ID)
- {
- name = record->data.S_LPROC32_ID.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LPROC32_ID.section, record->data.S_LPROC32_ID.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_GPROC32_ID)
- {
- name = record->data.S_GPROC32_ID.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_GPROC32_ID.section, record->data.S_GPROC32_ID.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_REGREL32)
- {
- name = record->data.S_REGREL32.name;
- // You can only get the address while running the program by checking the register value and adding the offset
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LDATA32)
- {
- name = record->data.S_LDATA32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LDATA32.section, record->data.S_LDATA32.offset);
- }
- else if (record->header.kind == PDB::CodeView::DBI::SymbolRecordKind::S_LTHREAD32)
- {
- name = record->data.S_LTHREAD32.name;
- rva = imageSectionStream.ConvertSectionOffsetToRVA(record->data.S_LTHREAD32.section, record->data.S_LTHREAD32.offset);
- }
-
- if (rva == 0u)
- {
- // certain symbols (e.g. control-flow guard symbols) don't have a valid RVA, ignore those
- return;
- }
-
- symbols.push_back(Symbol { name, rva });
- });
- }
-
- scope.Done(modules.GetLength());
- }
-
- total.Done(symbols.size());
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleTimedScope.cpp b/third_party/raw_pdb/src/Examples/ExampleTimedScope.cpp
deleted file mode 100644
index 74b3fb0..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleTimedScope.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-
-namespace
-{
- static unsigned int g_indent = 0u;
-
- static void PrintIndent(void)
- {
- printf("%.*s", g_indent * 2u, "| | | | | | | | ");
- }
-}
-
-
-TimedScope::TimedScope(const char* message)
- : m_begin(std::chrono::high_resolution_clock::now())
-{
- PrintIndent();
- ++g_indent;
-
- printf("%s\n", message);
-}
-
-
-void TimedScope::Done(void) const
-{
- --g_indent;
- PrintIndent();
-
- const double milliSeconds = ReadMilliseconds();
- printf("---> done in %.3fms\n", milliSeconds);
-}
-
-
-void TimedScope::Done(size_t count) const
-{
- --g_indent;
- PrintIndent();
-
- const double milliSeconds = ReadMilliseconds();
- printf("---> done in %.3fms (%zu elements)\n", milliSeconds, count);
-}
-
-
-double TimedScope::ReadMilliseconds(void) const
-{
- const std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
- const std::chrono::duration seconds = now - m_begin;
-
- return seconds.count() * 1000.0;
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleTimedScope.h b/third_party/raw_pdb/src/Examples/ExampleTimedScope.h
deleted file mode 100644
index 0488dbb..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleTimedScope.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Foundation/PDB_Macros.h"
-#include
-
-
-class TimedScope
-{
-public:
- explicit TimedScope(const char* message);
-
- void Done(void) const;
- void Done(size_t count) const;
-
-private:
- double ReadMilliseconds(void) const;
-
- const std::chrono::high_resolution_clock::time_point m_begin;
-
- PDB_DISABLE_COPY_MOVE(TimedScope);
-};
diff --git a/third_party/raw_pdb/src/Examples/ExampleTypeTable.cpp b/third_party/raw_pdb/src/Examples/ExampleTypeTable.cpp
deleted file mode 100644
index 260b4d2..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleTypeTable.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
-#include "ExampleTypeTable.h"
-#include "Foundation/PDB_Memory.h"
-
-TypeTable::TypeTable(const PDB::TPIStream& tpiStream) PDB_NO_EXCEPT
- : typeIndexBegin(tpiStream.GetFirstTypeIndex()), typeIndexEnd(tpiStream.GetLastTypeIndex()),
- m_recordCount(tpiStream.GetTypeRecordCount())
-{
- // Create coalesced stream from TPI stream, so the records can be referenced directly using pointers.
- const PDB::DirectMSFStream& directStream = tpiStream.GetDirectMSFStream();
- m_stream = PDB::CoalescedMSFStream(directStream, directStream.GetSize(), 0);
-
- // types in the TPI stream are accessed by their index from other streams.
- // however, the index is not stored with types in the TPI stream directly, but has to be built while walking the stream.
- // similarly, because types are variable-length records, there are no direct offsets to access individual types.
- // we therefore walk the TPI stream once, and store pointers to the records for trivial O(1) array lookup by index later.
- m_records = PDB_NEW_ARRAY(const PDB::CodeView::TPI::Record*, m_recordCount);
-
- // parse the CodeView records
- uint32_t typeIndex = 0u;
-
- tpiStream.ForEachTypeRecordHeaderAndOffset([this, &typeIndex](const PDB::CodeView::TPI::RecordHeader& header, size_t offset)
- {
- // The header includes the record kind and size, which can be stored along with offset
- // to allow for lazy loading of the types on-demand directly from the TPIStream::GetDirectMSFStream()
- // using DirectMSFStream::ReadAtOffset(...). Thus not needing a CoalescedMSFStream to look up the types.
- (void)header;
-
- const PDB::CodeView::TPI::Record* record = m_stream.GetDataAtOffset(offset);
- m_records[typeIndex] = record;
- ++typeIndex;
- });
-}
-
-TypeTable::~TypeTable() PDB_NO_EXCEPT
-{
- PDB_DELETE_ARRAY(m_records);
-}
diff --git a/third_party/raw_pdb/src/Examples/ExampleTypeTable.h b/third_party/raw_pdb/src/Examples/ExampleTypeTable.h
deleted file mode 100644
index 7448952..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleTypeTable.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include "PDB_TPIStream.h"
-#include "PDB_CoalescedMSFStream.h"
-
-class TypeTable
-{
-public:
- explicit TypeTable(const PDB::TPIStream& tpiStream) PDB_NO_EXCEPT;
- ~TypeTable() PDB_NO_EXCEPT;
-
- // Returns the index of the first type, which is not necessarily zero.
- PDB_NO_DISCARD inline uint32_t GetFirstTypeIndex(void) const PDB_NO_EXCEPT
- {
- return typeIndexBegin;
- }
-
- // Returns the index of the last type.
- PDB_NO_DISCARD inline uint32_t GetLastTypeIndex(void) const PDB_NO_EXCEPT
- {
- return typeIndexEnd;
- }
-
- PDB_NO_DISCARD inline const PDB::CodeView::TPI::Record* GetTypeRecord(uint32_t typeIndex) const PDB_NO_EXCEPT
- {
- if (typeIndex < typeIndexBegin || typeIndex > typeIndexEnd)
- return nullptr;
-
- return m_records[typeIndex - typeIndexBegin];
- }
-
- // Returns a view of all type records.
- // Records identified by a type index can be accessed via "allRecords[typeIndex - firstTypeIndex]".
- PDB_NO_DISCARD inline PDB::ArrayView GetTypeRecords(void) const PDB_NO_EXCEPT
- {
- return PDB::ArrayView(m_records, m_recordCount);
- }
-
-private:
- uint32_t typeIndexBegin;
- uint32_t typeIndexEnd;
-
- size_t m_recordCount;
- const PDB::CodeView::TPI::Record **m_records;
-
- PDB::CoalescedMSFStream m_stream;
-
- PDB_DISABLE_COPY(TypeTable);
-};
diff --git a/third_party/raw_pdb/src/Examples/ExampleTypes.cpp b/third_party/raw_pdb/src/Examples/ExampleTypes.cpp
deleted file mode 100644
index cd30b22..0000000
--- a/third_party/raw_pdb/src/Examples/ExampleTypes.cpp
+++ /dev/null
@@ -1,1418 +0,0 @@
-
-#include "Examples_PCH.h"
-#include "ExampleTimedScope.h"
-#include "ExampleTypeTable.h"
-#include "PDB_RawFile.h"
-#include "PDB_DBIStream.h"
-#include "PDB_TPIStream.h"
-#include
-#include
-
-// not all enumeration values are handled explicitly by some of the switch statements
-PDB_DISABLE_WARNING_MSVC(4061)
-PDB_DISABLE_WARNING_CLANG("-Wswitch-enum")
-
-// some format strings are not string literals
-PDB_DISABLE_WARNING_MSVC(4774)
-PDB_DISABLE_WARNING_CLANG("-Wformat-nonliteral")
-
-std::string GetTypeName(const TypeTable& typeTable, uint32_t typeIndex);
-
-static uint8_t GetLeafSize(PDB::CodeView::TPI::TypeRecordKind kind)
-{
- if (kind < PDB::CodeView::TPI::TypeRecordKind::LF_NUMERIC)
- {
- // No leaf can have an index less than LF_NUMERIC (0x8000)
- // so word is the value...
- return sizeof(PDB::CodeView::TPI::TypeRecordKind);
- }
-
- switch (kind)
- {
- case PDB::CodeView::TPI::TypeRecordKind::LF_CHAR:
- return sizeof(PDB::CodeView::TPI::TypeRecordKind) + sizeof(uint8_t);
-
- case PDB::CodeView::TPI::TypeRecordKind::LF_USHORT:
- case PDB::CodeView::TPI::TypeRecordKind::LF_SHORT:
- return sizeof(PDB::CodeView::TPI::TypeRecordKind) + sizeof(uint16_t);
-
- case PDB::CodeView::TPI::TypeRecordKind::LF_LONG:
- case PDB::CodeView::TPI::TypeRecordKind::LF_ULONG:
- return sizeof(PDB::CodeView::TPI::TypeRecordKind) + sizeof(uint32_t);
-
- case PDB::CodeView::TPI::TypeRecordKind::LF_QUADWORD:
- case PDB::CodeView::TPI::TypeRecordKind::LF_UQUADWORD:
- return sizeof(PDB::CodeView::TPI::TypeRecordKind) + sizeof(uint64_t);
-
- default:
- printf("Error! 0x%04x bogus type encountered, aborting...\n", PDB_AS_UNDERLYING(kind));
- }
- return 0;
-}
-
-
-static const char* GetLeafName(const char* data, PDB::CodeView::TPI::TypeRecordKind kind)
-{
- return &data[GetLeafSize(kind)];
-}
-
-
-static const char* GetTypeName(const TypeTable& typeTable, uint32_t typeIndex, uint8_t& pointerLevel, const PDB::CodeView::TPI::Record** referencedType, const PDB::CodeView::TPI::Record** modifierRecord)
-{
- const char* typeName = nullptr;
- const PDB::CodeView::TPI::Record* underlyingType = nullptr;
-
- if (referencedType)
- *referencedType = nullptr;
-
- if (modifierRecord)
- *modifierRecord = nullptr;
-
- auto typeIndexBegin = typeTable.GetFirstTypeIndex();
- if (typeIndex < typeIndexBegin)
- {
- auto type = static_cast(typeIndex);
- switch (type)
- {
- case PDB::CodeView::TPI::TypeIndexKind::T_NOTYPE:
- return "";
- case PDB::CodeView::TPI::TypeIndexKind::T_HRESULT:
- return "HRESULT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PHRESULT:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PHRESULT:
- return "PHRESULT";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_UNKNOWN_0600:
- return "UNKNOWN_0x0600";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_VOID:
- return "void";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PVOID:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PVOID:
- case PDB::CodeView::TPI::TypeIndexKind::T_PVOID:
- return "PVOID";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_32PBOOL08:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PBOOL16:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PBOOL32:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PBOOL64:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PBOOL08:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PBOOL16:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PBOOL32:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PBOOL64:
- return "PBOOL";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_BOOL08:
- case PDB::CodeView::TPI::TypeIndexKind::T_BOOL16:
- case PDB::CodeView::TPI::TypeIndexKind::T_BOOL32:
- return "BOOL";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_RCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_CHAR:
- return "CHAR";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PRCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PRCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_PRCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_PCHAR:
- return "PCHAR";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_UCHAR:
- return "UCHAR";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_PUCHAR:
- return "PUCHAR";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_WCHAR:
- return "WCHAR";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PWCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PWCHAR:
- case PDB::CodeView::TPI::TypeIndexKind::T_PWCHAR:
- return "PWCHAR";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_CHAR8:
- return "CHAR8";
- case PDB::CodeView::TPI::TypeIndexKind::T_PCHAR8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PFCHAR8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PHCHAR8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PCHAR8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PFCHAR8:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PCHAR8:
- return "PCHAR8";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_CHAR16:
- return "CHAR16";
- case PDB::CodeView::TPI::TypeIndexKind::T_PCHAR16:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PCHAR16:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PCHAR16:
- return "PCHAR16";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_CHAR32:
- return "CHAR32";
- case PDB::CodeView::TPI::TypeIndexKind::T_PCHAR32:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PCHAR32:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PCHAR32:
- return "PCHAR32";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_SHORT:
- return "SHORT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PSHORT:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PSHORT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PSHORT:
- return "PSHORT";
- case PDB::CodeView::TPI::TypeIndexKind::T_USHORT:
- return "USHORT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUSHORT:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUSHORT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PUSHORT:
- return "PUSHORT";
- case PDB::CodeView::TPI::TypeIndexKind::T_LONG:
- return "LONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PLONG:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PLONG:
- case PDB::CodeView::TPI::TypeIndexKind::T_PLONG:
- return "PLONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_ULONG:
- return "ULONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PULONG:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PULONG:
- case PDB::CodeView::TPI::TypeIndexKind::T_PULONG:
- return "PULONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_REAL32:
- return "FLOAT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PREAL32:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PREAL32:
- case PDB::CodeView::TPI::TypeIndexKind::T_PREAL32:
- return "PFLOAT";
- case PDB::CodeView::TPI::TypeIndexKind::T_REAL64:
- return "DOUBLE";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PREAL64:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PREAL64:
- case PDB::CodeView::TPI::TypeIndexKind::T_PREAL64:
- return "PDOUBLE";
- case PDB::CodeView::TPI::TypeIndexKind::T_REAL80:
- return "REAL80";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PREAL80:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PREAL80:
- case PDB::CodeView::TPI::TypeIndexKind::T_PREAL80:
- return "PREAL80";
- case PDB::CodeView::TPI::TypeIndexKind::T_QUAD:
- return "LONGLONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PQUAD:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PQUAD:
- case PDB::CodeView::TPI::TypeIndexKind::T_PQUAD:
- return "PLONGLONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_UQUAD:
- return "ULONGLONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUQUAD:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUQUAD:
- case PDB::CodeView::TPI::TypeIndexKind::T_PUQUAD:
- return "PULONGLONG";
- case PDB::CodeView::TPI::TypeIndexKind::T_INT4:
- return "INT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PINT4:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PINT4:
- case PDB::CodeView::TPI::TypeIndexKind::T_PINT4:
- return "PINT";
- case PDB::CodeView::TPI::TypeIndexKind::T_UINT4:
- return "UINT";
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUINT4:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUINT4:
- case PDB::CodeView::TPI::TypeIndexKind::T_PUINT4:
- return "PUINT";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_UINT8:
- return "UINT8";
- case PDB::CodeView::TPI::TypeIndexKind::T_PUINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PFUINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PHUINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PFUINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUINT8:
- return "PUINT8";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_INT8:
- return "INT8";
- case PDB::CodeView::TPI::TypeIndexKind::T_PINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PFINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_PHINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PFINT8:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PINT8:
- return "PINT8";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_OCT:
- return "OCTAL";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_POCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PFOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PHOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_32POCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PFOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_64POCT:
- return "POCTAL";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_UOCT:
- return "UOCTAL";
-
- case PDB::CodeView::TPI::TypeIndexKind::T_PUOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PFUOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_PHUOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PUOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_32PFUOCT:
- case PDB::CodeView::TPI::TypeIndexKind::T_64PUOCT:
- return "PUOCTAL";
-
- default:
- PDB_ASSERT(false, "Unhandled special type 0x%X", typeIndex);
- return "unhandled_special_type";
- }
- }
- else
- {
- auto typeRecord = typeTable.GetTypeRecord(typeIndex);
- if (!typeRecord)
- return nullptr;
-
- switch (typeRecord->header.kind)
- {
- case PDB::CodeView::TPI::TypeRecordKind::LF_MODIFIER:
- if(modifierRecord)
- *modifierRecord = typeRecord;
- return GetTypeName(typeTable, typeRecord->data.LF_MODIFIER.type, pointerLevel, referencedType, nullptr);
- case PDB::CodeView::TPI::TypeRecordKind::LF_POINTER:
- ++pointerLevel;
- if(referencedType)
- *referencedType = typeRecord;
- if (typeRecord->data.LF_POINTER.utype >= typeIndexBegin)
- {
- underlyingType = typeTable.GetTypeRecord(typeRecord->data.LF_POINTER.utype);
- if (!underlyingType)
- return nullptr;
-
- if(underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_POINTER)
- return GetTypeName(typeTable, typeRecord->data.LF_POINTER.utype, pointerLevel, referencedType, modifierRecord);
-
- // Type record order can be LF_POINTER -> LF_MODIFIER -> LF_POINTER -> ...
- if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MODIFIER)
- {
- if (modifierRecord)
- *modifierRecord = underlyingType;
-
- return GetTypeName(typeTable, underlyingType->data.LF_MODIFIER.type, pointerLevel, referencedType, nullptr);
- }
- }
-
- return GetTypeName(typeTable, typeRecord->data.LF_POINTER.utype, pointerLevel, &typeRecord, modifierRecord);
- case PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE:
- if (referencedType)
- *referencedType = typeRecord;
- return nullptr;
- case PDB::CodeView::TPI::TypeRecordKind::LF_BITFIELD:
- if (typeRecord->data.LF_BITFIELD.type < typeIndexBegin)
- {
- typeName = GetTypeName(typeTable, typeRecord->data.LF_BITFIELD.type, pointerLevel, nullptr, modifierRecord);
- if (referencedType)
- *referencedType = typeRecord;
- return typeName;
- }
- else
- {
- if (referencedType)
- *referencedType = typeRecord;
- return nullptr;
- }
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARRAY:
- if (referencedType)
- *referencedType = typeRecord;
- return GetTypeName(typeTable, typeRecord->data.LF_ARRAY.elemtype, pointerLevel, &typeRecord, modifierRecord);
- case PDB::CodeView::TPI::TypeRecordKind::LF_CLASS:
- case PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE:
- return GetLeafName(typeRecord->data.LF_CLASS.data, typeRecord->header.kind);
-
- case PDB::CodeView::TPI::TypeRecordKind::LF_CLASS2:
- case PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE2:
- return GetLeafName(typeRecord->data.LF_CLASS2.data, typeRecord->header.kind);
-
- case PDB::CodeView::TPI::TypeRecordKind::LF_UNION:
- return GetLeafName(typeRecord->data.LF_UNION.data, typeRecord->header.kind);
- case PDB::CodeView::TPI::TypeRecordKind::LF_ENUM:
- return &typeRecord->data.LF_ENUM.name[0];
- case PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION:
- if (referencedType)
- *referencedType = typeRecord;
- return nullptr;
-
- default:
- PDB_ASSERT(false, "Unhandled TypeRecordKind 0x%X", static_cast(typeRecord->header.kind));
- break;
- }
-
- }
-
- return "unknown_type";
-}
-
-static const char* GetModifierName(const PDB::CodeView::TPI::Record* modifierRecord)
-{
- if (modifierRecord->data.LF_MODIFIER.attr.MOD_const)
- return "const";
- else if (modifierRecord->data.LF_MODIFIER.attr.MOD_volatile)
- return "volatile";
- else if (modifierRecord->data.LF_MODIFIER.attr.MOD_unaligned)
- return "unaligned";
-
- return "";
-}
-
-static bool GetMethodPrototype(const TypeTable& typeTable, const PDB::CodeView::TPI::Record* methodRecord, std::string& methodPrototype);
-
-static bool GetFunctionPrototype(const TypeTable& typeTable, const PDB::CodeView::TPI::Record* functionRecord, std::string& functionPrototype)
-{
- PDB_ASSERT(functionRecord->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE, "TPI Record kind is 0x%X, expected 0x%X (LF_PROCEDURE)",
- (uint32_t)functionRecord->header.kind, (uint32_t)PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE);
-
- std::string underlyingTypePrototype;
-
- size_t markerPos = 0;
- uint8_t pointerLevel = 0;
- const PDB::CodeView::TPI::Record* referencedType = nullptr;
- const PDB::CodeView::TPI::Record* underlyingType = nullptr;
- const PDB::CodeView::TPI::Record* modifierRecord = nullptr;
-
- functionPrototype.clear();
-
- auto typeName = GetTypeName(typeTable, functionRecord->data.LF_PROCEDURE.rvtype, pointerLevel, &referencedType, &modifierRecord);
- if (typeName)
- {
- if (modifierRecord)
- {
- functionPrototype += GetModifierName(modifierRecord);
- functionPrototype += ' ';
- }
-
- functionPrototype += typeName;
-
- for (size_t i = 0; i < pointerLevel; i++)
- functionPrototype += '*';
- }
- else
- {
- PDB_ASSERT(referencedType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_POINTER, "Referenced type kind 0x%X != LF_POINTER (0x%X)", (uint32_t)referencedType->header.kind, (uint32_t)PDB::CodeView::TPI::TypeRecordKind::LF_POINTER);
-
- underlyingType = typeTable.GetTypeRecord(referencedType->data.LF_POINTER.utype);
- if (!underlyingType)
- return false;
-
- if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- if (!GetFunctionPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
- }
- else if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- if (!GetMethodPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
- }
- else
- {
- PDB_ASSERT(false, "Unhandled underlyingType kind 0x%X", (uint32_t)underlyingType->header.kind);
- }
-
- markerPos = underlyingTypePrototype.find("%s");
- underlyingTypePrototype.erase(markerPos, 2);
- functionPrototype = underlyingTypePrototype;
- }
-
- functionPrototype += " (*%s)(";
-
- if (functionRecord->data.LF_PROCEDURE.parmcount)
- {
- auto argList = typeTable.GetTypeRecord(functionRecord->data.LF_PROCEDURE.arglist);
- if (!argList)
- return false;
-
- for (size_t i = 0; i < argList->data.LF_ARGLIST.count; i++)
- {
- pointerLevel = 0;
- typeName = GetTypeName(typeTable, argList->data.LF_ARGLIST.arg[i], pointerLevel, &referencedType, &modifierRecord);
- if (referencedType)
- {
- if (referencedType->data.LF_POINTER.utype >= typeTable.GetFirstTypeIndex())
- {
- underlyingType = typeTable.GetTypeRecord(referencedType->data.LF_POINTER.utype);
- if (!underlyingType)
- return false;
- }
-
- if (!underlyingType || (underlyingType->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE && underlyingType->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION))
- {
- if (modifierRecord)
- {
- functionPrototype += GetModifierName(modifierRecord);
- functionPrototype += ' ';
- }
-
- functionPrototype += typeName;
- functionPrototype += '*';
-
- if (referencedType->data.LF_POINTER.attr.isvolatile)
- functionPrototype += "volatile";
- else if (referencedType->data.LF_POINTER.attr.isconst)
- functionPrototype += "const";
- }
- else if(underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- if (!GetFunctionPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
-
- markerPos = underlyingTypePrototype.find("%s");
- underlyingTypePrototype.erase(markerPos, 2);
-
- for (size_t j = 1; j < pointerLevel; j++)
- underlyingTypePrototype.insert(markerPos, 1, '*');
-
- functionPrototype += underlyingTypePrototype;
- }
- else if(underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- functionPrototype += GetTypeName(typeTable, argList->data.LF_ARGLIST.arg[i]);
- }
- }
- else
- {
- functionPrototype += typeName;
- }
-
- if (i < (argList->data.LF_ARGLIST.count - 1))
- functionPrototype += ", ";
- }
- }
-
- functionPrototype += ')';
-
- return true;
-}
-
-
-static bool GetMethodPrototype(const TypeTable& typeTable, const PDB::CodeView::TPI::Record* methodRecord, std::string& methodPrototype)
-{
- PDB_ASSERT(methodRecord->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION, "TPI Record kind is 0x%X, expected 0x%X (LF_MFUNCTION)",
- (uint32_t)methodRecord->header.kind, (uint32_t)PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION);
-
- std::string underlyingTypePrototype;
-
- size_t markerPos = 0;
- uint8_t pointerLevel = 0;
- const PDB::CodeView::TPI::Record* referencedType = nullptr;
- const PDB::CodeView::TPI::Record* underlyingType = nullptr;
- const PDB::CodeView::TPI::Record* modifierRecord = nullptr;
-
- methodPrototype.clear();
-
- auto typeName = GetTypeName(typeTable, methodRecord->data.LF_MFUNCTION.rvtype, pointerLevel, &referencedType, &modifierRecord);
- if (typeName)
- {
- if (modifierRecord)
- {
- methodPrototype += GetModifierName(modifierRecord);
- methodPrototype += ' ';
- }
-
- methodPrototype += typeName;
-
- for (size_t i = 0; i < pointerLevel; i++)
- methodPrototype += '*';
- }
- else
- {
- underlyingType = typeTable.GetTypeRecord(referencedType->data.LF_POINTER.utype);
- if (!underlyingType)
- return false;
-
- if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- if (!GetFunctionPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
- }
- else if(underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- if (!GetMethodPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
- }
- else
- {
- PDB_ASSERT(false, "Unhandled underlyingType kind 0x%X", (uint32_t)underlyingType->header.kind);
- }
-
- markerPos = underlyingTypePrototype.find("%s");
- underlyingTypePrototype.erase(markerPos, 2);
- methodPrototype = underlyingTypePrototype;
- }
-
- methodPrototype += " %s(";
-
- if (methodRecord->data.LF_MFUNCTION.parmcount)
- {
- auto argList = typeTable.GetTypeRecord(methodRecord->data.LF_MFUNCTION.arglist);
- if (!argList)
- return false;
-
- for (size_t i = 0; i < argList->data.LF_ARGLIST.count; i++)
- {
- pointerLevel = 0;
- typeName = GetTypeName(typeTable, argList->data.LF_ARGLIST.arg[i], pointerLevel, &referencedType, &modifierRecord);
- if (referencedType)
- {
- if (referencedType->data.LF_POINTER.utype >= typeTable.GetFirstTypeIndex())
- {
- underlyingType = typeTable.GetTypeRecord(referencedType->data.LF_POINTER.utype);
- if (!underlyingType)
- return false;
- }
-
- if (!underlyingType || (underlyingType->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE && underlyingType->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION))
- {
- if (modifierRecord)
- {
- methodPrototype += GetModifierName(modifierRecord);
- methodPrototype += ' ';
- }
-
- if(typeName)
- methodPrototype += typeName;
-
- methodPrototype += '*';
-
- if (referencedType->data.LF_POINTER.attr.isvolatile)
- methodPrototype += "volatile";
- else if (referencedType->data.LF_POINTER.attr.isconst)
- methodPrototype += "const";
- }
- else if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- if (!GetFunctionPrototype(typeTable, underlyingType, underlyingTypePrototype))
- return false;
-
- markerPos = underlyingTypePrototype.find("%s");
- underlyingTypePrototype.erase(markerPos, 2);
-
- for (size_t j = 1; j < pointerLevel; j++)
- underlyingTypePrototype.insert(markerPos, 1, '*');
-
- methodPrototype += underlyingTypePrototype;
- }
- else if (underlyingType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- methodPrototype += GetTypeName(typeTable, argList->data.LF_ARGLIST.arg[i]);
- }
- }
- else
- {
- methodPrototype += typeName;
- }
-
- if (i < (argList->data.LF_ARGLIST.count - 1))
- methodPrototype += ", ";
- }
- }
-
- methodPrototype += ')';
-
- return true;
-}
-
-
-static const char* GetMethodName(const PDB::CodeView::TPI::FieldList* fieldRecord)
-{
- auto methodAttributes = static_cast(fieldRecord->data.LF_ONEMETHOD.attributes.mprop);
- switch (methodAttributes)
- {
- case PDB::CodeView::TPI::MethodProperty::Intro:
- case PDB::CodeView::TPI::MethodProperty::PureIntro:
- return &reinterpret_cast(fieldRecord->data.LF_ONEMETHOD.vbaseoff)[sizeof(uint32_t)];
- default:
- break;
- }
-
- return &reinterpret_cast(fieldRecord->data.LF_ONEMETHOD.vbaseoff)[0];
-}
-
-
-static void DisplayFields(const TypeTable& typeTable, const PDB::CodeView::TPI::Record* record)
-{
- const PDB::CodeView::TPI::Record* referencedType = nullptr;
- const PDB::CodeView::TPI::Record* underlyingType = nullptr;
- const PDB::CodeView::TPI::Record* modifierRecord = nullptr;
- const char* leafName = nullptr;
- const char* typeName = nullptr;
- std::string functionPrototype;
- uint16_t offset = 0;
-
- auto maximumSize = record->header.size - sizeof(uint16_t);
-
- for (size_t i = 0; i < maximumSize;)
- {
- uint8_t pointerLevel = 0;
- auto fieldRecord = reinterpret_cast(reinterpret_cast(&record->data.LF_FIELD.list) + i);
-
- // Other kinds of records are not implemented
- PDB_ASSERT(
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_BCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VBCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_IVBCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_INDEX ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VFUNCTAB ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_NESTTYPE ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUM ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_MEMBER ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_STMEMBER ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_METHOD ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ONEMETHOD,
- "Unknown record kind %X",
- static_cast(fieldRecord->kind));
-
- if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_MEMBER)
- {
- if (fieldRecord->data.LF_MEMBER.lfEasy.kind < PDB::CodeView::TPI::TypeRecordKind::LF_NUMERIC)
- offset = *reinterpret_cast(&fieldRecord->data.LF_MEMBER.offset[0]);
- else
- offset = *reinterpret_cast(&fieldRecord->data.LF_MEMBER.offset[sizeof(PDB::CodeView::TPI::TypeRecordKind)]);
-
- leafName = GetLeafName(fieldRecord->data.LF_MEMBER.offset, fieldRecord->data.LF_MEMBER.lfEasy.kind);
-
- typeName = GetTypeName(typeTable, fieldRecord->data.LF_MEMBER.index, pointerLevel, &referencedType, &modifierRecord);
- if (referencedType)
- {
- switch (referencedType->header.kind)
- {
- case PDB::CodeView::TPI::TypeRecordKind::LF_POINTER:
- if (referencedType->data.LF_POINTER.utype >= typeTable.GetFirstTypeIndex())
- {
- underlyingType = typeTable.GetTypeRecord(referencedType->data.LF_POINTER.utype);
- if (!underlyingType)
- break;
-
- if (underlyingType->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- if (modifierRecord)
- printf("[0x%X]%s %s", offset, GetModifierName(modifierRecord), typeName);
- else
- printf("[0x%X]%s", offset, typeName);
-
- for (size_t j = 0; j < pointerLevel; j++)
- printf("*");
-
- printf(" %s\n", leafName);
- }
- else
- {
- if (!GetFunctionPrototype(typeTable, underlyingType, functionPrototype))
- break;
-
- printf("[0x%X]", offset);
- printf(functionPrototype.c_str(), leafName);
- printf("\n");
- }
- }
- else
- {
- printf("[0x%X]%s", offset, typeName);
-
- for (size_t j = 0; j < pointerLevel; j++)
- printf("*");
-
- if (referencedType->data.LF_POINTER.attr.isvolatile)
- printf(" volatile");
- else if (referencedType->data.LF_POINTER.attr.isconst)
- printf(" const");
-
- printf(" %s\n", leafName);
- }
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_BITFIELD:
- if (typeName)
- {
- printf("[0x%X]%s %s : %d\n",
- offset,
- typeName,
- leafName,
- referencedType->data.LF_BITFIELD.length);
- }
- else
- {
- modifierRecord = typeTable.GetTypeRecord(referencedType->data.LF_BITFIELD.type);
- if (!modifierRecord)
- break;
-
- printf("[0x%X]%s %s %s : %d\n",
- offset,
- GetModifierName(modifierRecord),
- GetTypeName(typeTable, modifierRecord->data.LF_MODIFIER.type, pointerLevel, nullptr, nullptr),
- leafName,
- referencedType->data.LF_BITFIELD.length);
- }
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARRAY:
- if (!modifierRecord)
- {
- printf("[0x%X]%s %s[] /*0x%X*/\n",
- offset,
- typeName,
- leafName,
- *reinterpret_cast(referencedType->data.LF_ARRAY.data));
- }
- else
- {
- printf("[0x%X]%s %s %s[] /*0x%X*/\n",
- offset,
- GetModifierName(modifierRecord),
- GetTypeName(typeTable, modifierRecord->data.LF_MODIFIER.type, pointerLevel, nullptr, nullptr),
- leafName,
- *reinterpret_cast(referencedType->data.LF_ARRAY.data));
- }
- break;
- default:
- break;
- }
- }
- else
- {
- if (modifierRecord)
- printf("[0x%X]%s %s %s\n", offset, GetModifierName(modifierRecord), typeName, leafName);
- else
- printf("[0x%X]%s %s\n", offset, typeName, leafName);
- }
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_NESTTYPE)
- {
- leafName = &fieldRecord->data.LF_NESTTYPE.name[0];
- typeName = GetTypeName(typeTable, fieldRecord->data.LF_NESTTYPE.index, pointerLevel, &referencedType, &modifierRecord);
-
- printf("%s %s\n", typeName, leafName);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_STMEMBER)
- {
- leafName = &fieldRecord->data.LF_STMEMBER.name[0];
- typeName = GetTypeName(typeTable, fieldRecord->data.LF_STMEMBER.index, pointerLevel, &referencedType, &modifierRecord);
-
- if (!modifierRecord)
- printf("%s %s\n", typeName, leafName);
- else
- printf("%s %s %s\n", GetModifierName(modifierRecord), typeName, leafName);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_METHOD)
- {
- leafName = fieldRecord->data.LF_METHOD.name;
-
- auto methodList = typeTable.GetTypeRecord(fieldRecord->data.LF_METHOD.mList);
- if (!methodList)
- break;
-
- // https://github.com/microsoft/microsoft-pdb/blob/master/PDB/include/symtypeutils.h#L220
- size_t offsetInMethodList = 0;
- for (size_t j = 0; j < fieldRecord->data.LF_METHOD.count; j++)
- {
- size_t entrySize = 2 * sizeof(uint32_t);
- const PDB::CodeView::TPI::MethodListEntry* entry = (const PDB::CodeView::TPI::MethodListEntry*)(methodList->data.LF_METHODLIST.mList + offsetInMethodList);
- if (!GetMethodPrototype(typeTable, typeTable.GetTypeRecord(entry->index), functionPrototype))
- break;
- printf(functionPrototype.c_str(), leafName);
- printf("\n");
- PDB::CodeView::TPI::MethodProperty methodProp = (PDB::CodeView::TPI::MethodProperty)entry->attributes.mprop;
- if (methodProp == PDB::CodeView::TPI::MethodProperty::Intro || methodProp == PDB::CodeView::TPI::MethodProperty::PureIntro)
- entrySize += sizeof(uint32_t);
- offsetInMethodList += entrySize;
- }
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ONEMETHOD)
- {
- leafName = GetMethodName(fieldRecord);
-
- referencedType = typeTable.GetTypeRecord(fieldRecord->data.LF_ONEMETHOD.index);
- if (!referencedType)
- break;
-
- if (!GetMethodPrototype(typeTable, referencedType, functionPrototype))
- break;
-
- printf(functionPrototype.c_str(), leafName);
- printf("\n");
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_BCLASS)
- {
- leafName = GetLeafName(fieldRecord->data.LF_BCLASS.offset, fieldRecord->data.LF_BCLASS.lfEasy.kind);
-
- i += static_cast(leafName - reinterpret_cast(fieldRecord));
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VBCLASS || fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_IVBCLASS)
- {
- // virtual base pointer offset from address point
- // followed by virtual base offset from vbtable
-
- const PDB::CodeView::TPI::TypeRecordKind vbpOffsetAddressPointKind = *(const PDB::CodeView::TPI::TypeRecordKind*)(fieldRecord->data.LF_IVBCLASS.vbpOffset);
- const uint8_t vbpOffsetAddressPointSize = GetLeafSize(vbpOffsetAddressPointKind);
-
- const PDB::CodeView::TPI::TypeRecordKind vbpOffsetVBTableKind = *(const PDB::CodeView::TPI::TypeRecordKind*)(fieldRecord->data.LF_IVBCLASS.vbpOffset + vbpOffsetAddressPointSize);
- const uint8_t vbpOffsetVBTableSize = GetLeafSize(vbpOffsetVBTableKind);
-
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_VBCLASS);
- i += vbpOffsetAddressPointSize + vbpOffsetVBTableSize;
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_INDEX)
- {
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_INDEX);
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VFUNCTAB)
- {
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_VFUNCTAB);
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else
- {
- break;
- }
-
- i += static_cast(leafName - reinterpret_cast(fieldRecord));
- i += strnlen(leafName, maximumSize - i - 1) + 1;
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- }
-}
-
-// Used in ExamplesFunctionVariables
-std::string GetTypeName(const TypeTable& typeTable, uint32_t typeIndex)
-{
- uint8_t pointerLevel = 0;
- const PDB::CodeView::TPI::Record* referencedType = nullptr;
- const PDB::CodeView::TPI::Record* modifierRecord = nullptr;
-
- const char* typeName = GetTypeName(typeTable, typeIndex, pointerLevel, &referencedType, &modifierRecord);
-
- if (typeName == nullptr)
- {
- if (referencedType == nullptr && (typeIndex & 0x80000000) != 0)
- {
- // d3d12.pdb\1DEAE23C86E6462A86018FB180EB8E4A1, S_CALLSITE for `dynamic initializer for 'g_Telemetry'': typeIndex == 0x80900001
- char typeIndexBuf[0x0C];
- sprintf_s(typeIndexBuf, sizeof(typeIndexBuf), "%08X", typeIndex);
- return std::string("";
- }
- PDB_ASSERT(referencedType != nullptr, "Neither typeName nor referencedType are set.");
-
- if (referencedType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_POINTER)
- {
- std::string pointerType = GetTypeName(typeTable, referencedType->data.LF_POINTER.utype);
-
- for (size_t i = 0; i < pointerLevel; i++)
- pointerType += '*';
-
- return pointerType;
- }
- else if (referencedType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_ARRAY)
- {
- const std::string elementType = GetTypeName(typeTable, referencedType->data.LF_ARRAY.elemtype);
- const std::string indexType = GetTypeName(typeTable, referencedType->data.LF_ARRAY.idxtype);
-
- return elementType + "[" + indexType + "]";
- }
- else if (referencedType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE)
- {
- std::string functionPrototype;
-
- if (!GetFunctionPrototype(typeTable, referencedType, functionPrototype))
- {
- PDB_ASSERT(false, "Resolving function prototype failed");
- return "resolving function type failed";
- }
-
- return functionPrototype;
- }
- else if (referencedType->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- std::string methodPrototype;
-
- if (!GetMethodPrototype(typeTable, referencedType, methodPrototype))
- {
- PDB_ASSERT(false, "Resolving method prototype failed");
- return "resolving method type failed";
- }
-
- std::string classTypeName = GetTypeName(typeTable, referencedType->data.LF_MFUNCTION.classtype);
- classTypeName += "::*";
-
- const int stringLength = std::snprintf(nullptr, 0, methodPrototype.c_str(), classTypeName.c_str());
- PDB_ASSERT(stringLength > 0, "String length %i <= 0", stringLength);
-
- std::vector resultString(static_cast(stringLength) + 1u);
-
- std::snprintf(&resultString[0], resultString.size(), methodPrototype.c_str(), classTypeName.c_str());
-
- return std::string(resultString.data());
- }
- else
- {
- PDB_ASSERT(false, "Unhandled referencedType kind 0x%X", static_cast(referencedType->header.kind));
- return "not found";
- }
- }
-
- return typeName;
-}
-
-static void DisplayEnumerates(const PDB::CodeView::TPI::Record* record, uint8_t underlyingTypeSize)
-{
- const char* leafName = nullptr;
- uint64_t value = 0;
- const char* valuePtr = nullptr;
-
- auto maximumSize = record->header.size - sizeof(uint16_t);
-
- for (size_t i = 0; i < maximumSize;)
- {
- auto fieldRecord = reinterpret_cast(reinterpret_cast(&record->data.LF_FIELD.list) + i);
-
- leafName = GetLeafName(fieldRecord->data.LF_ENUMERATE.value, fieldRecord->data.LF_ENUMERATE.lfEasy.kind);
-
- if (fieldRecord->data.LF_ENUMERATE.lfEasy.kind < PDB::CodeView::TPI::TypeRecordKind::LF_NUMERIC)
- valuePtr = &fieldRecord->data.LF_ENUMERATE.value[0];
- else
- valuePtr = &fieldRecord->data.LF_ENUMERATE.value[sizeof(PDB::CodeView::TPI::TypeRecordKind)];
-
- switch (underlyingTypeSize)
- {
- case 1:
- value = *reinterpret_cast(&fieldRecord->data.LF_ENUMERATE.value[0]);
- break;
- case 2:
- value = *reinterpret_cast(&fieldRecord->data.LF_ENUMERATE.value[0]);
- break;
- case 4:
- value = *reinterpret_cast(&fieldRecord->data.LF_ENUMERATE.value[0]);
- break;
- case 8:
- value = *reinterpret_cast(&fieldRecord->data.LF_ENUMERATE.value[0]);
- break;
- default:
- break;
- }
-
- printf("%s = %" PRIu64 "\n", leafName, value);
-
- i += static_cast(leafName - reinterpret_cast(fieldRecord));
- i += strnlen(leafName, maximumSize - i - 1) + 1;
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
-
- (void)valuePtr;
- }
-}
-
-
-void ExampleTypes(const PDB::TPIStream& tpiStream);
-void ExampleTypes(const PDB::TPIStream& tpiStream)
-{
- TimedScope total("\nRunning example \"Function types\"");
-
- TimedScope typeTableScope("Create TypeTable");
- TypeTable typeTable(tpiStream);
- typeTableScope.Done();
-
- for (const auto& record : typeTable.GetTypeRecords())
- {
- if ((record->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_CLASS) || (record->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE))
- {
- if (record->data.LF_CLASS.property.fwdref)
- continue;
-
- auto typeRecord = typeTable.GetTypeRecord(record->data.LF_CLASS.field);
- if (!typeRecord)
- continue;
-
- auto leafName = GetLeafName(record->data.LF_CLASS.data, record->data.LF_CLASS.lfEasy.kind);
-
- printf("struct %s\n{\n", leafName);
-
- DisplayFields(typeTable, typeRecord);
-
- printf("}\n");
- }
- else if (record->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_UNION)
- {
- if (record->data.LF_UNION.property.fwdref)
- continue;
-
- auto typeRecord = typeTable.GetTypeRecord(record->data.LF_UNION.field);
- if (!typeRecord)
- continue;
-
- auto leafName = GetLeafName(record->data.LF_UNION.data, static_cast(0));
-
- printf("union %s\n{\n", leafName);
-
- DisplayFields(typeTable, typeRecord);
-
- printf("}\n");
- }
- else if (record->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUM)
- {
- if (record->data.LF_ENUM.property.fwdref)
- continue;
-
- auto typeRecord = typeTable.GetTypeRecord(record->data.LF_ENUM.field);
- if (!typeRecord)
- continue;
-
- printf("enum %s\n{\n", record->data.LF_ENUM.name);
-
- DisplayEnumerates(typeRecord, GetLeafSize(static_cast(record->data.LF_ENUM.utype)));
-
- printf("}\n");
- }
- }
-
- total.Done(tpiStream.GetTypeRecordCount());
-}
-
-template
-static void TagRecursively(const TypeTable& typeTable, uint32_t typeIndex, T setName);
-
-#define TAG_AND_CHECK(typeIndex) if (setName(typeIndex)) TagRecursively(typeTable, typeIndex, setName)
-
-template
-static void TagChildren(const TypeTable& typeTable, const PDB::CodeView::TPI::Record* record, T setName)
-{
- const char* leafName = nullptr;
-
- auto maximumSize = record->header.size - sizeof(uint16_t);
-
- for (size_t i = 0; i < maximumSize;)
- {
- auto fieldRecord = reinterpret_cast(reinterpret_cast(&record->data.LF_FIELD.list) + i);
-
- // these are all the record kinds I have observed
- PDB_ASSERT(
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_BCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VBCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_IVBCLASS ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_INDEX ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VFUNCTAB ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_NESTTYPE ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUM ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_MEMBER ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_STMEMBER ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_METHOD ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ONEMETHOD ||
- fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUMERATE,
- "Unknown record kind %X",
- static_cast(fieldRecord->kind));
-
- if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_MEMBER)
- {
- leafName = GetLeafName(fieldRecord->data.LF_MEMBER.offset, fieldRecord->data.LF_MEMBER.lfEasy.kind);
- TAG_AND_CHECK(fieldRecord->data.LF_MEMBER.index);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_NESTTYPE)
- {
- leafName = &fieldRecord->data.LF_NESTTYPE.name[0];
- TAG_AND_CHECK(fieldRecord->data.LF_NESTTYPE.index);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_STMEMBER)
- {
- leafName = &fieldRecord->data.LF_STMEMBER.name[0];
- TAG_AND_CHECK(fieldRecord->data.LF_STMEMBER.index);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_METHOD)
- {
- leafName = fieldRecord->data.LF_METHOD.name;
- setName(fieldRecord->data.LF_METHOD.mList);
-
- auto methodList = typeTable.GetTypeRecord(fieldRecord->data.LF_METHOD.mList);
- if (!methodList)
- break;
-
- // https://github.com/microsoft/microsoft-pdb/blob/master/PDB/include/symtypeutils.h#L220
- size_t offsetInMethodList = 0;
- for (size_t j = 0; j < fieldRecord->data.LF_METHOD.count; j++)
- {
- size_t entrySize = sizeof(PDB::CodeView::TPI::MethodListEntry);
- const PDB::CodeView::TPI::MethodListEntry* entry = (const PDB::CodeView::TPI::MethodListEntry*)(methodList->data.LF_METHODLIST.mList + offsetInMethodList);
- TAG_AND_CHECK(entry->index);
- PDB::CodeView::TPI::MethodProperty methodProp = (PDB::CodeView::TPI::MethodProperty)entry->attributes.mprop;
- if (methodProp == PDB::CodeView::TPI::MethodProperty::Intro || methodProp == PDB::CodeView::TPI::MethodProperty::PureIntro)
- entrySize += sizeof(uint32_t);
- offsetInMethodList += entrySize;
- }
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ONEMETHOD)
- {
- leafName = GetMethodName(fieldRecord);
- TAG_AND_CHECK(fieldRecord->data.LF_ONEMETHOD.index);
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_BCLASS)
- {
- leafName = GetLeafName(fieldRecord->data.LF_BCLASS.offset, fieldRecord->data.LF_BCLASS.lfEasy.kind);
-
- i += static_cast(leafName - reinterpret_cast(fieldRecord));
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VBCLASS || fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_IVBCLASS)
- {
- // virtual base pointer offset from address point
- // followed by virtual base offset from vbtable
-
- const PDB::CodeView::TPI::TypeRecordKind vbpOffsetAddressPointKind = *(const PDB::CodeView::TPI::TypeRecordKind*)(fieldRecord->data.LF_IVBCLASS.vbpOffset);
- const uint8_t vbpOffsetAddressPointSize = GetLeafSize(vbpOffsetAddressPointKind);
-
- const PDB::CodeView::TPI::TypeRecordKind vbpOffsetVBTableKind = *(const PDB::CodeView::TPI::TypeRecordKind*)(fieldRecord->data.LF_IVBCLASS.vbpOffset + vbpOffsetAddressPointSize);
- const uint8_t vbpOffsetVBTableSize = GetLeafSize(vbpOffsetVBTableKind);
-
- TAG_AND_CHECK(fieldRecord->data.LF_VBCLASS.vbpIndex);
-
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_VBCLASS);
- i += vbpOffsetAddressPointSize + vbpOffsetVBTableSize;
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_INDEX)
- {
- // this is continued elsewhere
- setName(fieldRecord->data.LF_INDEX.type);
- auto continued = typeTable.GetTypeRecord(fieldRecord->data.LF_INDEX.type);
- if (continued)
- TagChildren(typeTable, continued, setName);
-
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_INDEX);
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_VFUNCTAB)
- {
- TAG_AND_CHECK(fieldRecord->data.LF_VFUNCTAB.type);
- i += sizeof(PDB::CodeView::TPI::FieldList::Data::LF_VFUNCTAB);
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- continue;
- }
- else if (fieldRecord->kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUMERATE)
- {
- leafName = GetLeafName(fieldRecord->data.LF_ENUMERATE.value, fieldRecord->data.LF_ENUMERATE.lfEasy.kind);
- }
- else
- {
- break;
- }
-
- i += static_cast(leafName - reinterpret_cast(fieldRecord));
- i += strnlen(leafName, maximumSize - i - 1) + 1;
- i = (i + (sizeof(uint32_t) - 1)) & (0 - sizeof(uint32_t));
- }
-}
-
-template
-static void TagRecursively(const TypeTable& typeTable, uint32_t typeIndex, T setName)
-{
- const PDB::CodeView::TPI::Record* record = typeTable.GetTypeRecord(typeIndex);
- if (!record)
- return;
- switch (record->header.kind)
- {
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARRAY:
- TAG_AND_CHECK(record->data.LF_ARRAY.elemtype);
- TAG_AND_CHECK(record->data.LF_ARRAY.idxtype);
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_POINTER:
- TAG_AND_CHECK(record->data.LF_POINTER.utype);
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_MODIFIER:
- TAG_AND_CHECK(record->data.LF_MODIFIER.type);
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE:
- TAG_AND_CHECK(record->data.LF_PROCEDURE.rvtype);
- TAG_AND_CHECK(record->data.LF_PROCEDURE.arglist);
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARGLIST:
- {
- size_t count = record->data.LF_ARGLIST.count;
- for (size_t i = 0; i < count; i++)
- {
- uint32_t type = record->data.LF_ARGLIST.arg[i];
- TAG_AND_CHECK(type);
- }
- break;
- }
- case PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION:
- TAG_AND_CHECK(record->data.LF_MFUNCTION.rvtype);
- TAG_AND_CHECK(record->data.LF_MFUNCTION.arglist);
- TAG_AND_CHECK(record->data.LF_MFUNCTION.thistype);
- break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_FIELDLIST:
- TagChildren(typeTable, record, setName);
- break;
- default:
- break;
- }
-}
-
-// This example takes a PDB's TPI stream and prints out a CSV file that contains all records in the TPI stream.
-// You can use it to figure out what's taking up space in the stream.
-//
-// The format of the CSV is Size; Kind; Name. "Size" is the size of the record in bytes, "Kind" is the kind of
-// the entry, and "Name" is a name associated with this entry.Type - definitions, member functions, and member
-// lists use their type as the name. The idea is that you can bucket by "Name" to get actionable information
-//and insight.
-//
-// The Name is set to "???" if no name was found, and it is set to "!!!" if multiple names reference the entry.
-void ExampleTPISize(const PDB::TPIStream& tpiStream, const char* outPath);
-void ExampleTPISize(const PDB::TPIStream& tpiStream, const char* outPath)
-{
- TimedScope total("\nRunning example \"TPI Size\"");
-
- FILE* f;
-#ifndef __unix
- fopen_s(&f, outPath, "w");
-#else
- f = fopen(outPath, "w");
-#endif
- PDB_ASSERT(f, "Failed to open %s for writing", outPath);
-
- fprintf(f, "Size;Kind;Name\n");
-
- TimedScope typeTableScope("Create TypeTable");
- TypeTable typeTable(tpiStream);
- typeTableScope.Done();
-
- std::vector names;
- names.resize(typeTable.GetTypeRecords().GetLength());
-
- const size_t minIndex = typeTable.GetFirstTypeIndex();
- // sets the name of an entry and returns whether the name changed (because it wasn't set, or because we've found
- // conflicting information).
- auto setNameGlobal = [&names, minIndex](uint32_t typeIndex, const char* name) -> bool {
- if (!name || typeIndex < minIndex)
- return false;
- size_t idx = typeIndex - minIndex;
- const char* prev = names[idx];
- if (names[idx] == nullptr)
- {
- names[idx] = name;
- return true;
- }
- else
- {
- names[idx] = "!!!"; // multiple references
- return names[idx] != prev;
- }
- };
-
- // collect base types and propagate their name
- auto typeRecords = typeTable.GetTypeRecords();
- for (size_t i = 0, n = typeRecords.GetLength(); i < n; i++)
- {
- const PDB::CodeView::TPI::Record* record = typeRecords[i];
- PDB::CodeView::TPI::TypeRecordKind kind = record->header.kind;
- if (kind == PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE)
- {
- names[i] = GetLeafName(record->data.LF_CLASS.data, record->data.LF_CLASS.lfEasy.kind);
- auto setName = [&setNameGlobal, names, i](uint32_t typeIndex) -> bool {
- return setNameGlobal(typeIndex, names[i]);
- };
- TAG_AND_CHECK(record->data.LF_CLASS.field);
- }
- else if (kind == PDB::CodeView::TPI::TypeRecordKind::LF_CLASS)
- {
- names[i] = GetLeafName(record->data.LF_CLASS.data, record->data.LF_CLASS.lfEasy.kind);
- auto setName = [&setNameGlobal, names, i](uint32_t typeIndex) -> bool {
- return setNameGlobal(typeIndex, names[i]);
- };
- TAG_AND_CHECK(record->data.LF_CLASS.field);
- }
- else if (kind == PDB::CodeView::TPI::TypeRecordKind::LF_UNION)
- {
- names[i] = GetLeafName(record->data.LF_UNION.data, static_cast(0));
- auto setName = [&setNameGlobal, names, i](uint32_t typeIndex) -> bool {
- return setNameGlobal(typeIndex, names[i]);
- };
- TAG_AND_CHECK(record->data.LF_UNION.field);
- }
- else if (kind == PDB::CodeView::TPI::TypeRecordKind::LF_ENUM)
- {
- names[i] = record->data.LF_ENUM.name;
- auto setName = [&setNameGlobal, names, i](uint32_t typeIndex) -> bool {
- return setNameGlobal(typeIndex, names[i]);
- };
- TAG_AND_CHECK(record->data.LF_ENUM.field);
- }
- else if (kind == PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION)
- {
- const char* name = names[i];
- if (!name)
- {
- const PDB::CodeView::TPI::Record* containingRecord = typeTable.GetTypeRecord((record->data.LF_MFUNCTION.classtype));
- if (containingRecord) {
- if (containingRecord->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_CLASS ||
- containingRecord->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE)
- name = GetLeafName(containingRecord->data.LF_CLASS.data, containingRecord->data.LF_CLASS.lfEasy.kind);
- else if (containingRecord->header.kind == PDB::CodeView::TPI::TypeRecordKind::LF_UNION)
- name = GetLeafName(record->data.LF_UNION.data, static_cast(0));
- else
- PDB_ASSERT(false, "unsupported");
- }
- }
- auto setName = [&setNameGlobal, name](uint32_t typeIndex) -> bool {
- return setNameGlobal(typeIndex, name);
- };
- uint32_t typeIndex = (uint32_t)(minIndex + i);
- TAG_AND_CHECK(typeIndex);
- }
- }
-
- for (size_t i = 0, n = typeRecords.GetLength(); i < n; i++)
- {
- const PDB::CodeView::TPI::Record* record = typeRecords[i];
- const char* kindName = nullptr;
- const char* typeName = i < names.size() ? names[i] : nullptr;
- switch (record->header.kind)
- {
- case PDB::CodeView::TPI::TypeRecordKind::LF_VTSHAPE: kindName = "LF_VTSHAPE;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_POINTER: kindName = "LF_POINTER;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_MODIFIER: kindName = "LF_MODIFIER;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE: kindName = "LF_PROCEDURE;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_FIELDLIST: kindName = "LF_FIELDLIST;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_LABEL: kindName = "LF_LABEL;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARGLIST: kindName = "LF_ARGLIST;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_BITFIELD: kindName = "LF_BITFIELD;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_METHODLIST: kindName = "LF_METHODLIST;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_ARRAY: kindName = "LF_ARRAY;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_PRECOMP: kindName = "LF_PRECOMP;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION: kindName = "LF_MFUNCTION;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE: kindName = "LF_STRUCTURE;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_CLASS: kindName = "LF_CLASS;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_UNION: kindName = "LF_UNION;"; break;
- case PDB::CodeView::TPI::TypeRecordKind::LF_ENUM: kindName = "LF_ENUM;"; break;
- default: break;
- }
-
- fprintf(f, "%hu;", 2 + record->header.size);
- if (kindName)
- fprintf(f, "%s;", kindName);
- else
- fprintf(f, "0x%04X;", static_cast(record->header.kind));
-
- if (typeName)
- fprintf(f, "%s\n", typeName);
- else
- fprintf(f, "???\n");
- }
-
- fclose(f);
- total.Done(tpiStream.GetTypeRecordCount());
-}
-#undef TAG_AND_CHECK
diff --git a/third_party/raw_pdb/src/Examples/Examples_PCH.cpp b/third_party/raw_pdb/src/Examples/Examples_PCH.cpp
deleted file mode 100644
index 993ae7d..0000000
--- a/third_party/raw_pdb/src/Examples/Examples_PCH.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "Examples_PCH.h"
diff --git a/third_party/raw_pdb/src/Examples/Examples_PCH.h b/third_party/raw_pdb/src/Examples/Examples_PCH.h
deleted file mode 100644
index 0a7f2e2..0000000
--- a/third_party/raw_pdb/src/Examples/Examples_PCH.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "Foundation/PDB_Warnings.h"
-
-// The following clang warnings must be disabled for the examples to build with 0 warnings
-#if PDB_COMPILER_CLANG
-# pragma clang diagnostic ignored "-Wformat-nonliteral" // format string is not a string literal
-# pragma clang diagnostic ignored "-Wswitch-default" // switch' missing 'default' label
-# pragma clang diagnostic ignored "-Wcast-align" // increases required alignment from X to Y
-# pragma clang diagnostic ignored "-Wold-style-cast" // use of old-style cast
-#endif
-
-#if PDB_COMPILER_MSVC
-# pragma warning(push, 0)
-#elif PDB_COMPILER_CLANG
-# pragma clang diagnostic push
-#endif
-
-#if PDB_COMPILER_MSVC
- // we compile without exceptions
-# define _ALLOW_RTCc_IN_STL
-
- // triggered by Windows.h
-# pragma warning (disable : 4668)
-
- // triggered by xlocale in VS 2017
-# pragma warning (disable : 4625) // copy constructor was implicitly defined as deleted
-# pragma warning (disable : 4626) // assignment operator was implicitly defined as deleted
-# pragma warning (disable : 5026) // move constructor was implicitly defined as deleted
-# pragma warning (disable : 5027) // move assignment operator was implicitly defined as deleted
-# pragma warning (disable : 4774) // format string expected in argument 1 is not a string literal
-#endif
-
-#ifdef _WIN32
-# define NOMINMAX
-# include
-# undef cdecl
-#endif
-# include
-# include
-# include
-# include
-# include
-# include
-
-#if PDB_COMPILER_MSVC
-# pragma warning(pop)
-#elif PDB_COMPILER_CLANG
-# pragma clang diagnostic pop
-#endif
diff --git a/third_party/raw_pdb/src/Foundation/PDB_ArrayView.h b/third_party/raw_pdb/src/Foundation/PDB_ArrayView.h
deleted file mode 100644
index 3c462ee..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_ArrayView.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Macros.h"
-#include "PDB_Assert.h"
-
-
-namespace PDB
-{
- // A read-only view into arrays of any type and length.
- template
- class PDB_NO_DISCARD ArrayView
- {
- public:
- // Constructs an array view from a C array with explicit length.
- inline constexpr explicit ArrayView(const T* const array, size_t length) PDB_NO_EXCEPT
- : m_data(array)
- , m_length(length)
- {
- }
-
- PDB_DEFAULT_COPY_CONSTRUCTOR(ArrayView);
- PDB_DEFAULT_MOVE_CONSTRUCTOR(ArrayView);
-
- // Provides read-only access to the underlying array.
- PDB_NO_DISCARD inline constexpr const T* Decay(void) const PDB_NO_EXCEPT
- {
- return m_data;
- }
-
- // Returns the length of the view.
- PDB_NO_DISCARD inline constexpr size_t GetLength(void) const PDB_NO_EXCEPT
- {
- return m_length;
- }
-
- // Returns the i-th element.
- PDB_NO_DISCARD inline const T& operator[](size_t i) const PDB_NO_EXCEPT
- {
- PDB_ASSERT(i < GetLength(), "Index %zu out of bounds [0, %zu).", i, GetLength());
- return m_data[i];
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // Range-based for-loop support
- // ------------------------------------------------------------------------------------------------
-
- PDB_NO_DISCARD inline const T* begin(void) const PDB_NO_EXCEPT
- {
- return m_data;
- }
-
- PDB_NO_DISCARD inline const T* end(void) const PDB_NO_EXCEPT
- {
- return m_data + m_length;
- }
-
- private:
- const T* const m_data;
- const size_t m_length;
-
- PDB_DISABLE_MOVE_ASSIGNMENT(ArrayView);
- PDB_DISABLE_COPY_ASSIGNMENT(ArrayView);
- };
-}
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Assert.h b/third_party/raw_pdb/src/Foundation/PDB_Assert.h
deleted file mode 100644
index cef2116..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Assert.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Macros.h"
-#include "PDB_Log.h"
-
-
-PDB_PUSH_WARNING_CLANG
-PDB_DISABLE_WARNING_CLANG("-Wgnu-zero-variadic-macro-arguments")
-PDB_DISABLE_WARNING_CLANG("-Wreserved-identifier")
-
-#if PDB_COMPILER_MSVC
-extern "C" void __cdecl __debugbreak(void);
-# pragma intrinsic(__debugbreak)
-#elif defined(__has_builtin) && __has_builtin(__builtin_debugtrap)
-# define __debugbreak() __builtin_debugtrap()
-#else
-# include
-# define __debugbreak() raise(SIGTRAP)
-#endif
-
-
-#ifdef _DEBUG
-# define PDB_ASSERT(_condition, _msg, ...) (_condition) ? (void)true : (PDB_LOG_ERROR(_msg, ##__VA_ARGS__), __debugbreak())
-#else
-# define PDB_ASSERT(_condition, _msg, ...) PDB_NOOP(_condition, _msg, ##__VA_ARGS__)
-#endif
-
-PDB_POP_WARNING_CLANG
diff --git a/third_party/raw_pdb/src/Foundation/PDB_BitOperators.h b/third_party/raw_pdb/src/Foundation/PDB_BitOperators.h
deleted file mode 100644
index 04f17a4..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_BitOperators.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Macros.h"
-
-
-#define PDB_DEFINE_BIT_OPERATORS(_type) \
- PDB_NO_DISCARD inline constexpr _type operator|(_type lhs, _type rhs) PDB_NO_EXCEPT \
- { \
- return static_cast<_type>(PDB_AS_UNDERLYING(lhs) | PDB_AS_UNDERLYING(rhs)); \
- } \
- \
- PDB_NO_DISCARD inline constexpr _type operator&(_type lhs, _type rhs) PDB_NO_EXCEPT \
- { \
- return static_cast<_type>(PDB_AS_UNDERLYING(lhs) & PDB_AS_UNDERLYING(rhs)); \
- } \
- \
- PDB_NO_DISCARD inline constexpr _type operator~(_type value) PDB_NO_EXCEPT \
- { \
- return static_cast<_type>(~PDB_AS_UNDERLYING(value)); \
- }
diff --git a/third_party/raw_pdb/src/Foundation/PDB_BitUtil.h b/third_party/raw_pdb/src/Foundation/PDB_BitUtil.h
deleted file mode 100644
index 7dc5ee3..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_BitUtil.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Assert.h"
-
-#ifdef _WIN32
- PDB_PUSH_WARNING_CLANG
- PDB_DISABLE_WARNING_CLANG("-Wreserved-identifier")
-
- extern "C" unsigned char _BitScanForward(unsigned long* _Index, unsigned long _Mask);
-
- PDB_POP_WARNING_CLANG
-
-# if PDB_COMPILER_MSVC
-# pragma intrinsic(_BitScanForward)
-# endif
-#endif
-
-
-namespace PDB
-{
- namespace BitUtil
- {
- // Returns whether the given unsigned value is a power of two.
- template
- PDB_NO_DISCARD inline constexpr bool IsPowerOfTwo(T value) PDB_NO_EXCEPT
- {
- PDB_ASSERT(value != 0u, "Invalid value.");
-
- return (value & (value - 1u)) == 0u;
- }
-
-
- // Rounds the given unsigned value up to the next multiple.
- template
- PDB_NO_DISCARD inline constexpr T RoundUpToMultiple(T numToRound, T multipleOf) PDB_NO_EXCEPT
- {
- PDB_ASSERT(IsPowerOfTwo(multipleOf), "Multiple must be a power-of-two.");
-
- return (numToRound + (multipleOf - 1u)) & ~(multipleOf - 1u);
- }
-
-
- // Finds the position of the first set bit in the given value starting from the LSB, e.g. FindFirstSetBit(0b00000010) == 1.
- // This operation is also known as CTZ (Count Trailing Zeros).
- template
- PDB_NO_DISCARD inline uint32_t FindFirstSetBit(T value) PDB_NO_EXCEPT;
-
- template <>
- PDB_NO_DISCARD inline uint32_t FindFirstSetBit(uint32_t value) PDB_NO_EXCEPT
- {
- PDB_ASSERT(value != 0u, "Invalid value.");
-
-#ifdef _WIN32
- unsigned long result = 0ul;
-
- _BitScanForward(&result, value);
-#else
- unsigned int result = 0u;
-
- result = static_cast(__builtin_ffs(static_cast(value)));
- if (result)
- {
- --result;
- }
-#endif
-
- return result;
- }
- }
-}
diff --git a/third_party/raw_pdb/src/Foundation/PDB_CRT.h b/third_party/raw_pdb/src/Foundation/PDB_CRT.h
deleted file mode 100644
index a7df4aa..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_CRT.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-// Original raw_pdb forward-declares CRT functions to avoid pulling in headers,
-// but this conflicts with MinGW's headers when compiled alongside Qt.
-// Include the real headers instead.
-#include
-#include
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Forward.h b/third_party/raw_pdb/src/Foundation/PDB_Forward.h
deleted file mode 100644
index ba82dfe..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Forward.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-
-// See Jonathan Mueller's blog for replacing std::move and std::forward:
-// https://foonathan.net/2021/09/move-forward/
-#define PDB_FORWARD(...) static_cast(__VA_ARGS__)
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Log.h b/third_party/raw_pdb/src/Foundation/PDB_Log.h
deleted file mode 100644
index 83a8518..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Log.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Macros.h"
-#include "PDB_CRT.h"
-
-
-PDB_PUSH_WARNING_CLANG
-PDB_DISABLE_WARNING_CLANG("-Wgnu-zero-variadic-macro-arguments")
-
-#define PDB_LOG_ERROR(_format, ...) printf(_format, ##__VA_ARGS__)
-
-PDB_POP_WARNING_CLANG
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Macros.h b/third_party/raw_pdb/src/Foundation/PDB_Macros.h
deleted file mode 100644
index fddcccf..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Macros.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Platform.h"
-#include "PDB_TypeTraits.h"
-
-
-// ------------------------------------------------------------------------------------------------
-// ATTRIBUTES
-// ------------------------------------------------------------------------------------------------
-
-// Indicates to the compiler that the return value of a function or class should not be ignored.
-#if PDB_CPP_17
-# define PDB_NO_DISCARD [[nodiscard]]
-#else
-# define PDB_NO_DISCARD
-#endif
-
-// Indicates to the compiler that a function does not throw an exception.
-#define PDB_NO_EXCEPT noexcept
-
-
-// ------------------------------------------------------------------------------------------------
-// SPECIAL MEMBER FUNCTIONS
-// ------------------------------------------------------------------------------------------------
-
-// Default special member functions.
-#define PDB_DEFAULT_COPY_CONSTRUCTOR(_name) _name(const _name&) PDB_NO_EXCEPT = default
-#define PDB_DEFAULT_COPY_ASSIGNMENT(_name) _name& operator=(const _name&) PDB_NO_EXCEPT = default
-#define PDB_DEFAULT_MOVE_CONSTRUCTOR(_name) _name(_name&&) PDB_NO_EXCEPT = default
-#define PDB_DEFAULT_MOVE_ASSIGNMENT(_name) _name& operator=(_name&&) PDB_NO_EXCEPT = default
-
-// Default copy member functions.
-#define PDB_DEFAULT_COPY(_name) PDB_DEFAULT_COPY_CONSTRUCTOR(_name); PDB_DEFAULT_COPY_ASSIGNMENT(_name)
-
-// Default move member functions.
-#define PDB_DEFAULT_MOVE(_name) PDB_DEFAULT_MOVE_CONSTRUCTOR(_name); PDB_DEFAULT_MOVE_ASSIGNMENT(_name)
-
-// Single macro to default all copy and move member functions.
-#define PDB_DEFAULT_COPY_MOVE(_name) PDB_DEFAULT_COPY(_name); PDB_DEFAULT_MOVE(_name)
-
-// Disable special member functions.
-#define PDB_DISABLE_COPY_CONSTRUCTOR(_name) _name(const _name&) PDB_NO_EXCEPT = delete
-#define PDB_DISABLE_COPY_ASSIGNMENT(_name) _name& operator=(const _name&) PDB_NO_EXCEPT = delete
-#define PDB_DISABLE_MOVE_CONSTRUCTOR(_name) _name(_name&&) PDB_NO_EXCEPT = delete
-#define PDB_DISABLE_MOVE_ASSIGNMENT(_name) _name& operator=(_name&&) PDB_NO_EXCEPT = delete
-
-// Disable copy member functions.
-#define PDB_DISABLE_COPY(_name) PDB_DISABLE_COPY_CONSTRUCTOR(_name); PDB_DISABLE_COPY_ASSIGNMENT(_name)
-
-// Disable move member functions.
-#define PDB_DISABLE_MOVE(_name) PDB_DISABLE_MOVE_CONSTRUCTOR(_name); PDB_DISABLE_MOVE_ASSIGNMENT(_name)
-
-// Single macro to disable all copy and move member functions.
-#define PDB_DISABLE_COPY_MOVE(_name) PDB_DISABLE_COPY(_name); PDB_DISABLE_MOVE(_name)
-
-
-// ------------------------------------------------------------------------------------------------
-// COMPILER WARNINGS
-// ------------------------------------------------------------------------------------------------
-
-#if PDB_COMPILER_MSVC
-# define PDB_PRAGMA(_x) __pragma(_x)
-
-# define PDB_PUSH_WARNING_MSVC PDB_PRAGMA(warning(push))
-# define PDB_SUPPRESS_WARNING_MSVC(_number) PDB_PRAGMA(warning(suppress : _number))
-# define PDB_DISABLE_WARNING_MSVC(_number) PDB_PRAGMA(warning(disable : _number))
-# define PDB_POP_WARNING_MSVC PDB_PRAGMA(warning(pop))
-
-# define PDB_PUSH_WARNING_CLANG
-# define PDB_DISABLE_WARNING_CLANG(_diagnostic)
-# define PDB_POP_WARNING_CLANG
-#elif PDB_COMPILER_CLANG
-# define PDB_PRAGMA(_x) _Pragma(#_x)
-
-# define PDB_PUSH_WARNING_MSVC
-# define PDB_SUPPRESS_WARNING_MSVC(_number)
-# define PDB_DISABLE_WARNING_MSVC(_number)
-# define PDB_POP_WARNING_MSVC
-
-# define PDB_PUSH_WARNING_CLANG PDB_PRAGMA(clang diagnostic push)
-# define PDB_DISABLE_WARNING_CLANG(_diagnostic) PDB_PRAGMA(clang diagnostic ignored _diagnostic)
-# define PDB_POP_WARNING_CLANG PDB_PRAGMA(clang diagnostic pop)
-#elif PDB_COMPILER_GCC
-# define PDB_PRAGMA(_x) _Pragma(#_x)
-
-# define PDB_PUSH_WARNING_MSVC
-# define PDB_SUPPRESS_WARNING_MSVC(_number)
-# define PDB_DISABLE_WARNING_MSVC(_number)
-# define PDB_POP_WARNING_MSVC
-
-# define PDB_PUSH_WARNING_CLANG
-# define PDB_DISABLE_WARNING_CLANG(_diagnostic)
-# define PDB_POP_WARNING_CLANG
-#endif
-
-
-// ------------------------------------------------------------------------------------------------
-// MISCELLANEOUS
-// ------------------------------------------------------------------------------------------------
-
-// Trick to make other macros require a semicolon at the end.
-#define PDB_REQUIRE_SEMICOLON static_assert(true, "")
-
-// Defines a C-like flexible array member.
-#define PDB_FLEXIBLE_ARRAY_MEMBER(_type, _name) \
- PDB_PUSH_WARNING_MSVC \
- PDB_PUSH_WARNING_CLANG \
- PDB_DISABLE_WARNING_MSVC(4200) \
- PDB_DISABLE_WARNING_CLANG("-Wzero-length-array") \
- _type _name[0]; \
- PDB_POP_WARNING_MSVC \
- PDB_POP_WARNING_CLANG \
- PDB_REQUIRE_SEMICOLON
-
-// Casts any value to the value of the underlying type.
-#define PDB_AS_UNDERLYING(_value) static_cast::type>(_value)
-
-// Signals to the compiler that a function should be ignored, but have its argument list parsed (and "used", so as to not generate "unused variable" warnings).
-#if PDB_COMPILER_MSVC
-# define PDB_NOOP __noop
-#else
-# define PDB_NOOP(...) (void)sizeof(__VA_ARGS__)
-#endif
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Memory.h b/third_party/raw_pdb/src/Foundation/PDB_Memory.h
deleted file mode 100644
index ccb7e86..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Memory.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-
-#define PDB_NEW(_type) new _type
-#define PDB_NEW_ARRAY(_type, _length) new _type[_length]
-
-#define PDB_DELETE(_ptr) delete _ptr
-#define PDB_DELETE_ARRAY(_ptr) delete[] _ptr
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Move.h b/third_party/raw_pdb/src/Foundation/PDB_Move.h
deleted file mode 100644
index 04bf78b..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Move.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_TypeTraits.h"
-
-
-// See Jonathan Mueller's blog for replacing std::move and std::forward:
-// https://foonathan.net/2020/09/move-forward/
-#define PDB_MOVE(...) static_cast::type&&>(__VA_ARGS__)
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Platform.h b/third_party/raw_pdb/src/Foundation/PDB_Platform.h
deleted file mode 100644
index 8775a54..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Platform.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-
-// determine the compiler/toolchain used
-#if defined(__clang__)
-# define PDB_COMPILER_MSVC 0
-# define PDB_COMPILER_CLANG 1
-# define PDB_COMPILER_GCC 0
-#elif defined(_MSC_VER)
-# define PDB_COMPILER_MSVC 1
-# define PDB_COMPILER_CLANG 0
-# define PDB_COMPILER_GCC 0
-#elif defined(__GNUC__)
-# define PDB_COMPILER_MSVC 0
-# define PDB_COMPILER_CLANG 0
-# define PDB_COMPILER_GCC 1
-#else
-# error("Unknown compiler.");
-#endif
-
-// check whether C++17 is available
-#if __cplusplus >= 201703L
-# define PDB_CPP_17 1
-#else
-# define PDB_CPP_17 0
-#endif
-
-// define used standard types
-typedef decltype(sizeof(0)) size_t;
-static_assert(sizeof(sizeof(0)) == sizeof(size_t), "Wrong size.");
-
-typedef int int32_t;
-static_assert(sizeof(int32_t) == 4u, "Wrong size.");
-
-typedef unsigned char uint8_t;
-static_assert(sizeof(uint8_t) == 1u, "Wrong size.");
-
-typedef unsigned short uint16_t;
-static_assert(sizeof(uint16_t) == 2u, "Wrong size.");
-
-typedef unsigned int uint32_t;
-static_assert(sizeof(uint32_t) == 4u, "Wrong size.");
diff --git a/third_party/raw_pdb/src/Foundation/PDB_PointerUtil.h b/third_party/raw_pdb/src/Foundation/PDB_PointerUtil.h
deleted file mode 100644
index 014297d..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_PointerUtil.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Macros.h"
-#include "PDB_TypeTraits.h"
-
-
-namespace PDB
-{
- namespace Pointer
- {
- // Offsets any pointer by a given number of bytes.
- template
- PDB_NO_DISCARD inline T Offset(U* anyPointer, V howManyBytes) PDB_NO_EXCEPT
- {
- static_assert(PDB::is_pointer::value == true, "Type T must be a pointer type.");
-
- union
- {
- T as_T;
- U* as_U_ptr;
- char* as_char_ptr;
- };
-
- as_U_ptr = anyPointer;
- as_char_ptr += howManyBytes;
-
- return as_T;
- }
- }
-}
diff --git a/third_party/raw_pdb/src/Foundation/PDB_TypeTraits.h b/third_party/raw_pdb/src/Foundation/PDB_TypeTraits.h
deleted file mode 100644
index 9286453..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_TypeTraits.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-
-// provide our own type traits to avoid pulling in unnecessary includes
-namespace PDB
-{
- template
- struct is_pointer
- {
- static constexpr bool value = false;
- };
-
- template
- struct is_pointer
- {
- static constexpr bool value = true;
- };
-
- template
- struct is_pointer
- {
- static constexpr bool value = true;
- };
-
- template
- struct is_pointer
- {
- static constexpr bool value = true;
- };
-
- template
- struct is_pointer
- {
- static constexpr bool value = true;
- };
-
-
- template
- struct remove_reference
- {
- using type = T;
- };
-
- template
- struct remove_reference
- {
- using type = T;
- };
-
- template
- struct remove_reference
- {
- using type = T;
- };
-
-
- template
- struct underlying_type
- {
- using type = __underlying_type(T);
- };
-}
diff --git a/third_party/raw_pdb/src/Foundation/PDB_Warnings.h b/third_party/raw_pdb/src/Foundation/PDB_Warnings.h
deleted file mode 100644
index fbc8a9d..0000000
--- a/third_party/raw_pdb/src/Foundation/PDB_Warnings.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "PDB_Platform.h"
-
-#if PDB_COMPILER_MSVC
- // some warnings were introduced with different versions of Visual Studio, so we disable this warning instead of using a bunch of #if/#endif
-# pragma warning (disable : 4619) // there is no warning number N
-
- // we compile with exceptions disabled
-# pragma warning (disable : 4530) // C++ exception handler used, but unwind semantics are not enabled.Specify / EHsc
-# pragma warning (disable : 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
-
- // ignore purely informational warnings
-# pragma warning (disable : 4514) // unreferenced inline function has been removed
-# pragma warning (disable : 4710) // function not inlined
-# pragma warning (disable : 4711) // function selected for automatic inline expansion
-# pragma warning (disable : 4820) // 'N' bytes padding added after data member 'm_member'
-# pragma warning (disable : 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
-#elif PDB_COMPILER_CLANG
- // turn on absolutely all available Clang warnings
-# pragma clang diagnostic warning "-Wall"
-# pragma clang diagnostic warning "-Wextra"
-# pragma clang diagnostic warning "-Weverything"
-# pragma clang diagnostic warning "-Wpedantic"
-
- // these warnings contradict -Weverything
-# pragma clang diagnostic ignored "-Wc++98-compat"
-# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
-
- // this warning is triggered for templates which are explicitly instantiated.
- // forgetting to instantiate the template would trigger a linker error anyway, so we disable this warning.
-# pragma clang diagnostic ignored "-Wundefined-func-template"
-
- // we don't strive for C++20 compatibility
-# pragma clang diagnostic ignored "-Wc++20-compat"
-
- // some structures will have to be padded
-# pragma clang diagnostic ignored "-Wpadded"
-
- // it's impossible to write C++ code using raw pointers without triggering this warning
-# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
-#endif
diff --git a/third_party/raw_pdb/src/PDB.cpp b/third_party/raw_pdb/src/PDB.cpp
deleted file mode 100644
index 0bbd3a7..0000000
--- a/third_party/raw_pdb/src/PDB.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "PDB_PCH.h"
-#include "PDB.h"
-#include "PDB_Types.h"
-#include "PDB_Util.h"
-#include "PDB_RawFile.h"
-#include "Foundation/PDB_PointerUtil.h"
-#include "Foundation/PDB_CRT.h"
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB_NO_DISCARD PDB::ErrorCode PDB::ValidateFile(const void* data, size_t size) PDB_NO_EXCEPT
-{
- // validate whether there is enough size for the super block
- if (size < sizeof(SuperBlock))
- {
- return ErrorCode::InvalidDataSize;
- }
- // validate the super block
- const SuperBlock* superBlock = Pointer::Offset(data, 0u);
- {
- // validate header magic
- if (memcmp(superBlock->fileMagic, SuperBlock::MAGIC, sizeof(SuperBlock::MAGIC)) != 0)
- {
- return ErrorCode::InvalidSuperBlock;
- }
-
- // validate whether enough size is provided for the PDB file
- // blockCount * blockSize is the size of the PDB file on disk
- if (size < superBlock->blockCount * superBlock->blockSize)
- {
- return ErrorCode::InvalidDataSize;
- }
-
- // validate free block map.
- // the free block map should always reside at either index 1 or 2.
- if (superBlock->freeBlockMapIndex != 1u && superBlock->freeBlockMapIndex != 2u)
- {
- return ErrorCode::InvalidFreeBlockMap;
- }
- }
-
- return ErrorCode::Success;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB_NO_DISCARD PDB::RawFile PDB::CreateRawFile(const void* data) PDB_NO_EXCEPT
-{
- return RawFile(data);
-}
diff --git a/third_party/raw_pdb/src/PDB.h b/third_party/raw_pdb/src/PDB.h
deleted file mode 100644
index 3f17f9f..0000000
--- a/third_party/raw_pdb/src/PDB.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "Foundation/PDB_Macros.h"
-#include "PDB_ErrorCodes.h"
-
-
-// https://llvm.org/docs/PDB/index.html
-namespace PDB
-{
- class RawFile;
-
-
- // Validates whether a PDB file is valid.
- PDB_NO_DISCARD ErrorCode ValidateFile(const void* data, size_t size) PDB_NO_EXCEPT;
-
- // Creates a raw PDB file that must have been validated.
- PDB_NO_DISCARD RawFile CreateRawFile(const void* data) PDB_NO_EXCEPT;
-}
diff --git a/third_party/raw_pdb/src/PDB_CoalescedMSFStream.cpp b/third_party/raw_pdb/src/PDB_CoalescedMSFStream.cpp
deleted file mode 100644
index fe544e4..0000000
--- a/third_party/raw_pdb/src/PDB_CoalescedMSFStream.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "PDB_PCH.h"
-#include "PDB_CoalescedMSFStream.h"
-#include "PDB_Util.h"
-#include "PDB_DirectMSFStream.h"
-#include "Foundation/PDB_PointerUtil.h"
-#include "Foundation/PDB_Memory.h"
-#include "Foundation/PDB_CRT.h"
-
-
-namespace
-{
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static bool AreBlockIndicesContiguous(const uint32_t* blockIndices, uint32_t blockSize, uint32_t streamSize) PDB_NO_EXCEPT
- {
- const uint32_t blockCount = PDB::ConvertSizeToBlockCount(streamSize, blockSize);
-
- // start with the first index, checking if all following indices are contiguous (N, N+1, N+2, ...)
- uint32_t expectedIndex = blockIndices[0];
- for (uint32_t i = 1u; i < blockCount; ++i)
- {
- ++expectedIndex;
- if (blockIndices[i] != expectedIndex)
- {
- return false;
- }
- }
-
- return true;
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream::CoalescedMSFStream(void) PDB_NO_EXCEPT
- : m_ownedData(nullptr)
- , m_data(nullptr)
- , m_size(0u)
-{
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream::CoalescedMSFStream(CoalescedMSFStream&& other) PDB_NO_EXCEPT
- : m_ownedData(PDB_MOVE(other.m_ownedData))
- , m_data(PDB_MOVE(other.m_data))
- , m_size(PDB_MOVE(other.m_size))
-{
- other.m_ownedData = nullptr;
- other.m_data = nullptr;
- other.m_size = 0u;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream& PDB::CoalescedMSFStream::operator=(CoalescedMSFStream&& other) PDB_NO_EXCEPT
-{
- if (this != &other)
- {
- PDB_DELETE_ARRAY(m_ownedData);
-
- m_ownedData = PDB_MOVE(other.m_ownedData);
- m_data = PDB_MOVE(other.m_data);
- m_size = PDB_MOVE(other.m_size);
-
- other.m_ownedData = nullptr;
- other.m_data = nullptr;
- other.m_size = 0u;
- }
-
- return *this;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream::CoalescedMSFStream(const void* data, uint32_t blockSize, const uint32_t* blockIndices, uint32_t streamSize) PDB_NO_EXCEPT
- : m_ownedData(nullptr)
- , m_data(nullptr)
- , m_size(streamSize)
-{
- if (AreBlockIndicesContiguous(blockIndices, blockSize, streamSize))
- {
- // fast path, all block indices are contiguous, so we don't have to copy any data at all.
- // instead, we directly point into the memory-mapped file at the correct offset.
- const uint32_t index = blockIndices[0];
- const size_t fileOffset = PDB::ConvertBlockIndexToFileOffset(index, blockSize);
- m_data = Pointer::Offset(data, fileOffset);
- }
- else
- {
- // slower path, we need to copy disjunct blocks into our own data array, block by block
- m_ownedData = PDB_NEW_ARRAY(Byte, streamSize);
- m_data = m_ownedData;
-
- Byte* destination = m_ownedData;
-
- // copy full blocks first
- const uint32_t fullBlockCount = streamSize / blockSize;
- for (uint32_t i = 0u; i < fullBlockCount; ++i)
- {
- const uint32_t index = blockIndices[i];
-
- // read one single block at the correct offset in the stream
- const size_t fileOffset = PDB::ConvertBlockIndexToFileOffset(index, blockSize);
- const void* sourceData = Pointer::Offset(data, fileOffset);
- memcpy(destination, sourceData, blockSize);
-
- destination += blockSize;
- }
-
- // account for non-full blocks
- const uint32_t remainingBytes = streamSize - (fullBlockCount * blockSize);
- if (remainingBytes != 0u)
- {
- const uint32_t index = blockIndices[fullBlockCount];
-
- // read remaining bytes at correct offset in the stream
- const size_t fileOffset = PDB::ConvertBlockIndexToFileOffset(index, blockSize);
- const void* sourceData = Pointer::Offset(data, fileOffset);
- memcpy(destination, sourceData, remainingBytes);
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream::CoalescedMSFStream(const DirectMSFStream& directStream, uint32_t size, uint32_t offset) PDB_NO_EXCEPT
- : m_ownedData(nullptr)
- , m_data(nullptr)
- , m_size(size)
-{
- const DirectMSFStream::IndexAndOffset indexAndOffset = directStream.GetBlockIndexForOffset(offset);
-
- // Note: we need to add the offset within the block to the size of the stream to determine if the block
- // indices are contiguous. This is needed to deal with the case where reading the requested number of bytes
- // from the specified offset would cross a block boundary. For example, if the offset within the block is
- // 64 and we want to read 4096 bytes with a block size of 4096, we need to consider *two* block indices,
- // not *one*, even though 4096 / 4096 = 1.
- if (AreBlockIndicesContiguous(directStream.GetBlockIndices() + indexAndOffset.index, directStream.GetBlockSize(), indexAndOffset.offsetWithinBlock + size))
- {
- // fast path, all block indices inside the direct stream from (data + offset) to (data + offset + size) are contiguous
- const size_t offsetWithinData = directStream.GetDataOffsetForIndexAndOffset(indexAndOffset);
- m_data = Pointer::Offset(directStream.GetData(), offsetWithinData);
- }
- else
- {
- // slower path, we need to copy from disjunct blocks, which is performed by the direct stream
- m_ownedData = PDB_NEW_ARRAY(Byte, size);
- m_data = m_ownedData;
-
- directStream.ReadAtOffset(m_ownedData, size, offset);
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::CoalescedMSFStream::~CoalescedMSFStream(void) PDB_NO_EXCEPT
-{
- PDB_DELETE_ARRAY(m_ownedData);
-}
diff --git a/third_party/raw_pdb/src/PDB_CoalescedMSFStream.h b/third_party/raw_pdb/src/PDB_CoalescedMSFStream.h
deleted file mode 100644
index 09d524c..0000000
--- a/third_party/raw_pdb/src/PDB_CoalescedMSFStream.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#pragma once
-
-#include "Foundation/PDB_Assert.h"
-#include "Foundation/PDB_Macros.h"
-#include "PDB_Types.h"
-
-// https://llvm.org/docs/PDB/index.html#the-msf-container
-// https://llvm.org/docs/PDB/MsfFile.html
-namespace PDB
-{
- class PDB_NO_DISCARD DirectMSFStream;
-
-
- // provides access to a coalesced version of an MSF stream.
- // inherently thread-safe, the stream doesn't carry any internal offset or similar.
- // coalesces all blocks into a contiguous stream of data upon construction.
- // very fast individual reads, useful when almost all data of a stream is needed anyway.
- class PDB_NO_DISCARD CoalescedMSFStream
- {
- public:
- CoalescedMSFStream(void) PDB_NO_EXCEPT;
- CoalescedMSFStream(CoalescedMSFStream&& other) PDB_NO_EXCEPT;
- CoalescedMSFStream& operator=(CoalescedMSFStream&& other) PDB_NO_EXCEPT;
-
- explicit CoalescedMSFStream(const void* data, uint32_t blockSize, const uint32_t* blockIndices, uint32_t streamSize) PDB_NO_EXCEPT;
-
- // Creates a coalesced stream from a direct stream at any offset.
- explicit CoalescedMSFStream(const DirectMSFStream& directStream, uint32_t size, uint32_t offset) PDB_NO_EXCEPT;
-
- ~CoalescedMSFStream(void) PDB_NO_EXCEPT;
-
- // Returns the size of the stream.
- PDB_NO_DISCARD inline size_t GetSize(void) const PDB_NO_EXCEPT
- {
- return m_size;
- }
-
- // Provides read-only access to the data.
- template
- PDB_NO_DISCARD inline const T* GetDataAtOffset(size_t offset) const PDB_NO_EXCEPT
- {
- return reinterpret_cast(m_data + offset);
- }
-
- template
- PDB_NO_DISCARD inline size_t GetPointerOffset(const T* pointer) const PDB_NO_EXCEPT
- {
- const Byte* bytePointer = reinterpret_cast(pointer);
- const Byte* dataEnd = m_data + m_size;
-
- PDB_ASSERT(bytePointer >= m_data && bytePointer <= dataEnd, "Pointer 0x%p not within stream range [0x%p:0x%p]",
- static_cast(bytePointer), static_cast(m_data), static_cast(dataEnd));
-
- return static_cast(bytePointer - m_data);
- }
-
- private:
- // contiguous, coalesced data, can be null
- Byte* m_ownedData;
-
- // either points to the owned data that has been copied from disjunct blocks, or points to the
- // memory-mapped data directly in case all stream blocks are contiguous.
- const Byte* m_data;
- size_t m_size;
-
- PDB_DISABLE_COPY(CoalescedMSFStream);
- };
-}
diff --git a/third_party/raw_pdb/src/PDB_DBIStream.cpp b/third_party/raw_pdb/src/PDB_DBIStream.cpp
deleted file mode 100644
index 5c9bf15..0000000
--- a/third_party/raw_pdb/src/PDB_DBIStream.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2011-2022, Molecular Matters GmbH
-// See LICENSE.txt for licensing details (2-clause BSD License: https://opensource.org/licenses/BSD-2-Clause)
-
-#include "PDB_PCH.h"
-#include "PDB_DBIStream.h"
-#include "PDB_RawFile.h"
-
-
-namespace
-{
- // the DBI stream always resides at index 3
- static constexpr const uint32_t DBIStreamIndex = 3u;
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetModuleInfoSubstreamOffset(const PDB::DBI::StreamHeader& /* dbiHeader */) PDB_NO_EXCEPT
- {
- return sizeof(PDB::DBI::StreamHeader);
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetSectionContributionSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetModuleInfoSubstreamOffset(dbiHeader) + dbiHeader.moduleInfoSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetSectionMapSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetSectionContributionSubstreamOffset(dbiHeader) + dbiHeader.sectionContributionSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetSourceInfoSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetSectionMapSubstreamOffset(dbiHeader) + dbiHeader.sectionMapSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetTypeServerMapSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetSourceInfoSubstreamOffset(dbiHeader) + dbiHeader.sourceInfoSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetECSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetTypeServerMapSubstreamOffset(dbiHeader) + dbiHeader.typeServerMapSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline uint32_t GetDebugHeaderSubstreamOffset(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return GetECSubstreamOffset(dbiHeader) + dbiHeader.ecSize;
- }
-
-
- // ------------------------------------------------------------------------------------------------
- // ------------------------------------------------------------------------------------------------
- PDB_NO_DISCARD static inline bool HasDebugHeaderSubstream(const PDB::DBI::StreamHeader& dbiHeader) PDB_NO_EXCEPT
- {
- return dbiHeader.optionalDebugHeaderSize != 0u;
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::DBIStream::DBIStream(void) PDB_NO_EXCEPT
- : m_header()
- , m_stream()
-{
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB::DBIStream::DBIStream(const RawFile& file, const DBI::StreamHeader& header) PDB_NO_EXCEPT
- : m_header(header)
- , m_stream(file.CreateMSFStream(DBIStreamIndex))
-{
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB_NO_DISCARD PDB::ErrorCode PDB::HasValidDBIStream(const RawFile& file) PDB_NO_EXCEPT
-{
- DirectMSFStream stream = file.CreateMSFStream(DBIStreamIndex);
- if (stream.GetSize() < sizeof(DBI::StreamHeader))
- {
- return ErrorCode::InvalidStream;
- }
-
- const DBI::StreamHeader header = stream.ReadAtOffset(0u);
- if (header.signature != DBI::StreamHeader::Signature)
- {
- return ErrorCode::InvalidSignature;
- }
- else if (header.version != DBI::StreamHeader::Version::V70)
- {
- return ErrorCode::UnknownVersion;
- }
-
- return ErrorCode::Success;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-PDB_NO_DISCARD PDB::DBIStream PDB::CreateDBIStream(const RawFile& file) PDB_NO_EXCEPT
-{
- DirectMSFStream stream = file.CreateMSFStream(DBIStreamIndex);
- const DBI::StreamHeader header = stream.ReadAtOffset