Commit c924193f authored by 4ast's avatar 4ast Committed by GitHub

Merge pull request #1022 from goldshtn/syms-multiple-regions

Symbol resolution with multiple executable regions per module
parents b69fe977 f141d1b9
...@@ -101,7 +101,11 @@ void ProcSyms::refresh() { ...@@ -101,7 +101,11 @@ void ProcSyms::refresh() {
int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end, int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
void *payload) { void *payload) {
ProcSyms *ps = static_cast<ProcSyms *>(payload); ProcSyms *ps = static_cast<ProcSyms *>(payload);
ps->modules_.emplace_back(modname, start, end); auto it = std::find_if(ps->modules_.begin(), ps->modules_.end(),
[=](const ProcSyms::Module &m) { return m.name_ == modname; });
if (it == ps->modules_.end())
it = ps->modules_.insert(ps->modules_.end(), modname);
it->ranges_.push_back(ProcSyms::Module::Range(start, end));
return 0; return 0;
} }
...@@ -116,7 +120,7 @@ bool ProcSyms::resolve_addr(uint64_t addr, struct bcc_symbol *sym) { ...@@ -116,7 +120,7 @@ bool ProcSyms::resolve_addr(uint64_t addr, struct bcc_symbol *sym) {
const char *original_module = nullptr; const char *original_module = nullptr;
for (Module &mod : modules_) { for (Module &mod : modules_) {
if (addr >= mod.start_ && addr < mod.end_) { if (mod.contains(addr)) {
bool res = mod.find_addr(addr, sym); bool res = mod.find_addr(addr, sym);
if (sym->name) { if (sym->name) {
sym->demangle_name = abi::__cxa_demangle(sym->name, nullptr, nullptr, nullptr); sym->demangle_name = abi::__cxa_demangle(sym->name, nullptr, nullptr, nullptr);
...@@ -155,8 +159,8 @@ bool ProcSyms::resolve_name(const char *module, const char *name, ...@@ -155,8 +159,8 @@ bool ProcSyms::resolve_name(const char *module, const char *name,
return false; return false;
} }
ProcSyms::Module::Module(const char *name, uint64_t start, uint64_t end) ProcSyms::Module::Module(const char *name)
: name_(name), start_(start), end_(end) { : name_(name) {
is_so_ = bcc_elf_is_shared_obj(name) == 1; is_so_ = bcc_elf_is_shared_obj(name) == 1;
} }
...@@ -184,12 +188,20 @@ void ProcSyms::Module::load_sym_table() { ...@@ -184,12 +188,20 @@ void ProcSyms::Module::load_sym_table() {
std::sort(syms_.begin(), syms_.end()); std::sort(syms_.begin(), syms_.end());
} }
bool ProcSyms::Module::contains(uint64_t addr) const {
for (const auto &range : ranges_) {
if (addr >= range.start && addr < range.end)
return true;
}
return false;
}
bool ProcSyms::Module::find_name(const char *symname, uint64_t *addr) { bool ProcSyms::Module::find_name(const char *symname, uint64_t *addr) {
load_sym_table(); load_sym_table();
for (Symbol &s : syms_) { for (Symbol &s : syms_) {
if (*(s.name) == symname) { if (*(s.name) == symname) {
*addr = is_so() ? start_ + s.start : s.start; *addr = is_so() ? start() + s.start : s.start;
return true; return true;
} }
} }
...@@ -197,7 +209,7 @@ bool ProcSyms::Module::find_name(const char *symname, uint64_t *addr) { ...@@ -197,7 +209,7 @@ bool ProcSyms::Module::find_name(const char *symname, uint64_t *addr) {
} }
bool ProcSyms::Module::find_addr(uint64_t addr, struct bcc_symbol *sym) { bool ProcSyms::Module::find_addr(uint64_t addr, struct bcc_symbol *sym) {
uint64_t offset = is_so() ? (addr - start_) : addr; uint64_t offset = is_so() ? (addr - start()) : addr;
load_sym_table(); load_sym_table();
...@@ -230,6 +242,9 @@ bool ProcSyms::Module::find_addr(uint64_t addr, struct bcc_symbol *sym) { ...@@ -230,6 +242,9 @@ bool ProcSyms::Module::find_addr(uint64_t addr, struct bcc_symbol *sym) {
sym->offset = (offset - it->start); sym->offset = (offset - it->start);
return true; return true;
} }
// But don't step beyond begin()!
if (it == syms_.begin())
break;
} }
return false; return false;
......
...@@ -79,15 +79,22 @@ class ProcSyms : SymbolCache { ...@@ -79,15 +79,22 @@ class ProcSyms : SymbolCache {
}; };
struct Module { struct Module {
Module(const char *name, uint64_t start, uint64_t end); struct Range {
uint64_t start;
uint64_t end;
Range(uint64_t s, uint64_t e) : start(s), end(e) {}
};
Module(const char *name);
std::string name_; std::string name_;
uint64_t start_; std::vector<Range> ranges_;
uint64_t end_;
bool is_so_; bool is_so_;
std::unordered_set<std::string> symnames_; std::unordered_set<std::string> symnames_;
std::vector<Symbol> syms_; std::vector<Symbol> syms_;
void load_sym_table(); void load_sym_table();
bool contains(uint64_t addr) const;
uint64_t start() const { return ranges_.begin()->start; }
bool find_addr(uint64_t addr, struct bcc_symbol *sym); bool find_addr(uint64_t addr, struct bcc_symbol *sym);
bool find_name(const char *symname, uint64_t *addr); bool find_name(const char *symname, uint64_t *addr);
bool is_so() const { return is_so_; } bool is_so() const { return is_so_; }
......
...@@ -63,7 +63,7 @@ bool Probe::resolve_global_address(uint64_t *global, const uint64_t addr) { ...@@ -63,7 +63,7 @@ bool Probe::resolve_global_address(uint64_t *global, const uint64_t addr) {
} }
bool Probe::add_to_semaphore(int16_t val) { bool Probe::add_to_semaphore(int16_t val) {
assert(pid_ && attached_semaphore_); assert(pid_);
if (!attached_semaphore_) { if (!attached_semaphore_) {
uint64_t addr; uint64_t addr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment