darwin: add even more wrappers for Mach syscalls

Rename `ThreadId` to `MachThread`.
This commit is contained in:
Jakub Konka 2022-12-14 00:10:14 +01:00
parent f5336a8fec
commit ec2697b7ea
3 changed files with 38 additions and 10 deletions

View File

@ -102,6 +102,8 @@ pub const MACH_EXCEPTION_MASK = MACH_EXCEPTION_CODES |
pub const TASK_NULL: task_t = 0;
pub const THREAD_NULL: thread_t = 0;
pub const MACH_PORT_NULL: mach_port_t = 0;
pub const MACH_MSG_TIMEOUT_NONE: mach_msg_timeout_t = 0;
pub const MACH_MSG_OPTION_NONE = 0x00000000;
@ -406,6 +408,7 @@ pub extern "c" fn task_resume(target_task: task_read_t) kern_return_t;
pub extern "c" fn task_suspend(target_task: task_read_t) kern_return_t;
pub extern "c" fn task_for_pid(target_tport: mach_port_name_t, pid: pid_t, t: *mach_port_name_t) kern_return_t;
pub extern "c" fn pid_for_task(target_tport: mach_port_name_t, pid: *pid_t) kern_return_t;
pub extern "c" fn mach_vm_read(
target_task: vm_map_read_t,
address: mach_vm_address_t,
@ -3054,11 +3057,20 @@ pub const _POSIX_SPAWN_RESLIDE = 0x0800;
pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000;
pub const PT_TRACE_ME = 0;
pub const PT_READ_I = 1;
pub const PT_READ_D = 2;
pub const PT_READ_U = 3;
pub const PT_WRITE_I = 4;
pub const PT_WRITE_D = 5;
pub const PT_WRITE_U = 6;
pub const PT_CONTINUE = 7;
pub const PT_KILL = 8;
pub const PT_STEP = 9;
pub const PT_DETACH = 11;
pub const PT_SIGEXC = 12;
pub const PT_THUPDATE = 13;
pub const PT_ATTACHEXC = 14;
pub const PT_FORCEQUOTA = 30;
pub const PT_DENY_ATTACH = 31;
pub const caddr_t = ?[*]u8;

View File

@ -24,6 +24,18 @@ const mach_task = if (builtin.target.isDarwin()) struct {
return self.port != std.c.TASK_NULL;
}
pub fn pidForTask(self: MachTask) MachError!std.os.pid_t {
var pid: std.os.pid_t = undefined;
switch (std.c.getKernError(std.c.pid_for_task(self.port, &pid))) {
.SUCCESS => return pid,
.FAILURE => return error.PermissionDenied,
else => |err| {
log.err("pid_for_task kernel call failed with error code: {s}", .{@tagName(err)});
return error.Unexpected;
},
}
}
pub fn allocatePort(self: MachTask, right: std.c.MACH_PORT_RIGHT) MachError!MachTask {
var out_port: std.c.mach_port_name_t = undefined;
switch (std.c.getKernError(std.c.mach_port_allocate(
@ -440,7 +452,7 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
const ThreadList = struct {
buf: []ThreadId,
buf: []MachThread,
pub fn deinit(list: ThreadList) void {
const self_task = machTaskForSelf();
@ -456,7 +468,7 @@ const mach_task = if (builtin.target.isDarwin()) struct {
var thread_list: std.c.mach_port_array_t = undefined;
var thread_count: std.c.mach_msg_type_number_t = undefined;
switch (std.c.getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) {
.SUCCESS => return ThreadList{ .buf = @ptrCast([*]ThreadId, thread_list)[0..thread_count] },
.SUCCESS => return ThreadList{ .buf = @ptrCast([*]MachThread, thread_list)[0..thread_count] },
else => |err| {
log.err("task_threads kernel call failed with error code: {s}", .{@tagName(err)});
return error.Unexpected;
@ -465,14 +477,18 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
};
pub const ThreadId = extern struct {
id: std.c.thread_act_t,
pub const MachThread = extern struct {
port: std.c.mach_port_t,
pub fn getBasicInfo(thread_id: ThreadId) MachError!std.c.thread_basic_info {
pub fn isValid(thread: MachThread) bool {
return thread.port != std.c.THREAD_NULL;
}
pub fn getBasicInfo(thread: MachThread) MachError!std.c.thread_basic_info {
var info: std.c.thread_basic_info = undefined;
var count = std.c.THREAD_BASIC_INFO_COUNT;
switch (std.c.getKernError(std.c.thread_info(
thread_id.id,
thread.port,
std.c.THREAD_BASIC_INFO,
@ptrCast(std.c.thread_info_t, &info),
&count,
@ -485,11 +501,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
}
pub fn getIdentifierInfo(thread_id: ThreadId) MachError!std.c.thread_identifier_info {
pub fn getIdentifierInfo(thread: MachThread) MachError!std.c.thread_identifier_info {
var info: std.c.thread_identifier_info = undefined;
var count = std.c.THREAD_IDENTIFIER_INFO_COUNT;
switch (std.c.getKernError(std.c.thread_info(
thread_id.id,
thread.port,
std.c.THREAD_IDENTIFIER_INFO,
@ptrCast(std.c.thread_info_t, &info),
&count,

View File

@ -16,8 +16,8 @@ const ptrace = if (builtin.target.isDarwin()) struct {
PermissionDenied,
} || UnexpectedError;
pub fn ptrace(request: i32, pid: pid_t) PtraceError!void {
switch (errno(system.ptrace(request, pid, null, 0))) {
pub fn ptrace(request: i32, pid: pid_t, addr: ?[*]u8, signal: i32) PtraceError!void {
switch (errno(system.ptrace(request, pid, addr, signal))) {
.SUCCESS => return,
.SRCH => return error.ProcessNotFound,
.INVAL => unreachable,