Commit 9e02d82d authored by Teng Qin's avatar Teng Qin

Fix symbol resolution for shared libraries with multiple load sections

parent a0c5de1a
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
#include <algorithm>
#include <cxxabi.h> #include <cxxabi.h>
#include <cstring> #include <cstring>
#include <fcntl.h> #include <fcntl.h>
...@@ -114,7 +113,7 @@ ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option) ...@@ -114,7 +113,7 @@ ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option)
int ProcSyms::_add_load_sections(uint64_t v_addr, uint64_t mem_sz, int ProcSyms::_add_load_sections(uint64_t v_addr, uint64_t mem_sz,
uint64_t file_offset, void *payload) { uint64_t file_offset, void *payload) {
auto module = static_cast<Module *>(payload); auto module = static_cast<Module *>(payload);
module->add_range(v_addr, v_addr + mem_sz); module->ranges_.emplace_back(v_addr, v_addr + mem_sz, file_offset);
return 0; return 0;
} }
...@@ -162,7 +161,11 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end, ...@@ -162,7 +161,11 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
else else
return 0; return 0;
} }
it->add_range(start, end); it->ranges_.emplace_back(start, end, offset);
// perf-PID map is added last. We try both inside the Process's mount
// namespace + chroot, and in global /tmp. Make sure we only add one.
if (it->type_ == ModuleType::PERF_MAP)
return -1;
return 0; return 0;
} }
...@@ -275,21 +278,12 @@ void ProcSyms::Module::load_sym_table() { ...@@ -275,21 +278,12 @@ void ProcSyms::Module::load_sym_table() {
std::sort(syms_.begin(), syms_.end()); std::sort(syms_.begin(), syms_.end());
} }
void ProcSyms::Module::add_range(uint64_t st, uint64_t en) {
if (!ranges_.empty()) {
Range &last = ranges_.back();
if (st >= last.start && st <= last.end) {
last.end = std::max(en, last.end);
return;
}
}
ranges_.emplace_back(st, en);
}
bool ProcSyms::Module::contains(uint64_t addr, uint64_t &offset) const { bool ProcSyms::Module::contains(uint64_t addr, uint64_t &offset) const {
for (const auto &range : ranges_) for (const auto &range : ranges_)
if (addr >= range.start && addr < range.end) { if (addr >= range.start && addr < range.end) {
offset = type_ == ModuleType::SO ? addr - range.start : addr; offset = (type_ == ModuleType::SO)
? (addr - range.start + range.file_offset)
: addr;
return true; return true;
} }
return false; return false;
......
...@@ -92,10 +92,12 @@ class ProcSyms : SymbolCache { ...@@ -92,10 +92,12 @@ class ProcSyms : SymbolCache {
struct Range { struct Range {
uint64_t start; uint64_t start;
uint64_t end; uint64_t end;
Range(uint64_t s, uint64_t e) : start(s), end(e) {} uint64_t file_offset;
Range(uint64_t s, uint64_t e, uint64_t f)
: start(s), end(e), file_offset(f) {}
}; };
Module(const char *name, ProcMountNS* mount_ns, Module(const char *name, ProcMountNS *mount_ns,
struct bcc_symbol_option *option); struct bcc_symbol_option *option);
bool init(); bool init();
...@@ -111,7 +113,6 @@ class ProcSyms : SymbolCache { ...@@ -111,7 +113,6 @@ class ProcSyms : SymbolCache {
void load_sym_table(); void load_sym_table();
void add_range(uint64_t st, uint64_t en);
bool contains(uint64_t addr, uint64_t &offset) const; bool contains(uint64_t addr, uint64_t &offset) const;
uint64_t start() const { return ranges_.begin()->start; } uint64_t start() const { return ranges_.begin()->start; }
......
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