Commit e1f8fd51 authored by Alastair Robertson's avatar Alastair Robertson

Semantic analyser: Add type checking for field accesses

parent 1e047247
#include <iostream>
#include "semantic_analyser.h"
#include "ast.h"
#include "fake_map.h"
......@@ -312,6 +310,9 @@ void SemanticAnalyser::visit(FieldAccess &acc)
err_ << "Struct/union of type '" << cast_type << "' does not contain "
<< "a field named '" << acc.field << "'" << std::endl;
}
else {
acc.type = std::get<0>(fields[acc.field]);
}
}
void SemanticAnalyser::visit(Cast &cast)
......
#pragma once
#include <iostream>
#include <sstream>
#include "ast.h"
......
......@@ -30,7 +30,8 @@ public:
std::map<std::string, std::unique_ptr<IMap>> maps_;
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
std::map<std::string, std::map<std::string, int>> structs_;
// structs_ = { struct_name: { field_name: { sized_type, offset } } }
std::map<std::string, std::map<std::string, std::tuple<SizedType, int>>> structs_;
std::vector<std::tuple<std::string, std::vector<SizedType>>> printf_args_;
std::unique_ptr<IMap> stackid_map_;
std::unique_ptr<IMap> perf_event_map_;
......
......@@ -41,6 +41,9 @@ void test(Driver &driver, const std::string &input, int expected_result=0)
void test(const std::string &input, int expected_result=0)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = std::make_tuple(SizedType(Type::integer, 8), 0);
bpftrace.structs_["type1"]["mystr"] = std::make_tuple(SizedType(Type::string, 8), 8);
bpftrace.structs_["type2"]["field"] = std::make_tuple(SizedType(Type::integer, 8), 0);
Driver driver;
test(bpftrace, driver, input, expected_result);
}
......@@ -302,36 +305,24 @@ TEST(semantic_analyser, profile)
TEST(semantic_analyser, variable_cast_types)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
bpftrace.structs_["type2"]["field"] = 0;
test(bpftrace, "kprobe:f { $x = (type1)cpu; $x = (type1)cpu; }", 0);
test(bpftrace, "kprobe:f { $x = (type1)cpu; $x = (type2)cpu; }", 1);
test("kprobe:f { $x = (type1)cpu; $x = (type1)cpu; }", 0);
test("kprobe:f { $x = (type1)cpu; $x = (type2)cpu; }", 1);
}
TEST(semantic_analyser, map_cast_types)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
bpftrace.structs_["type2"]["field"] = 0;
test(bpftrace, "kprobe:f { @x = (type1)cpu; @x = (type1)cpu; }", 0);
test(bpftrace, "kprobe:f { @x = (type1)cpu; @x = (type2)cpu; }", 1);
test("kprobe:f { @x = (type1)cpu; @x = (type1)cpu; }", 0);
test("kprobe:f { @x = (type1)cpu; @x = (type2)cpu; }", 1);
}
TEST(semantic_analyser, variable_casts_are_local)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
bpftrace.structs_["type2"]["field"] = 0;
test(bpftrace, "kprobe:f { $x = (type1)cpu } kprobe:g { $x = (type2)cpu; }", 0);
test("kprobe:f { $x = (type1)cpu } kprobe:g { $x = (type2)cpu; }", 0);
}
TEST(semantic_analyser, map_casts_are_global)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
bpftrace.structs_["type2"]["field"] = 0;
test(bpftrace, "kprobe:f { @x = (type1)cpu } kprobe:g { @x = (type2)cpu; }", 1);
test("kprobe:f { @x = (type1)cpu } kprobe:g { @x = (type2)cpu; }", 1);
}
TEST(semantic_analyser, cast_unknown_type)
......@@ -341,20 +332,16 @@ TEST(semantic_analyser, cast_unknown_type)
TEST(semantic_analyser, field_access)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
test(bpftrace, "kprobe:f { ((type1)cpu).field }", 0);
test(bpftrace, "kprobe:f { $x = (type1)cpu; $x.field }", 0);
test(bpftrace, "kprobe:f { @x = (type1)cpu; @x.field }", 0);
test("kprobe:f { ((type1)cpu).field }", 0);
test("kprobe:f { $x = (type1)cpu; $x.field }", 0);
test("kprobe:f { @x = (type1)cpu; @x.field }", 0);
}
TEST(semantic_analyser, field_access_wrong_field)
{
BPFtrace bpftrace;
bpftrace.structs_["type1"]["field"] = 0;
test(bpftrace, "kprobe:f { ((type1)cpu).blah }", 1);
test(bpftrace, "kprobe:f { $x = (type1)cpu; $x.blah }", 1);
test(bpftrace, "kprobe:f { @x = (type1)cpu; @x.blah }", 1);
test("kprobe:f { ((type1)cpu).blah }", 1);
test("kprobe:f { $x = (type1)cpu; $x.blah }", 1);
test("kprobe:f { @x = (type1)cpu; @x.blah }", 1);
}
TEST(semantic_analyser, field_access_wrong_expr)
......@@ -362,6 +349,18 @@ TEST(semantic_analyser, field_access_wrong_expr)
test("kprobe:f { 1234->field }", 1);
}
TEST(semantic_analyser, field_access_types)
{
test("kprobe:f { ((type1)0).field == 123 }", 0);
test("kprobe:f { ((type1)0).field == \"abc\" }", 10);
test("kprobe:f { ((type1)0).mystr == \"abc\" }", 0);
test("kprobe:f { ((type1)0).mystr == 123 }", 10);
test("kprobe:f { ((type1)0).field == ((type2)0).field }", 0);
test("kprobe:f { ((type1)0).mystr == ((type2)0).field }", 10);
}
} // namespace semantic_analyser
} // namespace test
} // namespace bpftrace
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