From 7d8c29ce872fc4d9dceeb456f034b25b86ff9d2e Mon Sep 17 00:00:00 2001 From: Sasha Goldshtein Date: Thu, 9 Feb 2017 01:18:34 -0500 Subject: [PATCH] cc: Correctly treat PIE files as shared objects for symbols When resolving symbols, ProcSyms would treat position-independent executables (PIE files) incorrectly, resulting in symbol resolution failures. Specifically, PIE files are treated like shared objects for ASLR, which means all symbol addresses in the file need to be taken relative to the executable load address at runtime, the same as with dynamic library shared objects. The fix is in the `is_so()` method on `ProcSyms::Module`, which now uses the correct `bcc_elf_is_shared` helper for testing if a file is a shared object rather than just looking at the extension ".so", which is very brittle -- and wrong. --- src/cc/bcc_syms.cc | 9 +++++---- src/cc/syms.h | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cc/bcc_syms.cc b/src/cc/bcc_syms.cc index ac9cc61..34d8845 100644 --- a/src/cc/bcc_syms.cc +++ b/src/cc/bcc_syms.cc @@ -140,6 +140,11 @@ bool ProcSyms::resolve_name(const char *module, const char *name, return false; } +ProcSyms::Module::Module(const char *name, uint64_t start, uint64_t end) + : name_(name), start_(start), end_(end) { + is_so_ = bcc_elf_is_shared_obj(name) == 1; +} + int ProcSyms::Module::_add_symbol(const char *symname, uint64_t start, uint64_t end, int flags, void *p) { Module *m = static_cast(p); @@ -148,10 +153,6 @@ int ProcSyms::Module::_add_symbol(const char *symname, uint64_t start, return 0; } -bool ProcSyms::Module::is_so() const { - return strstr(name_.c_str(), ".so") != nullptr; -} - bool ProcSyms::Module::is_perf_map() const { return strstr(name_.c_str(), ".map") != nullptr; } diff --git a/src/cc/syms.h b/src/cc/syms.h index 12ee59e..6fbf843 100644 --- a/src/cc/syms.h +++ b/src/cc/syms.h @@ -79,18 +79,18 @@ class ProcSyms : SymbolCache { }; struct Module { - Module(const char *name, uint64_t start, uint64_t end) - : name_(name), start_(start), end_(end) {} + Module(const char *name, uint64_t start, uint64_t end); std::string name_; uint64_t start_; uint64_t end_; + bool is_so_; std::unordered_set symnames_; std::vector syms_; void load_sym_table(); bool find_addr(uint64_t addr, struct bcc_symbol *sym); bool find_name(const char *symname, uint64_t *addr); - bool is_so() const; + bool is_so() const { return is_so_; } bool is_perf_map() const; static int _add_symbol(const char *symname, uint64_t start, uint64_t end, -- 2.7.4