aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/pdb/address.hpp35
-rw-r--r--include/pdb/dbghelp.hpp44
-rw-r--r--include/pdb/error.hpp53
-rw-r--r--include/pdb/handle.hpp30
-rw-r--r--include/pdb/module.hpp61
-rw-r--r--include/pdb/repo.hpp58
-rw-r--r--include/pdb/symbol.hpp167
-rw-r--r--include/pdb/utils/file.hpp77
-rw-r--r--src/dbghelp.cpp243
-rw-r--r--src/error.cpp75
-rw-r--r--src/module.cpp99
-rw-r--r--src/repo.cpp302
-rw-r--r--src/utils/file.cpp110
-rw-r--r--utils/addr2name.cpp163
-rw-r--r--utils/command_line.hpp44
-rw-r--r--utils/enum_symbols.cpp94
-rw-r--r--utils/name2addr.cpp96
-rw-r--r--utils/pdb_descr.hpp59
18 files changed, 789 insertions, 1021 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
diff --git a/src/dbghelp.cpp b/src/dbghelp.cpp
index 38cb6f5..40c2ba5 100644
--- a/src/dbghelp.cpp
+++ b/src/dbghelp.cpp
@@ -5,180 +5,137 @@
#include "pdb/all.hpp"
-#include <safeint.h>
-
#include <Windows.h>
+#include <safeint.h>
#pragma warning(push, 0)
#include <DbgHelp.h>
#pragma warning(pop, 0)
#include <cstddef>
#include <cstring>
-
#include <stdexcept>
#include <string>
-namespace pdb
-{
- namespace
- {
- void set_dbghelp_options()
- {
- SymSetOptions(SymGetOptions()
- | SYMOPT_DEBUG
- | SYMOPT_LOAD_LINES
- | SYMOPT_UNDNAME);
- }
-
- void initialize(HANDLE id)
- {
- set_dbghelp_options();
-
- if (!SymInitialize(id, NULL, FALSE))
- throw error::windows(GetLastError());
- }
-
- void clean_up(HANDLE id)
- {
- if (!SymCleanup(id))
- throw error::windows(GetLastError());
- }
-
- Address next_offline_base = 0x10000000;
-
- Address gen_next_offline_base(std::size_t pdb_size)
- {
- const auto base = next_offline_base;
- using msl::utilities::SafeAdd;
- if (!SafeAdd(next_offline_base, pdb_size, next_offline_base))
- throw std::runtime_error{"no more PDB files can be added, the internal address space is exhausted"};
- return base;
- }
-
- BOOL CALLBACK enum_symbols_callback(
- SYMBOL_INFO *info,
- ULONG,
- VOID *raw_callback_ptr)
- {
- const auto callback_ptr = reinterpret_cast<DbgHelp::OnSymbol*>(raw_callback_ptr);
- const auto& callback = *callback_ptr;
- callback(SymbolInfo{*info});
- return TRUE;
- }
- }
+namespace pdb {
+namespace {
- DbgHelp::DbgHelp()
- {
- initialize(id);
- }
+void set_dbghelp_options() {
+ SymSetOptions(SymGetOptions() | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
+}
- DbgHelp::~DbgHelp()
- {
- try
- {
- close();
- }
- catch (...)
- { }
- }
+void initialize(HANDLE id) {
+ set_dbghelp_options();
- void DbgHelp::close()
- {
- if (!closed)
- {
- clean_up(id);
- closed = true;
- }
- }
+ if (!SymInitialize(id, NULL, FALSE))
+ throw error::windows(GetLastError());
+}
- ModuleInfo DbgHelp::load_pdb(const std::string& path) const
- {
- DWORD size = 0;
- if (!msl::utilities::SafeCast(file::get_size(path), size))
- throw std::range_error{"PDB file is too large"};
+void clean_up(HANDLE id) {
+ if (!SymCleanup(id))
+ throw error::windows(GetLastError());
+}
- const auto offline_base = SymLoadModule64(
- id,
- NULL,
- path.c_str(),
- NULL,
- gen_next_offline_base(size),
- size);
+Address next_offline_base = 0x10000000;
- if (!offline_base)
- throw error::windows(GetLastError());
+Address gen_next_offline_base(std::size_t pdb_size) {
+ const auto base = next_offline_base;
+ using msl::utilities::SafeAdd;
+ if (!SafeAdd(next_offline_base, pdb_size, next_offline_base))
+ throw std::runtime_error{
+ "no more PDB files can be added, the internal address space is exhausted"};
+ return base;
+}
- return get_module_info(offline_base);
- }
+BOOL CALLBACK enum_symbols_callback(SYMBOL_INFO* info, ULONG, VOID* raw_callback_ptr) {
+ const auto callback_ptr = reinterpret_cast<DbgHelp::OnSymbol*>(raw_callback_ptr);
+ const auto& callback = *callback_ptr;
+ callback(SymbolInfo{*info});
+ return TRUE;
+}
- ModuleInfo DbgHelp::get_module_info(Address offline_base) const
- {
- ModuleInfo info;
+} // namespace
- if (!SymGetModuleInfo64(
- id,
- offline_base,
- &static_cast<ModuleInfo::Raw&>(info)))
- throw error::windows(GetLastError());
+DbgHelp::DbgHelp() {
+ initialize(id);
+}
- return info;
+DbgHelp::~DbgHelp() {
+ try {
+ close();
+ } catch (...) {
}
+}
- void DbgHelp::enum_symbols(const ModuleInfo& module, const OnSymbol& callback) const
- {
- if (!SymEnumSymbols(
- id,
- module.get_offline_base(),
- NULL,
- &enum_symbols_callback,
- const_cast<OnSymbol*>(&callback)))
- throw error::windows(GetLastError());
+void DbgHelp::close() {
+ if (!closed) {
+ clean_up(id);
+ closed = true;
}
+}
- SymbolInfo DbgHelp::resolve_symbol(Address offline) const
- {
- Address displacement = 0;
- SymbolInfo symbol;
+ModuleInfo DbgHelp::load_pdb(const std::string& path) const {
+ DWORD size = 0;
+ if (!msl::utilities::SafeCast(file::get_size(path), size))
+ throw std::range_error{"PDB file is too large"};
- if (!SymFromAddr(
- id,
- offline,
- &displacement,
- &static_cast<SYMBOL_INFO&>(symbol)))
- throw error::windows(GetLastError());
+ const auto offline_base =
+ SymLoadModule64(id, NULL, path.c_str(), NULL, gen_next_offline_base(size), size);
- symbol.set_displacement(displacement);
- return symbol;
- }
+ if (!offline_base)
+ throw error::windows(GetLastError());
- SymbolInfo DbgHelp::resolve_symbol(const std::string& name) const
- {
- SymbolInfo symbol;
+ return get_module_info(offline_base);
+}
- if (!SymFromName(
- id,
- name.c_str(),
- &static_cast<SYMBOL_INFO&>(symbol)))
- throw error::windows(GetLastError());
+ModuleInfo DbgHelp::get_module_info(Address offline_base) const {
+ ModuleInfo info;
- return symbol;
- }
+ if (!SymGetModuleInfo64(id, offline_base, &static_cast<ModuleInfo::Raw&>(info)))
+ throw error::windows(GetLastError());
- LineInfo DbgHelp::resolve_line(Address offline) const
- {
- IMAGEHLP_LINE64 raw;
- std::memset(&raw, 0, sizeof(raw));
- raw.SizeOfStruct = sizeof(raw);
+ return info;
+}
- DWORD displacement = 0;
+void DbgHelp::enum_symbols(const ModuleInfo& module, const OnSymbol& callback) const {
+ if (!SymEnumSymbols(id,
+ module.get_offline_base(),
+ NULL,
+ &enum_symbols_callback,
+ const_cast<OnSymbol*>(&callback)))
+ throw error::windows(GetLastError());
+}
- if (!SymGetLineFromAddr64(
- id,
- offline,
- &displacement,
- &raw))
- throw error::windows(GetLastError());
+SymbolInfo DbgHelp::resolve_symbol(Address offline) const {
+ Address displacement = 0;
+ SymbolInfo symbol;
- return LineInfo{raw};
- }
+ if (!SymFromAddr(id, offline, &displacement, &static_cast<SYMBOL_INFO&>(symbol)))
+ throw error::windows(GetLastError());
+
+ symbol.set_displacement(displacement);
+ return symbol;
}
+
+SymbolInfo DbgHelp::resolve_symbol(const std::string& name) const {
+ SymbolInfo symbol;
+
+ if (!SymFromName(id, name.c_str(), &static_cast<SYMBOL_INFO&>(symbol)))
+ throw error::windows(GetLastError());
+
+ return symbol;
+}
+
+LineInfo DbgHelp::resolve_line(Address offline) const {
+ IMAGEHLP_LINE64 raw;
+ std::memset(&raw, 0, sizeof(raw));
+ raw.SizeOfStruct = sizeof(raw);
+
+ DWORD displacement = 0;
+
+ if (!SymGetLineFromAddr64(id, offline, &displacement, &raw))
+ throw error::windows(GetLastError());
+
+ return LineInfo{raw};
+}
+
+} // namespace pdb
diff --git a/src/error.cpp b/src/error.cpp
index 10b668b..320c5d0 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -9,45 +9,40 @@
#include <string>
-namespace pdb
-{
- namespace error
- {
- namespace
- {
- std::string trim_trailing_newline(const std::string& s)
- {
- const auto last_pos = s.find_last_not_of("\r\n");
- if (std::string::npos == last_pos)
- return {};
- return s.substr(0, last_pos + 1);
- }
- }
-
- std::string CategoryWindows::message(int code) const
- {
- char* buf;
-
- const auto nbwritten = FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER
- | FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- code,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- reinterpret_cast<char*>(&buf),
- 0,
- NULL);
-
- if (0 == nbwritten)
- {
- LocalFree(buf);
- return "Couldn't format the error message";
- }
-
- std::string msg{buf, nbwritten};
- LocalFree(buf);
- return trim_trailing_newline(msg);
- }
+namespace pdb {
+namespace error {
+namespace {
+
+std::string trim_trailing_newline(const std::string& s) {
+ const auto last_pos = s.find_last_not_of("\r\n");
+ if (std::string::npos == last_pos)
+ return {};
+ return s.substr(0, last_pos + 1);
+}
+
+} // namespace
+
+std::string CategoryWindows::message(int code) const {
+ char* buf;
+
+ const auto nbwritten = FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ reinterpret_cast<char*>(&buf),
+ 0,
+ NULL);
+
+ if (0 == nbwritten) {
+ LocalFree(buf);
+ return "Couldn't format the error message";
}
+
+ std::string msg{buf, nbwritten};
+ LocalFree(buf);
+ return trim_trailing_newline(msg);
}
+
+} // namespace error
+} // namespace pdb
diff --git a/src/module.cpp b/src/module.cpp
index 2c1d26c..0bf9329 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -8,69 +8,58 @@
#include <safeint.h>
#include <cstring>
-
#include <sstream>
#include <stdexcept>
#include <string>
-namespace pdb
-{
- ModuleInfo::ModuleInfo()
- : ModuleInfo{create_raw()}
- { }
+namespace pdb {
+
+ModuleInfo::ModuleInfo() : ModuleInfo{create_raw()} {}
- ModuleInfo::ModuleInfo(const Raw& raw)
- : raw{raw}
- {
- if (raw.SizeOfStruct != sizeof(raw))
- throw std::runtime_error{"invalid IMAGEHLP_MODULE64.SizeOfStruct"};
- }
+ModuleInfo::ModuleInfo(const Raw& raw) : raw{raw} {
+ if (raw.SizeOfStruct != sizeof(raw))
+ throw std::runtime_error{"invalid IMAGEHLP_MODULE64.SizeOfStruct"};
+}
- ModuleInfo::Raw ModuleInfo::create_raw()
- {
- Raw raw;
- std::memset(&raw, 0, sizeof(raw));
- raw.SizeOfStruct = sizeof(raw);
- return raw;
- }
+ModuleInfo::Raw ModuleInfo::create_raw() {
+ Raw raw;
+ std::memset(&raw, 0, sizeof(raw));
+ raw.SizeOfStruct = sizeof(raw);
+ return raw;
+}
- Address Module::translate_offline_address(Address offline) const
- {
- if (offline < get_offline_base())
- throw std::range_error{invalid_offline_address(offline)};
- const auto offset = offline - get_offline_base();
- auto online = offset;
- if (!msl::utilities::SafeAdd(online, get_online_base(), online))
- throw std::range_error{invalid_offline_address(offline)};
- return online;
- }
+Address Module::translate_offline_address(Address offline) const {
+ if (offline < get_offline_base())
+ throw std::range_error{invalid_offline_address(offline)};
+ const auto offset = offline - get_offline_base();
+ auto online = offset;
+ if (!msl::utilities::SafeAdd(online, get_online_base(), online))
+ throw std::range_error{invalid_offline_address(offline)};
+ return online;
+}
- Address Module::translate_online_address(Address online) const
- {
- if (online < get_online_base())
- throw std::range_error{invalid_online_address(online)};
- const auto offset = online - get_online_base();
- auto offline = offset;
- if (!msl::utilities::SafeAdd(offline, get_offline_base(), offline))
- throw std::range_error{invalid_online_address(offline)};
- return offline;
- }
+Address Module::translate_online_address(Address online) const {
+ if (online < get_online_base())
+ throw std::range_error{invalid_online_address(online)};
+ const auto offset = online - get_online_base();
+ auto offline = offset;
+ if (!msl::utilities::SafeAdd(offline, get_offline_base(), offline))
+ throw std::range_error{invalid_online_address(offline)};
+ return offline;
+}
- std::string Module::invalid_offline_address(Address offline) const
- {
- std::ostringstream oss;
- oss << "offline address " << format_address(offline)
- << " doesn't belong to module " << get_name()
- << " (base offline address " << format_address(get_offline_base()) << ')';
- return oss.str();
- }
+std::string Module::invalid_offline_address(Address offline) const {
+ std::ostringstream oss;
+ oss << "offline address " << format_address(offline) << " doesn't belong to module "
+ << get_name() << " (base offline address " << format_address(get_offline_base()) << ')';
+ return oss.str();
+}
- std::string Module::invalid_online_address(Address online) const
- {
- std::ostringstream oss;
- oss << "online address " << format_address(online)
- << " doesn't belong to module " << get_name()
- << " (base online address " << format_address(get_online_base()) << ')';
- return oss.str();
- }
+std::string Module::invalid_online_address(Address online) const {
+ std::ostringstream oss;
+ oss << "online address " << format_address(online) << " doesn't belong to module " << get_name()
+ << " (base online address " << format_address(get_online_base()) << ')';
+ return oss.str();
}
+
+} // namespace pdb
diff --git a/src/repo.cpp b/src/repo.cpp
index 7a19c83..d7f2c74 100644
--- a/src/repo.cpp
+++ b/src/repo.cpp
@@ -11,194 +11,160 @@
#include <string>
#include <utility>
-namespace pdb
-{
- namespace
- {
- std::string pdb_already_loaded(Address online_base, const std::string& path)
- {
- std::ostringstream oss;
- oss << "module with online base address " << format_address(online_base)
- << " has already been loaded: " << path;
- return oss.str();
- }
-
- std::string pdb_already_loaded(const std::string& path)
- {
- std::ostringstream oss;
- oss << "module has already been loaded: " << path;
- return oss.str();
- }
-
- std::string offline_base_already_used(Address base)
- {
- std::ostringstream oss;
- oss << "module with offline base address " << format_address(base)
- << " has already been loaded (shouldn't happen)";
- return oss.str();
- }
-
- std::string module_not_found(Address base)
- {
- std::ostringstream oss;
- oss << "module with base address " << format_address(base)
- << " wasn't found";
- return oss.str();
- }
-
- std::string guess_module_no_modules(Address pivot)
- {
- std::ostringstream oss;
- oss << "couldn't select a module for address " << format_address(pivot)
- << ": no modules have been loaded yet";
- return oss.str();
- }
-
- std::string guess_module_address_too_low(Address pivot)
- {
- std::ostringstream oss;
- oss << "couldn't select a module for address " << format_address(pivot)
- << ": it's too low";
- return oss.str();
- }
-
- template <typename Value>
- const Module& lookup_module(
- const std::map<Address, Value>& modules,
- Address base)
- {
- const auto it = modules.find(base);
- if (it == modules.cend())
- throw std::runtime_error{module_not_found(base)};
- return it->second;
- }
-
- template <typename Value>
- const Module& guess_module(
- const std::map<Address, Value>& modules,
- Address pivot)
- {
- if (modules.empty())
- throw std::range_error{guess_module_no_modules(pivot)};
-
- auto it = modules.lower_bound(pivot);
-
- if (it == modules.cend())
- {
- --it;
- return it->second;
- }
-
- if (it->first > pivot)
- {
- if (it == modules.cbegin())
- throw std::range_error{guess_module_address_too_low(pivot)};
- --it;
- return it->second;
- }
-
- return it->second;
- }
- }
+namespace pdb {
+namespace {
+
+std::string pdb_already_loaded(Address online_base, const std::string& path) {
+ std::ostringstream oss;
+ oss << "module with online base address " << format_address(online_base)
+ << " has already been loaded: " << path;
+ return oss.str();
+}
- Address Repo::add_pdb(Address online_base, const std::string& path)
- {
- if (online_bases.find(online_base) != online_bases.cend())
- throw std::runtime_error{pdb_already_loaded(online_base, path)};
+std::string pdb_already_loaded(const std::string& path) {
+ std::ostringstream oss;
+ oss << "module has already been loaded: " << path;
+ return oss.str();
+}
- auto file_id = file::query_id(path);
- if (file_ids.find(file_id) != file_ids.cend())
- throw std::runtime_error{pdb_already_loaded(path)};
+std::string offline_base_already_used(Address base) {
+ std::ostringstream oss;
+ oss << "module with offline base address " << format_address(base)
+ << " has already been loaded (shouldn't happen)";
+ return oss.str();
+}
- Module module{online_base, dbghelp.load_pdb(path)};
- const auto offline_base = module.get_offline_base();
+std::string module_not_found(Address base) {
+ std::ostringstream oss;
+ oss << "module with base address " << format_address(base) << " wasn't found";
+ return oss.str();
+}
- if (offline_bases.find(offline_base) != offline_bases.cend())
- throw std::runtime_error{offline_base_already_used(offline_base)};
+std::string guess_module_no_modules(Address pivot) {
+ std::ostringstream oss;
+ oss << "couldn't select a module for address " << format_address(pivot)
+ << ": no modules have been loaded yet";
+ return oss.str();
+}
- file_ids.emplace(std::move(file_id));
- const auto it = online_bases.emplace(online_base, std::move(module));
- offline_bases.emplace(offline_base, it.first->second);
+std::string guess_module_address_too_low(Address pivot) {
+ std::ostringstream oss;
+ oss << "couldn't select a module for address " << format_address(pivot) << ": it's too low";
+ return oss.str();
+}
- return offline_base;
- }
+template <typename Value>
+const Module& lookup_module(const std::map<Address, Value>& modules, Address base) {
+ const auto it = modules.find(base);
+ if (it == modules.cend())
+ throw std::runtime_error{module_not_found(base)};
+ return it->second;
+}
- void Repo::enum_symbols(const OnSymbol& callback) const
- {
- for (const auto& it : offline_bases)
- enum_symbols(it.second, callback);
- }
+template <typename Value>
+const Module& guess_module(const std::map<Address, Value>& modules, Address pivot) {
+ if (modules.empty())
+ throw std::range_error{guess_module_no_modules(pivot)};
- void Repo::enum_symbols(Address offline_base, const OnSymbol& callback) const
- {
- const auto it = offline_bases.find(offline_base);
- if (it == offline_bases.cend())
- throw std::runtime_error{"unknown module"};
- enum_symbols(it->second, callback);
- }
+ auto it = modules.lower_bound(pivot);
- void Repo::enum_symbols(const Module& module, const OnSymbol& callback) const
- {
- dbghelp.enum_symbols(module, [&] (const SymbolInfo& raw)
- {
- callback(symbol_from_buffer(module, raw));
- });
+ if (it == modules.cend()) {
+ --it;
+ return it->second;
}
- Symbol Repo::resolve_symbol(Address online) const
- {
- return symbol_from_buffer(dbghelp.resolve_symbol(address_online_to_offline(online)));
+ if (it->first > pivot) {
+ if (it == modules.cbegin())
+ throw std::range_error{guess_module_address_too_low(pivot)};
+ --it;
+ return it->second;
}
- Symbol Repo::resolve_symbol(const std::string& name) const
- {
- return symbol_from_buffer(dbghelp.resolve_symbol(name));
- }
+ return it->second;
+}
- LineInfo Repo::resolve_line(Address online) const
- {
- return dbghelp.resolve_line(address_online_to_offline(online));
- }
+} // namespace
- const Module& Repo::module_with_online_base(Address base) const
- {
- return lookup_module(online_bases, base);
- }
+Address Repo::add_pdb(Address online_base, const std::string& path) {
+ if (online_bases.find(online_base) != online_bases.cend())
+ throw std::runtime_error{pdb_already_loaded(online_base, path)};
- const Module& Repo::module_with_offline_base(Address base) const
- {
- return lookup_module(offline_bases, base);
- }
+ auto file_id = file::query_id(path);
+ if (file_ids.find(file_id) != file_ids.cend())
+ throw std::runtime_error{pdb_already_loaded(path)};
- Symbol Repo::symbol_from_buffer(const SymbolInfo& raw) const
- {
- return symbol_from_buffer(module_with_offline_base(raw.get_offline_base()), raw);
- }
+ Module module{online_base, dbghelp.load_pdb(path)};
+ const auto offline_base = module.get_offline_base();
- Symbol Repo::symbol_from_buffer(const Module& module, const SymbolInfo& raw)
- {
- return {module.translate_offline_address(raw.get_offline_address()), raw};
- }
+ if (offline_bases.find(offline_base) != offline_bases.cend())
+ throw std::runtime_error{offline_base_already_used(offline_base)};
- Address Repo::address_online_to_offline(Address online) const
- {
- return module_from_online_address(online)
- .translate_online_address(online);
- }
+ file_ids.emplace(std::move(file_id));
+ const auto it = online_bases.emplace(online_base, std::move(module));
+ offline_bases.emplace(offline_base, it.first->second);
- Address Repo::address_offline_to_online(Address offline) const
- {
- return module_from_offline_address(offline)
- .translate_offline_address(offline);
- }
+ return offline_base;
+}
- const Module& Repo::module_from_online_address(Address online) const
- {
- return guess_module(online_bases, online);
- }
+void Repo::enum_symbols(const OnSymbol& callback) const {
+ for (const auto& it : offline_bases)
+ enum_symbols(it.second, callback);
+}
- const Module& Repo::module_from_offline_address(Address offline) const
- {
- return guess_module(offline_bases, offline);
- }
+void Repo::enum_symbols(Address offline_base, const OnSymbol& callback) const {
+ const auto it = offline_bases.find(offline_base);
+ if (it == offline_bases.cend())
+ throw std::runtime_error{"unknown module"};
+ enum_symbols(it->second, callback);
}
+
+void Repo::enum_symbols(const Module& module, const OnSymbol& callback) const {
+ dbghelp.enum_symbols(module,
+ [&](const SymbolInfo& raw) { callback(symbol_from_buffer(module, raw)); });
+}
+
+Symbol Repo::resolve_symbol(Address online) const {
+ return symbol_from_buffer(dbghelp.resolve_symbol(address_online_to_offline(online)));
+}
+
+Symbol Repo::resolve_symbol(const std::string& name) const {
+ return symbol_from_buffer(dbghelp.resolve_symbol(name));
+}
+
+LineInfo Repo::resolve_line(Address online) const {
+ return dbghelp.resolve_line(address_online_to_offline(online));
+}
+
+const Module& Repo::module_with_online_base(Address base) const {
+ return lookup_module(online_bases, base);
+}
+
+const Module& Repo::module_with_offline_base(Address base) const {
+ return lookup_module(offline_bases, base);
+}
+
+Symbol Repo::symbol_from_buffer(const SymbolInfo& raw) const {
+ return symbol_from_buffer(module_with_offline_base(raw.get_offline_base()), raw);
+}
+
+Symbol Repo::symbol_from_buffer(const Module& module, const SymbolInfo& raw) {
+ return {module.translate_offline_address(raw.get_offline_address()), raw};
+}
+
+Address Repo::address_online_to_offline(Address online) const {
+ return module_from_online_address(online).translate_online_address(online);
+}
+
+Address Repo::address_offline_to_online(Address offline) const {
+ return module_from_offline_address(offline).translate_offline_address(offline);
+}
+
+const Module& Repo::module_from_online_address(Address online) const {
+ return guess_module(online_bases, online);
+}
+
+const Module& Repo::module_from_offline_address(Address offline) const {
+ return guess_module(offline_bases, offline);
+}
+
+} // namespace pdb
diff --git a/src/utils/file.cpp b/src/utils/file.cpp
index c0bb4bd..c25307a 100644
--- a/src/utils/file.cpp
+++ b/src/utils/file.cpp
@@ -5,70 +5,60 @@
#include "pdb/all.hpp"
-#include <safeint.h>
-
#include <Windows.h>
+#include <safeint.h>
#include <cstddef>
-
#include <stdexcept>
#include <string>
-namespace pdb
-{
- namespace file
- {
- std::size_t get_size(const std::string& path)
- {
- const Handle handle{CreateFileA(
- path.c_str(),
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL)};
-
- if (handle.get() == INVALID_HANDLE_VALUE)
- throw error::windows(GetLastError());
-
- LARGE_INTEGER size;
-
- if (!GetFileSizeEx(handle.get(), &size))
- throw error::windows(GetLastError());
-
- std::size_t result = 0;
-
- if (!msl::utilities::SafeCast(size.QuadPart, result))
- throw std::runtime_error{"invalid file size"};
-
- return result;
- }
-
- ID query_id(const std::string& path)
- {
- const Handle handle{CreateFileA(
- path.c_str(),
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL)};
-
- if (handle.get() == INVALID_HANDLE_VALUE)
- throw error::windows(GetLastError());
-
- FILE_ID_INFO id;
-
- if (!GetFileInformationByHandleEx(
- handle.get(),
- FileIdInfo,
- &id,
- sizeof(id)))
- throw error::windows(GetLastError());
-
- return {id};
- }
- }
+namespace pdb {
+namespace file {
+
+std::size_t get_size(const std::string& path) {
+ const Handle handle{CreateFileA(path.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)};
+
+ if (handle.get() == INVALID_HANDLE_VALUE)
+ throw error::windows(GetLastError());
+
+ LARGE_INTEGER size;
+
+ if (!GetFileSizeEx(handle.get(), &size))
+ throw error::windows(GetLastError());
+
+ std::size_t result = 0;
+
+ if (!msl::utilities::SafeCast(size.QuadPart, result))
+ throw std::runtime_error{"invalid file size"};
+
+ return result;
}
+
+ID query_id(const std::string& path) {
+ const Handle handle{CreateFileA(path.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)};
+
+ if (handle.get() == INVALID_HANDLE_VALUE)
+ throw error::windows(GetLastError());
+
+ FILE_ID_INFO id;
+
+ if (!GetFileInformationByHandleEx(handle.get(), FileIdInfo, &id, sizeof(id)))
+ throw error::windows(GetLastError());
+
+ return {id};
+}
+
+} // namespace file
+} // namespace pdb
diff --git a/utils/addr2name.cpp b/utils/addr2name.cpp
index 87206f2..fe749b8 100644
--- a/utils/addr2name.cpp
+++ b/utils/addr2name.cpp
@@ -4,9 +4,8 @@
// Distributed under the MIT License.
#include "command_line.hpp"
-#include "pdb_descr.hpp"
-
#include "pdb/all.hpp"
+#include "pdb_descr.hpp"
#pragma warning(push, 0)
#include <boost/program_options.hpp>
@@ -18,113 +17,89 @@
#include <string>
#include <vector>
-namespace
-{
- class Addr2Name : public SettingsParser
- {
- public:
- explicit Addr2Name(const std::string& argv0)
- : SettingsParser{argv0}
- {
- visible.add_options()
- ("pdb",
- boost::program_options::value<std::vector<PDB>>(&pdbs)
- ->value_name("ADDR,PATH"),
- "load a PDB file")
- ("lines,l",
- boost::program_options::bool_switch(&lines),
- "try to resolve source files & line numbers");
- hidden.add_options()
- ("address",
- boost::program_options::value<std::vector<pdb::Address>>(&addresses)
- ->value_name("ADDR"),
- "add an address to resolve");
- positional.add("address", -1);
- }
-
- const char* get_short_description() const override
- {
- return "[-h|--help] [--pdb ADDR,PATH]... [--] [ADDR]...";
- }
-
- std::vector<PDB> pdbs;
- std::vector<pdb::Address> addresses;
- bool lines = false;
- };
-
- std::string format_symbol(const pdb::Module& module, const pdb::Symbol& symbol)
- {
- std::ostringstream oss;
- oss << module.get_name() << '!' << symbol.get_name();
- const auto displacement = symbol.get_displacement();
- if (displacement)
- oss << '+' << pdb::format_address(displacement);
- return oss.str();
+namespace {
+
+class Addr2Name : public SettingsParser {
+public:
+ explicit Addr2Name(const std::string& argv0) : SettingsParser{argv0} {
+ namespace po = boost::program_options;
+
+ visible.add_options()(
+ "pdb", po::value<std::vector<PDB>>(&pdbs)->value_name("ADDR,PATH"), "load a PDB file");
+ visible.add_options()(
+ "lines,l", po::bool_switch(&lines), "try to resolve source files & line numbers");
+ hidden.add_options()("address",
+ po::value<std::vector<pdb::Address>>(&addresses)->value_name("ADDR"),
+ "add an address to resolve");
+ positional.add("address", -1);
}
- std::string format_line_info(const pdb::LineInfo& line_info)
- {
- std::ostringstream oss;
- oss << '[' << line_info.file_path << " @ " << line_info.line_number << ']';
- return oss.str();
+ const char* get_short_description() const override {
+ return "[-h|--help] [--pdb ADDR,PATH]... [--] [ADDR]...";
}
- void dump_error(const std::exception& e)
- {
- std::cerr << "error: " << e.what() << '\n';
- }
+ std::vector<PDB> pdbs;
+ std::vector<pdb::Address> addresses;
+ bool lines = false;
+};
+
+std::string format_symbol(const pdb::Module& module, const pdb::Symbol& symbol) {
+ std::ostringstream oss;
+ oss << module.get_name() << '!' << symbol.get_name();
+ const auto displacement = symbol.get_displacement();
+ if (displacement)
+ oss << '+' << pdb::format_address(displacement);
+ return oss.str();
+}
- void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = false)
- {
- try
- {
- const auto symbol = repo.resolve_symbol(address);
- const auto& module = repo.module_with_offline_base(symbol.get_offline_base());
-
- std::ostringstream msg;
- msg << format_symbol(module, symbol);
-
- if (lines)
- {
- try
- {
- const auto line_info = repo.resolve_line(address);
- msg << ' ' << format_line_info(line_info);
- }
- catch (const std::exception& e)
- {
- dump_error(e);
- }
- }
+std::string format_line_info(const pdb::LineInfo& line_info) {
+ std::ostringstream oss;
+ oss << '[' << line_info.file_path << " @ " << line_info.line_number << ']';
+ return oss.str();
+}
- std::cout << msg.str() << '\n';
- }
- catch (const std::exception& e)
- {
- dump_error(e);
- std::cout << pdb::format_address(address) << '\n';
+void dump_error(const std::exception& e) {
+ std::cerr << "error: " << e.what() << '\n';
+}
+
+void resolve_symbol(const pdb::Repo& repo, pdb::Address address, bool lines = false) {
+ try {
+ const auto symbol = repo.resolve_symbol(address);
+ const auto& module = repo.module_with_offline_base(symbol.get_offline_base());
+
+ std::ostringstream msg;
+ msg << format_symbol(module, symbol);
+
+ if (lines) {
+ try {
+ const auto line_info = repo.resolve_line(address);
+ msg << ' ' << format_line_info(line_info);
+ } catch (const std::exception& e) {
+ dump_error(e);
+ }
}
+
+ std::cout << msg.str() << '\n';
+ } catch (const std::exception& e) {
+ dump_error(e);
+ std::cout << pdb::format_address(address) << '\n';
}
}
-int main(int argc, char* argv[])
-{
- try
- {
+} // namespace
+
+int main(int argc, char* argv[]) {
+ try {
Addr2Name settings{argv[0]};
- try
- {
+ try {
settings.parse(argc, argv);
- }
- catch (const boost::program_options::error& e)
- {
+ } catch (const boost::program_options::error& e) {
settings.usage_error(e);
return 1;
}
- if (settings.exit_with_usage)
- {
+ if (settings.exit_with_usage) {
settings.usage();
return 0;
}
@@ -136,9 +111,7 @@ int main(int argc, char* argv[])
for (const auto& address : settings.addresses)
resolve_symbol(repo, address, settings.lines);
- }
- catch (const std::exception& e)
- {
+ } catch (const std::exception& e) {
dump_error(e);
return 1;
}
diff --git a/utils/command_line.hpp b/utils/command_line.hpp
index 352c210..c991e4a 100644
--- a/utils/command_line.hpp
+++ b/utils/command_line.hpp
@@ -15,35 +15,25 @@
#include <ostream>
#include <string>
-class SettingsParser
-{
+class SettingsParser {
public:
- explicit SettingsParser(const std::string& argv0)
- : prog_name{extract_filename(argv0)}
- {
- visible.add_options()
- ("help,h",
- "show this message and exit");
+ explicit SettingsParser(const std::string& argv0) : prog_name{extract_filename(argv0)} {
+ visible.add_options()("help,h", "show this message and exit");
}
virtual ~SettingsParser() = default;
- virtual const char* get_short_description() const
- {
- return "[--option VALUE]...";
- }
+ virtual const char* get_short_description() const { return "[--option VALUE]..."; }
- virtual void parse(int argc, char* argv[])
- {
+ virtual void parse(int argc, char* argv[]) {
boost::program_options::options_description all;
all.add(hidden).add(visible);
boost::program_options::variables_map vm;
- boost::program_options::store(
- boost::program_options::command_line_parser{argc, argv}
- .options(all)
- .positional(positional)
- .run(),
- vm);
+ boost::program_options::store(boost::program_options::command_line_parser{argc, argv}
+ .options(all)
+ .positional(positional)
+ .run(),
+ vm);
if (vm.count("help"))
exit_with_usage = true;
else
@@ -52,13 +42,9 @@ public:
bool exit_with_usage = false;
- void usage() const
- {
- std::cout << *this;
- }
+ void usage() const { std::cout << *this; }
- void usage_error(const std::exception& e) const
- {
+ void usage_error(const std::exception& e) const {
std::cerr << "usage error: " << e.what() << '\n';
std::cerr << *this;
}
@@ -69,15 +55,13 @@ protected:
boost::program_options::positional_options_description positional;
private:
- static std::string extract_filename(const std::string& path)
- {
+ static std::string extract_filename(const std::string& path) {
return boost::filesystem::path{path}.filename().string();
}
const std::string prog_name;
- friend std::ostream& operator<<(std::ostream& os, const SettingsParser& parser)
- {
+ friend std::ostream& operator<<(std::ostream& os, const SettingsParser& parser) {
const auto short_descr = parser.get_short_description();
os << "usage: " << parser.prog_name << ' ' << short_descr << '\n';
os << parser.visible;
diff --git a/utils/enum_symbols.cpp b/utils/enum_symbols.cpp
index 8fa0960..0759dd6 100644
--- a/utils/enum_symbols.cpp
+++ b/utils/enum_symbols.cpp
@@ -4,9 +4,8 @@
// Distributed under the MIT License.
#include "command_line.hpp"
-#include "pdb_descr.hpp"
-
#include "pdb/all.hpp"
+#include "pdb_descr.hpp"
#pragma warning(push, 0)
#include <boost/program_options.hpp>
@@ -17,88 +16,67 @@
#include <string>
#include <vector>
-namespace
-{
- class EnumSymbols : public SettingsParser
- {
- public:
- explicit EnumSymbols(const std::string& argv0)
- : SettingsParser{argv0}
- {
- visible.add_options()
- ("pdb",
- boost::program_options::value<std::vector<PDB>>(&pdbs)
- ->value_name("ADDR,PATH"),
- "load a PDB file")
- ("functions",
- boost::program_options::value<pdb::Symbol::Tag>(&tag)
- ->implicit_value(function_tag)
- ->zero_tokens(),
- "only list functions");
- }
+namespace {
- const char* get_short_description() const override
- {
- return "[-h|--help] [--pdb ADDR,PATH]... [--functions]";
- }
+class EnumSymbols : public SettingsParser {
+public:
+ explicit EnumSymbols(const std::string& argv0) : SettingsParser{argv0} {
+ namespace po = boost::program_options;
- std::vector<PDB> pdbs;
+ visible.add_options()(
+ "pdb", po::value<std::vector<PDB>>(&pdbs)->value_name("ADDR,PATH"), "load a PDB file");
+ visible.add_options()(
+ "functions",
+ po::value<pdb::Symbol::Tag>(&tag)->implicit_value(function_tag)->zero_tokens(),
+ "only list functions");
+ }
- bool type_specified() const
- {
- return tag != reserved_tag;
- }
+ const char* get_short_description() const override {
+ return "[-h|--help] [--pdb ADDR,PATH]... [--functions]";
+ }
- pdb::Symbol::Type get_type() const
- {
- return static_cast<pdb::Symbol::Type>(tag);
- }
+ std::vector<PDB> pdbs;
- private:
- static const auto reserved_tag = static_cast<pdb::Symbol::Tag>(pdb::Symbol::Type::RESERVED);
- static const auto function_tag = static_cast<pdb::Symbol::Tag>(pdb::Symbol::Type::Function);
+ bool type_specified() const { return tag != reserved_tag; }
- pdb::Symbol::Tag tag = reserved_tag;
- };
-}
+ pdb::Symbol::Type get_type() const { return static_cast<pdb::Symbol::Type>(tag); }
+
+private:
+ static const auto reserved_tag = static_cast<pdb::Symbol::Tag>(pdb::Symbol::Type::RESERVED);
+ static const auto function_tag = static_cast<pdb::Symbol::Tag>(pdb::Symbol::Type::Function);
+
+ pdb::Symbol::Tag tag = reserved_tag;
+};
-int main(int argc, char* argv[])
-{
- try
- {
+} // namespace
+
+int main(int argc, char* argv[]) {
+ try {
EnumSymbols settings{argv[0]};
- try
- {
+ try {
settings.parse(argc, argv);
- }
- catch (const boost::program_options::error& e)
- {
+ } catch (const boost::program_options::error& e) {
settings.usage_error(e);
return 1;
}
- if (settings.exit_with_usage)
- {
+ if (settings.exit_with_usage) {
settings.usage();
return 0;
}
pdb::Repo repo;
- for (const auto& pdb : settings.pdbs)
- {
+ for (const auto& pdb : settings.pdbs) {
const auto id = repo.add_pdb(pdb.online_base, pdb.path);
- repo.enum_symbols(id, [&] (const pdb::Symbol& symbol)
- {
+ repo.enum_symbols(id, [&](const pdb::Symbol& symbol) {
if (!settings.type_specified() || settings.get_type() == symbol.get_type())
std::cout << symbol.get_name() << '\n';
});
}
- }
- catch (const std::exception& e)
- {
+ } catch (const std::exception& e) {
std::cerr << "error: " << e.what() << '\n';
return 1;
}
diff --git a/utils/name2addr.cpp b/utils/name2addr.cpp
index 22c637b..f5b3b26 100644
--- a/utils/name2addr.cpp
+++ b/utils/name2addr.cpp
@@ -4,9 +4,8 @@
// Distributed under the MIT License.
#include "command_line.hpp"
-#include "pdb_descr.hpp"
-
#include "pdb/all.hpp"
+#include "pdb_descr.hpp"
#pragma warning(push, 0)
#include <boost/program_options.hpp>
@@ -17,74 +16,57 @@
#include <string>
#include <vector>
-namespace
-{
- class Name2Addr : public SettingsParser
- {
- public:
- explicit Name2Addr(const std::string& argv0)
- : SettingsParser{argv0}
- {
- visible.add_options()
- ("pdb",
- boost::program_options::value<std::vector<PDB>>(&pdbs)
- ->value_name("ADDR,PATH"),
- "load a PDB file");
- hidden.add_options()
- ("name",
- boost::program_options::value<std::vector<std::string>>(&names)
- ->value_name("NAME"),
- "add a name to resolve");
- positional.add("name", -1);
- }
+namespace {
- const char* get_short_description() const override
- {
- return "[-h|--help] [--pdb ADDR,PATH]... [--] [NAME]...";
- }
+class Name2Addr : public SettingsParser {
+public:
+ explicit Name2Addr(const std::string& argv0) : SettingsParser{argv0} {
+ namespace po = boost::program_options;
- std::vector<PDB> pdbs;
- std::vector<std::string> names;
- };
+ visible.add_options()(
+ "pdb", po::value<std::vector<PDB>>(&pdbs)->value_name("ADDR,PATH"), "load a PDB file");
+ hidden.add_options()("name",
+ po::value<std::vector<std::string>>(&names)->value_name("NAME"),
+ "add a name to resolve");
+ positional.add("name", -1);
+ }
- void dump_error(const std::exception& e)
- {
- std::cerr << "error: " << e.what() << '\n';
+ const char* get_short_description() const override {
+ return "[-h|--help] [--pdb ADDR,PATH]... [--] [NAME]...";
}
- void resolve_symbol(const pdb::Repo& repo, const std::string& name)
- {
- try
- {
- const auto address = repo.resolve_symbol(name).get_online_address();
- std::cout << pdb::format_address(address) << '\n';
- }
- catch (const std::exception& e)
- {
- dump_error(e);
- std::cout << name << '\n';
- }
+ std::vector<PDB> pdbs;
+ std::vector<std::string> names;
+};
+
+void dump_error(const std::exception& e) {
+ std::cerr << "error: " << e.what() << '\n';
+}
+
+void resolve_symbol(const pdb::Repo& repo, const std::string& name) {
+ try {
+ const auto address = repo.resolve_symbol(name).get_online_address();
+ std::cout << pdb::format_address(address) << '\n';
+ } catch (const std::exception& e) {
+ dump_error(e);
+ std::cout << name << '\n';
}
}
-int main(int argc, char* argv[])
-{
- try
- {
+} // namespace
+
+int main(int argc, char* argv[]) {
+ try {
Name2Addr settings{argv[0]};
- try
- {
+ try {
settings.parse(argc, argv);
- }
- catch (const boost::program_options::error& e)
- {
+ } catch (const boost::program_options::error& e) {
settings.usage_error(e);
return 1;
}
- if (settings.exit_with_usage)
- {
+ if (settings.exit_with_usage) {
settings.usage();
return 0;
}
@@ -96,9 +78,7 @@ int main(int argc, char* argv[])
for (const auto& name : settings.names)
resolve_symbol(repo, name);
- }
- catch (const std::exception& e)
- {
+ } catch (const std::exception& e) {
dump_error(e);
return 1;
}
diff --git a/utils/pdb_descr.hpp b/utils/pdb_descr.hpp
index cde815a..f2e6f38 100644
--- a/utils/pdb_descr.hpp
+++ b/utils/pdb_descr.hpp
@@ -15,13 +15,11 @@
#include <string>
#include <vector>
-struct PDB
-{
+struct PDB {
pdb::Address online_base;
std::string path;
- static PDB parse(std::string src)
- {
+ static PDB parse(std::string src) {
static constexpr auto sep = ',';
const auto sep_pos = src.find(sep);
@@ -35,8 +33,7 @@ struct PDB
return {online_base, src.substr(sep_pos + 1)};
}
- static pdb::Address parse_address(const std::string& src)
- {
+ static pdb::Address parse_address(const std::string& src) {
pdb::Address dest;
if (!pdb::parse_address(dest, src))
boost::throw_exception(boost::program_options::invalid_option_value{src});
@@ -44,32 +41,28 @@ struct PDB
}
};
-namespace boost
-{
- namespace program_options
- {
- template <typename charT>
- void validate(
- boost::any& dest,
- const std::vector<std::basic_string<charT>>& src_tokens,
- PDB*,
- int)
- {
- validators::check_first_occurrence(dest);
- const auto& src_token = validators::get_single_string(src_tokens);
- dest = any{PDB::parse(src_token)};
- }
+namespace boost {
+namespace program_options {
- template <typename charT>
- void validate(
- boost::any& dest,
- const std::vector<std::basic_string<charT>>& src_tokens,
- pdb::Address*,
- int)
- {
- validators::check_first_occurrence(dest);
- const auto& src_token = validators::get_single_string(src_tokens);
- dest = any{PDB::parse_address(src_token)};
- }
- }
+template <typename charT>
+void validate(boost::any& dest,
+ const std::vector<std::basic_string<charT>>& src_tokens,
+ PDB*,
+ int) {
+ validators::check_first_occurrence(dest);
+ const auto& src_token = validators::get_single_string(src_tokens);
+ dest = any{PDB::parse(src_token)};
+}
+
+template <typename charT>
+void validate(boost::any& dest,
+ const std::vector<std::basic_string<charT>>& src_tokens,
+ pdb::Address*,
+ int) {
+ validators::check_first_occurrence(dest);
+ const auto& src_token = validators::get_single_string(src_tokens);
+ dest = any{PDB::parse_address(src_token)};
}
+
+} // namespace program_options
+} // namespace boost