Commit 888490d0 authored by Alastair Robertson's avatar Alastair Robertson

Add support for char and short

parent 5c31a0a6
......@@ -174,7 +174,6 @@ void CodegenLLVM::visit(Call &call)
else if (call.func == "printf")
{
ArrayType *string_type = ArrayType::get(b_.getInt8Ty(), STRING_SIZE);
StructType *printf_struct = StructType::create(module_->getContext(), "printf_t");
std::vector<llvm::Type *> elements = { b_.getInt64Ty() }; // printf ID
String &fmt = static_cast<String&>(*call.vargs->at(0));
......@@ -185,7 +184,7 @@ void CodegenLLVM::visit(Call &call)
llvm::Type *ty = b_.GetType(t);
elements.push_back(ty);
}
printf_struct->setBody(elements);
StructType *printf_struct = StructType::create(elements, "printf_t", true);
int struct_size = layout_.getTypeAllocSize(printf_struct);
AllocaInst *printf_args = b_.CreateAllocaBPF(printf_struct, "printf_args");
......
......@@ -71,6 +71,12 @@ llvm::Type *IRBuilderBPF::GetType(const SizedType &stype)
case 4:
ty = getInt32Ty();
break;
case 2:
ty = getInt16Ty();
break;
case 1:
ty = getInt8Ty();
break;
default:
abort();
}
......
......@@ -15,6 +15,7 @@ namespace bpftrace {
// print(",\n".join([f"{{\"{l+s}\", Type::integer}}" for l in lengths for s in specifiers]))
const std::unordered_map<std::string, Type> printf_format_types = {
{"s", Type::string},
{"c", Type::integer},
{"d", Type::integer},
{"u", Type::integer},
{"x", Type::integer},
......
......@@ -1382,6 +1382,172 @@ attributes #1 = { argmemonly nounwind }
expected);
}
TEST(codegen, struct_long)
{
auto expected = R"EXPECTED(; 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* nocapture readnone) local_unnamed_addr section "s_kprobe:f" {
entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%Foo.x = alloca i64, align 8
%1 = bitcast i64* %Foo.x to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
%probe_read = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i64* nonnull %Foo.x, i64 8, i64 0)
%2 = load i64, i64* %Foo.x, align 8
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
%3 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %3)
store i64 0, i64* %"@x_key", align 8
%4 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %4)
store i64 %2, i64* %"@x_val", align 8
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo, i64* nonnull %"@x_key", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %3)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %4)
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("struct Foo { long x; }"
"kprobe:f"
"{"
" $foo = (Foo)0;"
" @x = $foo.x;"
"}",
expected);
test("struct Foo { long x; }"
"kprobe:f"
"{"
" $foo = (Foo*)0;"
" @x = $foo->x;"
"}",
expected);
}
TEST(codegen, struct_short)
{
auto expected = R"EXPECTED(; 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* nocapture readnone) local_unnamed_addr section "s_kprobe:f" {
entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%Foo.x = alloca i16, align 2
%1 = bitcast i16* %Foo.x to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
%probe_read = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i16* nonnull %Foo.x, i64 2, i64 0)
%2 = load i16, i16* %Foo.x, align 2
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
%3 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %3)
store i64 0, i64* %"@x_key", align 8
%4 = zext i16 %2 to i64
%5 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %5)
store i64 %4, i64* %"@x_val", align 8
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo, i64* nonnull %"@x_key", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %3)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %5)
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("struct Foo { short x; }"
"kprobe:f"
"{"
" $foo = (Foo)0;"
" @x = $foo.x;"
"}",
expected);
test("struct Foo { short x; }"
"kprobe:f"
"{"
" $foo = (Foo*)0;"
" @x = $foo->x;"
"}",
expected);
}
TEST(codegen, struct_char)
{
auto expected = R"EXPECTED(; 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* nocapture readnone) local_unnamed_addr section "s_kprobe:f" {
entry:
%"@x_val" = alloca i64, align 8
%"@x_key" = alloca i64, align 8
%Foo.x = alloca i8, align 1
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %Foo.x)
%probe_read = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i8* nonnull %Foo.x, i64 1, i64 0)
%1 = load i8, i8* %Foo.x, align 1
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %Foo.x)
%2 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2)
store i64 0, i64* %"@x_key", align 8
%3 = zext i8 %1 to i64
%4 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %4)
store i64 %3, i64* %"@x_val", align 8
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo, i64* nonnull %"@x_key", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %2)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %4)
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("struct Foo { char x; }"
"kprobe:f"
"{"
" $foo = (Foo)0;"
" @x = $foo.x;"
"}",
expected);
test("struct Foo { char x; }"
"kprobe:f"
"{"
" $foo = (Foo*)0;"
" @x = $foo->x;"
"}",
expected);
}
TEST(codegen, struct_integer_ptr)
{
auto expected = R"EXPECTED(; Function Attrs: nounwind
......
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