Commit c198723b authored by Alastair Robertson's avatar Alastair Robertson

Add ustack builtin

parent 99d36e85
...@@ -103,7 +103,9 @@ int BPFtrace::print_map(Map &map) const ...@@ -103,7 +103,9 @@ int BPFtrace::print_map(Map &map) const
return -1; return -1;
} }
if (map.type_ == Type::stack) if (map.type_ == Type::stack)
std::cout << get_stack(value, 8); std::cout << get_stack(value, false, 8);
else if (map.type_ == Type::ustack)
std::cout << get_stack(value, true, 8);
else else
std::cout << value << std::endl; std::cout << value << std::endl;
...@@ -269,13 +271,13 @@ std::vector<uint8_t> BPFtrace::find_empty_key(Map &map, size_t size) const ...@@ -269,13 +271,13 @@ std::vector<uint8_t> BPFtrace::find_empty_key(Map &map, size_t size) const
throw std::runtime_error("Could not find empty key"); throw std::runtime_error("Could not find empty key");
} }
std::string BPFtrace::get_stack(uint32_t stackid, int indent) const std::string BPFtrace::get_stack(uint32_t stackid, bool ustack, int indent) const
{ {
auto stack_trace = std::vector<uint64_t>(MAX_STACK_SIZE); auto stack_trace = std::vector<uint64_t>(MAX_STACK_SIZE);
int err = bpf_lookup_elem(stackid_map_->mapfd_, &stackid, stack_trace.data()); int err = bpf_lookup_elem(stackid_map_->mapfd_, &stackid, stack_trace.data());
if (err) if (err)
{ {
std::cerr << "Error looking up stack id: " << err << std::endl; std::cerr << "Error looking up stack id " << stackid << ": " << err << std::endl;
return ""; return "";
} }
...@@ -289,7 +291,7 @@ std::string BPFtrace::get_stack(uint32_t stackid, int indent) const ...@@ -289,7 +291,7 @@ std::string BPFtrace::get_stack(uint32_t stackid, int indent) const
{ {
if (addr == 0) if (addr == 0)
break; break;
if (ksyms.resolve_addr(addr, &sym)) if (!ustack && ksyms.resolve_addr(addr, &sym))
stack << padding << sym.name << "+" << sym.offset << ":" << sym.module << std::endl; stack << padding << sym.name << "+" << sym.offset << ":" << sym.module << std::endl;
else else
stack << padding << (void*)addr << std::endl; stack << padding << (void*)addr << std::endl;
......
...@@ -19,7 +19,7 @@ public: ...@@ -19,7 +19,7 @@ public:
int start(); int start();
void stop(); void stop();
int print_maps() const; int print_maps() const;
std::string get_stack(uint32_t stackid, int indent=0) const; std::string get_stack(uint32_t stackid, bool ustack, int indent=0) const;
std::map<std::string, std::unique_ptr<Map>> maps_; std::map<std::string, std::unique_ptr<Map>> maps_;
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_; std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
......
...@@ -23,9 +23,9 @@ void CodegenLLVM::visit(Builtin &builtin) ...@@ -23,9 +23,9 @@ void CodegenLLVM::visit(Builtin &builtin)
{ {
expr_ = b_.CreateGetNs(); expr_ = b_.CreateGetNs();
} }
else if (builtin.ident == "stack") else if (builtin.ident == "stack" || builtin.ident == "ustack")
{ {
expr_ = b_.CreateGetStackId(ctx_); expr_ = b_.CreateGetStackId(ctx_, builtin.ident == "ustack");
} }
else if (builtin.ident == "pid" || builtin.ident == "tid") else if (builtin.ident == "pid" || builtin.ident == "tid")
{ {
......
...@@ -182,10 +182,14 @@ CallInst *IRBuilderBPF::CreateGetUidGid() ...@@ -182,10 +182,14 @@ CallInst *IRBuilderBPF::CreateGetUidGid()
return CreateCall(getuidgid_func); return CreateCall(getuidgid_func);
} }
CallInst *IRBuilderBPF::CreateGetStackId(Value *ctx) CallInst *IRBuilderBPF::CreateGetStackId(Value *ctx, bool ustack)
{ {
Value *map_ptr = CreateBpfPseudoCall(bpftrace_.stackid_map_->mapfd_); Value *map_ptr = CreateBpfPseudoCall(bpftrace_.stackid_map_->mapfd_);
Value *flags = getInt64(0);
int flags = 0;
if (ustack)
flags |= (1<<8);
Value *flags_val = getInt64(flags);
// int bpf_get_stackid(ctx, map, flags) // int bpf_get_stackid(ctx, map, flags)
// Return: >= 0 stackid on success or negative error // Return: >= 0 stackid on success or negative error
...@@ -198,7 +202,7 @@ CallInst *IRBuilderBPF::CreateGetStackId(Value *ctx) ...@@ -198,7 +202,7 @@ CallInst *IRBuilderBPF::CreateGetStackId(Value *ctx)
Instruction::IntToPtr, Instruction::IntToPtr,
getInt64(BPF_FUNC_get_stackid), getInt64(BPF_FUNC_get_stackid),
getstackid_func_ptr_type); getstackid_func_ptr_type);
return CreateCall(getstackid_func, {ctx, map_ptr, flags}); return CreateCall(getstackid_func, {ctx, map_ptr, flags_val});
} }
} // namespace ast } // namespace ast
......
...@@ -27,7 +27,7 @@ public: ...@@ -27,7 +27,7 @@ public:
CallInst *CreateGetNs(); CallInst *CreateGetNs();
CallInst *CreateGetPidTgid(); CallInst *CreateGetPidTgid();
CallInst *CreateGetUidGid(); CallInst *CreateGetUidGid();
CallInst *CreateGetStackId(Value *ctx); CallInst *CreateGetStackId(Value *ctx, bool ustack);
private: private:
Module &module_; Module &module_;
......
...@@ -66,7 +66,9 @@ std::string MapKey::argument_value(const BPFtrace &bpftrace, ...@@ -66,7 +66,9 @@ std::string MapKey::argument_value(const BPFtrace &bpftrace,
return std::to_string(*(int32_t*)data); return std::to_string(*(int32_t*)data);
} }
case Type::stack: case Type::stack:
return bpftrace.get_stack(*(uint32_t*)data); return bpftrace.get_stack(*(uint32_t*)data, false);
case Type::ustack:
return bpftrace.get_stack(*(uint32_t*)data, true);
} }
abort(); abort();
} }
......
...@@ -23,11 +23,14 @@ void SemanticAnalyser::visit(Builtin &builtin) ...@@ -23,11 +23,14 @@ void SemanticAnalyser::visit(Builtin &builtin)
builtin.ident == "retval") { builtin.ident == "retval") {
type_ = Type::integer; type_ = Type::integer;
} }
else if (builtin.ident == "stack") else if (builtin.ident == "stack") {
{
type_ = Type::stack; type_ = Type::stack;
needs_stackid_map_ = true; needs_stackid_map_ = true;
} }
else if (builtin.ident == "ustack") {
type_ = Type::ustack;
needs_stackid_map_ = true;
}
else if (!builtin.ident.compare(0, 3, "arg") && builtin.ident.size() == 4 && else if (!builtin.ident.compare(0, 3, "arg") && builtin.ident.size() == 4 &&
builtin.ident.at(3) >= '0' && builtin.ident.at(3) <= '9') { builtin.ident.at(3) >= '0' && builtin.ident.at(3) <= '9') {
int arg_num = atoi(builtin.ident.substr(3).c_str()); int arg_num = atoi(builtin.ident.substr(3).c_str());
......
...@@ -30,6 +30,7 @@ std::string typestr(Type t) ...@@ -30,6 +30,7 @@ std::string typestr(Type t)
case Type::quantize: return "quantize"; break; case Type::quantize: return "quantize"; break;
case Type::count: return "count"; break; case Type::count: return "count"; break;
case Type::stack: return "stack"; break; case Type::stack: return "stack"; break;
case Type::ustack: return "ustack"; break;
default: abort(); default: abort();
} }
} }
......
...@@ -19,6 +19,7 @@ enum class Type ...@@ -19,6 +19,7 @@ enum class Type
quantize, quantize,
count, count,
stack, stack,
ustack,
}; };
std::ostream &operator<<(std::ostream &os, Type type); std::ostream &operator<<(std::ostream &os, Type type);
......
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