Commit dd0a6064 authored by Vicent Marti's avatar Vicent Marti

cc: Implement symbol resolution for USDT

parent 48501550
...@@ -40,28 +40,18 @@ Probe::Probe(const char *bin_path, const char *provider, const char *name, ...@@ -40,28 +40,18 @@ Probe::Probe(const char *bin_path, const char *provider, const char *name,
name_(name), name_(name),
semaphore_(semaphore) {} semaphore_(semaphore) {}
const std::string &Probe::usdt_thunks(const std::string &prefix) { bool Probe::usdt_thunks(std::ostream &stream, const std::string &prefix) {
if (!gen_thunks_.empty())
return gen_thunks_;
std::ostringstream stream;
for (size_t i = 0; i < locations_.size(); ++i) { for (size_t i = 0; i < locations_.size(); ++i) {
tfm::format( tfm::format(
stream, stream,
"int %s_thunk_%d(struct pt_regs *ctx) { return %s(ctx, %d); }\n", "int %s_thunk_%d(struct pt_regs *ctx) { return %s(ctx, %d); }\n",
prefix, i, prefix, i); prefix, i, prefix, i);
} }
return true;
gen_thunks_ = stream.str();
return gen_thunks_;
} }
const std::string &Probe::usdt_cases(const optional<int> &pid) { bool Probe::usdt_cases(std::ostream &stream, const optional<int> &pid) {
if (!gen_cases_.empty()) const size_t arg_count = locations_[0].arguments_.size();
return gen_cases_;
std::ostringstream stream;
size_t arg_count = locations_[0].arguments_.size();
for (size_t arg_n = 0; arg_n < arg_count; ++arg_n) { for (size_t arg_n = 0; arg_n < arg_count; ++arg_n) {
Argument *largest = nullptr; Argument *largest = nullptr;
...@@ -80,14 +70,13 @@ const std::string &Probe::usdt_cases(const optional<int> &pid) { ...@@ -80,14 +70,13 @@ const std::string &Probe::usdt_cases(const optional<int> &pid) {
for (size_t arg_n = 0; arg_n < location.arguments_.size(); ++arg_n) { for (size_t arg_n = 0; arg_n < location.arguments_.size(); ++arg_n) {
Argument *arg = location.arguments_[arg_n]; Argument *arg = location.arguments_[arg_n];
arg->assign_to_local(stream, tfm::format("arg%d", arg_n + 1), bin_path_, if (!arg->assign_to_local(stream, tfm::format("arg%d", arg_n + 1),
pid); bin_path_, pid))
return false;
} }
stream << "}\n"; stream << "}\n";
} }
return true;
gen_cases_ = stream.str();
return gen_cases_;
} }
void Probe::add_location(uint64_t addr, const char *fmt) { void Probe::add_location(uint64_t addr, const char *fmt) {
......
...@@ -35,15 +35,15 @@ private: ...@@ -35,15 +35,15 @@ private:
optional<std::string> deref_ident_; optional<std::string> deref_ident_;
optional<std::string> register_name_; optional<std::string> register_name_;
uint64_t get_global_address(const std::string &binpath, bool get_global_address(uint64_t *address, const std::string &binpath,
const optional<int> &pid) const; const optional<int> &pid) const;
static const std::unordered_map<std::string, std::string> translations_; static const std::unordered_map<std::string, std::string> translations_;
public: public:
Argument(); Argument();
~Argument(); ~Argument();
void assign_to_local(std::ostream &stream, const std::string &local_name, bool assign_to_local(std::ostream &stream, const std::string &local_name,
const std::string &binpath, const std::string &binpath,
const optional<int> &pid = nullopt) const; const optional<int> &pid = nullopt) const;
...@@ -103,19 +103,16 @@ class Probe { ...@@ -103,19 +103,16 @@ class Probe {
std::vector<Location> locations_; std::vector<Location> locations_;
std::string gen_thunks_;
std::string gen_cases_;
public: public:
Probe(const char *bin_path, const char *provider, const char *name, Probe(const char *bin_path, const char *provider, const char *name,
uint64_t semaphore); uint64_t semaphore);
void add_location(uint64_t addr, const char *fmt); void add_location(uint64_t addr, const char *fmt);
bool need_enable() const { return semaphore_ != 0x0; } bool need_enable() const { return semaphore_ != 0x0; }
size_t location_count() const { return locations_.size(); } size_t num_locations() const { return locations_.size(); }
const std::string &usdt_thunks(const std::string &prefix); bool usdt_thunks(std::ostream &stream, const std::string &prefix);
const std::string &usdt_cases(const optional<int> &pid); bool usdt_cases(std::ostream &stream, const optional<int> &pid = nullopt);
friend class Context; friend class Context;
}; };
...@@ -131,5 +128,7 @@ class Context { ...@@ -131,5 +128,7 @@ class Context {
public: public:
Context(const std::string &bin_path); Context(const std::string &bin_path);
Context(int pid); Context(int pid);
size_t num_probes() const { return probes_.size(); }
}; };
} }
...@@ -15,9 +15,13 @@ ...@@ -15,9 +15,13 @@
*/ */
#include <unordered_map> #include <unordered_map>
#include "syms.h"
#include "usdt.h" #include "usdt.h"
#include "vendor/tinyformat.hpp" #include "vendor/tinyformat.hpp"
#include "bcc_elf.h"
#include "bcc_syms.h"
namespace USDT { namespace USDT {
Argument::Argument() {} Argument::Argument() {}
...@@ -49,12 +53,25 @@ void Argument::normalize_register_name(std::string *normalized) const { ...@@ -49,12 +53,25 @@ void Argument::normalize_register_name(std::string *normalized) const {
normalized->assign(it->second); normalized->assign(it->second);
} }
uint64_t Argument::get_global_address(const std::string &binpath, bool Argument::get_global_address(uint64_t *address, const std::string &binpath,
const optional<int> &pid) const { const optional<int> &pid) const {
return 0x0; if (pid) {
return ProcSyms(*pid).resolve_name(binpath.c_str(), deref_ident_->c_str(),
address);
}
if (bcc_elf_is_shared_obj(binpath.c_str()) == 0) {
struct bcc_symbol sym = {deref_ident_->c_str(), binpath.c_str(), 0x0};
if (!bcc_find_symbol_addr(&sym) && sym.offset) {
*address = sym.offset;
return true;
}
}
return false;
} }
void Argument::assign_to_local(std::ostream &stream, bool Argument::assign_to_local(std::ostream &stream,
const std::string &local_name, const std::string &local_name,
const std::string &binpath, const std::string &binpath,
const optional<int> &pid) const { const optional<int> &pid) const {
...@@ -63,12 +80,12 @@ void Argument::assign_to_local(std::ostream &stream, ...@@ -63,12 +80,12 @@ void Argument::assign_to_local(std::ostream &stream,
if (constant_) { if (constant_) {
tfm::format(stream, "%s = %d;\n", local_name, *constant_); tfm::format(stream, "%s = %d;\n", local_name, *constant_);
return; return true;
} }
if (!deref_offset_) { if (!deref_offset_) {
tfm::format(stream, "%s = (%s)ctx->%s;\n", local_name, ctype(), regname); tfm::format(stream, "%s = (%s)ctx->%s;\n", local_name, ctype(), regname);
return; return true;
} }
if (deref_offset_ && !deref_ident_) { if (deref_offset_ && !deref_ident_) {
...@@ -78,16 +95,24 @@ void Argument::assign_to_local(std::ostream &stream, ...@@ -78,16 +95,24 @@ void Argument::assign_to_local(std::ostream &stream,
" bpf_probe_read(&%s, sizeof(%s), (void *)__temp);\n" " bpf_probe_read(&%s, sizeof(%s), (void *)__temp);\n"
"}\n", "}\n",
regname, *deref_offset_, local_name, local_name); regname, *deref_offset_, local_name, local_name);
return; return true;
}
if (deref_offset_ && deref_ident_) {
uint64_t global_address;
if (!get_global_address(&global_address, binpath, pid))
return false;
tfm::format(stream,
"{\n"
" u64 __temp = 0x%xull + %d;\n"
" bpf_probe_read(&%s, sizeof(%s), (void *)__temp);\n"
"}\n",
global_address, *deref_offset_, local_name, local_name);
return true;
} }
tfm::format(stream, return false;
"{\n"
" u64 __temp = 0x%xull + %d;\n"
" bpf_probe_read(&%s, sizeof(%s), (void *)__temp);\n"
"}\n",
get_global_address(binpath, pid), *deref_offset_, local_name,
local_name);
} }
ssize_t ArgumentParser::parse_number(ssize_t pos, optional<int> *result) { ssize_t ArgumentParser::parse_number(ssize_t pos, optional<int> *result) {
......
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