Skip to content
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
17 changes: 15 additions & 2 deletions lib/std/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10856,6 +10856,18 @@ pub const pthread_threadid_np = switch (native_os) {
else => {},
};

pub const caddr_t = ?[*]u8;

pub const ptrace = switch (native_os) {
.linux, .serenity => private.ptrace,
.macos, .ios, .tvos, .watchos, .visionos => darwin.ptrace,
.dragonfly => dragonfly.ptrace,
.freebsd => freebsd.ptrace,
.netbsd => netbsd.ptrace,
.openbsd => openbsd.ptrace,
else => {},
};

pub extern "c" fn sem_init(sem: *sem_t, pshared: c_int, value: c_uint) c_int;
pub extern "c" fn sem_destroy(sem: *sem_t) c_int;
pub extern "c" fn sem_open(name: [*:0]const u8, flag: c_int, mode: mode_t, value: c_uint) *sem_t;
Expand Down Expand Up @@ -11305,7 +11317,6 @@ pub const pthread_attr_get_qos_class_np = darwin.pthread_attr_get_qos_class_np;
pub const pthread_attr_set_qos_class_np = darwin.pthread_attr_set_qos_class_np;
pub const pthread_get_qos_class_np = darwin.pthread_get_qos_class_np;
pub const pthread_set_qos_class_self_np = darwin.pthread_set_qos_class_self_np;
pub const ptrace = darwin.ptrace;
pub const qos_class_t = darwin.qos_class_t;
pub const task_flavor_t = darwin.task_flavor_t;
pub const task_for_pid = darwin.task_for_pid;
Expand Down Expand Up @@ -11341,7 +11352,6 @@ pub const vm_region_submap_info_64 = darwin.vm_region_submap_info_64;
pub const vm_region_submap_short_info_64 = darwin.vm_region_submap_short_info_64;
pub const vm_region_top_info = darwin.vm_region_top_info;

