aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-09-14 21:57:01 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-09-14 21:57:01 -0700
commit5d8fec3d4cdfa58b54756c4368bdb3e76d21380f (patch)
treebf300a4a12b43ca4f9487193cc3fb6b0b15e4b90 /lib
parent6acd903a9510d0e145b7bba3a9d42d4b9c07cc34 (diff)
parent5e39ab460073b0068d30a74488abf83333761c8d (diff)
downloadzig-5d8fec3d4cdfa58b54756c4368bdb3e76d21380f.tar.gz
zig-5d8fec3d4cdfa58b54756c4368bdb3e76d21380f.zip
Merge remote-tracking branch 'origin/master' into stage2-zig-cc
Diffstat (limited to 'lib')
-rw-r--r--lib/std/builtin.zig1
-rw-r--r--lib/std/fmt.zig2
-rw-r--r--lib/std/hash/auto_hash.zig5
-rw-r--r--lib/std/hash/crc.zig5
-rw-r--r--lib/std/io/serialization.zig4
-rw-r--r--lib/std/json.zig4
-rw-r--r--lib/std/meta.zig12
-rw-r--r--lib/std/os.zig10
-rw-r--r--lib/std/os/linux/bpf.zig1
-rw-r--r--lib/std/os/linux/bpf/helpers.zig157
-rw-r--r--lib/std/os/linux/bpf/kern.zig39
11 files changed, 221 insertions, 19 deletions
diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig
index 911a0eb15c..52b8f641cd 100644
--- a/lib/std/builtin.zig
+++ b/lib/std/builtin.zig
@@ -317,7 +317,6 @@ pub const TypeInfo = union(enum) {
/// therefore must be kept in sync with the compiler implementation.
pub const UnionField = struct {
name: []const u8,
- enum_field: ?EnumField,
field_type: type,
};
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index a652bd8c21..8d31733959 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -399,7 +399,7 @@ pub fn formatType(
try writer.writeAll(@tagName(@as(UnionTagType, value)));
try writer.writeAll(" = ");
inline for (info.fields) |u_field| {
- if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
+ if (value == @field(UnionTagType, u_field.name)) {
try formatType(@field(value, u_field.name), fmt, options, writer, max_depth - 1);
}
}
diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig
index 5877c77b5d..2e707d5450 100644
--- a/lib/std/hash/auto_hash.zig
+++ b/lib/std/hash/auto_hash.zig
@@ -139,9 +139,8 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
const tag = meta.activeTag(key);
const s = hash(hasher, tag, strat);
inline for (info.fields) |field| {
- const enum_field = field.enum_field.?;
- if (enum_field.value == @enumToInt(tag)) {
- hash(hasher, @field(key, enum_field.name), strat);
+ if (@field(tag_type, field.name) == tag) {
+ hash(hasher, @field(key, field.name), strat);
// TODO use a labelled break when it does not crash the compiler. cf #2908
// break :blk;
return;
diff --git a/lib/std/hash/crc.zig b/lib/std/hash/crc.zig
index 37695df8b3..6290369fca 100644
--- a/lib/std/hash/crc.zig
+++ b/lib/std/hash/crc.zig
@@ -71,10 +71,7 @@ pub fn Crc32WithPoly(comptime poly: Polynomial) type {
const p = input[i .. i + 8];
// Unrolling this way gives ~50Mb/s increase
- self.crc ^= (@as(u32, p[0]) << 0);
- self.crc ^= (@as(u32, p[1]) << 8);
- self.crc ^= (@as(u32, p[2]) << 16);
- self.crc ^= (@as(u32, p[3]) << 24);
+ self.crc ^= std.mem.readIntLittle(u32, p[0..4]);
self.crc =
lookup_tables[0][p[7]] ^
diff --git a/lib/std/io/serialization.zig b/lib/std/io/serialization.zig
index 925c929cee..79a12989b8 100644
--- a/lib/std/io/serialization.zig
+++ b/lib/std/io/serialization.zig
@@ -156,7 +156,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
const tag = try self.deserializeInt(TagInt);
inline for (info.fields) |field_info| {
- if (field_info.enum_field.?.value == tag) {
+ if (@enumToInt(@field(TagType, field_info.name)) == tag) {
const name = field_info.name;
const FieldType = field_info.field_type;
ptr.* = @unionInit(C, name, undefined);
@@ -320,7 +320,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
// value, but @field requires a comptime value. Our alternative
// is to check each field for a match
inline for (info.fields) |field_info| {
- if (field_info.enum_field.?.value == @enumToInt(active_tag)) {
+ if (@field(TagType, field_info.name) == active_tag) {
const name = field_info.name;
const FieldType = field_info.field_type;
try self.serialize(@field(value, name));
diff --git a/lib/std/json.zig b/lib/std/json.zig
index 2f8a70d0ef..cf479ab2cd 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -1613,7 +1613,7 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
.Union => |unionInfo| {
if (unionInfo.tag_type) |UnionTagType| {
inline for (unionInfo.fields) |u_field| {
- if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
+ if (value == @field(UnionTagType, u_field.name)) {
parseFree(u_field.field_type, @field(value, u_field.name), options);
break;
}
@@ -2458,7 +2458,7 @@ pub fn stringify(
const info = @typeInfo(T).Union;
if (info.tag_type) |UnionTagType| {
inline for (info.fields) |u_field| {
- if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
+ if (value == @field(UnionTagType, u_field.name)) {
return try stringify(@field(value, u_field.name), options, out_stream);
}
}
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index 73e0661498..b27f168ac9 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -465,10 +465,13 @@ pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type {
testing.expect(trait.is(.Union)(U));
const info = @typeInfo(U).Union;
+ const tag_info = @typeInfo(@TagType(U)).Enum;
inline for (info.fields) |field_info| {
- if (field_info.enum_field.?.value == @enumToInt(tag)) return field_info.field_type;
+ if (comptime mem.eql(u8, field_info.name, @tagName(tag)))
+ return field_info.field_type;
}
+
unreachable;
}
@@ -504,15 +507,14 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool {
}
},
.Union => |info| {
- if (info.tag_type) |_| {
+ if (info.tag_type) |Tag| {
const tag_a = activeTag(a);
const tag_b = activeTag(b);
if (tag_a != tag_b) return false;
inline for (info.fields) |field_info| {
- const enum_field = field_info.enum_field.?;
- if (enum_field.value == @enumToInt(tag_a)) {
- return eql(@field(a, enum_field.name), @field(b, enum_field.name));
+ if (@field(Tag, field_info.name) == tag_a) {
+ return eql(@field(a, field_info.name), @field(b, field_info.name));
}
}
return false;
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 91365c81dd..bdc746419a 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -320,6 +320,7 @@ pub const ReadError = error{
/// Linux has a limit on how many bytes may be transferred in one `read` call, which is `0x7ffff000`
/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
/// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
/// For POSIX the limit is `math.maxInt(isize)`.
pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
if (builtin.os.tag == .windows) {
@@ -353,6 +354,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
// Prevents EINVAL.
const max_count = switch (std.Target.current.os.tag) {
.linux => 0x7ffff000,
+ .macosx, .ios, .watchos, .tvos => math.maxInt(i32),
else => math.maxInt(isize),
};
const adjusted_len = math.min(max_count, buf.len);
@@ -693,6 +695,7 @@ pub const WriteError = error{
/// Linux has a limit on how many bytes may be transferred in one `write` call, which is `0x7ffff000`
/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL.
/// The corresponding POSIX limit is `math.maxInt(isize)`.
pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
if (builtin.os.tag == .windows) {
@@ -726,6 +729,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
const max_count = switch (std.Target.current.os.tag) {
.linux => 0x7ffff000,
+ .macosx, .ios, .watchos, .tvos => math.maxInt(i32),
else => math.maxInt(isize),
};
const adjusted_len = math.min(max_count, bytes.len);
@@ -851,6 +855,7 @@ pub const PWriteError = WriteError || error{Unseekable};
/// Linux has a limit on how many bytes may be transferred in one `pwrite` call, which is `0x7ffff000`
/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
/// The corresponding POSIX limit is `math.maxInt(isize)`.
pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
if (std.Target.current.os.tag == .windows) {
@@ -888,6 +893,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
// Prevent EINVAL.
const max_count = switch (std.Target.current.os.tag) {
.linux => 0x7ffff000,
+ .macosx, .ios, .watchos, .tvos => math.maxInt(i32),
else => math.maxInt(isize),
};
const adjusted_len = math.min(max_count, bytes.len);
@@ -3084,7 +3090,7 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con
.WSAECONNREFUSED => return error.ConnectionRefused,
.WSAETIMEDOUT => return error.ConnectionTimedOut,
.WSAEHOSTUNREACH // TODO: should we return NetworkUnreachable in this case as well?
- , .WSAENETUNREACH => return error.NetworkUnreachable,
+ , .WSAENETUNREACH => return error.NetworkUnreachable,
.WSAEFAULT => unreachable,
.WSAEINVAL => unreachable,
.WSAEISCONN => unreachable,
@@ -4711,6 +4717,7 @@ fn count_iovec_bytes(iovs: []const iovec_const) usize {
/// Linux has a limit on how many bytes may be transferred in one `sendfile` call, which is `0x7ffff000`
/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as
/// well as stuffing the errno codes into the last `4096` values. This is cited on the `sendfile` man page.
+/// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL.
/// The corresponding POSIX limit on this is `math.maxInt(isize)`.
pub fn sendfile(
out_fd: fd_t,
@@ -4733,6 +4740,7 @@ pub fn sendfile(
});
const max_count = switch (std.Target.current.os.tag) {
.linux => 0x7ffff000,
+ .macosx, .ios, .watchos, .tvos => math.maxInt(i32),
else => math.maxInt(size_t),
};
diff --git a/lib/std/os/linux/bpf.zig b/lib/std/os/linux/bpf.zig
index be9f599d92..44c938feb8 100644
--- a/lib/std/os/linux/bpf.zig
+++ b/lib/std/os/linux/bpf.zig
@@ -12,6 +12,7 @@ const expectError = std.testing.expectError;
const expect = std.testing.expect;
pub const btf = @import("bpf/btf.zig");
+pub const kern = @import("bpf/kern.zig");
// instruction classes
pub const LD = 0x00;
diff --git a/lib/std/os/linux/bpf/helpers.zig b/lib/std/os/linux/bpf/helpers.zig
new file mode 100644
index 0000000000..9228e1f1fd
--- /dev/null
+++ b/lib/std/os/linux/bpf/helpers.zig
@@ -0,0 +1,157 @@
+// 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 kern = @import("kern.zig");
+
+// in BPF, all the helper calls
+// TODO: when https://github.com/ziglang/zig/issues/1717 is here, make a nice
+// function that uses the Helper enum
+//
+// Note, these function signatures were created from documentation found in
+// '/usr/include/linux/bpf.h'
+pub const map_lookup_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const c_void) ?*c_void, 1);
+pub const map_update_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const c_void, value: ?*const c_void, flags: u64) c_long, 2);
+pub const map_delete_elem = @intToPtr(fn (map: *const kern.MapDef, key: ?*const c_void) c_long, 3);
+pub const probe_read = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 4);
+pub const ktime_get_ns = @intToPtr(fn () u64, 5);
+pub const trace_printk = @intToPtr(fn (fmt: [*:0]const u8, fmt_size: u32, arg1: u64, arg2: u64, arg3: u64) c_long, 6);
+pub const get_prandom_u32 = @intToPtr(fn () u32, 7);
+pub const get_smp_processor_id = @intToPtr(fn () u32, 8);
+pub const skb_store_bytes = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: ?*const c_void, len: u32, flags: u64) c_long, 9);
+pub const l3_csum_replace = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, size: u64) c_long, 10);
+pub const l4_csum_replace = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: u64, to: u64, flags: u64) c_long, 11);
+pub const tail_call = @intToPtr(fn (ctx: ?*c_void, prog_array_map: *const kern.MapDef, index: u32) c_long, 12);
+pub const clone_redirect = @intToPtr(fn (skb: *kern.SkBuff, ifindex: u32, flags: u64) c_long, 13);
+pub const get_current_pid_tgid = @intToPtr(fn () u64, 14);
+pub const get_current_uid_gid = @intToPtr(fn () u64, 15);
+pub const get_current_comm = @intToPtr(fn (buf: ?*c_void, size_of_buf: u32) c_long, 16);
+pub const get_cgroup_classid = @intToPtr(fn (skb: *kern.SkBuff) u32, 17);
+// Note vlan_proto is big endian
+pub const skb_vlan_push = @intToPtr(fn (skb: *kern.SkBuff, vlan_proto: u16, vlan_tci: u16) c_long, 18);
+pub const skb_vlan_pop = @intToPtr(fn (skb: *kern.SkBuff) c_long, 19);
+pub const skb_get_tunnel_key = @intToPtr(fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 20);
+pub const skb_set_tunnel_key = @intToPtr(fn (skb: *kern.SkBuff, key: *kern.TunnelKey, size: u32, flags: u64) c_long, 21);
+pub const perf_event_read = @intToPtr(fn (map: *const kern.MapDef, flags: u64) u64, 22);
+pub const redirect = @intToPtr(fn (ifindex: u32, flags: u64) c_long, 23);
+pub const get_route_realm = @intToPtr(fn (skb: *kern.SkBuff) u32, 24);
+pub const perf_event_output = @intToPtr(fn (ctx: ?*c_void, map: *const kern.MapDef, flags: u64, data: ?*c_void, size: u64) c_long, 25);
+pub const skb_load_bytes = @intToPtr(fn (skb: ?*c_void, offset: u32, to: ?*c_void, len: u32) c_long, 26);
+pub const get_stackid = @intToPtr(fn (ctx: ?*c_void, map: *const kern.MapDef, flags: u64) c_long, 27);
+// from and to point to __be32
+pub const csum_diff = @intToPtr(fn (from: *u32, from_size: u32, to: *u32, to_size: u32, seed: u32) i64, 28);
+pub const skb_get_tunnel_opt = @intToPtr(fn (skb: *kern.SkBuff, opt: ?*c_void, size: u32) c_long, 29);
+pub const skb_set_tunnel_opt = @intToPtr(fn (skb: *kern.SkBuff, opt: ?*c_void, size: u32) c_long, 30);
+// proto is __be16
+pub const skb_change_proto = @intToPtr(fn (skb: *kern.SkBuff, proto: u16, flags: u64) c_long, 31);
+pub const skb_change_type = @intToPtr(fn (skb: *kern.SkBuff, skb_type: u32) c_long, 32);
+pub const skb_under_cgroup = @intToPtr(fn (skb: *kern.SkBuff, map: ?*const c_void, index: u32) c_long, 33);
+pub const get_hash_recalc = @intToPtr(fn (skb: *kern.SkBuff) u32, 34);
+pub const get_current_task = @intToPtr(fn () u64, 35);
+pub const probe_write_user = @intToPtr(fn (dst: ?*c_void, src: ?*const c_void, len: u32) c_long, 36);
+pub const current_task_under_cgroup = @intToPtr(fn (map: *const kern.MapDef, index: u32) c_long, 37);
+pub const skb_change_tail = @intToPtr(fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 38);
+pub const skb_pull_data = @intToPtr(fn (skb: *kern.SkBuff, len: u32) c_long, 39);
+pub const csum_update = @intToPtr(fn (skb: *kern.SkBuff, csum: u32) i64, 40);
+pub const set_hash_invalid = @intToPtr(fn (skb: *kern.SkBuff) void, 41);
+pub const get_numa_node_id = @intToPtr(fn () c_long, 42);
+pub const skb_change_head = @intToPtr(fn (skb: *kern.SkBuff, len: u32, flags: u64) c_long, 43);
+pub const xdp_adjust_head = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 44);
+pub const probe_read_str = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 45);
+pub const get_socket_cookie = @intToPtr(fn (ctx: ?*c_void) u64, 46);
+pub const get_socket_uid = @intToPtr(fn (skb: *kern.SkBuff) u32, 47);
+pub const set_hash = @intToPtr(fn (skb: *kern.SkBuff, hash: u32) c_long, 48);
+pub const setsockopt = @intToPtr(fn (bpf_socket: *kern.SockOps, level: c_int, optname: c_int, optval: ?*c_void, optlen: c_int) c_long, 49);
+pub const skb_adjust_room = @intToPtr(fn (skb: *kern.SkBuff, len_diff: i32, mode: u32, flags: u64) c_long, 50);
+pub const redirect_map = @intToPtr(fn (map: *const kern.MapDef, key: u32, flags: u64) c_long, 51);
+pub const sk_redirect_map = @intToPtr(fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: u32, flags: u64) c_long, 52);
+pub const sock_map_update = @intToPtr(fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*c_void, flags: u64) c_long, 53);
+pub const xdp_adjust_meta = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 54);
+pub const perf_event_read_value = @intToPtr(fn (map: *const kern.MapDef, flags: u64, buf: *kern.PerfEventValue, buf_size: u32) c_long, 55);
+pub const perf_prog_read_value = @intToPtr(fn (ctx: *kern.PerfEventData, buf: *kern.PerfEventValue, buf_size: u32) c_long, 56);
+pub const getsockopt = @intToPtr(fn (bpf_socket: ?*c_void, level: c_int, optname: c_int, optval: ?*c_void, optlen: c_int) c_long, 57);
+pub const override_return = @intToPtr(fn (regs: *PtRegs, rc: u64) c_long, 58);
+pub const sock_ops_cb_flags_set = @intToPtr(fn (bpf_sock: *kern.SockOps, argval: c_int) c_long, 59);
+pub const msg_redirect_map = @intToPtr(fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: u32, flags: u64) c_long, 60);
+pub const msg_apply_bytes = @intToPtr(fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 61);
+pub const msg_cork_bytes = @intToPtr(fn (msg: *kern.SkMsgMd, bytes: u32) c_long, 62);
+pub const msg_pull_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, end: u32, flags: u64) c_long, 63);
+pub const bind = @intToPtr(fn (ctx: *kern.BpfSockAddr, addr: *kern.SockAddr, addr_len: c_int) c_long, 64);
+pub const xdp_adjust_tail = @intToPtr(fn (xdp_md: *kern.XdpMd, delta: c_int) c_long, 65);
+pub const skb_get_xfrm_state = @intToPtr(fn (skb: *kern.SkBuff, index: u32, xfrm_state: *kern.XfrmState, size: u32, flags: u64) c_long, 66);
+pub const get_stack = @intToPtr(fn (ctx: ?*c_void, buf: ?*c_void, size: u32, flags: u64) c_long, 67);
+pub const skb_load_bytes_relative = @intToPtr(fn (skb: ?*const c_void, offset: u32, to: ?*c_void, len: u32, start_header: u32) c_long, 68);
+pub const fib_lookup = @intToPtr(fn (ctx: ?*c_void, params: *kern.FibLookup, plen: c_int, flags: u32) c_long, 69);
+pub const sock_hash_update = @intToPtr(fn (skops: *kern.SockOps, map: *const kern.MapDef, key: ?*c_void, flags: u64) c_long, 70);
+pub const msg_redirect_hash = @intToPtr(fn (msg: *kern.SkMsgMd, map: *const kern.MapDef, key: ?*c_void, flags: u64) c_long, 71);
+pub const sk_redirect_hash = @intToPtr(fn (skb: *kern.SkBuff, map: *const kern.MapDef, key: ?*c_void, flags: u64) c_long, 72);
+pub const lwt_push_encap = @intToPtr(fn (skb: *kern.SkBuff, typ: u32, hdr: ?*c_void, len: u32) c_long, 73);
+pub const lwt_seg6_store_bytes = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, from: ?*const c_void, len: u32) c_long, 74);
+pub const lwt_seg6_adjust_srh = @intToPtr(fn (skb: *kern.SkBuff, offset: u32, delta: i32) c_long, 75);
+pub const lwt_seg6_action = @intToPtr(fn (skb: *kern.SkBuff, action: u32, param: ?*c_void, param_len: u32) c_long, 76);
+pub const rc_repeat = @intToPtr(fn (ctx: ?*c_void) c_long, 77);
+pub const rc_keydown = @intToPtr(fn (ctx: ?*c_void, protocol: u32, scancode: u64, toggle: u32) c_long, 78);
+pub const skb_cgroup_id = @intToPtr(fn (skb: *kern.SkBuff) u64, 79);
+pub const get_current_cgroup_id = @intToPtr(fn () u64, 80);
+pub const get_local_storage = @intToPtr(fn (map: ?*c_void, flags: u64) ?*c_void, 81);
+pub const sk_select_reuseport = @intToPtr(fn (reuse: *kern.SkReusePortMd, map: *const kern.MapDef, key: ?*c_void, flags: u64) c_long, 82);
+pub const skb_ancestor_cgroup_id = @intToPtr(fn (skb: *kern.SkBuff, ancestor_level: c_int) u64, 83);
+pub const sk_lookup_tcp = @intToPtr(fn (ctx: ?*c_void, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 84);
+pub const sk_lookup_udp = @intToPtr(fn (ctx: ?*c_void, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 85);
+pub const sk_release = @intToPtr(fn (sock: *kern.Sock) c_long, 86);
+pub const map_push_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*const c_void, flags: u64) c_long, 87);
+pub const map_pop_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*c_void) c_long, 88);
+pub const map_peek_elem = @intToPtr(fn (map: *const kern.MapDef, value: ?*c_void) c_long, 89);
+pub const msg_push_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 90);
+pub const msg_pop_data = @intToPtr(fn (msg: *kern.SkMsgMd, start: u32, len: u32, flags: u64) c_long, 91);
+pub const rc_pointer_rel = @intToPtr(fn (ctx: ?*c_void, rel_x: i32, rel_y: i32) c_long, 92);
+pub const spin_lock = @intToPtr(fn (lock: *kern.SpinLock) c_long, 93);
+pub const spin_unlock = @intToPtr(fn (lock: *kern.SpinLock) c_long, 94);
+pub const sk_fullsock = @intToPtr(fn (sk: *kern.Sock) ?*SkFullSock, 95);
+pub const tcp_sock = @intToPtr(fn (sk: *kern.Sock) ?*kern.TcpSock, 96);
+pub const skb_ecn_set_ce = @intToPtr(fn (skb: *kern.SkBuff) c_long, 97);
+pub const get_listener_sock = @intToPtr(fn (sk: *kern.Sock) ?*kern.Sock, 98);
+pub const skc_lookup_tcp = @intToPtr(fn (ctx: ?*c_void, tuple: *kern.SockTuple, tuple_size: u32, netns: u64, flags: u64) ?*kern.Sock, 99);
+pub const tcp_check_syncookie = @intToPtr(fn (sk: *kern.Sock, iph: ?*c_void, iph_len: u32, th: *TcpHdr, th_len: u32) c_long, 100);
+pub const sysctl_get_name = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong, flags: u64) c_long, 101);
+pub const sysctl_get_current_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 102);
+pub const sysctl_get_new_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*u8, buf_len: c_ulong) c_long, 103);
+pub const sysctl_set_new_value = @intToPtr(fn (ctx: *kern.SysCtl, buf: ?*const u8, buf_len: c_ulong) c_long, 104);
+pub const strtol = @intToPtr(fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_long) c_long, 105);
+pub const strtoul = @intToPtr(fn (buf: *const u8, buf_len: c_ulong, flags: u64, res: *c_ulong) c_long, 106);
+pub const sk_storage_get = @intToPtr(fn (map: *const kern.MapDef, sk: *kern.Sock, value: ?*c_void, flags: u64) ?*c_void, 107);
+pub const sk_storage_delete = @intToPtr(fn (map: *const kern.MapDef, sk: *kern.Sock) c_long, 108);
+pub const send_signal = @intToPtr(fn (sig: u32) c_long, 109);
+pub const tcp_gen_syncookie = @intToPtr(fn (sk: *kern.Sock, iph: ?*c_void, iph_len: u32, th: *TcpHdr, th_len: u32) i64, 110);
+pub const skb_output = @intToPtr(fn (ctx: ?*c_void, map: *const kern.MapDef, flags: u64, data: ?*c_void, size: u64) c_long, 111);
+pub const probe_read_user = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 112);
+pub const probe_read_kernel = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 113);
+pub const probe_read_user_str = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 114);
+pub const probe_read_kernel_str = @intToPtr(fn (dst: ?*c_void, size: u32, unsafe_ptr: ?*const c_void) c_long, 115);
+pub const tcp_send_ack = @intToPtr(fn (tp: ?*c_void, rcv_nxt: u32) c_long, 116);
+pub const send_signal_thread = @intToPtr(fn (sig: u32) c_long, 117);
+pub const jiffies64 = @intToPtr(fn () u64, 118);
+pub const read_branch_records = @intToPtr(fn (ctx: *kern.PerfEventData, buf: ?*c_void, size: u32, flags: u64) c_long, 119);
+pub const get_ns_current_pid_tgid = @intToPtr(fn (dev: u64, ino: u64, nsdata: *kern.PidNsInfo, size: u32) c_long, 120);
+pub const xdp_output = @intToPtr(fn (ctx: ?*c_void, map: *const kern.MapDef, flags: u64, data: ?*c_void, size: u64) c_long, 121);
+pub const get_netns_cookie = @intToPtr(fn (ctx: ?*c_void) u64, 122);
+pub const get_current_ancestor_cgroup_id = @intToPtr(fn (ancestor_level: c_int) u64, 123);
+pub const sk_assign = @intToPtr(fn (skb: *kern.SkBuff, sk: *kern.Sock, flags: u64) c_long, 124);
+pub const ktime_get_boot_ns = @intToPtr(fn () u64, 125);
+pub const seq_printf = @intToPtr(fn (m: *kern.SeqFile, fmt: ?*const u8, fmt_size: u32, data: ?*const c_void, data_len: u32) c_long, 126);
+pub const seq_write = @intToPtr(fn (m: *kern.SeqFile, data: ?*const u8, len: u32) c_long, 127);
+pub const sk_cgroup_id = @intToPtr(fn (sk: *kern.BpfSock) u64, 128);
+pub const sk_ancestor_cgroup_id = @intToPtr(fn (sk: *kern.BpfSock, ancestor_level: c_long) u64, 129);
+pub const ringbuf_output = @intToPtr(fn (ringbuf: ?*c_void, data: ?*c_void, size: u64, flags: u64) ?*c_void, 130);
+pub const ringbuf_reserve = @intToPtr(fn (ringbuf: ?*c_void, size: u64, flags: u64) ?*c_void, 131);
+pub const ringbuf_submit = @intToPtr(fn (data: ?*c_void, flags: u64) void, 132);
+pub const ringbuf_discard = @intToPtr(fn (data: ?*c_void, flags: u64) void, 133);
+pub const ringbuf_query = @intToPtr(fn (ringbuf: ?*c_void, flags: u64) u64, 134);
+pub const csum_level = @intToPtr(fn (skb: *kern.SkBuff, level: u64) c_long, 134);
+pub const skc_to_tcp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Tcp6Sock, 135);
+pub const skc_to_tcp_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpSock, 136);
+pub const skc_to_tcp_timewait_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpTimewaitSock, 137);
+pub const skc_to_tcp_request_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.TcpRequestSock, 138);
+pub const skc_to_udp6_sock = @intToPtr(fn (sk: ?*c_void) ?*kern.Udp6Sock, 139);
+pub const get_task_stack = @intToPtr(fn (task: ?*c_void, buf: ?*c_void, size: u32, flags: u64) c_long, 140);
diff --git a/lib/std/os/linux/bpf/kern.zig b/lib/std/os/linux/bpf/kern.zig
new file mode 100644
index 0000000000..3bd605301a
--- /dev/null
+++ b/lib/std/os/linux/bpf/kern.zig
@@ -0,0 +1,39 @@
+// 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 std = @import("../../../std.zig");
+
+const in_bpf_program = switch (std.builtin.arch) {
+ .bpfel, .bpfeb => true,
+ else => false,
+};
+
+pub const helpers = if (in_bpf_program) @import("helpers.zig") else struct {};
+
+pub const BpfSock = @Type(.Opaque);
+pub const BpfSockAddr = @Type(.Opaque);
+pub const FibLookup = @Type(.Opaque);
+pub const MapDef = @Type(.Opaque);
+pub const PerfEventData = @Type(.Opaque);
+pub const PerfEventValue = @Type(.Opaque);
+pub const PidNsInfo = @Type(.Opaque);
+pub const SeqFile = @Type(.Opaque);
+pub const SkBuff = @Type(.Opaque);
+pub const SkMsgMd = @Type(.Opaque);
+pub const SkReusePortMd = @Type(.Opaque);
+pub const Sock = @Type(.Opaque);
+pub const SockAddr = @Type(.Opaque);
+pub const SockOps = @Type(.Opaque);
+pub const SockTuple = @Type(.Opaque);
+pub const SpinLock = @Type(.Opaque);
+pub const SysCtl = @Type(.Opaque);
+pub const Tcp6Sock = @Type(.Opaque);
+pub const TcpRequestSock = @Type(.Opaque);
+pub const TcpSock = @Type(.Opaque);
+pub const TcpTimewaitSock = @Type(.Opaque);
+pub const TunnelKey = @Type(.Opaque);
+pub const Udp6Sock = @Type(.Opaque);
+pub const XdpMd = @Type(.Opaque);
+pub const XfrmState = @Type(.Opaque);