Commit 5db9d37b authored by Teng Qin's avatar Teng Qin

Add ELF load ranges for executable binaries

parent 97562956
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* 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>
...@@ -28,9 +29,10 @@ ...@@ -28,9 +29,10 @@
#include "bcc_perf_map.h" #include "bcc_perf_map.h"
#include "bcc_proc.h" #include "bcc_proc.h"
#include "bcc_syms.h" #include "bcc_syms.h"
#include "common.h"
#include "vendor/tinyformat.hpp"
#include "syms.h" #include "syms.h"
#include "vendor/tinyformat.hpp"
ino_t ProcStat::getinode_() { ino_t ProcStat::getinode_() {
struct stat s; struct stat s;
...@@ -109,8 +111,33 @@ ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option) ...@@ -109,8 +111,33 @@ ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option)
load_modules(); load_modules();
} }
bool ProcSyms::load_modules() { int ProcSyms::_add_load_sections(uint64_t v_addr, uint64_t mem_sz,
return bcc_procutils_each_module(pid_, _add_module, this) == 0; uint64_t file_offset, void *payload) {
auto module = static_cast<Module *>(payload);
module->add_range(v_addr, v_addr + mem_sz);
return 0;
}
void ProcSyms::load_exe() {
std::string exe = ebpf::get_pid_exe(pid_);
Module module(exe.c_str(), mount_ns_instance_.get(), &symbol_option_);
if (!module.init())
return;
if (module.type_ != ModuleType::EXEC)
return;
ProcMountNSGuard g(mount_ns_instance_.get());
bcc_elf_foreach_load_section(exe.c_str(), &_add_load_sections, &module);
if (!module.ranges_.empty())
modules_.emplace_back(std::move(module));
}
void ProcSyms::load_modules() {
load_exe();
bcc_procutils_each_module(pid_, _add_module, this);
} }
void ProcSyms::refresh() { void ProcSyms::refresh() {
...@@ -135,7 +162,7 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end, ...@@ -135,7 +162,7 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
else else
return 0; return 0;
} }
it->ranges_.emplace_back(start, end); it->add_range(start, end);
return 0; return 0;
} }
...@@ -248,6 +275,17 @@ void ProcSyms::Module::load_sym_table() { ...@@ -248,6 +275,17 @@ 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) {
......
...@@ -110,8 +110,11 @@ class ProcSyms : SymbolCache { ...@@ -110,8 +110,11 @@ class ProcSyms : SymbolCache {
std::vector<Symbol> syms_; std::vector<Symbol> syms_;
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; }
bool find_addr(uint64_t offset, struct bcc_symbol *sym); bool find_addr(uint64_t offset, struct bcc_symbol *sym);
bool find_name(const char *symname, uint64_t *addr); bool find_name(const char *symname, uint64_t *addr);
...@@ -125,8 +128,11 @@ class ProcSyms : SymbolCache { ...@@ -125,8 +128,11 @@ class ProcSyms : SymbolCache {
std::unique_ptr<ProcMountNS> mount_ns_instance_; std::unique_ptr<ProcMountNS> mount_ns_instance_;
bcc_symbol_option symbol_option_; bcc_symbol_option symbol_option_;
static int _add_load_sections(uint64_t v_addr, uint64_t mem_sz,
uint64_t file_offset, void *payload);
static int _add_module(const char *, uint64_t, uint64_t, bool, void *); static int _add_module(const char *, uint64_t, uint64_t, bool, void *);
bool load_modules(); void load_exe();
void load_modules();
public: public:
ProcSyms(int pid, struct bcc_symbol_option *option = nullptr); ProcSyms(int pid, struct bcc_symbol_option *option = nullptr);
......
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