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
return -1;
}
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
std::cout << value << std::endl;
......@@ -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");
}
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);
int err = bpf_lookup_elem(stackid_map_->mapfd_, &stackid, stack_trace.data());
if (err)
{
std::cerr << "Error looking up stack id: " << err << std::endl;
std::cerr << "Error looking up stack id " << stackid << ": " << err << std::endl;
return "";
}
......@@ -289,7 +291,7 @@ std::string BPFtrace::get_stack(uint32_t stackid, int indent) const
{
if (addr == 0)
break;
if (ksyms.resolve_addr(addr, &sym))
if (!ustack && ksyms.resolve_addr(addr, &sym))
stack << padding << sym.name << "+" << sym.offset << ":" << sym.module << std::endl;
else
stack << padding << (void*)addr << std::endl;
......
......@@ -19,7 +19,7 @@ public:
int start();
void stop();
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::tuple<uint8_t *, uintptr_t>> sections_;
......
......@@ -23,9 +23,9 @@ void CodegenLLVM::visit(Builtin &builtin)
{
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")
{
......
......@@ -182,10 +182,14 @@ CallInst *IRBuilderBPF::CreateGetUidGid()
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 *flags = getInt64(0);
int flags = 0;
if (ustack)
flags |= (1<<8);
Value *flags_val = getInt64(flags);
// int bpf_get_stackid(ctx, map, flags)
// Return: >= 0 stackid on success or negative error
......@@ -198,7 +202,7 @@ CallInst *IRBuilderBPF::CreateGetStackId(Value *ctx)
Instruction::IntToPtr,
getInt64(BPF_FUNC_get_stackid),
getstackid_func_ptr_type);
return CreateCall(getstackid_func, {ctx, map_ptr, flags});
return CreateCall(getstackid_func, {ctx, map_ptr, flags_val});
}
} // namespace ast
......
......@@ -27,7 +27,7 @@ public:
CallInst *CreateGetNs();
CallInst *CreateGetPidTgid();
CallInst *CreateGetUidGid();
CallInst *CreateGetStackId(Value *ctx);
CallInst *CreateGetStackId(Value *ctx, bool ustack);
private:
Module &module_;
......
......@@ -66,7 +66,9 @@ std::string MapKey::argument_value(const BPFtrace &bpftrace,
return std::to_string(*(int32_t*)data);
}
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();
}
......
......@@ -23,11 +23,14 @@ void SemanticAnalyser::visit(Builtin &builtin)
builtin.ident == "retval") {
type_ = Type::integer;
}
else if (builtin.ident == "stack")
{
else if (builtin.ident == "stack") {
type_ = Type::stack;
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 &&
builtin.ident.at(3) >= '0' && builtin.ident.at(3) <= '9') {
int arg_num = atoi(builtin.ident.substr(3).c_str());
......
......@@ -30,6 +30,7 @@ std::string typestr(Type t)
case Type::quantize: return "quantize"; break;
case Type::count: return "count"; break;
case Type::stack: return "stack"; break;
case Type::ustack: return "ustack"; break;
default: abort();
}
}
......
......@@ -19,6 +19,7 @@ enum class Type
quantize,
count,
stack,
ustack,
};
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