pub const caddr_t = darwin.caddr_t;
pub const exception_behavior_array_t = darwin.exception_behavior_array_t;
pub const exception_behavior_t = darwin.exception_behavior_t;
pub const exception_data_t = darwin.exception_data_t;
Expand Down Expand Up @@ -11466,6 +11476,9 @@ const private = struct {
extern "c" fn mlockall(flags: MCL) c_int;
extern "c" fn munlockall() c_int;

// linux and https://github.com/SerenityOS/serenity/blob/502caef9a40bccc7459f9835f2174a601106299a/Userland/Libraries/LibC/sys/ptrace.cpp
extern "c" fn ptrace(request: c_int, pid: pid_t, addr: ?*anyopaque, data: ?*anyopaque) c_long;

/// macos modernized symbols.
/// x86_64 links to $INODE64 suffix for 64-bit support.
/// Note these are not necessary on aarch64.
Expand Down
3 changes: 1 addition & 2 deletions lib/std/c/darwin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const native_arch = builtin.target.cpu.arch;
const assert = std.debug.assert;
const AF = std.c.AF;
const PROT = std.c.PROT;
const caddr_t = std.c.caddr_t;
const fd_t = std.c.fd_t;
const iovec_const = std.posix.iovec_const;
const mode_t = std.c.mode_t;
Expand Down Expand Up @@ -1318,8 +1319,6 @@ pub const PT = enum(c_int) {
_,
};

pub const caddr_t = ?[*]u8;

pub extern "c" fn ptrace(request: PT, pid: pid_t, addr: caddr_t, data: c_int) c_int;

pub const POSIX_SPAWN = packed struct(c_short) {
Expand Down
2 changes: 2 additions & 0 deletions lib/std/c/dragonfly.zig
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
const std = @import("../std.zig");

const SIG = std.c.SIG;
const caddr_t = std.c.caddr_t;
const gid_t = std.c.gid_t;
const iovec = std.c.iovec;
const pid_t = std.c.pid_t;
const socklen_t = std.c.socklen_t;
const uid_t = std.c.uid_t;

pub extern "c" fn lwp_gettid() c_int;
pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;
pub extern "c" fn umtx_sleep(ptr: *const volatile c_int, value: c_int, timeout: c_int) c_int;
pub extern "c" fn umtx_wakeup(ptr: *const volatile c_int, count: c_int) c_int;

Expand Down
3 changes: 3 additions & 0 deletions lib/std/c/freebsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const assert = std.debug.assert;
const PATH_MAX = std.c.PATH_MAX;
const blkcnt_t = std.c.blkcnt_t;
const blksize_t = std.c.blksize_t;
const caddr_t = std.c.caddr_t;
const dev_t = std.c.dev_t;
const fd_t = std.c.fd_t;
const gid_t = std.c.gid_t;
Expand All @@ -25,6 +26,8 @@ comptime {
assert(builtin.os.tag == .freebsd); // Prevent access of std.c symbols on wrong OS.
}

pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;

pub extern "c" fn kinfo_getfile(pid: pid_t, cntp: *c_int) ?[*]kinfo_file;
pub extern "c" fn copy_file_range(fd_in: fd_t, off_in: ?*off_t, fd_out: fd_t, off_out: ?*off_t, len: usize, flags: u32) usize;

Expand Down
2 changes: 2 additions & 0 deletions lib/std/c/netbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const pthread_t = std.c.pthread_t;
const sigval_t = std.c.sigval_t;
const uid_t = std.c.uid_t;

pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: ?*anyopaque, data: c_int) c_int;

pub const lwpid_t = i32;

pub extern "c" fn _lwp_self() lwpid_t;
Expand Down
3 changes: 3 additions & 0 deletions lib/std/c/openbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const std = @import("../std.zig");
const assert = std.debug.assert;
const maxInt = std.math.maxInt;
const builtin = @import("builtin");
const caddr_t = std.c.caddr_t;
const iovec = std.posix.iovec;
const iovec_const = std.posix.iovec_const;
const passwd = std.c.passwd;
Expand All @@ -13,6 +14,8 @@ comptime {
assert(builtin.os.tag == .openbsd); // Prevent access of std.c symbols on wrong OS.
}

pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;

pub const pthread_spinlock_t = extern struct {
inner: ?*anyopaque = null,
};
Expand Down
27 changes: 27 additions & 0 deletions lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9648,6 +9648,33 @@ pub const PTRACE = struct {
pub const SECCOMP_GET_FILTER = 0x420c;
pub const SECCOMP_GET_METADATA = 0x420d;
pub const GET_SYSCALL_INFO = 0x420e;

pub const EVENT = struct {
pub const FORK = 1;
pub const VFORK = 2;
pub const CLONE = 3;
pub const EXEC = 4;
pub const VFORK_DONE = 5;
pub const EXIT = 6;
pub const SECCOMP = 7;
pub const STOP = 128;
};

pub const O = struct {
pub const TRACESYSGOOD = 1;
pub const TRACEFORK = 1 << PTRACE.EVENT.FORK;
pub const TRACEVFORK = 1 << PTRACE.EVENT.VFORK;
pub const TRACECLONE = 1 << PTRACE.EVENT.CLONE;
pub const TRACEEXEC = 1 << PTRACE.EVENT.EXEC;
pub const TRACEVFORKDONE = 1 << PTRACE.EVENT.VFORK_DONE;
pub const TRACEEXIT = 1 << PTRACE.EVENT.EXIT;
pub const TRACESECCOMP = 1 << PTRACE.EVENT.SECCOMP;

pub const EXITKILL = 1 << 20;
pub const SUSPEND_SECCOMP = 1 << 21;

pub const MASK = 0x000000ff | PTRACE.O.EXITKILL | PTRACE.O.SUSPEND_SECCOMP;
};
};

/// For futex2_waitv and futex2_requeue. Arrays of `futex2_waitone` allow
Expand Down
82 changes: 75 additions & 7 deletions lib/std/posix.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7377,18 +7377,33 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!system.itimerspec {
}

pub const PtraceError = error{
DeadLock,
DeviceBusy,
InputOutput,
NameTooLong,
OperationNotSupported,
OutOfMemory,
ProcessNotFound,
PermissionDenied,
} || UnexpectedError;

pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!void {
if (native_os == .windows or native_os == .wasi)
@compileError("Unsupported OS");

pub fn ptrace(request: u32, pid: pid_t, addr: usize, data: usize) PtraceError!void {
return switch (native_os) {
.linux => switch (errno(linux.ptrace(request, pid, addr, signal, 0))) {
.windows,
.wasi,
.emscripten,
.haiku,
.solaris,
.illumos,
.plan9,
=> @compileError("ptrace unsupported by target OS"),

.linux => switch (errno(if (builtin.link_libc) std.c.ptrace(
@intCast(request),
pid,
@ptrFromInt(addr),
@ptrFromInt(data),
) else linux.ptrace(request, pid, addr, data, 0))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.FAULT => unreachable,
Expand All @@ -7400,27 +7415,80 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!
},

.macos, .ios, .tvos, .watchos, .visionos => switch (errno(std.c.ptrace(
@enumFromInt(request),
pid,
@ptrFromInt(addr),
@intCast(data),
))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.INVAL => unreachable,
.PERM => error.PermissionDenied,
.BUSY => error.DeviceBusy,
else => |err| return unexpectedErrno(err),
},

.dragonfly => switch (errno(std.c.ptrace(
@intCast(request),
pid,
@ptrFromInt(addr),
@intCast(data),
))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.INVAL => unreachable,
.PERM => error.PermissionDenied,
.BUSY => error.DeviceBusy,
else => |err| return unexpectedErrno(err),
},

.freebsd => switch (errno(std.c.ptrace(
@intCast(request),
pid,
@ptrFromInt(addr),
@intCast(data),
))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.INVAL => unreachable,
.PERM => error.PermissionDenied,
.BUSY => error.DeviceBusy,
.NOENT, .NOMEM => error.OutOfMemory,
.NAMETOOLONG => error.NameTooLong,
else => |err| return unexpectedErrno(err),
},

.netbsd => switch (errno(std.c.ptrace(
@intCast(request),
pid,
@ptrFromInt(addr),
@intCast(signal),
@intCast(data),
))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.INVAL => unreachable,
.PERM => error.PermissionDenied,
.BUSY => error.DeviceBusy,
.DEADLK => error.DeadLock,
else => |err| return unexpectedErrno(err),
},

else => switch (errno(system.ptrace(request, pid, addr, signal))) {
.openbsd => switch (errno(std.c.ptrace(
@intCast(request),
pid,
@ptrFromInt(addr),
@intCast(data),
))) {
.SUCCESS => {},
.SRCH => error.ProcessNotFound,
.INVAL => unreachable,
.PERM => error.PermissionDenied,
.BUSY => error.DeviceBusy,
.NOTSUP => error.OperationNotSupported,
else => |err| return unexpectedErrno(err),
},

else => @compileError("std.posix.ptrace unimplemented for target OS"),
};
}

Expand Down