Commit dd6bb122 authored by Brendan Gregg's avatar Brendan Gregg Committed by GitHub

Merge pull request #78 from iovisor/uaddr

Uaddr
parents d2d3179a 278f840b
......@@ -303,13 +303,20 @@ void CodegenLLVM::visit(Call &call)
b_.CreateProbeReadStr(buf, call.type.size, expr_);
expr_ = buf;
}
else if (call.func == "kaddr")
else if (call.func == "kaddr")
{
uint64_t addr;
auto &name = static_cast<String&>(*call.vargs->at(0)).str;
addr = bpftrace_.resolve_kname(name.c_str());
expr_ = b_.getInt64(addr);
}
else if (call.func == "uaddr")
{
uint64_t addr;
auto &name = static_cast<String&>(*call.vargs->at(0)).str;
addr = bpftrace_.resolve_uname(name.c_str());
expr_ = b_.getInt64(addr);
}
else if (call.func == "join")
{
call.vargs->front()->accept(*this);
......
......@@ -5,6 +5,7 @@
#include "printf.h"
#include "arch/arch.h"
#include <sys/stat.h>
#include <regex>
#include "libbpf.h"
......@@ -216,6 +217,17 @@ void SemanticAnalyser::visit(Call &call)
}
}
call.type = SizedType(Type::integer, 8);
}
else if (call.func == "uaddr")
{
if (check_nargs(call, 1)) {
if (check_arg(call, Type::string, 0, true)) {
if (check_alpha_numeric(call, 0)) {
;
}
}
}
call.type = SizedType(Type::integer, 8);
}
else if (call.func == "printf") {
check_assignment(call, false, false);
......@@ -909,5 +921,23 @@ bool SemanticAnalyser::check_arg(const Call &call, Type type, int arg_num, bool
return true;
}
bool SemanticAnalyser::check_alpha_numeric(const Call &call, int arg_num)
{
if (!call.vargs)
return false;
auto &arg = static_cast<String&>(*call.vargs->at(0)).str;
bool is_alpha = std::regex_match(arg, std::regex("^[a-zA-Z0-9_-]+$"));
if (!is_alpha)
{
err_ << call.func << "() expects an alpha numeric string as input";
err_ << " (\"" << arg << "\" provided)" << std::endl;
return false;
}
return true;
}
} // namespace ast
} // namespace bpftrace
......@@ -55,6 +55,7 @@ private:
bool check_nargs(const Call &call, int expected_nargs);
bool check_varargs(const Call &call, int min_nargs, int max_nargs);
bool check_arg(const Call &call, Type type, int arg_num, bool want_literal=false);
bool check_alpha_numeric(const Call &call, int arg_num);
Probe *probe_;
std::map<std::string, SizedType> variable_val_;
......
......@@ -1145,8 +1145,7 @@ uint64_t BPFtrace::resolve_kname(const char *name)
if (found)
{
std::string first_word = line.substr(0, line.find(" "));
addr = std::stoull(first_word, 0, 16);
addr = read_address_from_output(line);
}
}
......@@ -1155,6 +1154,39 @@ uint64_t BPFtrace::resolve_kname(const char *name)
return addr;
}
uint64_t BPFtrace::resolve_uname(const char *name)
{
uint64_t addr = 0;
// TODO: switch from objdump to library call
std::string call_str = "objdump -tT /bin/bash | grep ";
call_str += name;
const char *call = call_str.c_str();
auto result = exec_system(call);
addr = read_address_from_output(result);
return addr;
}
std::string BPFtrace::exec_system(const char* cmd)
{
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
uint64_t BPFtrace::read_address_from_output(std::string output)
{
std::string first_word = output.substr(0, output.find(" "));
return std::stoull(first_word, 0, 16);
}
std::string BPFtrace::resolve_usym(uintptr_t addr, int pid, bool show_offset)
{
struct bcc_symbol sym;
......
......@@ -38,6 +38,7 @@ public:
std::string resolve_sym(uintptr_t addr, bool show_offset=false);
std::string resolve_usym(uintptr_t addr, int pid, bool show_offset=false);
uint64_t resolve_kname(const char *name);
uint64_t resolve_uname(const char *name);
std::string resolve_name(uint64_t name_id);
int pid_;
......@@ -82,6 +83,8 @@ private:
static uint64_t reduce_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t min_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t max_value(const std::vector<uint8_t> &value, int ncpus);
static uint64_t read_address_from_output(std::string output);
static std::string exec_system(const char* cmd);
static std::string hist_index_label(int power);
static std::string lhist_index_label(int number);
std::vector<uint8_t> find_empty_key(IMap &map, size_t size) const;
......
......@@ -1029,6 +1029,11 @@ TEST(codegen, call_kaddr)
// TODO: test kaddr()
}
TEST(codegen, call_uaddr)
{
// TODO: test uaddr()
}
TEST(codegen, call_hist)
{
test("kprobe:f { @x = hist(pid) }",
......
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