aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/pdb/address.hpp13
-rw-r--r--include/pdb/all.hpp15
-rw-r--r--include/pdb/dbghelp.hpp44
-rw-r--r--include/pdb/error.hpp42
-rw-r--r--include/pdb/handle.hpp29
-rw-r--r--include/pdb/module.hpp65
-rw-r--r--include/pdb/repo.hpp49
-rw-r--r--include/pdb/symbol.hpp81
-rw-r--r--include/pdb/utils/file.hpp18
9 files changed, 356 insertions, 0 deletions
diff --git a/include/pdb/address.hpp b/include/pdb/address.hpp
new file mode 100644
index 0000000..53b25e8
--- /dev/null
+++ b/include/pdb/address.hpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include <Windows.h>
+
+namespace pdb
+{
+ typedef DWORD64 Address;
+}
diff --git a/include/pdb/all.hpp b/include/pdb/all.hpp
new file mode 100644
index 0000000..84be09e
--- /dev/null
+++ b/include/pdb/all.hpp
@@ -0,0 +1,15 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include "address.hpp"
+#include "dbghelp.hpp"
+#include "error.hpp"
+#include "handle.hpp"
+#include "module.hpp"
+#include "repo.hpp"
+#include "symbol.hpp"
+#include "utils/file.hpp"
diff --git a/include/pdb/dbghelp.hpp b/include/pdb/dbghelp.hpp
new file mode 100644
index 0000000..7b018bc
--- /dev/null
+++ b/include/pdb/dbghelp.hpp
@@ -0,0 +1,44 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include "address.hpp"
+#include "module.hpp"
+#include "symbol.hpp"
+
+#include <Windows.h>
+
+#include <functional>
+#include <string>
+
+namespace pdb
+{
+ class DbgHelp
+ {
+ public:
+ DbgHelp();
+ ~DbgHelp();
+
+ ModuleInfo load_pdb(const std::string& path) const;
+
+ typedef std::function<void (const SymbolInfo&)> OnSymbol;
+ void enum_symbols(const ModuleInfo&, const OnSymbol&) const;
+
+ SymbolInfo resolve_symbol(Address) const;
+ SymbolInfo resolve_symbol(const std::string&) const;
+
+ void close();
+
+ private:
+ ModuleInfo get_module_info(Address offline_base) const;
+
+ const HANDLE id = GetCurrentProcess();
+ bool closed = false;
+
+ DbgHelp(const DbgHelp&) = delete;
+ DbgHelp& operator=(const DbgHelp&) = delete;
+ };
+}
diff --git a/include/pdb/error.hpp b/include/pdb/error.hpp
new file mode 100644
index 0000000..6640907
--- /dev/null
+++ b/include/pdb/error.hpp
@@ -0,0 +1,42 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include <Windows.h>
+
+#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()};
+ }
+ }
+}
diff --git a/include/pdb/handle.hpp b/include/pdb/handle.hpp
new file mode 100644
index 0000000..52fb805
--- /dev/null
+++ b/include/pdb/handle.hpp
@@ -0,0 +1,29 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#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);
+ }
+ };
+
+ typedef std::unique_ptr<void, CloseHandle> Handle;
+}
diff --git a/include/pdb/module.hpp b/include/pdb/module.hpp
new file mode 100644
index 0000000..118a53b
--- /dev/null
+++ b/include/pdb/module.hpp
@@ -0,0 +1,65 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include "address.hpp"
+
+#include <Windows.h>
+#include <DbgHelp.h>
+
+#include <cstring>
+
+#include <string>
+
+namespace pdb
+{
+ class ModuleInfo
+ {
+ public:
+ typedef IMAGEHLP_MODULE64 Raw;
+
+ ModuleInfo()
+ : raw{prepare_buffer()}
+ { }
+
+ explicit ModuleInfo(const Raw& raw)
+ : raw{raw}
+ { }
+
+ explicit operator Raw&() { return raw; }
+
+ explicit operator const Raw&() const { return raw; }
+
+ Address get_offline_base() const { return raw.BaseOfImage; }
+
+ std::string get_name() const { return raw.ModuleName; }
+
+ private:
+ static Raw prepare_buffer()
+ {
+ Raw raw;
+ std::memset(&raw, 0, sizeof(raw));
+ raw.SizeOfStruct = sizeof(raw);
+ return raw;
+ }
+
+ Raw raw;
+ };
+
+ class Module : public ModuleInfo
+ {
+ public:
+ Module(Address online_base, const ModuleInfo& info)
+ : ModuleInfo{info}
+ , online_base{online_base}
+ { }
+
+ Address get_online_base() const { return online_base; }
+
+ private:
+ const Address online_base;
+ };
+}
diff --git a/include/pdb/repo.hpp b/include/pdb/repo.hpp
new file mode 100644
index 0000000..239bd7e
--- /dev/null
+++ b/include/pdb/repo.hpp
@@ -0,0 +1,49 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include "address.hpp"
+#include "dbghelp.hpp"
+#include "module.hpp"
+#include "symbol.hpp"
+
+#include <functional>
+#include <map>
+#include <string>
+
+namespace pdb
+{
+ class Repo
+ {
+ public:
+ Repo() = default;
+
+ Address add_pdb(Address online_base, const std::string& path);
+
+ 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;
+
+ Symbol resolve_symbol(Address) const;
+ Symbol resolve_symbol(const std::string&) const;
+
+ private:
+ Symbol symbol_from_buffer(const SymbolInfo&) const;
+ Symbol symbol_from_buffer(const Module&, const SymbolInfo&) const;
+
+ const Module& module_from_online_address(Address) const;
+ const Module& module_from_offline_address(Address) const;
+
+ Address address_offline_to_online(Address) const;
+ Address address_online_to_offline(Address) const;
+
+ const DbgHelp dbghelp;
+
+ std::map<Address, Module> online_modules;
+ std::map<Address, const Module&> offline_modules;
+ };
+}
diff --git a/include/pdb/symbol.hpp b/include/pdb/symbol.hpp
new file mode 100644
index 0000000..9e11d04
--- /dev/null
+++ b/include/pdb/symbol.hpp
@@ -0,0 +1,81 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include "module.hpp"
+
+#include <Windows.h>
+#include <DbgHelp.h>
+
+#include <cstring>
+
+#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;
+ }
+
+ SymbolInfo(const Raw& raw)
+ : SymbolInfo{}
+ {
+ std::memcpy(buffer, &raw, raw.SizeOfStruct + raw.NameLen - 1);
+ }
+
+ explicit operator Raw&() { return raw; }
+
+ explicit operator const Raw&() const { return raw; }
+
+ std::string get_name() const { return {raw.Name, raw.NameLen}; }
+
+ Address get_offline_base() const { return raw.ModBase; }
+
+ Address get_offline_address() const { return raw.Address; }
+
+ typedef ULONG Tag;
+
+ Tag get_tag() const { return raw.Tag; }
+
+ enum class Type : Tag
+ {
+ Function = SymTagFunction,
+ RESERVED = SymTagMax,
+ };
+
+ Type get_type() const { return static_cast<Type>(get_tag()); }
+
+ bool is_function() const { return get_type() == Type::Function; }
+
+ private:
+ unsigned char buffer[sizeof(Raw) + MAX_SYM_NAME - 1];
+
+ protected:
+ Raw& raw;
+ };
+
+ 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; }
+
+ private:
+ const Address online_address;
+ };
+}
diff --git a/include/pdb/utils/file.hpp b/include/pdb/utils/file.hpp
new file mode 100644
index 0000000..5b83f2b
--- /dev/null
+++ b/include/pdb/utils/file.hpp
@@ -0,0 +1,18 @@
+// Copyright (c) 2017 Egor Tensin <Egor.Tensin@gmail.com>
+// This file is part of the "PDB repository" project.
+// For details, see https://github.com/egor-tensin/pdb-repo.
+// Distributed under the MIT License.
+
+#pragma once
+
+#include <cstddef>
+
+#include <string>
+
+namespace pdb
+{
+ namespace file
+ {
+ std::size_t get_size(const std::string&);
+ }
+}