Commit 1bef2f5f authored by williangaspar's avatar williangaspar

tests

parent 7d490e54
......@@ -461,7 +461,7 @@ void CodegenLLVM::visit(Call &call)
AllocaInst *system_args = b_.CreateAllocaBPF(printf_struct, "system_args");
b_.CreateMemSet(system_args, b_.getInt8(0), struct_size, 1);
b_.CreateStore(b_.getInt64(system_id_ + 10000), system_args);
b_.CreateStore(b_.getInt64(system_id_ + asyncactionint(AsyncAction::syscall)), system_args);
for (int i=1; i<call.vargs->size(); i++)
{
Expression &arg = *call.vargs->at(i);
......@@ -471,7 +471,6 @@ void CodegenLLVM::visit(Call &call)
b_.CreateMemCpy(offset, expr_, arg.type.size, 1);
else
b_.CreateStore(expr_, offset);
// b_.CreateStore(b_.getInt64(asyncactionint(AsyncAction::exit)), perfdata);
}
system_id_++;
......
......@@ -213,38 +213,39 @@ void perf_event_printer(void *cb_cookie, void *data, int size)
auto args = std::get<1>(bpftrace->system_args_[id]);
std::vector<uint64_t> arg_values = bpftrace->get_arg_values(args, arg_data);
std::string command = "";
char buffer [255];
switch (args.size())
{
case 0:
system(fmt);
break;
case 1:
command = bpftrace->format_string(fmt, arg_values.at(0));
system(command.c_str());
sprintf(buffer, fmt, arg_values.at(0));
system(buffer);
break;
case 2:
command = bpftrace->format_string(fmt, arg_values.at(0), arg_values.at(1));
system(command.c_str());
sprintf(buffer, fmt, arg_values.at(0), arg_values.at(1));
system(buffer);
break;
case 3:
command = bpftrace->format_string(fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2));
system(command.c_str());
sprintf(buffer, fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2));
system(buffer);
break;
case 4:
command = bpftrace->format_string(fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
sprintf(buffer, fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
arg_values.at(3));
system(command.c_str());
system(buffer);
break;
case 5:
command = bpftrace->format_string(fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
sprintf(buffer, fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
arg_values.at(3), arg_values.at(4));
system(command.c_str());
system(buffer);
break;
case 6:
command = bpftrace->format_string(fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
sprintf(buffer, fmt, arg_values.at(0), arg_values.at(1), arg_values.at(2),
arg_values.at(3), arg_values.at(4), arg_values.at(5));
system(command.c_str());
system(buffer);
break;
default:
abort();
......@@ -289,47 +290,6 @@ void perf_event_printer(void *cb_cookie, void *data, int size)
}
}
void BPFtrace::format_impl(std::stringstream &ss, const char *format)
{
while (*format)
{
if (*format == '%' && *++format != '%') // %% == % (not a format directive)
throw std::invalid_argument("not enough arguments !\n");
ss << *format++;
}
}
template <typename Arg, typename... Args>
void BPFtrace::format_impl(std::stringstream &ss, const char *format, Arg arg, Args... args)
{
while (*format)
{
if (*format == '%' && *++format != '%')
{
auto current_format_qualifier = *format;
switch (current_format_qualifier)
{
case 'd':
if (!std::is_integral<Arg>())
throw std::invalid_argument("%d introduces integral argument");
}
ss << arg; // arg type is deduced
return format_impl(ss, ++format, args...); // one arg less
}
ss << *format++;
} // the format string is exhausted and we still have args : throw
throw std::invalid_argument("Too many arguments\n");
}
template <typename... Args>
std::string BPFtrace::format_string(const char *fmt, Args... args)
{
std::stringstream ss;
format_impl(ss, fmt, args...);
return ss.str();
}
std::vector<uint64_t> BPFtrace::get_arg_values(std::vector<Field> args, uint8_t* arg_data)
{
std::vector<uint64_t> arg_values;
......
......@@ -43,16 +43,6 @@ public:
std::string resolve_name(uint64_t name_id);
std::vector<uint64_t> get_arg_values(std::vector<Field> args, uint8_t* arg_data);
void format_impl(std::stringstream& ss, const char* format);
template <typename Arg, typename... Args>
void format_impl(std::stringstream& ss, const char* format, Arg arg, Args... args);
template <typename... Args>
std::string format(const char* fmt, Args... args);
template <typename... Args>
std::string format_string(const char* fmt, Args... args);
int pid_;
std::map<std::string, std::unique_ptr<IMap>> maps_;
......
......@@ -1702,6 +1702,41 @@ attributes #1 = { argmemonly nounwind }
)EXPECTED");
}
TEST(codegen, call_system)
{
test(" kprobe:f { system(\"echo %d\", 100) }",
R"EXPECTED(%system_t = type { i64, i64 }
; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
define i64 @"kprobe:f"(i8*) local_unnamed_addr section "s_kprobe:f" {
entry:
%system_args = alloca %system_t, align 8
%1 = bitcast %system_t* %system_args to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10000, %system_t* %system_args, align 8
%2 = getelementptr inbounds %system_t, %system_t* %system_args, i64 0, i32 1
store i64 100, i64* %2, align 8
%pseudo = tail call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%get_cpu_id = tail call i64 inttoptr (i64 8 to i64 ()*)()
%perf_event_output = call i64 inttoptr (i64 25 to i64 (i8*, i8*, i64, i8*, i64)*)(i8* %0, i64 %pseudo, i64 %get_cpu_id, %system_t* nonnull %system_args, i64 16)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
}
TEST(codegen, call_exit)
{
test("kprobe:f { exit() }",
......@@ -1717,7 +1752,7 @@ entry:
%perfdata = alloca [8 x i8], align 8
%1 = getelementptr inbounds [8 x i8], [8 x i8]* %perfdata, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10000, [8 x i8]* %perfdata, align 8
store i64 20000, [8 x i8]* %perfdata, align 8
%pseudo = tail call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%get_cpu_id = tail call i64 inttoptr (i64 8 to i64 ()*)()
%perf_event_output = call i64 inttoptr (i64 25 to i64 (i8*, i8*, i64, i8*, i64)*)(i8* %0, i64 %pseudo, i64 %get_cpu_id, [8 x i8]* nonnull %perfdata, i64 8)
......@@ -1768,7 +1803,7 @@ entry:
%perfdata = alloca [27 x i8], align 8
%1 = getelementptr inbounds [27 x i8], [27 x i8]* %perfdata, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10001, [27 x i8]* %perfdata, align 8
store i64 20001, [27 x i8]* %perfdata, align 8
%2 = getelementptr inbounds [27 x i8], [27 x i8]* %perfdata, i64 0, i64 8
%str.sroa.0.0..sroa_idx = getelementptr inbounds [27 x i8], [27 x i8]* %perfdata, i64 0, i64 24
call void @llvm.memset.p0i8.i64(i8* nonnull %2, i8 0, i64 16, i32 8, i1 false)
......@@ -1827,7 +1862,7 @@ entry:
%perfdata = alloca [11 x i8], align 8
%1 = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10002, [11 x i8]* %perfdata, align 8
store i64 20002, [11 x i8]* %perfdata, align 8
%str.sroa.0.0..sroa_idx = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 8
store i8 64, i8* %str.sroa.0.0..sroa_idx, align 8
%str.sroa.4.0..sroa_idx = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 9
......@@ -1881,7 +1916,7 @@ entry:
%perfdata = alloca [11 x i8], align 8
%1 = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10003, [11 x i8]* %perfdata, align 8
store i64 20003, [11 x i8]* %perfdata, align 8
%str.sroa.0.0..sroa_idx = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 8
store i8 64, i8* %str.sroa.0.0..sroa_idx, align 8
%str.sroa.4.0..sroa_idx = getelementptr inbounds [11 x i8], [11 x i8]* %perfdata, i64 0, i64 9
......@@ -1915,7 +1950,7 @@ entry:
%perfdata = alloca [16 x i8], align 8
%1 = getelementptr inbounds [16 x i8], [16 x i8]* %perfdata, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
store i64 10004, [16 x i8]* %perfdata, align 8
store i64 20004, [16 x i8]* %perfdata, align 8
%2 = getelementptr inbounds [16 x i8], [16 x i8]* %perfdata, i64 0, i64 8
store i64 0, i8* %2, align 8
%pseudo = tail call i64 @llvm.bpf.pseudo(i64 1, i64 1)
......
......@@ -88,6 +88,7 @@ TEST(semantic_analyser, builtin_functions)
test("kprobe:f { exit() }", 0);
test("kprobe:f { str(0xffff) }", 0);
test("kprobe:f { printf(\"hello\\n\") }", 0);
test("kprobe:f { system(\"ls\\n\") }", 0);
test("kprobe:f { join(0) }", 0);
test("kprobe:f { sym(0xffff) }", 0);
test("kprobe:f { usym(0xffff) }", 0);
......@@ -370,6 +371,14 @@ TEST(semantic_analyser, printf)
test("kprobe:f { $x = printf(\"hi\") }", 1);
}
TEST(semantic_analyser, system)
{
test("kprobe:f { system(\"ls\") }", 0);
test("kprobe:f { system(1234) }", 1);
test("kprobe:f { system() }", 1);
test("kprobe:f { $fmt = \"mystring\"; system($fmt) }", 1);
}
TEST(semantic_analyser, printf_format_int)
{
test("kprobe:f { printf(\"int: %d\", 1234) }", 0);
......
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