mirror of
https://github.com/ziglang/zig.git
synced 2025-12-18 04:03:14 +00:00
macos: update Mach routines for accessing page info
This commit is contained in:
parent
3c3826bf93
commit
648afbc839
@ -155,6 +155,7 @@ pub const vm_map_t = mach_port_t;
|
|||||||
pub const vm_map_read_t = mach_port_t;
|
pub const vm_map_read_t = mach_port_t;
|
||||||
pub const vm_region_flavor_t = c_int;
|
pub const vm_region_flavor_t = c_int;
|
||||||
pub const vm_region_info_t = *c_int;
|
pub const vm_region_info_t = *c_int;
|
||||||
|
pub const vm_region_recurse_info_t = *c_int;
|
||||||
pub const mach_vm_address_t = usize;
|
pub const mach_vm_address_t = usize;
|
||||||
pub const vm_offset_t = usize;
|
pub const vm_offset_t = usize;
|
||||||
pub const mach_vm_size_t = u64;
|
pub const mach_vm_size_t = u64;
|
||||||
@ -193,13 +194,20 @@ pub extern "c" fn mach_vm_region(
|
|||||||
info_cnt: *mach_msg_type_number_t,
|
info_cnt: *mach_msg_type_number_t,
|
||||||
object_name: *mach_port_t,
|
object_name: *mach_port_t,
|
||||||
) kern_return_t;
|
) kern_return_t;
|
||||||
|
pub extern "c" fn mach_vm_region_recurse(
|
||||||
pub const VM_REGION_BASIC_INFO_64 = 9;
|
target_task: vm_map_t,
|
||||||
pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);
|
address: *mach_vm_address_t,
|
||||||
|
size: *mach_vm_size_t,
|
||||||
|
nesting_depth: *natural_t,
|
||||||
|
info: vm_region_recurse_info_t,
|
||||||
|
info_cnt: *mach_msg_type_number_t,
|
||||||
|
) kern_return_t;
|
||||||
|
|
||||||
pub const vm_inherit_t = u32;
|
pub const vm_inherit_t = u32;
|
||||||
pub const memory_object_offset_t = u64;
|
pub const memory_object_offset_t = u64;
|
||||||
pub const vm_behavior_t = i32;
|
pub const vm_behavior_t = i32;
|
||||||
|
pub const vm32_object_id_t = u32;
|
||||||
|
pub const vm_object_id_t = u64;
|
||||||
|
|
||||||
pub const VM_INHERIT_SHARE: vm_inherit_t = 0;
|
pub const VM_INHERIT_SHARE: vm_inherit_t = 0;
|
||||||
pub const VM_INHERIT_COPY: vm_inherit_t = 1;
|
pub const VM_INHERIT_COPY: vm_inherit_t = 1;
|
||||||
@ -221,8 +229,47 @@ pub const VM_BEHAVIOR_REUSE: vm_behavior_t = 9;
|
|||||||
pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10;
|
pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10;
|
||||||
pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11;
|
pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11;
|
||||||
|
|
||||||
pub const vm32_object_id_t = u32;
|
pub const VM_REGION_BASIC_INFO_64 = 9;
|
||||||
pub const vm_object_id_t = u64;
|
pub const VM_REGION_EXTENDED_INFO = 13;
|
||||||
|
pub const VM_REGION_TOP_INFO = 12;
|
||||||
|
pub const VM_REGION_SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);
|
||||||
|
pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t);
|
||||||
|
pub const VM_REGION_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int);
|
||||||
|
pub const VM_REGION_EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t);
|
||||||
|
pub const VM_REGION_TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t);
|
||||||
|
|
||||||
|
pub const vm_region_basic_info_64 = extern struct {
|
||||||
|
protection: vm_prot_t,
|
||||||
|
max_protection: vm_prot_t,
|
||||||
|
inheritance: vm_inherit_t,
|
||||||
|
shared: boolean_t,
|
||||||
|
reserved: boolean_t,
|
||||||
|
offset: memory_object_offset_t,
|
||||||
|
behavior: vm_behavior_t,
|
||||||
|
user_wired_count: u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const vm_region_extended_info = extern struct {
|
||||||
|
protection: vm_prot_t,
|
||||||
|
user_tag: u32,
|
||||||
|
pages_resident: u32,
|
||||||
|
pages_shared_now_private: u32,
|
||||||
|
pages_swapped_out: u32,
|
||||||
|
pages_dirtied: u32,
|
||||||
|
ref_count: u32,
|
||||||
|
shadow_depth: u16,
|
||||||
|
external_pager: u8,
|
||||||
|
share_mode: u8,
|
||||||
|
pages_reusable: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const vm_region_top_info = extern struct {
|
||||||
|
obj_id: u32,
|
||||||
|
ref_count: u32,
|
||||||
|
private_pages_resident: u32,
|
||||||
|
shared_pages_resident: u32,
|
||||||
|
share_mode: u8,
|
||||||
|
};
|
||||||
|
|
||||||
pub const vm_region_submap_info_64 = extern struct {
|
pub const vm_region_submap_info_64 = extern struct {
|
||||||
// present across protection
|
// present across protection
|
||||||
@ -262,6 +309,34 @@ pub const vm_region_submap_info_64 = extern struct {
|
|||||||
object_id_full: vm_object_id_t,
|
object_id_full: vm_object_id_t,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const vm_region_submap_short_info_64 = extern struct {
|
||||||
|
// present access protection
|
||||||
|
protection: vm_prot_t,
|
||||||
|
// max avail through vm_prot
|
||||||
|
max_protection: vm_prot_t,
|
||||||
|
// behavior of map/obj on fork
|
||||||
|
inheritance: vm_inherit_t,
|
||||||
|
// offset into object/map
|
||||||
|
offset: memory_object_offset_t,
|
||||||
|
// user tag on map entry
|
||||||
|
user_tag: u32,
|
||||||
|
// obj/map mappers, etc
|
||||||
|
ref_count: u32,
|
||||||
|
// only for obj
|
||||||
|
shadow_depth: u16,
|
||||||
|
// only for obj
|
||||||
|
external_pager: u8,
|
||||||
|
// see enumeration
|
||||||
|
share_mode: u8,
|
||||||
|
// submap vs obj
|
||||||
|
is_submap: boolean_t,
|
||||||
|
// access behavior hint
|
||||||
|
behavior: vm_behavior_t,
|
||||||
|
// obj/map name, not a handle
|
||||||
|
object_id: vm32_object_id_t,
|
||||||
|
user_wired_count: u16,
|
||||||
|
};
|
||||||
|
|
||||||
pub const thread_act_t = mach_port_t;
|
pub const thread_act_t = mach_port_t;
|
||||||
pub const thread_state_t = *natural_t;
|
pub const thread_state_t = *natural_t;
|
||||||
pub const mach_port_array_t = *mach_port_t;
|
pub const mach_port_array_t = *mach_port_t;
|
||||||
@ -986,9 +1061,13 @@ pub const MAP = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const MSF = struct {
|
pub const MSF = struct {
|
||||||
pub const ASYNC = 1;
|
pub const ASYNC = 0x1;
|
||||||
pub const INVALIDATE = 2;
|
pub const INVALIDATE = 0x2;
|
||||||
pub const SYNC = 4;
|
// invalidate, leave mapped
|
||||||
|
pub const KILLPAGES = 0x4;
|
||||||
|
// deactivate, leave mapped
|
||||||
|
pub const DEACTIVATE = 0x8;
|
||||||
|
pub const SYNC = 0x10;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SA = struct {
|
pub const SA = struct {
|
||||||
|
|||||||
@ -24,22 +24,63 @@ const mach_task = if (builtin.target.isDarwin()) struct {
|
|||||||
return self.port != 0;
|
return self.port != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!std.c.vm_prot_t {
|
pub const RegionInfo = struct {
|
||||||
var base_addr = address;
|
pub const Tag = enum {
|
||||||
|
basic,
|
||||||
|
extended,
|
||||||
|
top,
|
||||||
|
};
|
||||||
|
|
||||||
|
base_addr: u64,
|
||||||
|
tag: Tag,
|
||||||
|
info: union {
|
||||||
|
basic: std.c.vm_region_basic_info_64,
|
||||||
|
extended: std.c.vm_region_extended_info,
|
||||||
|
top: std.c.vm_region_top_info,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn getRegionInfo(
|
||||||
|
task: MachTask,
|
||||||
|
address: u64,
|
||||||
|
len: usize,
|
||||||
|
tag: RegionInfo.Tag,
|
||||||
|
) MachError!RegionInfo {
|
||||||
|
var info: RegionInfo = .{
|
||||||
|
.base_addr = address,
|
||||||
|
.tag = tag,
|
||||||
|
.info = undefined,
|
||||||
|
};
|
||||||
|
switch (tag) {
|
||||||
|
.basic => info.info = .{ .basic = undefined },
|
||||||
|
.extended => info.info = .{ .extended = undefined },
|
||||||
|
.top => info.info = .{ .top = undefined },
|
||||||
|
}
|
||||||
var base_len: std.c.mach_vm_size_t = if (len == 1) 2 else len;
|
var base_len: std.c.mach_vm_size_t = if (len == 1) 2 else len;
|
||||||
var objname: std.c.mach_port_t = undefined;
|
var objname: std.c.mach_port_t = undefined;
|
||||||
var info: std.c.vm_region_submap_info_64 = undefined;
|
var count: std.c.mach_msg_type_number_t = switch (tag) {
|
||||||
var count: std.c.mach_msg_type_number_t = std.c.VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
|
.basic => std.c.VM_REGION_BASIC_INFO_COUNT,
|
||||||
|
.extended => std.c.VM_REGION_EXTENDED_INFO_COUNT,
|
||||||
|
.top => std.c.VM_REGION_TOP_INFO_COUNT,
|
||||||
|
};
|
||||||
switch (std.c.getKernError(std.c.mach_vm_region(
|
switch (std.c.getKernError(std.c.mach_vm_region(
|
||||||
task.port,
|
task.port,
|
||||||
&base_addr,
|
&info.base_addr,
|
||||||
&base_len,
|
&base_len,
|
||||||
std.c.VM_REGION_BASIC_INFO_64,
|
switch (tag) {
|
||||||
@ptrCast(std.c.vm_region_info_t, &info),
|
.basic => std.c.VM_REGION_BASIC_INFO_64,
|
||||||
|
.extended => std.c.VM_REGION_EXTENDED_INFO,
|
||||||
|
.top => std.c.VM_REGION_TOP_INFO,
|
||||||
|
},
|
||||||
|
switch (tag) {
|
||||||
|
.basic => @ptrCast(std.c.vm_region_info_t, &info.info.basic),
|
||||||
|
.extended => @ptrCast(std.c.vm_region_info_t, &info.info.extended),
|
||||||
|
.top => @ptrCast(std.c.vm_region_info_t, &info.info.top),
|
||||||
|
},
|
||||||
&count,
|
&count,
|
||||||
&objname,
|
&objname,
|
||||||
))) {
|
))) {
|
||||||
.SUCCESS => return info.protection,
|
.SUCCESS => return info,
|
||||||
.FAILURE => return error.PermissionDenied,
|
.FAILURE => return error.PermissionDenied,
|
||||||
else => |err| {
|
else => |err| {
|
||||||
log.err("mach_vm_region kernel call failed with error code: {s}", .{@tagName(err)});
|
log.err("mach_vm_region kernel call failed with error code: {s}", .{@tagName(err)});
|
||||||
@ -48,6 +89,67 @@ const mach_task = if (builtin.target.isDarwin()) struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const RegionSubmapInfo = struct {
|
||||||
|
pub const Tag = enum {
|
||||||
|
short,
|
||||||
|
full,
|
||||||
|
};
|
||||||
|
|
||||||
|
tag: Tag,
|
||||||
|
base_addr: u64,
|
||||||
|
info: union {
|
||||||
|
short: std.c.vm_region_submap_short_info_64,
|
||||||
|
full: std.c.vm_region_submap_info_64,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn getRegionSubmapInfo(
|
||||||
|
task: MachTask,
|
||||||
|
address: u64,
|
||||||
|
len: usize,
|
||||||
|
nesting_depth: u32,
|
||||||
|
tag: RegionSubmapInfo.Tag,
|
||||||
|
) MachError!RegionSubmapInfo {
|
||||||
|
var info: RegionSubmapInfo = .{
|
||||||
|
.base_addr = address,
|
||||||
|
.tag = tag,
|
||||||
|
.info = undefined,
|
||||||
|
};
|
||||||
|
switch (tag) {
|
||||||
|
.short => info.info = .{ .short = undefined },
|
||||||
|
.full => info.info = .{ .full = undefined },
|
||||||
|
}
|
||||||
|
var nesting = nesting_depth;
|
||||||
|
var base_len: std.c.mach_vm_size_t = if (len == 1) 2 else len;
|
||||||
|
var count: std.c.mach_msg_type_number_t = switch (tag) {
|
||||||
|
.short => std.c.VM_REGION_SUBMAP_SHORT_INFO_COUNT_64,
|
||||||
|
.full => std.c.VM_REGION_SUBMAP_INFO_COUNT_64,
|
||||||
|
};
|
||||||
|
switch (std.c.getKernError(std.c.mach_vm_region_recurse(
|
||||||
|
task.port,
|
||||||
|
&info.base_addr,
|
||||||
|
&base_len,
|
||||||
|
&nesting,
|
||||||
|
switch (tag) {
|
||||||
|
.short => @ptrCast(std.c.vm_region_recurse_info_t, &info.info.short),
|
||||||
|
.full => @ptrCast(std.c.vm_region_recurse_info_t, &info.info.full),
|
||||||
|
},
|
||||||
|
&count,
|
||||||
|
))) {
|
||||||
|
.SUCCESS => return info,
|
||||||
|
.FAILURE => return error.PermissionDenied,
|
||||||
|
else => |err| {
|
||||||
|
log.err("mach_vm_region kernel call failed with error code: {s}", .{@tagName(err)});
|
||||||
|
return error.Unexpected;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!std.c.vm_prot_t {
|
||||||
|
const info = try task.getRegionSubmapInfo(address, len, 0, .short);
|
||||||
|
return info.info.short.protection;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: std.c.vm_prot_t) MachError!void {
|
pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: std.c.vm_prot_t) MachError!void {
|
||||||
return task.setProtectionImpl(address, len, true, prot);
|
return task.setProtectionImpl(address, len, true, prot);
|
||||||
}
|
}
|
||||||
@ -216,4 +318,8 @@ const mach_task = if (builtin.target.isDarwin()) struct {
|
|||||||
}
|
}
|
||||||
return MachTask{ .port = port };
|
return MachTask{ .port = port };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn machTaskForSelf() MachTask {
|
||||||
|
return .{ .port = std.c.mach_task_self() };
|
||||||
|
}
|
||||||
} else struct {};
|
} else struct {};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user