Skip to content

BPF: add BTF #6267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/std/os/linux/bpf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ usingnamespace std.os;
const std = @import("../../std.zig");
const expectEqual = std.testing.expectEqual;

pub const btf = @import("bpf/btf.zig");

// instruction classes
pub const LD = 0x00;
pub const LDX = 0x01;
Expand Down
156 changes: 156 additions & 0 deletions lib/std/os/linux/bpf/btf.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const magic = 0xeb9f;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All standard library source files now have a license notice at the top of the file. It would make sense to add them to new files as well.

const version = 1;

pub const ext = @import("ext.zig");

/// All offsets are in bytes relative to the end of this header
pub const Header = packed struct {
magic: u16,
version: u8,
flags: u8,
hdr_len: u32,

/// offset of type section
type_off: u32,

/// length of type section
type_len: u32,

/// offset of string section
str_off: u32,

/// length of string section
str_len: u32,
};

/// Max number of type identifiers
pub const max_type = 0xfffff;

/// Max offset into string section
pub const max_name_offset = 0xffffff;

/// Max number of struct/union/enum member of func args
pub const max_vlen = 0xffff;

pub const Type = packed struct {
name_off: u32,
info: packed struct {
/// number of struct's members
vlen: u16,

unused_1: u8,
kind: Kind,
unused_2: u3,

/// used by Struct, Union, and Fwd
kind_flag: bool,
},

/// size is used by Int, Enum, Struct, Union, and DataSec, it tells the size
/// of the type it is describing
///
/// type is used by Ptr, Typedef, Volatile, Const, Restrict, Func,
/// FuncProto, and Var. It is a type_id referring to another type
size_type: union { size: u32, typ: u32 },
};

/// For some kinds, Type is immediately followed by extra data
pub const Kind = enum(u4) {
unknown,
int,
ptr,
array,
structure,
kind_union,
enumeration,
fwd,
typedef,
kind_volatile,
constant,
restrict,
func,
funcProto,
variable,
dataSec,
};

/// Int kind is followed by this struct
pub const IntInfo = packed struct {
bits: u8,
unused: u8,
offset: u8,
encoding: enum(u4) {
signed = 1 << 0,
char = 1 << 1,
boolean = 1 << 2,
},
};

test "IntInfo is 32 bits" {
std.testing.expectEqual(@bitSizeOf(IntInfo), 32);
}

/// Enum kind is followed by this struct
pub const Enum = packed struct {
name_off: u32,
val: i32,
};

/// Array kind is followd by this struct
pub const Array = packed struct {
typ: u32,
index_type: u32,
nelems: u32,
};

/// Struct and Union kinds are followed by multiple Member structs. The exact
/// number is stored in vlen
pub const Member = packed struct {
name_off: u32,
typ: u32,

/// if the kind_flag is set, offset contains both member bitfield size and
/// bit offset, the bitfield size is set for bitfield members. If the type
/// info kind_flag is not set, the offset contains only bit offset
offset: packed struct {
bit: u24,
bitfield_size: u8,
},
};

/// FuncProto is followed by multiple Params, the exact number is stored in vlen
pub const Param = packed struct {
name_off: u32,
typ: u32,
};

pub const VarLinkage = enum {
static,
global_allocated,
global_extern,
};

pub const FuncLinkage = enum {
static,
global,
external,
};

/// Var kind is followd by a single Var struct to describe additional
/// information related to the variable such as its linkage
pub const Var = packed struct {
linkage: u32,
};

/// Datasec kind is followed by multible VarSecInfo to describe all Var kind
/// types it contains along with it's in-section offset as well as size.
pub const VarSecInfo = packed struct {
typ: u32,
offset: u32,
size: u32,
};
24 changes: 24 additions & 0 deletions lib/std/os/linux/bpf/btf_ext.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
pub const Header = packed struct {
magic: u16,
version: u8,
flags: u8,
hdr_len: u32,

/// All offsets are in bytes relative to the end of this header
func_info_off: u32,
func_info_len: u32,
line_info_off: u32,
line_info_len: u32,
};

pub const InfoSec = packed struct {
sec_name_off: u32,
num_info: u32,
// TODO: communicate that there is data here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible usecase for #4016

Copy link
Contributor Author

@mattnite mattnite Sep 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that would be an excellent addition to Zig, we get to put the billion dollar mistake to use and get to emulate something available in C.

//data: [0]u8,
};