Commit 648afbc839
Changed files (2)
lib
std
lib/std/c/darwin.zig
@@ -155,6 +155,7 @@ pub const vm_map_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_info_t = *c_int;
+pub const vm_region_recurse_info_t = *c_int;
pub const mach_vm_address_t = usize;
pub const vm_offset_t = usize;
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,
object_name: *mach_port_t,
) kern_return_t;
-
-pub const VM_REGION_BASIC_INFO_64 = 9;
-pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);
+pub extern "c" fn mach_vm_region_recurse(
+ target_task: vm_map_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 memory_object_offset_t = u64;
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_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_PAGEOUT: vm_behavior_t = 11;
-pub const vm32_object_id_t = u32;
-pub const vm_object_id_t = u64;
+pub const VM_REGION_BASIC_INFO_64 = 9;
+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 {
// present across protection
@@ -262,6 +309,34 @@ pub const vm_region_submap_info_64 = extern struct {
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_state_t = *natural_t;
pub const mach_port_array_t = *mach_port_t;
@@ -986,9 +1061,13 @@ pub const MAP = struct {
};
pub const MSF = struct {
- pub const ASYNC = 1;
- pub const INVALIDATE = 2;
- pub const SYNC = 4;
+ pub const ASYNC = 0x1;
+ pub const INVALIDATE = 0x2;
+ // invalidate, leave mapped
+ pub const KILLPAGES = 0x4;
+ // deactivate, leave mapped
+ pub const DEACTIVATE = 0x8;
+ pub const SYNC = 0x10;
};
pub const SA = struct {
lib/std/os/darwin.zig
@@ -24,22 +24,119 @@ const mach_task = if (builtin.target.isDarwin()) struct {
return self.port != 0;
}
- pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!std.c.vm_prot_t {
- var base_addr = address;
+ pub const RegionInfo = struct {
+ 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 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 = std.c.VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
+ var count: std.c.mach_msg_type_number_t = switch (tag) {
+ .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(
task.port,
- &base_addr,
+ &info.base_addr,
&base_len,
- std.c.VM_REGION_BASIC_INFO_64,
- @ptrCast(std.c.vm_region_info_t, &info),
+ switch (tag) {
+ .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,
&objname,
))) {
- .SUCCESS => return info.protection,
+ .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 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)});
@@ -48,6 +145,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
}
+ 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 {
return task.setProtectionImpl(address, len, true, prot);
}
@@ -216,4 +318,8 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
return MachTask{ .port = port };
}
+
+ pub fn machTaskForSelf() MachTask {
+ return .{ .port = std.c.mach_task_self() };
+ }
} else struct {};