diff options
Diffstat (limited to 'include/pdb')
-rw-r--r-- | include/pdb/address.hpp | 35 | ||||
-rw-r--r-- | include/pdb/dbghelp.hpp | 44 | ||||
-rw-r--r-- | include/pdb/error.hpp | 53 | ||||
-rw-r--r-- | include/pdb/handle.hpp | 30 | ||||
-rw-r--r-- | include/pdb/module.hpp | 61 | ||||
-rw-r--r-- | include/pdb/repo.hpp | 58 | ||||
-rw-r--r-- | include/pdb/symbol.hpp | 167 | ||||
-rw-r--r-- | include/pdb/utils/file.hpp | 77 |
8 files changed, 244 insertions, 281 deletions
diff --git a/include/pdb/address.hpp b/include/pdb/address.hpp index 4a62249..ea3b79d 100644 --- a/include/pdb/address.hpp +++ b/include/pdb/address.hpp @@ -10,22 +10,21 @@ #include <sstream> #include <string> -namespace pdb -{ - typedef DWORD64 Address; - - inline std::string format_address(Address address) - { - std::ostringstream oss; - oss << std::hex << std::showbase << address; - return oss.str(); - } - - inline bool parse_address(Address& dest, const std::string& src) - { - std::istringstream iss{src}; - iss >> std::hex; - char c; - return iss >> dest && !iss.get(c); - } +namespace pdb { + +typedef DWORD64 Address; + +inline std::string format_address(Address address) { + std::ostringstream oss; + oss << std::hex << std::showbase << address; + return oss.str(); } + +inline bool parse_address(Address& dest, const std::string& src) { + std::istringstream iss{src}; + iss >> std::hex; + char c; + return iss >> dest && !iss.get(c); +} + +} // namespace pdb diff --git a/include/pdb/dbghelp.hpp b/include/pdb/dbghelp.hpp index 2555de1..4f11e22 100644 --- a/include/pdb/dbghelp.hpp +++ b/include/pdb/dbghelp.hpp @@ -14,33 +14,33 @@ #include <functional> #include <string> -namespace pdb -{ - class DbgHelp - { - public: - DbgHelp(); - ~DbgHelp(); +namespace pdb { - void close(); +class DbgHelp { +public: + DbgHelp(); + ~DbgHelp(); - ModuleInfo load_pdb(const std::string& path) const; + void close(); - typedef std::function<void (const SymbolInfo&)> OnSymbol; - void enum_symbols(const ModuleInfo&, const OnSymbol&) const; + ModuleInfo load_pdb(const std::string& path) const; - SymbolInfo resolve_symbol(Address) const; - SymbolInfo resolve_symbol(const std::string&) const; + typedef std::function<void(const SymbolInfo&)> OnSymbol; + void enum_symbols(const ModuleInfo&, const OnSymbol&) const; - LineInfo resolve_line(Address) const; + SymbolInfo resolve_symbol(Address) const; + SymbolInfo resolve_symbol(const std::string&) const; - private: - ModuleInfo get_module_info(Address offline_base) const; + LineInfo resolve_line(Address) const; - const HANDLE id = GetCurrentProcess(); - bool closed = false; +private: + ModuleInfo get_module_info(Address offline_base) const; - DbgHelp(const DbgHelp&) = delete; - DbgHelp& operator=(const DbgHelp&) = delete; - }; -} + const HANDLE id = GetCurrentProcess(); + bool closed = false; + + DbgHelp(const DbgHelp&) = delete; + DbgHelp& operator=(const DbgHelp&) = delete; +}; + +} // namespace pdb diff --git a/include/pdb/error.hpp b/include/pdb/error.hpp index 6640907..2b9a8be 100644 --- a/include/pdb/error.hpp +++ b/include/pdb/error.hpp @@ -10,33 +10,28 @@ #include <string> #include <system_error> -namespace pdb -{ - namespace error - { - class CategoryWindows : public std::error_category - { - public: - CategoryWindows() = default; - - const char* name() const noexcept { return "Windows"; } - - std::string message(int) const; - }; - - inline const CategoryWindows& category_windows() - { - static const CategoryWindows instance; - return instance; - } - - inline std::system_error windows(DWORD code) - { - static_assert(sizeof(DWORD) == sizeof(int), "Aren't DWORDs the same size as ints?"); - - return std::system_error{ - static_cast<int>(code), - category_windows()}; - } - } +namespace pdb { +namespace error { + +class CategoryWindows : public std::error_category { +public: + CategoryWindows() = default; + + const char* name() const noexcept { return "Windows"; } + + std::string message(int) const; +}; + +inline const CategoryWindows& category_windows() { + static const CategoryWindows instance; + return instance; } + +inline std::system_error windows(DWORD code) { + static_assert(sizeof(DWORD) == sizeof(int), "Aren't DWORDs the same size as ints?"); + + return std::system_error{static_cast<int>(code), category_windows()}; +} + +} // namespace error +} // namespace pdb diff --git a/include/pdb/handle.hpp b/include/pdb/handle.hpp index 52fb805..7c0cc40 100644 --- a/include/pdb/handle.hpp +++ b/include/pdb/handle.hpp @@ -8,22 +8,20 @@ #include <Windows.h> #include <cassert> - #include <memory> -namespace pdb -{ - struct CloseHandle - { - void operator()(HANDLE raw) const - { - if (raw == NULL || raw == INVALID_HANDLE_VALUE) - return; - const auto ret = ::CloseHandle(raw); - assert(ret); - UNREFERENCED_PARAMETER(ret); - } - }; +namespace pdb { + +struct CloseHandle { + void operator()(HANDLE raw) const { + if (raw == NULL || raw == INVALID_HANDLE_VALUE) + return; + const auto ret = ::CloseHandle(raw); + assert(ret); + UNREFERENCED_PARAMETER(ret); + } +}; + +typedef std::unique_ptr<void, CloseHandle> Handle; - typedef std::unique_ptr<void, CloseHandle> Handle; -} +} // namespace pdb diff --git a/include/pdb/module.hpp b/include/pdb/module.hpp index 926db2c..47eeef3 100644 --- a/include/pdb/module.hpp +++ b/include/pdb/module.hpp @@ -14,46 +14,43 @@ #include <string> -namespace pdb -{ - class ModuleInfo - { - public: - typedef IMAGEHLP_MODULE64 Raw; +namespace pdb { - ModuleInfo(); - explicit ModuleInfo(const Raw& raw); +class ModuleInfo { +public: + typedef IMAGEHLP_MODULE64 Raw; - explicit operator Raw&() { return raw; } - explicit operator const Raw&() const { return raw; } + ModuleInfo(); + explicit ModuleInfo(const Raw& raw); - Address get_offline_base() const { return raw.BaseOfImage; } + explicit operator Raw&() { return raw; } + explicit operator const Raw&() const { return raw; } - std::string get_name() const { return raw.ModuleName; } + Address get_offline_base() const { return raw.BaseOfImage; } - private: - static Raw create_raw(); + std::string get_name() const { return raw.ModuleName; } - Raw raw; - }; +private: + static Raw create_raw(); - class Module : public ModuleInfo - { - public: - Module(Address online_base, const ModuleInfo& info) - : ModuleInfo{info} - , online_base{online_base} - { } + Raw raw; +}; - Address get_online_base() const { return online_base; } +class Module : public ModuleInfo { +public: + Module(Address online_base, const ModuleInfo& info) + : ModuleInfo{info}, online_base{online_base} {} - Address translate_offline_address(Address offline) const; - Address translate_online_address(Address online) const; + Address get_online_base() const { return online_base; } - private: - std::string invalid_offline_address(Address offline) const; - std::string invalid_online_address(Address online) const; + Address translate_offline_address(Address offline) const; + Address translate_online_address(Address online) const; - const Address online_base; - }; -} +private: + std::string invalid_offline_address(Address offline) const; + std::string invalid_online_address(Address online) const; + + const Address online_base; +}; + +} // namespace pdb diff --git a/include/pdb/repo.hpp b/include/pdb/repo.hpp index c8a2964..8bc5596 100644 --- a/include/pdb/repo.hpp +++ b/include/pdb/repo.hpp @@ -16,42 +16,42 @@ #include <string> #include <unordered_set> -namespace pdb -{ - class Repo - { - public: - Repo() = default; +namespace pdb { - Address add_pdb(Address online_base, const std::string& path); +class Repo { +public: + Repo() = default; - typedef std::function<void (const Symbol&)> OnSymbol; - void enum_symbols(const OnSymbol&) const; - void enum_symbols(Address offline_base, const OnSymbol&) const; - void enum_symbols(const Module&, const OnSymbol&) const; + Address add_pdb(Address online_base, const std::string& path); - Symbol resolve_symbol(Address) const; - Symbol resolve_symbol(const std::string&) const; + typedef std::function<void(const Symbol&)> OnSymbol; + void enum_symbols(const OnSymbol&) const; + void enum_symbols(Address offline_base, const OnSymbol&) const; + void enum_symbols(const Module&, const OnSymbol&) const; - LineInfo resolve_line(Address) const; + Symbol resolve_symbol(Address) const; + Symbol resolve_symbol(const std::string&) const; - const Module& module_with_online_base(Address) const; - const Module& module_with_offline_base(Address) const; + LineInfo resolve_line(Address) const; - private: - Symbol symbol_from_buffer(const SymbolInfo&) const; - static Symbol symbol_from_buffer(const Module&, const SymbolInfo&); + const Module& module_with_online_base(Address) const; + const Module& module_with_offline_base(Address) const; - const Module& module_from_online_address(Address) const; - const Module& module_from_offline_address(Address) const; +private: + Symbol symbol_from_buffer(const SymbolInfo&) const; + static Symbol symbol_from_buffer(const Module&, const SymbolInfo&); - Address address_offline_to_online(Address) const; - Address address_online_to_offline(Address) const; + const Module& module_from_online_address(Address) const; + const Module& module_from_offline_address(Address) const; - const DbgHelp dbghelp; + Address address_offline_to_online(Address) const; + Address address_online_to_offline(Address) const; - std::unordered_set<file::ID> file_ids; - std::map<Address, Module> online_bases; - std::map<Address, const Module&> offline_bases; - }; -} + const DbgHelp dbghelp; + + std::unordered_set<file::ID> file_ids; + std::map<Address, Module> online_bases; + std::map<Address, const Module&> offline_bases; +}; + +} // namespace pdb diff --git a/include/pdb/symbol.hpp b/include/pdb/symbol.hpp index ec0f80c..d9f3f0c 100644 --- a/include/pdb/symbol.hpp +++ b/include/pdb/symbol.hpp @@ -8,134 +8,113 @@ #include "address.hpp" #include "module.hpp" -#include <safeint.h> - #include <Windows.h> +#include <safeint.h> #pragma warning(push, 0) #include <DbgHelp.h> #pragma warning(pop) #include <cstddef> #include <cstring> - #include <stdexcept> #include <string> -namespace pdb -{ - class SymbolInfo - { - public: - typedef SYMBOL_INFO Raw; - - SymbolInfo() - : raw{*reinterpret_cast<Raw*>(buffer)} - { - raw.SizeOfStruct = sizeof(Raw); - raw.MaxNameLen = MAX_SYM_NAME; - } +namespace pdb { - explicit SymbolInfo(const Raw& raw) - : SymbolInfo{} - { - if (raw.SizeOfStruct != sizeof(raw)) - throw std::runtime_error{"invalid SYMBOL_INFO.SizeOfStruct"}; - const auto raw_size = calc_size(raw); - if (raw_size > sizeof(buffer)) - throw std::runtime_error{"SYMBOL_INFO is too large"}; - std::memcpy(buffer, &raw, raw_size); - } +class SymbolInfo { +public: + typedef SYMBOL_INFO Raw; - explicit operator Raw&() { return raw; } + SymbolInfo() : raw{*reinterpret_cast<Raw*>(buffer)} { + raw.SizeOfStruct = sizeof(Raw); + raw.MaxNameLen = MAX_SYM_NAME; + } - explicit operator const Raw&() const { return raw; } + explicit SymbolInfo(const Raw& raw) : SymbolInfo{} { + if (raw.SizeOfStruct != sizeof(raw)) + throw std::runtime_error{"invalid SYMBOL_INFO.SizeOfStruct"}; + const auto raw_size = calc_size(raw); + if (raw_size > sizeof(buffer)) + throw std::runtime_error{"SYMBOL_INFO is too large"}; + std::memcpy(buffer, &raw, raw_size); + } - Address get_displacement() const { return displacement; } + explicit operator Raw&() { return raw; } - void set_displacement(Address new_value) - { - displacement = new_value; - } + explicit operator const Raw&() const { return raw; } - std::string get_name() const { return {raw.Name, raw.NameLen}; } + Address get_displacement() const { return displacement; } - Address get_offline_base() const { return raw.ModBase; } + void set_displacement(Address new_value) { displacement = new_value; } - Address get_offline_address() const { return raw.Address; } + std::string get_name() const { return {raw.Name, raw.NameLen}; } - typedef ULONG Tag; + Address get_offline_base() const { return raw.ModBase; } - Tag get_tag() const { return raw.Tag; } + Address get_offline_address() const { return raw.Address; } - enum class Type : Tag - { - Function = SymTagFunction, - RESERVED = SymTagMax, - }; + typedef ULONG Tag; - Type get_type() const { return static_cast<Type>(get_tag()); } + Tag get_tag() const { return raw.Tag; } - bool is_function() const { return get_type() == Type::Function; } + enum class Type : Tag { + Function = SymTagFunction, + RESERVED = SymTagMax, + }; - private: - static constexpr std::size_t max_buffer_size = sizeof(Raw) + MAX_SYM_NAME - 1; + Type get_type() const { return static_cast<Type>(get_tag()); } - static std::size_t calc_size(const Raw& raw) - { - using namespace msl::utilities; - try - { - return SafeInt<std::size_t>{raw.SizeOfStruct} + raw.NameLen - 1; - } - catch (const SafeIntException&) - { - throw std::runtime_error{"invalid SYMBOL_INFO size"}; - } + bool is_function() const { return get_type() == Type::Function; } + +private: + static constexpr std::size_t max_buffer_size = sizeof(Raw) + MAX_SYM_NAME - 1; + + static std::size_t calc_size(const Raw& raw) { + using namespace msl::utilities; + try { + return SafeInt<std::size_t>{raw.SizeOfStruct} + raw.NameLen - 1; + } catch (const SafeIntException&) { + throw std::runtime_error{"invalid SYMBOL_INFO size"}; } + } - unsigned char buffer[max_buffer_size] = {0}; - Address displacement = 0; + unsigned char buffer[max_buffer_size] = {0}; + Address displacement = 0; - protected: - Raw& raw; - }; +protected: + Raw& raw; +}; - class Symbol : public SymbolInfo - { - public: - Symbol(Address online_address, const SymbolInfo& info) - : SymbolInfo{info} - , online_address{online_address} - { } +class Symbol : public SymbolInfo { +public: + Symbol(Address online_address, const SymbolInfo& info) + : SymbolInfo{info}, online_address{online_address} {} - Address get_online_address() const { return online_address; } + Address get_online_address() const { return online_address; } - private: - const Address online_address; - }; +private: + const Address online_address; +}; - class LineInfo - { - public: - typedef IMAGEHLP_LINE64 Raw; +class LineInfo { +public: + typedef IMAGEHLP_LINE64 Raw; - explicit LineInfo(const Raw& raw) - : file_path{raw.FileName} - , line_number{cast_line_number(raw.LineNumber)} - { } + explicit LineInfo(const Raw& raw) + : file_path{raw.FileName}, line_number{cast_line_number(raw.LineNumber)} {} - const std::string file_path; - const unsigned long line_number; + const std::string file_path; + const unsigned long line_number; - private: - static unsigned long cast_line_number(DWORD raw) - { - unsigned long dest = 0; +private: + static unsigned long cast_line_number(DWORD raw) { + unsigned long dest = 0; - if (!msl::utilities::SafeCast(raw, dest)) - throw std::runtime_error{"invalid line number"}; + if (!msl::utilities::SafeCast(raw, dest)) + throw std::runtime_error{"invalid line number"}; - return dest; - } - }; -} + return dest; + } +}; + +} // namespace pdb diff --git a/include/pdb/utils/file.hpp b/include/pdb/utils/file.hpp index bf97115..acb5cfc 100644 --- a/include/pdb/utils/file.hpp +++ b/include/pdb/utils/file.hpp @@ -5,55 +5,50 @@ #pragma once -#include <Windows.h> - #pragma warning(push, 0) #include <boost/functional/hash.hpp> #pragma warning(pop) +#include <Windows.h> + #include <cstddef> #include <cstring> - #include <functional> #include <string> -namespace pdb -{ - namespace file - { - std::size_t get_size(const std::string&); - - inline bool operator==(const FILE_ID_128& a, const FILE_ID_128& b) - { - return 0 == std::memcmp(a.Identifier, b.Identifier, sizeof(a.Identifier)); - } - - struct ID - { - const FILE_ID_INFO raw; - - bool operator==(const ID& other) const - { - return raw.VolumeSerialNumber == other.raw.VolumeSerialNumber - && raw.FileId == other.raw.FileId; - } - }; - - ID query_id(const std::string&); - } -} +namespace pdb { +namespace file { -namespace std -{ - template <> - struct hash<pdb::file::ID> - { - std::size_t operator()(const pdb::file::ID& id) const - { - std::size_t seed = 0; - boost::hash_combine(seed, id.raw.VolumeSerialNumber); - boost::hash_combine(seed, id.raw.FileId.Identifier); - return seed; - } - }; +std::size_t get_size(const std::string&); + +inline bool operator==(const FILE_ID_128& a, const FILE_ID_128& b) { + return 0 == std::memcmp(a.Identifier, b.Identifier, sizeof(a.Identifier)); } + +struct ID { + const FILE_ID_INFO raw; + + bool operator==(const ID& other) const { + return raw.VolumeSerialNumber == other.raw.VolumeSerialNumber && + raw.FileId == other.raw.FileId; + } +}; + +ID query_id(const std::string&); + +} // namespace file +} // namespace pdb + +namespace std { + +template <> +struct hash<pdb::file::ID> { + std::size_t operator()(const pdb::file::ID& id) const { + std::size_t seed = 0; + boost::hash_combine(seed, id.raw.VolumeSerialNumber); + boost::hash_combine(seed, id.raw.FileId.Identifier); + return seed; + } +}; + +} // namespace std |