aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--include/pdb/repo.hpp3
-rw-r--r--src/repo.cpp101
2 files changed, 74 insertions, 30 deletions
diff --git a/include/pdb/repo.hpp b/include/pdb/repo.hpp
index fa64260..dd41b17 100644
--- a/include/pdb/repo.hpp
+++ b/include/pdb/repo.hpp
@@ -33,6 +33,9 @@ namespace pdb
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;
+
private:
Symbol symbol_from_buffer(const SymbolInfo&) const;
static Symbol symbol_from_buffer(const Module&, const SymbolInfo&);
diff --git a/src/repo.cpp b/src/repo.cpp
index 691051b..edd62d5 100644
--- a/src/repo.cpp
+++ b/src/repo.cpp
@@ -15,13 +15,71 @@ 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{"there're no modules to choose from"};
+ throw std::range_error{guess_module_no_modules(pivot)};
auto it = modules.lower_bound(pivot);
@@ -34,36 +92,13 @@ namespace pdb
if (it->first > pivot)
{
if (it == modules.cbegin())
- throw std::range_error{"couldn't choose a module"};
+ throw std::range_error{guess_module_address_too_low(pivot)};
--it;
return it->second;
}
return it->second;
}
-
- 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();
- }
}
Address Repo::add_pdb(Address online_base, const std::string& path)
@@ -120,13 +155,19 @@ namespace pdb
return symbol_from_buffer(dbghelp.resolve_symbol(name));
}
+ 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
{
- const auto offline_base = raw.get_offline_base();
- const auto it = offline_bases.find(offline_base);
- if (it == offline_bases.cend())
- throw std::runtime_error{"symbol's module hasn't been loaded (shouldn't happen)"};
- return symbol_from_buffer(it->second, raw);
+ return symbol_from_buffer(module_with_offline_base(raw.get_offline_base()), raw);
}
Symbol Repo::symbol_from_buffer(const Module& module, const SymbolInfo& raw)