Skip to content

Commit

Permalink
build: merge test-vmlinux-offset to test step
Browse files Browse the repository at this point in the history
  • Loading branch information
tw4452852 committed Jan 24, 2025
1 parent 054b67f commit 9179346
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 91 deletions.
18 changes: 7 additions & 11 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ pub fn build(b: *std.Build) !void {

try create_main_step(&ctx);
try create_trace_step(&ctx);
try create_test_step(&ctx);
const vot = try create_vmlinux_offset_test_step(&ctx, vmlinux_offset_tests_generator);
try create_test_step(&ctx, vot);
try create_fuzz_test_step(&ctx);
try create_vmlinux_offset_test_step(&ctx, vmlinux_offset_tests_generator);
try create_docs_step(&ctx);
}

Expand Down Expand Up @@ -294,7 +294,7 @@ fn create_target_step(ctx: *const Ctx, main_path: []const u8, prog_path: []const
}
}

fn create_test_step(ctx: *const Ctx) !void {
fn create_test_step(ctx: *const Ctx, vmlinux_offset_test_step: *std.Build.Step) !void {
// Creates a step for unit testing.
const filter = ctx.test_filter;
const exe_tests = ctx.b.addTest(.{
Expand Down Expand Up @@ -356,14 +356,7 @@ fn create_test_step(ctx: *const Ctx) !void {
.target = ctx.target,
.optimize = ctx.optimize,
});
vmlinux_test.root_module.addAnonymousImport("@build_options", .{
.root_source_file = ctx.b.addWriteFiles().add(
"generated_test_build_ctx.zig",
ctx.b.fmt("pub const vmlinux_bin_path :[:0]const u8 = \"{s}\";", .{if (ctx.vmlinux_bin_path) |path| path else ""}),
),
});
vmlinux_test.root_module.addImport("vmlinux", ctx.vmlinux);
vmlinux_test.linkLibrary(ctx.libbpf_step);
const test_vmlinux_step = ctx.b.step("test-vmlinux", "Build vmlinux unit test");
test_vmlinux_step.dependOn(&vmlinux_test.step);

Expand All @@ -372,6 +365,7 @@ fn create_test_step(ctx: *const Ctx) !void {
test_step.dependOn(test_tool_trace_step);
test_step.dependOn(test_btf_translator_step);
test_step.dependOn(test_vmlinux_step);
test_step.dependOn(vmlinux_offset_test_step);
}

fn create_btf_translator_test(ctx: *const Ctx) *std.Build.Step.Compile {
Expand Down Expand Up @@ -419,7 +413,7 @@ fn create_fuzz_test_step(ctx: *const Ctx) !void {
step.dependOn(&run.step);
}

fn create_vmlinux_offset_test_step(ctx: *const Ctx, generator: *std.Build.Step.Compile) !void {
fn create_vmlinux_offset_test_step(ctx: *const Ctx, generator: *std.Build.Step.Compile) !*std.Build.Step {
const run_exe = ctx.b.addRunArtifact(generator);

if (ctx.vmlinux_bin_path) |vmlinux| run_exe.addPrefixedFileArg("-vmlinux", .{ .cwd_relative = vmlinux });
Expand All @@ -437,6 +431,8 @@ fn create_vmlinux_offset_test_step(ctx: *const Ctx, generator: *std.Build.Step.C

const step = ctx.b.step("test-vmlinux-offset", "Build vmlinux offset tests");
step.dependOn(&run.step);

return step;
}

fn create_docs_step(ctx: *const Ctx) !void {
Expand Down
80 changes: 0 additions & 80 deletions src/tests/vmlinux.zig
Original file line number Diff line number Diff line change
@@ -1,87 +1,7 @@
const std = @import("std");
const print = std.debug.print;
const c = @cImport({
@cInclude("btf.h");
});
const gpa = std.testing.allocator;
const vmlinux = @import("vmlinux");
const build_options = @import("@build_options");

test "vmlinux_compile" {
@setEvalBranchQuota(1000000);
std.testing.refAllDeclsRecursive(vmlinux);
}

test "vmlinux_check_offset_one" {
try test_offset("task_struct");
}

fn test_offset(comptime struct_name_filter: ?[]const u8) !void {
@setEvalBranchQuota(1000000);

const btf = if (build_options.vmlinux_bin_path.len > 0) c.btf__parse(build_options.vmlinux_bin_path, null) else c.btf__load_vmlinux_btf();
if (btf == null) {
print("failed to get BTF: {}\n", .{std.posix.errno(-1)});
return error.PARSE;
}

const sizes, const offsets = blk: {
comptime var size_array: []const struct { []const u8, usize } = &.{};
comptime var offset_array: []const struct { []const u8, usize } = &.{};
const decls = @typeInfo(vmlinux).@"struct".decls;

inline for (decls) |decl| {
const t = @field(vmlinux, decl.name);
const ti = @typeInfo(t);
switch (ti) {
.@"struct" => |info| {
comptime if (struct_name_filter == null or std.mem.eql(u8, struct_name_filter.?, decl.name)) {
size_array = size_array ++ .{.{ decl.name, @sizeOf(t) }};
for (info.fields) |field| {
offset_array = offset_array ++ .{.{ decl.name ++ "/" ++ field.name, @bitOffsetOf(t, field.name) }};
}
};
},
else => {},
}
}

break :blk .{ std.StaticStringMap(usize).initComptime(size_array), std.StaticStringMap(usize).initComptime(offset_array) };
};

// Check structure size and non-bitfield offsets are consistent with btf
for (1..c.btf__type_cnt(btf)) |i| {
const t: *const c.btf_type = c.btf__type_by_id(btf, @intCast(i));
if (c.btf_kind(t) == c.BTF_KIND_STRUCT) {
const struct_sz = t.unnamed_0.size;
const m: [*c]const c.struct_btf_member = c.btf_members(t);
const vlen: u16 = c.btf_vlen(t);
const btf_name: [:0]const u8 = std.mem.sliceTo(c.btf__name_by_offset(btf, t.name_off), 0);
const struct_name = if (btf_name.len != 0)
try gpa.dupe(u8, btf_name)
else
try std.fmt.allocPrint(gpa, "struct_{d}", .{i});
defer gpa.free(struct_name);
if (struct_name_filter == null or std.mem.eql(u8, struct_name_filter.?, struct_name)) {
try std.testing.expectEqual(struct_sz, sizes.get(struct_name).?);
for (0..vlen) |vi| {
const m_sz = c.btf_member_bitfield_size(t, @intCast(vi));
const m_off = c.btf_member_bit_offset(t, @intCast(vi));

// TODO: skip bitfield right now
if (m_sz != 0) continue;

const field_name = if (m[vi].name_off != 0)
try gpa.dupe(u8, std.mem.sliceTo(c.btf__name_by_offset(btf, m[vi].name_off), 0))
else
try std.fmt.allocPrint(gpa, "field{}", .{vi});
defer gpa.free(field_name);
const key = try std.fmt.allocPrint(gpa, "{s}/{s}", .{ struct_name, field_name });
defer gpa.free(key);

try std.testing.expectEqual(m_off, offsets.get(key).?);
}
}
}
}
}

0 comments on commit 9179346

Please sign in to comment.