cc: Correctly treat PIE files as shared objects for symbols
authorSasha Goldshtein <goldshtn@gmail.com>
Thu, 9 Feb 2017 06:18:34 +0000 (01:18 -0500)
committerSasha Goldshtein <goldshtn@gmail.com>
Tue, 21 Feb 2017 09:30:43 +0000 (09:30 +0000)
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
src/cc/syms.h

index ac9cc61..34d8845 100644 (file)
@@ -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<Module *>(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;
 }
index 12ee59e..6fbf843 100644 (file)
@@ -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<std::string> symnames_;
     std::vector<Symbol> 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,