Commit 9b4cae4750
Changed files (7)
lib/std/c/darwin.zig
@@ -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;
@@ -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) {
lib/std/c/dragonfly.zig
@@ -1,6 +1,7 @@
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;
@@ -8,6 +9,7 @@ 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;
lib/std/c/freebsd.zig
@@ -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;
@@ -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;
lib/std/c/netbsd.zig
@@ -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;
lib/std/c/openbsd.zig
@@ -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;
@@ -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,
};
lib/std/c.zig
@@ -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;
@@ -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;
@@ -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;
@@ -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.
lib/std/posix.zig
@@ -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,
@@ -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"),
};
}