authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-13 09:32:21+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-13 09:42:24+01:00
loga60292dfb3c09fe08d84f2b737fd25f751afa64d
tree823968aabbf5f82034863b8de1cf71e2fedd8977
parent0bc96354909c0828b7fd36ce0be5705b7b21d63c

macos: add more mach primitives


3 files changed, 311 insertions(+), 0 deletions(-)

lib/std/c/darwin.zig+299
......@@ -6,6 +6,9 @@ const native_arch = builtin.target.cpu.arch;
66const maxInt = std.math.maxInt;
77const iovec_const = std.os.iovec_const;
88
9pub const aarch64 = @import("darwin/aarch64.zig");
10pub const x86_64 = @import("darwin/x86_64.zig");
11
912const arch_bits = switch (native_arch) {
1013 .aarch64 => @import("darwin/aarch64.zig"),
1114 .x86_64 => @import("darwin/x86_64.zig"),
......@@ -124,8 +127,12 @@ pub extern "c" fn mach_host_self() mach_port_t;
124127pub extern "c" fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;
125128
126129pub const vm_map_t = mach_port_t;
130pub const vm_map_read_t = mach_port_t;
131pub const vm_region_flavor_t = c_int;
132pub const vm_region_info_t = *c_int;
127133pub const mach_vm_address_t = usize;
128134pub const vm_offset_t = usize;
135pub const mach_vm_size_t = u64;
129136pub const mach_msg_type_number_t = natural_t;
130137
131138extern "c" var mach_task_self_: mach_port_t;
......@@ -133,13 +140,284 @@ pub fn mach_task_self() callconv(.C) mach_port_t {
133140 return mach_task_self_;
134141}
135142
143pub const task_read_t = mach_port_t;
144
145pub extern "c" fn task_resume(target_task: task_read_t) kern_return_t;
146pub extern "c" fn task_suspend(target_task: task_read_t) kern_return_t;
147
136148pub extern "c" fn task_for_pid(target_tport: mach_port_name_t, pid: pid_t, t: *mach_port_name_t) kern_return_t;
149pub extern "c" fn mach_vm_read(
150 target_task: vm_map_read_t,
151 address: mach_vm_address_t,
152 size: mach_vm_size_t,
153 data: *vm_offset_t,
154 data_cnt: *mach_msg_type_number_t,
155) kern_return_t;
137156pub extern "c" fn mach_vm_write(
138157 target_task: vm_map_t,
139158 address: mach_vm_address_t,
140159 data: vm_offset_t,
141160 data_cnt: mach_msg_type_number_t,
142161) kern_return_t;
162pub extern "c" fn mach_vm_region(
163 target_task: vm_map_t,
164 address: *mach_vm_address_t,
165 size: *mach_vm_size_t,
166 flavor: vm_region_flavor_t,
167 info: vm_region_info_t,
168 info_cnt: *mach_msg_type_number_t,
169 object_name: *mach_port_t,
170) kern_return_t;
171
172pub const VM_REGION_BASIC_INFO_64 = 9;
173pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t);
174
175pub const vm_inherit_t = u32;
176pub const memory_object_offset_t = u64;
177pub const vm_behavior_t = i32;
178
179pub const VM_INHERIT_SHARE: vm_inherit_t = 0;
180pub const VM_INHERIT_COPY: vm_inherit_t = 1;
181pub const VM_INHERIT_NONE: vm_inherit_t = 2;
182pub const VM_INHERIT_DONATE_COPY: vm_inherit_t = 3;
183pub const VM_INHERIT_DEFAULT = VM_INHERIT_COPY;
184
185pub const VM_BEHAVIOR_DEFAULT: vm_behavior_t = 0;
186pub const VM_BEHAVIOR_RANDOM: vm_behavior_t = 1;
187pub const VM_BEHAVIOR_SEQUENTIAL: vm_behavior_t = 2;
188pub const VM_BEHAVIOR_RSEQNTL: vm_behavior_t = 3;
189
190pub const VM_BEHAVIOR_WILLNEED: vm_behavior_t = 4;
191pub const VM_BEHAVIOR_DONTNEED: vm_behavior_t = 5;
192pub const VM_BEHAVIOR_FREE: vm_behavior_t = 6;
193pub const VM_BEHAVIOR_ZERO_WIRED_PAGES: vm_behavior_t = 7;
194pub const VM_BEHAVIOR_REUSABLE: vm_behavior_t = 8;
195pub const VM_BEHAVIOR_REUSE: vm_behavior_t = 9;
196pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10;
197pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11;
198
199pub const vm32_object_id_t = u32;
200pub const vm_object_id_t = u64;
201
202pub const vm_region_submap_info_64 = extern struct {
203 // present across protection
204 protection: std.macho.vm_prot_t,
205 // max avail through vm_prot
206 max_protection: std.macho.vm_prot_t,
207 // behavior of map/obj on fork
208 inheritance: vm_inherit_t,
209 // offset into object/map
210 offset: memory_object_offset_t,
211 // user tag on map entry
212 user_tag: u32,
213 // only valid for objects
214 pages_resident: u32,
215 // only for objects
216 pages_shared_now_private: u32,
217 // only for objects
218 pages_swapped_out: u32,
219 // only for objects
220 pages_dirtied: u32,
221 // obj/map mappers, etc.
222 ref_count: u32,
223 // only for obj
224 shadow_depth: u16,
225 // only for obj
226 external_pager: u8,
227 // see enumeration
228 share_mode: u8,
229 // submap vs obj
230 is_submap: boolean_t,
231 // access behavior hint
232 behavior: vm_behavior_t,
233 // obj/map name, not a handle
234 object_id: vm32_object_id_t,
235 user_wired_count: u16,
236 pages_reusable: u32,
237 object_id_full: vm_object_id_t,
238};
239
240pub const thread_act_t = mach_port_t;
241pub const thread_state_t = *natural_t;
242pub const mach_port_array_t = *mach_port_t;
243
244pub extern "c" fn task_threads(
245 target_task: mach_port_t,
246 init_port_set: *mach_port_array_t,
247 init_port_count: *mach_msg_type_number_t,
248) kern_return_t;
249pub extern "c" fn thread_get_state(
250 thread: thread_act_t,
251 flavor: thread_flavor_t,
252 state: thread_state_t,
253 count: *mach_msg_type_number_t,
254) kern_return_t;
255pub extern "c" fn thread_set_state(
256 thread: thread_act_t,
257 flavor: thread_flavor_t,
258 new_state: thread_state_t,
259 count: mach_msg_type_number_t,
260) kern_return_t;
261pub extern "c" fn thread_info(
262 thread: thread_act_t,
263 flavor: thread_flavor_t,
264 info: thread_info_t,
265 count: *mach_msg_type_number_t,
266) kern_return_t;
267pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t;
268
269pub const THREAD_BASIC_INFO = 3;
270pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);
271
272pub const thread_flavor_t = natural_t;
273pub const thread_info_t = *integer_t;
274pub const time_value_t = time_value;
275pub const task_policy_flavor_t = natural_t;
276pub const task_policy_t = *integer_t;
277pub const policy_t = c_int;
278
279pub const time_value = extern struct {
280 seconds: integer_t,
281 microseconds: integer_t,
282};
283
284pub const thread_basic_info = extern struct {
285 // user run time
286 user_time: time_value_t,
287 // system run time
288 system_time: time_value_t,
289 // scaled cpu usage percentage
290 cpu_usage: integer_t,
291 // scheduling policy in effect
292 policy: policy_t,
293 // run state
294 run_state: integer_t,
295 // various flags
296 flags: integer_t,
297 // suspend count for thread
298 suspend_count: integer_t,
299 // number of seconds that thread has been sleeping
300 sleep_time: integer_t,
301};
302
303/// Cachability
304pub const MATTR_CACHE = 1;
305/// Migrability
306pub const MATTR_MIGRATE = 2;
307/// Replicability
308pub const MATTR_REPLICATE = 4;
309
310/// (Generic) turn attribute off
311pub const MATTR_VAL_OFF = 0;
312/// (Generic) turn attribute on
313pub const MATTR_VAL_ON = 1;
314/// (Generic) return current value
315pub const MATTR_VAL_GET = 2;
316/// Flush from all caches
317pub const MATTR_VAL_CACHE_FLUSH = 6;
318/// Flush from data caches
319pub const MATTR_VAL_DCACHE_FLUSH = 7;
320/// Flush from instruction caches
321pub const MATTR_VAL_ICACHE_FLUSH = 8;
322/// Sync I+D caches
323pub const MATTR_VAL_CACHE_SYNC = 9;
324/// Get page info (stats)
325pub const MATTR_VAL_GET_INFO = 10;
326
327pub const TASK_VM_INFO = 22;
328pub const TASK_VM_INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t);
329
330pub const task_vm_info = extern struct {
331 // virtual memory size (bytes)
332 virtual_size: mach_vm_size_t,
333 // number of memory regions
334 region_count: integer_t,
335 page_size: integer_t,
336 // resident memory size (bytes)
337 resident_size: mach_vm_size_t,
338 // peak resident size (bytes)
339 resident_size_peak: mach_vm_size_t,
340
341 device: mach_vm_size_t,
342 device_peak: mach_vm_size_t,
343 internal: mach_vm_size_t,
344 internal_peak: mach_vm_size_t,
345 external: mach_vm_size_t,
346 external_peak: mach_vm_size_t,
347 reusable: mach_vm_size_t,
348 reusable_peak: mach_vm_size_t,
349 purgeable_volatile_pmap: mach_vm_size_t,
350 purgeable_volatile_resident: mach_vm_size_t,
351 purgeable_volatile_virtual: mach_vm_size_t,
352 compressed: mach_vm_size_t,
353 compressed_peak: mach_vm_size_t,
354 compressed_lifetime: mach_vm_size_t,
355
356 // added for rev1
357 phys_footprint: mach_vm_size_t,
358
359 // added for rev2
360 min_address: mach_vm_address_t,
361 max_address: mach_vm_address_t,
362
363 // added for rev3
364 ledger_phys_footprint_peak: i64,
365 ledger_purgeable_nonvolatile: i64,
366 ledger_purgeable_novolatile_compressed: i64,
367 ledger_purgeable_volatile: i64,
368 ledger_purgeable_volatile_compressed: i64,
369 ledger_tag_network_nonvolatile: i64,
370 ledger_tag_network_nonvolatile_compressed: i64,
371 ledger_tag_network_volatile: i64,
372 ledger_tag_network_volatile_compressed: i64,
373 ledger_tag_media_footprint: i64,
374 ledger_tag_media_footprint_compressed: i64,
375 ledger_tag_media_nofootprint: i64,
376 ledger_tag_media_nofootprint_compressed: i64,
377 ledger_tag_graphics_footprint: i64,
378 ledger_tag_graphics_footprint_compressed: i64,
379 ledger_tag_graphics_nofootprint: i64,
380 ledger_tag_graphics_nofootprint_compressed: i64,
381 ledger_tag_neural_footprint: i64,
382 ledger_tag_neural_footprint_compressed: i64,
383 ledger_tag_neural_nofootprint: i64,
384 ledger_tag_neural_nofootprint_compressed: i64,
385
386 // added for rev4
387 limit_bytes_remaining: u64,
388
389 // added for rev5
390 decompressions: integer_t,
391};
392pub const task_vm_info_data_t = task_vm_info;
393
394pub const boolean_t = c_int;
395
396pub extern "c" fn mach_vm_protect(
397 target_task: vm_map_t,
398 address: mach_vm_address_t,
399 size: mach_vm_size_t,
400 set_maximum: boolean_t,
401 new_protection: std.macho.vm_prot_t,
402) kern_return_t;
403
404pub extern "c" fn mach_port_deallocate(target_tport: mach_port_name_t, task: mach_port_name_t) kern_return_t;
405
406pub extern "c" fn task_info(
407 target_task: task_name_t,
408 flavor: task_flavor_t,
409 task_info_out: task_info_t,
410 task_info_outCnt: *mach_msg_type_number_t,
411) kern_return_t;
412pub extern "c" fn _host_page_size(task: mach_port_t, size: *vm_size_t) kern_return_t;
413pub extern "c" fn vm_deallocate(target_task: vm_map_t, address: vm_address_t, size: vm_size_t) kern_return_t;
414pub extern "c" fn vm_machine_attribute(
415 target_task: vm_map_t,
416 address: vm_address_t,
417 size: vm_size_t,
418 attribute: vm_machine_attribute_t,
419 value: *vm_machine_attribute_val_t,
420) kern_return_t;
143421
144422pub const sf_hdtr = extern struct {
145423 headers: [*]const iovec_const,
......@@ -622,6 +900,15 @@ pub const mach_timespec_t = extern struct {
622900};
623901pub const kern_return_t = c_int;
624902pub const host_t = mach_port_t;
903pub const integer_t = c_int;
904pub const task_flavor_t = natural_t;
905pub const task_info_t = *integer_t;
906pub const task_name_t = mach_port_name_t;
907pub const vm_address_t = vm_offset_t;
908pub const vm_size_t = mach_vm_size_t;
909pub const vm_machine_attribute_t = usize;
910pub const vm_machine_attribute_val_t = isize;
911
625912pub const CALENDAR_CLOCK = 1;
626913
627914pub const PATH_MAX = 1024;
......@@ -2051,3 +2338,15 @@ pub const _POSIX_SPAWN_DISABLE_ASLR: c_int = 0x0100;
20512338pub const POSIX_SPAWN_SETSID: c_int = 0x0400;
20522339pub const _POSIX_SPAWN_RESLIDE: c_int = 0x0800;
20532340pub const POSIX_SPAWN_CLOEXEC_DEFAULT: c_int = 0x4000;
2341
2342pub const PT_TRACE_ME = 0;
2343pub const PT_CONTINUE = 7;
2344pub const PT_KILL = 8;
2345pub const PT_STEP = 9;
2346pub const PT_DETACH = 11;
2347pub const PT_ATTACHEXC = 14;
2348pub const PT_DENY_ATTACH = 31;
2349
2350pub const caddr_t = ?[*]u8;
2351
2352pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;
lib/std/c/darwin/x86_64.zig+5
......@@ -1,3 +1,5 @@
1const c = @import("../darwin.zig");
2
13pub const exception_state = extern struct {
24 trapno: u16,
35 cpu: u16,
......@@ -28,3 +30,6 @@ pub const thread_state = extern struct {
2830 fs: u64,
2931 gs: u64,
3032};
33
34pub const THREAD_STATE = 4;
35pub const THREAD_STATE_COUNT: c.mach_msg_type_number_t = @sizeOf(thread_state) / @sizeOf(c_int);
lib/std/macho.zig+7
......@@ -1468,6 +1468,13 @@ pub const VM_PROT_WRITE: vm_prot_t = 0x2;
14681468/// VM execute permission
14691469pub const VM_PROT_EXECUTE: vm_prot_t = 0x4;
14701470
1471/// When a caller finds that they cannot obtain write permission on a
1472/// mapped entry, the following flag can be used. The entry will be
1473/// made "needs copy" effectively copying the object (using COW),
1474/// and write permission will be added to the maximum protections for
1475/// the associated entry.
1476pub const VM_PROT_COPY: vm_prot_t = 0x10;
1477
14711478// The following are used to encode rebasing information
14721479pub const REBASE_TYPE_POINTER: u8 = 1;
14731480pub const REBASE_TYPE_TEXT_ABSOLUTE32: u8 = 2;