| author | |
| committer | |
| log | 8c4a2dc1dfe05a67eb9811b8c8291c5541816a99 |
| tree | 9437f16152597b75b6a8b7ec77abbba1252c937d |
| parent | e8c4e79499fbb2a83a0f4fe2cac0d80e5d12a07e |
3 files changed, 743 insertions(+), 713 deletions(-)
lib/std/c.zig+35| ... | @@ -9541,10 +9541,24 @@ pub const CPUFAMILY = darwin.CPUFAMILY; | ... | @@ -9541,10 +9541,24 @@ pub const CPUFAMILY = darwin.CPUFAMILY; |
| 9541 | pub const DB_RECORDTYPE = darwin.DB_RECORDTYPE; | 9541 | pub const DB_RECORDTYPE = darwin.DB_RECORDTYPE; |
| 9542 | pub const EXC = darwin.EXC; | 9542 | pub const EXC = darwin.EXC; |
| 9543 | pub const EXCEPTION = darwin.EXCEPTION; | 9543 | pub const EXCEPTION = darwin.EXCEPTION; |
| 9544 | pub const MACH_MSG_TYPE = darwin.MACH_MSG_TYPE; | ||
| 9545 | pub const MACH_PORT_RIGHT = darwin.MACH_PORT_RIGHT; | ||
| 9546 | pub const MACH_TASK_BASIC_INFO = darwin.MACH_TASK_BASIC_INFO; | ||
| 9547 | pub const MACH_TASK_BASIC_INFO_COUNT = darwin.MACH_TASK_BASIC_INFO_COUNT; | ||
| 9548 | pub const MATTR = darwin.MATTR; | ||
| 9544 | pub const NSVersionOfRunTimeLibrary = darwin.NSVersionOfRunTimeLibrary; | 9549 | pub const NSVersionOfRunTimeLibrary = darwin.NSVersionOfRunTimeLibrary; |
| 9545 | pub const OPEN_MAX = darwin.OPEN_MAX; | 9550 | pub const OPEN_MAX = darwin.OPEN_MAX; |
| 9551 | pub const POSIX_SPAWN = darwin.POSIX_SPAWN; | ||
| 9552 | pub const TASK_NULL = darwin.TASK_NULL; | ||
| 9553 | pub const TASK_VM_INFO = darwin.TASK_VM_INFO; | ||
| 9554 | pub const TASK_VM_INFO_COUNT = darwin.TASK_VM_INFO_COUNT; | ||
| 9555 | pub const THREAD_BASIC_INFO = darwin.THREAD_BASIC_INFO; | ||
| 9556 | pub const THREAD_BASIC_INFO_COUNT = darwin.THREAD_BASIC_INFO_COUNT; | ||
| 9557 | pub const THREAD_IDENTIFIER_INFO_COUNT = darwin.THREAD_IDENTIFIER_INFO_COUNT; | ||
| 9558 | pub const THREAD_NULL = darwin.THREAD_NULL; | ||
| 9546 | pub const THREAD_STATE_NONE = darwin.THREAD_STATE_NONE; | 9559 | pub const THREAD_STATE_NONE = darwin.THREAD_STATE_NONE; |
| 9547 | pub const UL = darwin.UL; | 9560 | pub const UL = darwin.UL; |
| 9561 | pub const VM = darwin.VM; | ||
| 9548 | pub const _NSGetExecutablePath = darwin._NSGetExecutablePath; | 9562 | pub const _NSGetExecutablePath = darwin._NSGetExecutablePath; |
| 9549 | pub const __getdirentries64 = darwin.__getdirentries64; | 9563 | pub const __getdirentries64 = darwin.__getdirentries64; |
| 9550 | pub const __ulock_wait = darwin.__ulock_wait; | 9564 | pub const __ulock_wait = darwin.__ulock_wait; |
| ... | @@ -9562,16 +9576,21 @@ pub const dispatch_semaphore_signal = darwin.dispatch_semaphore_signal; | ... | @@ -9562,16 +9576,21 @@ pub const dispatch_semaphore_signal = darwin.dispatch_semaphore_signal; |
| 9562 | pub const dispatch_semaphore_wait = darwin.dispatch_semaphore_wait; | 9576 | pub const dispatch_semaphore_wait = darwin.dispatch_semaphore_wait; |
| 9563 | pub const dispatch_time = darwin.dispatch_time; | 9577 | pub const dispatch_time = darwin.dispatch_time; |
| 9564 | pub const fcopyfile = darwin.fcopyfile; | 9578 | pub const fcopyfile = darwin.fcopyfile; |
| 9579 | pub const kern_return_t = darwin.kern_return_t; | ||
| 9565 | pub const kevent64 = darwin.kevent64; | 9580 | pub const kevent64 = darwin.kevent64; |
| 9566 | pub const mach_absolute_time = darwin.mach_absolute_time; | 9581 | pub const mach_absolute_time = darwin.mach_absolute_time; |
| 9567 | pub const mach_continuous_time = darwin.mach_continuous_time; | 9582 | pub const mach_continuous_time = darwin.mach_continuous_time; |
| 9568 | pub const mach_hdr = darwin.mach_hdr; | 9583 | pub const mach_hdr = darwin.mach_hdr; |
| 9569 | pub const mach_host_self = darwin.mach_host_self; | 9584 | pub const mach_host_self = darwin.mach_host_self; |
| 9570 | pub const mach_msg = darwin.mach_msg; | 9585 | pub const mach_msg = darwin.mach_msg; |
| 9586 | pub const mach_msg_type_number_t = darwin.mach_msg_type_number_t; | ||
| 9571 | pub const mach_port_allocate = darwin.mach_port_allocate; | 9587 | pub const mach_port_allocate = darwin.mach_port_allocate; |
| 9588 | pub const mach_port_array_t = darwin.mach_port_array_t; | ||
| 9572 | pub const mach_port_deallocate = darwin.mach_port_deallocate; | 9589 | pub const mach_port_deallocate = darwin.mach_port_deallocate; |
| 9573 | pub const mach_port_insert_right = darwin.mach_port_insert_right; | 9590 | pub const mach_port_insert_right = darwin.mach_port_insert_right; |
| 9591 | pub const mach_port_name_t = darwin.mach_port_name_t; | ||
| 9574 | pub const mach_port_t = darwin.mach_port_t; | 9592 | pub const mach_port_t = darwin.mach_port_t; |
| 9593 | pub const mach_task_basic_info = darwin.mach_task_basic_info; | ||
| 9575 | pub const mach_task_self = darwin.mach_task_self; | 9594 | pub const mach_task_self = darwin.mach_task_self; |
| 9576 | pub const mach_timebase_info = darwin.mach_timebase_info; | 9595 | pub const mach_timebase_info = darwin.mach_timebase_info; |
| 9577 | pub const mach_vm_protect = darwin.mach_vm_protect; | 9596 | pub const mach_vm_protect = darwin.mach_vm_protect; |
| ... | @@ -9602,10 +9621,12 @@ pub const posix_spawn_file_actions_addinherit_np = darwin.posix_spawn_file_actio | ... | @@ -9602,10 +9621,12 @@ pub const posix_spawn_file_actions_addinherit_np = darwin.posix_spawn_file_actio |
| 9602 | pub const posix_spawn_file_actions_addopen = darwin.posix_spawn_file_actions_addopen; | 9621 | pub const posix_spawn_file_actions_addopen = darwin.posix_spawn_file_actions_addopen; |
| 9603 | pub const posix_spawn_file_actions_destroy = darwin.posix_spawn_file_actions_destroy; | 9622 | pub const posix_spawn_file_actions_destroy = darwin.posix_spawn_file_actions_destroy; |
| 9604 | pub const posix_spawn_file_actions_init = darwin.posix_spawn_file_actions_init; | 9623 | pub const posix_spawn_file_actions_init = darwin.posix_spawn_file_actions_init; |
| 9624 | pub const posix_spawn_file_actions_t = darwin.posix_spawn_file_actions_t; | ||
| 9605 | pub const posix_spawnattr_destroy = darwin.posix_spawnattr_destroy; | 9625 | pub const posix_spawnattr_destroy = darwin.posix_spawnattr_destroy; |
| 9606 | pub const posix_spawnattr_getflags = darwin.posix_spawnattr_getflags; | 9626 | pub const posix_spawnattr_getflags = darwin.posix_spawnattr_getflags; |
| 9607 | pub const posix_spawnattr_init = darwin.posix_spawnattr_init; | 9627 | pub const posix_spawnattr_init = darwin.posix_spawnattr_init; |
| 9608 | pub const posix_spawnattr_setflags = darwin.posix_spawnattr_setflags; | 9628 | pub const posix_spawnattr_setflags = darwin.posix_spawnattr_setflags; |
| 9629 | pub const posix_spawnattr_t = darwin.posix_spawnattr_t; | ||
| 9609 | pub const posix_spawnp = darwin.posix_spawnp; | 9630 | pub const posix_spawnp = darwin.posix_spawnp; |
| 9610 | pub const pthread_attr_get_qos_class_np = darwin.pthread_attr_get_qos_class_np; | 9631 | pub const pthread_attr_get_qos_class_np = darwin.pthread_attr_get_qos_class_np; |
| 9611 | pub const pthread_attr_set_qos_class_np = darwin.pthread_attr_set_qos_class_np; | 9632 | pub const pthread_attr_set_qos_class_np = darwin.pthread_attr_set_qos_class_np; |
| ... | @@ -9616,17 +9637,31 @@ pub const sigaddset = darwin.sigaddset; | ... | @@ -9616,17 +9637,31 @@ pub const sigaddset = darwin.sigaddset; |
| 9616 | pub const task_for_pid = darwin.task_for_pid; | 9637 | pub const task_for_pid = darwin.task_for_pid; |
| 9617 | pub const task_get_exception_ports = darwin.task_get_exception_ports; | 9638 | pub const task_get_exception_ports = darwin.task_get_exception_ports; |
| 9618 | pub const task_info = darwin.task_info; | 9639 | pub const task_info = darwin.task_info; |
| 9640 | pub const task_info_t = darwin.task_info_t; | ||
| 9619 | pub const task_resume = darwin.task_resume; | 9641 | pub const task_resume = darwin.task_resume; |
| 9620 | pub const task_set_exception_ports = darwin.task_set_exception_ports; | 9642 | pub const task_set_exception_ports = darwin.task_set_exception_ports; |
| 9621 | pub const task_suspend = darwin.task_suspend; | 9643 | pub const task_suspend = darwin.task_suspend; |
| 9622 | pub const task_threads = darwin.task_threads; | 9644 | pub const task_threads = darwin.task_threads; |
| 9645 | pub const task_vm_info_data_t = darwin.task_vm_info_data_t; | ||
| 9646 | pub const thread_basic_info = darwin.thread_basic_info; | ||
| 9623 | pub const thread_get_state = darwin.thread_get_state; | 9647 | pub const thread_get_state = darwin.thread_get_state; |
| 9648 | pub const thread_identifier_info = darwin.thread_identifier_info; | ||
| 9624 | pub const thread_info = darwin.thread_info; | 9649 | pub const thread_info = darwin.thread_info; |
| 9650 | pub const thread_info_t = darwin.thread_info_t; | ||
| 9625 | pub const thread_resume = darwin.thread_resume; | 9651 | pub const thread_resume = darwin.thread_resume; |
| 9626 | pub const thread_set_state = darwin.thread_set_state; | 9652 | pub const thread_set_state = darwin.thread_set_state; |
| 9627 | pub const vm_deallocate = darwin.vm_deallocate; | 9653 | pub const vm_deallocate = darwin.vm_deallocate; |
| 9628 | pub const vm_machine_attribute = darwin.vm_machine_attribute; | 9654 | pub const vm_machine_attribute = darwin.vm_machine_attribute; |
| 9655 | pub const vm_machine_attribute_val_t = darwin.vm_machine_attribute_val_t; | ||
| 9656 | pub const vm_offset_t = darwin.vm_offset_t; | ||
| 9629 | pub const vm_prot_t = darwin.vm_prot_t; | 9657 | pub const vm_prot_t = darwin.vm_prot_t; |
| 9658 | pub const vm_region_basic_info_64 = darwin.vm_region_basic_info_64; | ||
| 9659 | pub const vm_region_extended_info = darwin.vm_region_extended_info; | ||
| 9660 | pub const vm_region_info_t = darwin.vm_region_info_t; | ||
| 9661 | pub const vm_region_recurse_info_t = darwin.vm_region_recurse_info_t; | ||
| 9662 | pub const vm_region_submap_info_64 = darwin.vm_region_submap_info_64; | ||
| 9663 | pub const vm_region_submap_short_info_64 = darwin.vm_region_submap_short_info_64; | ||
| 9664 | pub const vm_region_top_info = darwin.vm_region_top_info; | ||
| 9630 | 9665 | ||
| 9631 | pub const _ksiginfo = netbsd._ksiginfo; | 9666 | pub const _ksiginfo = netbsd._ksiginfo; |
| 9632 | pub const _lwp_self = netbsd._lwp_self; | 9667 | pub const _lwp_self = netbsd._lwp_self; |
lib/std/c/darwin.zig+63-711| ... | @@ -355,31 +355,22 @@ pub const MACH_PORT_RIGHT = enum(mach_port_right_t) { | ... | @@ -355,31 +355,22 @@ pub const MACH_PORT_RIGHT = enum(mach_port_right_t) { |
| 355 | pub const MACH_MSG_TYPE = enum(mach_msg_type_name_t) { | 355 | pub const MACH_MSG_TYPE = enum(mach_msg_type_name_t) { |
| 356 | /// Must hold receive right | 356 | /// Must hold receive right |
| 357 | MOVE_RECEIVE = 16, | 357 | MOVE_RECEIVE = 16, |
| 358 | |||
| 359 | /// Must hold send right(s) | 358 | /// Must hold send right(s) |
| 360 | MOVE_SEND = 17, | 359 | MOVE_SEND = 17, |
| 361 | |||
| 362 | /// Must hold sendonce right | 360 | /// Must hold sendonce right |
| 363 | MOVE_SEND_ONCE = 18, | 361 | MOVE_SEND_ONCE = 18, |
| 364 | |||
| 365 | /// Must hold send right(s) | 362 | /// Must hold send right(s) |
| 366 | COPY_SEND = 19, | 363 | COPY_SEND = 19, |
| 367 | |||
| 368 | /// Must hold receive right | 364 | /// Must hold receive right |
| 369 | MAKE_SEND = 20, | 365 | MAKE_SEND = 20, |
| 370 | |||
| 371 | /// Must hold receive right | 366 | /// Must hold receive right |
| 372 | MAKE_SEND_ONCE = 21, | 367 | MAKE_SEND_ONCE = 21, |
| 373 | |||
| 374 | /// NOT VALID | 368 | /// NOT VALID |
| 375 | COPY_RECEIVE = 22, | 369 | COPY_RECEIVE = 22, |
| 376 | |||
| 377 | /// Must hold receive right | 370 | /// Must hold receive right |
| 378 | DISPOSE_RECEIVE = 24, | 371 | DISPOSE_RECEIVE = 24, |
| 379 | |||
| 380 | /// Must hold send right(s) | 372 | /// Must hold send right(s) |
| 381 | DISPOSE_SEND = 25, | 373 | DISPOSE_SEND = 25, |
| 382 | |||
| 383 | /// Must hold sendonce right | 374 | /// Must hold sendonce right |
| 384 | DISPOSE_SEND_ONCE = 26, | 375 | DISPOSE_SEND_ONCE = 26, |
| 385 | }; | 376 | }; |
| ... | @@ -469,38 +460,45 @@ pub const vm_behavior_t = i32; | ... | @@ -469,38 +460,45 @@ pub const vm_behavior_t = i32; |
| 469 | pub const vm32_object_id_t = u32; | 460 | pub const vm32_object_id_t = u32; |
| 470 | pub const vm_object_id_t = u64; | 461 | pub const vm_object_id_t = u64; |
| 471 | 462 | ||
| 472 | pub const VM_INHERIT_SHARE: vm_inherit_t = 0; | 463 | pub const VM = struct { |
| 473 | pub const VM_INHERIT_COPY: vm_inherit_t = 1; | 464 | pub const INHERIT = struct { |
| 474 | pub const VM_INHERIT_NONE: vm_inherit_t = 2; | 465 | pub const SHARE: vm_inherit_t = 0; |
| 475 | pub const VM_INHERIT_DONATE_COPY: vm_inherit_t = 3; | 466 | pub const COPY: vm_inherit_t = 1; |
| 476 | pub const VM_INHERIT_DEFAULT = VM_INHERIT_COPY; | 467 | pub const NONE: vm_inherit_t = 2; |
| 477 | 468 | pub const DONATE_COPY: vm_inherit_t = 3; | |
| 478 | pub const VM_BEHAVIOR_DEFAULT: vm_behavior_t = 0; | 469 | pub const DEFAULT = COPY; |
| 479 | pub const VM_BEHAVIOR_RANDOM: vm_behavior_t = 1; | 470 | }; |
| 480 | pub const VM_BEHAVIOR_SEQUENTIAL: vm_behavior_t = 2; | 471 | |
| 481 | pub const VM_BEHAVIOR_RSEQNTL: vm_behavior_t = 3; | 472 | pub const BEHAVIOR = struct { |
| 482 | 473 | pub const DEFAULT: vm_behavior_t = 0; | |
| 483 | pub const VM_BEHAVIOR_WILLNEED: vm_behavior_t = 4; | 474 | pub const RANDOM: vm_behavior_t = 1; |
| 484 | pub const VM_BEHAVIOR_DONTNEED: vm_behavior_t = 5; | 475 | pub const SEQUENTIAL: vm_behavior_t = 2; |
| 485 | pub const VM_BEHAVIOR_FREE: vm_behavior_t = 6; | 476 | pub const RSEQNTL: vm_behavior_t = 3; |
| 486 | pub const VM_BEHAVIOR_ZERO_WIRED_PAGES: vm_behavior_t = 7; | 477 | pub const WILLNEED: vm_behavior_t = 4; |
| 487 | pub const VM_BEHAVIOR_REUSABLE: vm_behavior_t = 8; | 478 | pub const DONTNEED: vm_behavior_t = 5; |
| 488 | pub const VM_BEHAVIOR_REUSE: vm_behavior_t = 9; | 479 | pub const FREE: vm_behavior_t = 6; |
| 489 | pub const VM_BEHAVIOR_CAN_REUSE: vm_behavior_t = 10; | 480 | pub const ZERO_WIRED_PAGES: vm_behavior_t = 7; |
| 490 | pub const VM_BEHAVIOR_PAGEOUT: vm_behavior_t = 11; | 481 | pub const REUSABLE: vm_behavior_t = 8; |
| 491 | 482 | pub const REUSE: vm_behavior_t = 9; | |
| 492 | pub const VM_REGION_BASIC_INFO_64 = 9; | 483 | pub const CAN_REUSE: vm_behavior_t = 10; |
| 493 | pub const VM_REGION_EXTENDED_INFO = 13; | 484 | pub const PAGEOUT: vm_behavior_t = 11; |
| 494 | pub const VM_REGION_TOP_INFO = 12; | 485 | }; |
| 495 | pub const VM_REGION_SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t); | 486 | |
| 496 | pub const VM_REGION_SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t); | 487 | pub const REGION = struct { |
| 497 | pub const VM_REGION_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int); | 488 | pub const BASIC_INFO_64 = 9; |
| 498 | pub const VM_REGION_EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t); | 489 | pub const EXTENDED_INFO = 13; |
| 499 | pub const VM_REGION_TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t); | 490 | pub const TOP_INFO = 12; |
| 500 | 491 | pub const SUBMAP_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_info_64) / @sizeOf(natural_t); | |
| 501 | pub fn VM_MAKE_TAG(tag: u8) u32 { | 492 | pub const SUBMAP_SHORT_INFO_COUNT_64: mach_msg_type_number_t = @sizeOf(vm_region_submap_short_info_64) / @sizeOf(natural_t); |
| 502 | return @as(u32, tag) << 24; | 493 | pub const BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_basic_info_64) / @sizeOf(c_int); |
| 503 | } | 494 | pub const EXTENDED_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_extended_info) / @sizeOf(natural_t); |
| 495 | pub const TOP_INFO_COUNT: mach_msg_type_number_t = @sizeOf(vm_region_top_info) / @sizeOf(natural_t); | ||
| 496 | }; | ||
| 497 | |||
| 498 | pub fn MAKE_TAG(tag: u8) u32 { | ||
| 499 | return @as(u32, tag) << 24; | ||
| 500 | } | ||
| 501 | }; | ||
| 504 | 502 | ||
| 505 | pub const vm_region_basic_info_64 = extern struct { | 503 | pub const vm_region_basic_info_64 = extern struct { |
| 506 | protection: vm_prot_t, | 504 | protection: vm_prot_t, |
| ... | @@ -678,29 +676,30 @@ pub const thread_identifier_info = extern struct { | ... | @@ -678,29 +676,30 @@ pub const thread_identifier_info = extern struct { |
| 678 | dispatch_qaddr: u64, | 676 | dispatch_qaddr: u64, |
| 679 | }; | 677 | }; |
| 680 | 678 | ||
| 681 | /// Cachability | 679 | pub const MATTR = struct { |
| 682 | pub const MATTR_CACHE = 1; | 680 | /// Cachability |
| 683 | /// Migrability | 681 | pub const CACHE = 1; |
| 684 | pub const MATTR_MIGRATE = 2; | 682 | /// Migrability |
| 685 | /// Replicability | 683 | pub const MIGRATE = 2; |
| 686 | pub const MATTR_REPLICATE = 4; | 684 | /// Replicability |
| 687 | 685 | pub const REPLICATE = 4; | |
| 688 | /// (Generic) turn attribute off | 686 | /// (Generic) turn attribute off |
| 689 | pub const MATTR_VAL_OFF = 0; | 687 | pub const VAL_OFF = 0; |
| 690 | /// (Generic) turn attribute on | 688 | /// (Generic) turn attribute on |
| 691 | pub const MATTR_VAL_ON = 1; | 689 | pub const VAL_ON = 1; |
| 692 | /// (Generic) return current value | 690 | /// (Generic) return current value |
| 693 | pub const MATTR_VAL_GET = 2; | 691 | pub const VAL_GET = 2; |
| 694 | /// Flush from all caches | 692 | /// Flush from all caches |
| 695 | pub const MATTR_VAL_CACHE_FLUSH = 6; | 693 | pub const VAL_CACHE_FLUSH = 6; |
| 696 | /// Flush from data caches | 694 | /// Flush from data caches |
| 697 | pub const MATTR_VAL_DCACHE_FLUSH = 7; | 695 | pub const VAL_DCACHE_FLUSH = 7; |
| 698 | /// Flush from instruction caches | 696 | /// Flush from instruction caches |
| 699 | pub const MATTR_VAL_ICACHE_FLUSH = 8; | 697 | pub const VAL_ICACHE_FLUSH = 8; |
| 700 | /// Sync I+D caches | 698 | /// Sync I+D caches |
| 701 | pub const MATTR_VAL_CACHE_SYNC = 9; | 699 | pub const VAL_CACHE_SYNC = 9; |
| 702 | /// Get page info (stats) | 700 | /// Get page info (stats) |
| 703 | pub const MATTR_VAL_GET_INFO = 10; | 701 | pub const VAL_GET_INFO = 10; |
| 702 | }; | ||
| 704 | 703 | ||
| 705 | pub const TASK_VM_INFO = 22; | 704 | pub const TASK_VM_INFO = 22; |
| 706 | pub const TASK_VM_INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t); | 705 | pub const TASK_VM_INFO_COUNT: mach_msg_type_number_t = @sizeOf(task_vm_info_data_t) / @sizeOf(natural_t); |
| ... | @@ -804,19 +803,14 @@ pub extern "c" fn task_info( | ... | @@ -804,19 +803,14 @@ pub extern "c" fn task_info( |
| 804 | pub const mach_task_basic_info = extern struct { | 803 | pub const mach_task_basic_info = extern struct { |
| 805 | /// Virtual memory size (bytes) | 804 | /// Virtual memory size (bytes) |
| 806 | virtual_size: mach_vm_size_t, | 805 | virtual_size: mach_vm_size_t, |
| 807 | |||
| 808 | /// Resident memory size (bytes) | 806 | /// Resident memory size (bytes) |
| 809 | resident_size: mach_vm_size_t, | 807 | resident_size: mach_vm_size_t, |
| 810 | |||
| 811 | /// Total user run time for terminated threads | 808 | /// Total user run time for terminated threads |
| 812 | user_time: time_value_t, | 809 | user_time: time_value_t, |
| 813 | |||
| 814 | /// Total system run time for terminated threads | 810 | /// Total system run time for terminated threads |
| 815 | system_time: time_value_t, | 811 | system_time: time_value_t, |
| 816 | |||
| 817 | /// Default policy for new threads | 812 | /// Default policy for new threads |
| 818 | policy: policy_t, | 813 | policy: policy_t, |
| 819 | |||
| 820 | /// Suspend count for task | 814 | /// Suspend count for task |
| 821 | suspend_count: mach_vm_size_t, | 815 | suspend_count: mach_vm_size_t, |
| 822 | }; | 816 | }; |
| ... | @@ -925,486 +919,6 @@ pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool; | ... | @@ -925,486 +919,6 @@ pub extern "c" fn os_unfair_lock_trylock(o: os_unfair_lock_t) bool; |
| 925 | pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void; | 919 | pub extern "c" fn os_unfair_lock_assert_owner(o: os_unfair_lock_t) void; |
| 926 | pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void; | 920 | pub extern "c" fn os_unfair_lock_assert_not_owner(o: os_unfair_lock_t) void; |
| 927 | 921 | ||
| 928 | pub fn getKernError(err: kern_return_t) KernE { | ||
| 929 | return @as(KernE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err)))))); | ||
| 930 | } | ||
| 931 | |||
| 932 | pub fn unexpectedKernError(err: KernE) std.posix.UnexpectedError { | ||
| 933 | if (std.posix.unexpected_error_tracing) { | ||
| 934 | std.debug.print("unexpected error: {d}\n", .{@intFromEnum(err)}); | ||
| 935 | std.debug.dumpCurrentStackTrace(null); | ||
| 936 | } | ||
| 937 | return error.Unexpected; | ||
| 938 | } | ||
| 939 | |||
| 940 | pub const MachError = error{ | ||
| 941 | /// Not enough permissions held to perform the requested kernel | ||
| 942 | /// call. | ||
| 943 | PermissionDenied, | ||
| 944 | } || std.posix.UnexpectedError; | ||
| 945 | |||
| 946 | pub const MachTask = extern struct { | ||
| 947 | port: mach_port_name_t, | ||
| 948 | |||
| 949 | pub fn isValid(self: MachTask) bool { | ||
| 950 | return self.port != TASK_NULL; | ||
| 951 | } | ||
| 952 | |||
| 953 | pub fn pidForTask(self: MachTask) MachError!std.c.pid_t { | ||
| 954 | var pid: std.c.pid_t = undefined; | ||
| 955 | switch (getKernError(pid_for_task(self.port, &pid))) { | ||
| 956 | .SUCCESS => return pid, | ||
| 957 | .FAILURE => return error.PermissionDenied, | ||
| 958 | else => |err| return unexpectedKernError(err), | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 962 | pub fn allocatePort(self: MachTask, right: MACH_PORT_RIGHT) MachError!MachTask { | ||
| 963 | var out_port: mach_port_name_t = undefined; | ||
| 964 | switch (getKernError(mach_port_allocate( | ||
| 965 | self.port, | ||
| 966 | @intFromEnum(right), | ||
| 967 | &out_port, | ||
| 968 | ))) { | ||
| 969 | .SUCCESS => return .{ .port = out_port }, | ||
| 970 | .FAILURE => return error.PermissionDenied, | ||
| 971 | else => |err| return unexpectedKernError(err), | ||
| 972 | } | ||
| 973 | } | ||
| 974 | |||
| 975 | pub fn deallocatePort(self: MachTask, port: MachTask) void { | ||
| 976 | _ = getKernError(mach_port_deallocate(self.port, port.port)); | ||
| 977 | } | ||
| 978 | |||
| 979 | pub fn insertRight(self: MachTask, port: MachTask, msg: MACH_MSG_TYPE) !void { | ||
| 980 | switch (getKernError(mach_port_insert_right( | ||
| 981 | self.port, | ||
| 982 | port.port, | ||
| 983 | port.port, | ||
| 984 | @intFromEnum(msg), | ||
| 985 | ))) { | ||
| 986 | .SUCCESS => return, | ||
| 987 | .FAILURE => return error.PermissionDenied, | ||
| 988 | else => |err| return unexpectedKernError(err), | ||
| 989 | } | ||
| 990 | } | ||
| 991 | |||
| 992 | pub const PortInfo = struct { | ||
| 993 | mask: exception_mask_t, | ||
| 994 | masks: [EXC.TYPES_COUNT]exception_mask_t, | ||
| 995 | ports: [EXC.TYPES_COUNT]mach_port_t, | ||
| 996 | behaviors: [EXC.TYPES_COUNT]exception_behavior_t, | ||
| 997 | flavors: [EXC.TYPES_COUNT]thread_state_flavor_t, | ||
| 998 | count: mach_msg_type_number_t, | ||
| 999 | }; | ||
| 1000 | |||
| 1001 | pub fn getExceptionPorts(self: MachTask, mask: exception_mask_t) !PortInfo { | ||
| 1002 | var info = PortInfo{ | ||
| 1003 | .mask = mask, | ||
| 1004 | .masks = undefined, | ||
| 1005 | .ports = undefined, | ||
| 1006 | .behaviors = undefined, | ||
| 1007 | .flavors = undefined, | ||
| 1008 | .count = 0, | ||
| 1009 | }; | ||
| 1010 | info.count = info.ports.len / @sizeOf(mach_port_t); | ||
| 1011 | |||
| 1012 | switch (getKernError(task_get_exception_ports( | ||
| 1013 | self.port, | ||
| 1014 | info.mask, | ||
| 1015 | &info.masks, | ||
| 1016 | &info.count, | ||
| 1017 | &info.ports, | ||
| 1018 | &info.behaviors, | ||
| 1019 | &info.flavors, | ||
| 1020 | ))) { | ||
| 1021 | .SUCCESS => return info, | ||
| 1022 | .FAILURE => return error.PermissionDenied, | ||
| 1023 | else => |err| return unexpectedKernError(err), | ||
| 1024 | } | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | pub fn setExceptionPorts( | ||
| 1028 | self: MachTask, | ||
| 1029 | mask: exception_mask_t, | ||
| 1030 | new_port: MachTask, | ||
| 1031 | behavior: exception_behavior_t, | ||
| 1032 | new_flavor: thread_state_flavor_t, | ||
| 1033 | ) !void { | ||
| 1034 | switch (getKernError(task_set_exception_ports( | ||
| 1035 | self.port, | ||
| 1036 | mask, | ||
| 1037 | new_port.port, | ||
| 1038 | behavior, | ||
| 1039 | new_flavor, | ||
| 1040 | ))) { | ||
| 1041 | .SUCCESS => return, | ||
| 1042 | .FAILURE => return error.PermissionDenied, | ||
| 1043 | else => |err| return unexpectedKernError(err), | ||
| 1044 | } | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | pub const RegionInfo = struct { | ||
| 1048 | pub const Tag = enum { | ||
| 1049 | basic, | ||
| 1050 | extended, | ||
| 1051 | top, | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | base_addr: u64, | ||
| 1055 | tag: Tag, | ||
| 1056 | info: union { | ||
| 1057 | basic: vm_region_basic_info_64, | ||
| 1058 | extended: vm_region_extended_info, | ||
| 1059 | top: vm_region_top_info, | ||
| 1060 | }, | ||
| 1061 | }; | ||
| 1062 | |||
| 1063 | pub fn getRegionInfo( | ||
| 1064 | task: MachTask, | ||
| 1065 | address: u64, | ||
| 1066 | len: usize, | ||
| 1067 | tag: RegionInfo.Tag, | ||
| 1068 | ) MachError!RegionInfo { | ||
| 1069 | var info: RegionInfo = .{ | ||
| 1070 | .base_addr = address, | ||
| 1071 | .tag = tag, | ||
| 1072 | .info = undefined, | ||
| 1073 | }; | ||
| 1074 | switch (tag) { | ||
| 1075 | .basic => info.info = .{ .basic = undefined }, | ||
| 1076 | .extended => info.info = .{ .extended = undefined }, | ||
| 1077 | .top => info.info = .{ .top = undefined }, | ||
| 1078 | } | ||
| 1079 | var base_len: mach_vm_size_t = if (len == 1) 2 else len; | ||
| 1080 | var objname: mach_port_t = undefined; | ||
| 1081 | var count: mach_msg_type_number_t = switch (tag) { | ||
| 1082 | .basic => VM_REGION_BASIC_INFO_COUNT, | ||
| 1083 | .extended => VM_REGION_EXTENDED_INFO_COUNT, | ||
| 1084 | .top => VM_REGION_TOP_INFO_COUNT, | ||
| 1085 | }; | ||
| 1086 | switch (getKernError(mach_vm_region( | ||
| 1087 | task.port, | ||
| 1088 | &info.base_addr, | ||
| 1089 | &base_len, | ||
| 1090 | switch (tag) { | ||
| 1091 | .basic => VM_REGION_BASIC_INFO_64, | ||
| 1092 | .extended => VM_REGION_EXTENDED_INFO, | ||
| 1093 | .top => VM_REGION_TOP_INFO, | ||
| 1094 | }, | ||
| 1095 | switch (tag) { | ||
| 1096 | .basic => @as(vm_region_info_t, @ptrCast(&info.info.basic)), | ||
| 1097 | .extended => @as(vm_region_info_t, @ptrCast(&info.info.extended)), | ||
| 1098 | .top => @as(vm_region_info_t, @ptrCast(&info.info.top)), | ||
| 1099 | }, | ||
| 1100 | &count, | ||
| 1101 | &objname, | ||
| 1102 | ))) { | ||
| 1103 | .SUCCESS => return info, | ||
| 1104 | .FAILURE => return error.PermissionDenied, | ||
| 1105 | else => |err| return unexpectedKernError(err), | ||
| 1106 | } | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | pub const RegionSubmapInfo = struct { | ||
| 1110 | pub const Tag = enum { | ||
| 1111 | short, | ||
| 1112 | full, | ||
| 1113 | }; | ||
| 1114 | |||
| 1115 | tag: Tag, | ||
| 1116 | base_addr: u64, | ||
| 1117 | info: union { | ||
| 1118 | short: vm_region_submap_short_info_64, | ||
| 1119 | full: vm_region_submap_info_64, | ||
| 1120 | }, | ||
| 1121 | }; | ||
| 1122 | |||
| 1123 | pub fn getRegionSubmapInfo( | ||
| 1124 | task: MachTask, | ||
| 1125 | address: u64, | ||
| 1126 | len: usize, | ||
| 1127 | nesting_depth: u32, | ||
| 1128 | tag: RegionSubmapInfo.Tag, | ||
| 1129 | ) MachError!RegionSubmapInfo { | ||
| 1130 | var info: RegionSubmapInfo = .{ | ||
| 1131 | .base_addr = address, | ||
| 1132 | .tag = tag, | ||
| 1133 | .info = undefined, | ||
| 1134 | }; | ||
| 1135 | switch (tag) { | ||
| 1136 | .short => info.info = .{ .short = undefined }, | ||
| 1137 | .full => info.info = .{ .full = undefined }, | ||
| 1138 | } | ||
| 1139 | var nesting = nesting_depth; | ||
| 1140 | var base_len: mach_vm_size_t = if (len == 1) 2 else len; | ||
| 1141 | var count: mach_msg_type_number_t = switch (tag) { | ||
| 1142 | .short => VM_REGION_SUBMAP_SHORT_INFO_COUNT_64, | ||
| 1143 | .full => VM_REGION_SUBMAP_INFO_COUNT_64, | ||
| 1144 | }; | ||
| 1145 | switch (getKernError(mach_vm_region_recurse( | ||
| 1146 | task.port, | ||
| 1147 | &info.base_addr, | ||
| 1148 | &base_len, | ||
| 1149 | &nesting, | ||
| 1150 | switch (tag) { | ||
| 1151 | .short => @as(vm_region_recurse_info_t, @ptrCast(&info.info.short)), | ||
| 1152 | .full => @as(vm_region_recurse_info_t, @ptrCast(&info.info.full)), | ||
| 1153 | }, | ||
| 1154 | &count, | ||
| 1155 | ))) { | ||
| 1156 | .SUCCESS => return info, | ||
| 1157 | .FAILURE => return error.PermissionDenied, | ||
| 1158 | else => |err| return unexpectedKernError(err), | ||
| 1159 | } | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!vm_prot_t { | ||
| 1163 | const info = try task.getRegionSubmapInfo(address, len, 0, .short); | ||
| 1164 | return info.info.short.protection; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: vm_prot_t) MachError!void { | ||
| 1168 | return task.setProtectionImpl(address, len, true, prot); | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | pub fn setCurrProtection(task: MachTask, address: u64, len: usize, prot: vm_prot_t) MachError!void { | ||
| 1172 | return task.setProtectionImpl(address, len, false, prot); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | fn setProtectionImpl(task: MachTask, address: u64, len: usize, set_max: bool, prot: vm_prot_t) MachError!void { | ||
| 1176 | switch (getKernError(mach_vm_protect(task.port, address, len, @intFromBool(set_max), prot))) { | ||
| 1177 | .SUCCESS => return, | ||
| 1178 | .FAILURE => return error.PermissionDenied, | ||
| 1179 | else => |err| return unexpectedKernError(err), | ||
| 1180 | } | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | /// Will write to VM even if current protection attributes specifically prohibit | ||
| 1184 | /// us from doing so, by temporarily setting protection level to a level with VM_PROT_COPY | ||
| 1185 | /// variant, and resetting after a successful or unsuccessful write. | ||
| 1186 | pub fn writeMemProtected(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize { | ||
| 1187 | const curr_prot = try task.getCurrProtection(address, buf.len); | ||
| 1188 | try task.setCurrProtection( | ||
| 1189 | address, | ||
| 1190 | buf.len, | ||
| 1191 | PROT.READ | PROT.WRITE | PROT.COPY, | ||
| 1192 | ); | ||
| 1193 | defer { | ||
| 1194 | task.setCurrProtection(address, buf.len, curr_prot) catch {}; | ||
| 1195 | } | ||
| 1196 | return task.writeMem(address, buf, arch); | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | pub fn writeMem(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize { | ||
| 1200 | const count = buf.len; | ||
| 1201 | var total_written: usize = 0; | ||
| 1202 | var curr_addr = address; | ||
| 1203 | const page_size = try getPageSize(task); // TODO we probably can assume value here | ||
| 1204 | var out_buf = buf[0..]; | ||
| 1205 | |||
| 1206 | while (total_written < count) { | ||
| 1207 | const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_written); | ||
| 1208 | switch (getKernError(mach_vm_write( | ||
| 1209 | task.port, | ||
| 1210 | curr_addr, | ||
| 1211 | @intFromPtr(out_buf.ptr), | ||
| 1212 | @as(mach_msg_type_number_t, @intCast(curr_size)), | ||
| 1213 | ))) { | ||
| 1214 | .SUCCESS => {}, | ||
| 1215 | .FAILURE => return error.PermissionDenied, | ||
| 1216 | else => |err| return unexpectedKernError(err), | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | switch (arch) { | ||
| 1220 | .aarch64 => { | ||
| 1221 | var mattr_value: vm_machine_attribute_val_t = MATTR_VAL_CACHE_FLUSH; | ||
| 1222 | switch (getKernError(vm_machine_attribute( | ||
| 1223 | task.port, | ||
| 1224 | curr_addr, | ||
| 1225 | curr_size, | ||
| 1226 | MATTR_CACHE, | ||
| 1227 | &mattr_value, | ||
| 1228 | ))) { | ||
| 1229 | .SUCCESS => {}, | ||
| 1230 | .FAILURE => return error.PermissionDenied, | ||
| 1231 | else => |err| return unexpectedKernError(err), | ||
| 1232 | } | ||
| 1233 | }, | ||
| 1234 | .x86_64 => {}, | ||
| 1235 | else => unreachable, | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | out_buf = out_buf[curr_size..]; | ||
| 1239 | total_written += curr_size; | ||
| 1240 | curr_addr += curr_size; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | return total_written; | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | pub fn readMem(task: MachTask, address: u64, buf: []u8) MachError!usize { | ||
| 1247 | const count = buf.len; | ||
| 1248 | var total_read: usize = 0; | ||
| 1249 | var curr_addr = address; | ||
| 1250 | const page_size = try getPageSize(task); // TODO we probably can assume value here | ||
| 1251 | var out_buf = buf[0..]; | ||
| 1252 | |||
| 1253 | while (total_read < count) { | ||
| 1254 | const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_read); | ||
| 1255 | var curr_bytes_read: mach_msg_type_number_t = 0; | ||
| 1256 | var vm_memory: vm_offset_t = undefined; | ||
| 1257 | switch (getKernError(mach_vm_read(task.port, curr_addr, curr_size, &vm_memory, &curr_bytes_read))) { | ||
| 1258 | .SUCCESS => {}, | ||
| 1259 | .FAILURE => return error.PermissionDenied, | ||
| 1260 | else => |err| return unexpectedKernError(err), | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | @memcpy(out_buf[0..curr_bytes_read], @as([*]const u8, @ptrFromInt(vm_memory))); | ||
| 1264 | _ = vm_deallocate(mach_task_self(), vm_memory, curr_bytes_read); | ||
| 1265 | |||
| 1266 | out_buf = out_buf[curr_bytes_read..]; | ||
| 1267 | curr_addr += curr_bytes_read; | ||
| 1268 | total_read += curr_bytes_read; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | return total_read; | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | fn maxBytesLeftInPage(page_size: usize, address: u64, count: usize) usize { | ||
| 1275 | var left = count; | ||
| 1276 | if (page_size > 0) { | ||
| 1277 | const page_offset = address % page_size; | ||
| 1278 | const bytes_left_in_page = page_size - page_offset; | ||
| 1279 | if (count > bytes_left_in_page) { | ||
| 1280 | left = bytes_left_in_page; | ||
| 1281 | } | ||
| 1282 | } | ||
| 1283 | return left; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | fn getPageSize(task: MachTask) MachError!usize { | ||
| 1287 | if (task.isValid()) { | ||
| 1288 | var info_count = TASK_VM_INFO_COUNT; | ||
| 1289 | var vm_info: task_vm_info_data_t = undefined; | ||
| 1290 | switch (getKernError(task_info( | ||
| 1291 | task.port, | ||
| 1292 | TASK_VM_INFO, | ||
| 1293 | @as(task_info_t, @ptrCast(&vm_info)), | ||
| 1294 | &info_count, | ||
| 1295 | ))) { | ||
| 1296 | .SUCCESS => return @as(usize, @intCast(vm_info.page_size)), | ||
| 1297 | else => {}, | ||
| 1298 | } | ||
| 1299 | } | ||
| 1300 | var page_size: vm_size_t = undefined; | ||
| 1301 | switch (getKernError(_host_page_size(mach_host_self(), &page_size))) { | ||
| 1302 | .SUCCESS => return page_size, | ||
| 1303 | else => |err| return unexpectedKernError(err), | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | pub fn basicTaskInfo(task: MachTask) MachError!mach_task_basic_info { | ||
| 1308 | var info: mach_task_basic_info = undefined; | ||
| 1309 | var count = MACH_TASK_BASIC_INFO_COUNT; | ||
| 1310 | switch (getKernError(task_info( | ||
| 1311 | task.port, | ||
| 1312 | MACH_TASK_BASIC_INFO, | ||
| 1313 | @as(task_info_t, @ptrCast(&info)), | ||
| 1314 | &count, | ||
| 1315 | ))) { | ||
| 1316 | .SUCCESS => return info, | ||
| 1317 | else => |err| return unexpectedKernError(err), | ||
| 1318 | } | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | pub fn @"resume"(task: MachTask) MachError!void { | ||
| 1322 | switch (getKernError(task_resume(task.port))) { | ||
| 1323 | .SUCCESS => {}, | ||
| 1324 | else => |err| return unexpectedKernError(err), | ||
| 1325 | } | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | pub fn @"suspend"(task: MachTask) MachError!void { | ||
| 1329 | switch (getKernError(task_suspend(task.port))) { | ||
| 1330 | .SUCCESS => {}, | ||
| 1331 | else => |err| return unexpectedKernError(err), | ||
| 1332 | } | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | const ThreadList = struct { | ||
| 1336 | buf: []MachThread, | ||
| 1337 | |||
| 1338 | pub fn deinit(list: ThreadList) void { | ||
| 1339 | const self_task = machTaskForSelf(); | ||
| 1340 | _ = vm_deallocate( | ||
| 1341 | self_task.port, | ||
| 1342 | @intFromPtr(list.buf.ptr), | ||
| 1343 | @as(vm_size_t, @intCast(list.buf.len * @sizeOf(mach_port_t))), | ||
| 1344 | ); | ||
| 1345 | } | ||
| 1346 | }; | ||
| 1347 | |||
| 1348 | pub fn getThreads(task: MachTask) MachError!ThreadList { | ||
| 1349 | var thread_list: mach_port_array_t = undefined; | ||
| 1350 | var thread_count: mach_msg_type_number_t = undefined; | ||
| 1351 | switch (getKernError(task_threads(task.port, &thread_list, &thread_count))) { | ||
| 1352 | .SUCCESS => return ThreadList{ .buf = @as([*]MachThread, @ptrCast(thread_list))[0..thread_count] }, | ||
| 1353 | else => |err| return unexpectedKernError(err), | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | }; | ||
| 1357 | |||
| 1358 | pub const MachThread = extern struct { | ||
| 1359 | port: mach_port_t, | ||
| 1360 | |||
| 1361 | pub fn isValid(thread: MachThread) bool { | ||
| 1362 | return thread.port != THREAD_NULL; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | pub fn getBasicInfo(thread: MachThread) MachError!thread_basic_info { | ||
| 1366 | var info: thread_basic_info = undefined; | ||
| 1367 | var count = THREAD_BASIC_INFO_COUNT; | ||
| 1368 | switch (getKernError(thread_info( | ||
| 1369 | thread.port, | ||
| 1370 | THREAD_BASIC_INFO, | ||
| 1371 | @as(thread_info_t, @ptrCast(&info)), | ||
| 1372 | &count, | ||
| 1373 | ))) { | ||
| 1374 | .SUCCESS => return info, | ||
| 1375 | else => |err| return unexpectedKernError(err), | ||
| 1376 | } | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | pub fn getIdentifierInfo(thread: MachThread) MachError!thread_identifier_info { | ||
| 1380 | var info: thread_identifier_info = undefined; | ||
| 1381 | var count = THREAD_IDENTIFIER_INFO_COUNT; | ||
| 1382 | switch (getKernError(thread_info( | ||
| 1383 | thread.port, | ||
| 1384 | THREAD_IDENTIFIER_INFO, | ||
| 1385 | @as(thread_info_t, @ptrCast(&info)), | ||
| 1386 | &count, | ||
| 1387 | ))) { | ||
| 1388 | .SUCCESS => return info, | ||
| 1389 | else => |err| return unexpectedKernError(err), | ||
| 1390 | } | ||
| 1391 | } | ||
| 1392 | }; | ||
| 1393 | |||
| 1394 | pub fn machTaskForPid(pid: std.c.pid_t) MachError!MachTask { | ||
| 1395 | var port: mach_port_name_t = undefined; | ||
| 1396 | switch (getKernError(task_for_pid(mach_task_self(), pid, &port))) { | ||
| 1397 | .SUCCESS => {}, | ||
| 1398 | .FAILURE => return error.PermissionDenied, | ||
| 1399 | else => |err| return unexpectedKernError(err), | ||
| 1400 | } | ||
| 1401 | return MachTask{ .port = port }; | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | pub fn machTaskForSelf() MachTask { | ||
| 1405 | return .{ .port = mach_task_self() }; | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | pub const os_signpost_id_t = u64; | 922 | pub const os_signpost_id_t = u64; |
| 1409 | 923 | ||
| 1410 | pub const OS_SIGNPOST_ID_NULL: os_signpost_id_t = 0; | 924 | pub const OS_SIGNPOST_ID_NULL: os_signpost_id_t = 0; |
| ... | @@ -1503,168 +1017,6 @@ pub const KEVENT_FLAG_ERROR_EVENTS = 0x002; | ... | @@ -1503,168 +1017,6 @@ pub const KEVENT_FLAG_ERROR_EVENTS = 0x002; |
| 1503 | 1017 | ||
| 1504 | pub const SYSPROTO_EVENT = 1; | 1018 | pub const SYSPROTO_EVENT = 1; |
| 1505 | pub const SYSPROTO_CONTROL = 2; | 1019 | pub const SYSPROTO_CONTROL = 2; |
| 1506 | /// Kernel return values | ||
| 1507 | pub const KernE = enum(u32) { | ||
| 1508 | SUCCESS = 0, | ||
| 1509 | /// Specified address is not currently valid | ||
| 1510 | INVALID_ADDRESS = 1, | ||
| 1511 | /// Specified memory is valid, but does not permit the | ||
| 1512 | /// required forms of access. | ||
| 1513 | PROTECTION_FAILURE = 2, | ||
| 1514 | /// The address range specified is already in use, or | ||
| 1515 | /// no address range of the size specified could be | ||
| 1516 | /// found. | ||
| 1517 | NO_SPACE = 3, | ||
| 1518 | /// The function requested was not applicable to this | ||
| 1519 | /// type of argument, or an argument is invalid | ||
| 1520 | INVALID_ARGUMENT = 4, | ||
| 1521 | /// The function could not be performed. A catch-all. | ||
| 1522 | FAILURE = 5, | ||
| 1523 | /// A system resource could not be allocated to fulfill | ||
| 1524 | /// this request. This failure may not be permanent. | ||
| 1525 | RESOURCE_SHORTAGE = 6, | ||
| 1526 | /// The task in question does not hold receive rights | ||
| 1527 | /// for the port argument. | ||
| 1528 | NOT_RECEIVER = 7, | ||
| 1529 | /// Bogus access restriction. | ||
| 1530 | NO_ACCESS = 8, | ||
| 1531 | /// During a page fault, the target address refers to a | ||
| 1532 | /// memory object that has been destroyed. This | ||
| 1533 | /// failure is permanent. | ||
| 1534 | MEMORY_FAILURE = 9, | ||
| 1535 | /// During a page fault, the memory object indicated | ||
| 1536 | /// that the data could not be returned. This failure | ||
| 1537 | /// may be temporary; future attempts to access this | ||
| 1538 | /// same data may succeed, as defined by the memory | ||
| 1539 | /// object. | ||
| 1540 | MEMORY_ERROR = 10, | ||
| 1541 | /// The receive right is already a member of the portset. | ||
| 1542 | ALREADY_IN_SET = 11, | ||
| 1543 | /// The receive right is not a member of a port set. | ||
| 1544 | NOT_IN_SET = 12, | ||
| 1545 | /// The name already denotes a right in the task. | ||
| 1546 | NAME_EXISTS = 13, | ||
| 1547 | /// The operation was aborted. Ipc code will | ||
| 1548 | /// catch this and reflect it as a message error. | ||
| 1549 | ABORTED = 14, | ||
| 1550 | /// The name doesn't denote a right in the task. | ||
| 1551 | INVALID_NAME = 15, | ||
| 1552 | /// Target task isn't an active task. | ||
| 1553 | INVALID_TASK = 16, | ||
| 1554 | /// The name denotes a right, but not an appropriate right. | ||
| 1555 | INVALID_RIGHT = 17, | ||
| 1556 | /// A blatant range error. | ||
| 1557 | INVALID_VALUE = 18, | ||
| 1558 | /// Operation would overflow limit on user-references. | ||
| 1559 | UREFS_OVERFLOW = 19, | ||
| 1560 | /// The supplied (port) capability is improper. | ||
| 1561 | INVALID_CAPABILITY = 20, | ||
| 1562 | /// The task already has send or receive rights | ||
| 1563 | /// for the port under another name. | ||
| 1564 | RIGHT_EXISTS = 21, | ||
| 1565 | /// Target host isn't actually a host. | ||
| 1566 | INVALID_HOST = 22, | ||
| 1567 | /// An attempt was made to supply "precious" data | ||
| 1568 | /// for memory that is already present in a | ||
| 1569 | /// memory object. | ||
| 1570 | MEMORY_PRESENT = 23, | ||
| 1571 | /// A page was requested of a memory manager via | ||
| 1572 | /// memory_object_data_request for an object using | ||
| 1573 | /// a MEMORY_OBJECT_COPY_CALL strategy, with the | ||
| 1574 | /// VM_PROT_WANTS_COPY flag being used to specify | ||
| 1575 | /// that the page desired is for a copy of the | ||
| 1576 | /// object, and the memory manager has detected | ||
| 1577 | /// the page was pushed into a copy of the object | ||
| 1578 | /// while the kernel was walking the shadow chain | ||
| 1579 | /// from the copy to the object. This error code | ||
| 1580 | /// is delivered via memory_object_data_error | ||
| 1581 | /// and is handled by the kernel (it forces the | ||
| 1582 | /// kernel to restart the fault). It will not be | ||
| 1583 | /// seen by users. | ||
| 1584 | MEMORY_DATA_MOVED = 24, | ||
| 1585 | /// A strategic copy was attempted of an object | ||
| 1586 | /// upon which a quicker copy is now possible. | ||
| 1587 | /// The caller should retry the copy using | ||
| 1588 | /// vm_object_copy_quickly. This error code | ||
| 1589 | /// is seen only by the kernel. | ||
| 1590 | MEMORY_RESTART_COPY = 25, | ||
| 1591 | /// An argument applied to assert processor set privilege | ||
| 1592 | /// was not a processor set control port. | ||
| 1593 | INVALID_PROCESSOR_SET = 26, | ||
| 1594 | /// The specified scheduling attributes exceed the thread's | ||
| 1595 | /// limits. | ||
| 1596 | POLICY_LIMIT = 27, | ||
| 1597 | /// The specified scheduling policy is not currently | ||
| 1598 | /// enabled for the processor set. | ||
| 1599 | INVALID_POLICY = 28, | ||
| 1600 | /// The external memory manager failed to initialize the | ||
| 1601 | /// memory object. | ||
| 1602 | INVALID_OBJECT = 29, | ||
| 1603 | /// A thread is attempting to wait for an event for which | ||
| 1604 | /// there is already a waiting thread. | ||
| 1605 | ALREADY_WAITING = 30, | ||
| 1606 | /// An attempt was made to destroy the default processor | ||
| 1607 | /// set. | ||
| 1608 | DEFAULT_SET = 31, | ||
| 1609 | /// An attempt was made to fetch an exception port that is | ||
| 1610 | /// protected, or to abort a thread while processing a | ||
| 1611 | /// protected exception. | ||
| 1612 | EXCEPTION_PROTECTED = 32, | ||
| 1613 | /// A ledger was required but not supplied. | ||
| 1614 | INVALID_LEDGER = 33, | ||
| 1615 | /// The port was not a memory cache control port. | ||
| 1616 | INVALID_MEMORY_CONTROL = 34, | ||
| 1617 | /// An argument supplied to assert security privilege | ||
| 1618 | /// was not a host security port. | ||
| 1619 | INVALID_SECURITY = 35, | ||
| 1620 | /// thread_depress_abort was called on a thread which | ||
| 1621 | /// was not currently depressed. | ||
| 1622 | NOT_DEPRESSED = 36, | ||
| 1623 | /// Object has been terminated and is no longer available | ||
| 1624 | TERMINATED = 37, | ||
| 1625 | /// Lock set has been destroyed and is no longer available. | ||
| 1626 | LOCK_SET_DESTROYED = 38, | ||
| 1627 | /// The thread holding the lock terminated before releasing | ||
| 1628 | /// the lock | ||
| 1629 | LOCK_UNSTABLE = 39, | ||
| 1630 | /// The lock is already owned by another thread | ||
| 1631 | LOCK_OWNED = 40, | ||
| 1632 | /// The lock is already owned by the calling thread | ||
| 1633 | LOCK_OWNED_SELF = 41, | ||
| 1634 | /// Semaphore has been destroyed and is no longer available. | ||
| 1635 | SEMAPHORE_DESTROYED = 42, | ||
| 1636 | /// Return from RPC indicating the target server was | ||
| 1637 | /// terminated before it successfully replied | ||
| 1638 | RPC_SERVER_TERMINATED = 43, | ||
| 1639 | /// Terminate an orphaned activation. | ||
| 1640 | RPC_TERMINATE_ORPHAN = 44, | ||
| 1641 | /// Allow an orphaned activation to continue executing. | ||
| 1642 | RPC_CONTINUE_ORPHAN = 45, | ||
| 1643 | /// Empty thread activation (No thread linked to it) | ||
| 1644 | NOT_SUPPORTED = 46, | ||
| 1645 | /// Remote node down or inaccessible. | ||
| 1646 | NODE_DOWN = 47, | ||
| 1647 | /// A signalled thread was not actually waiting. | ||
| 1648 | NOT_WAITING = 48, | ||
| 1649 | /// Some thread-oriented operation (semaphore_wait) timed out | ||
| 1650 | OPERATION_TIMED_OUT = 49, | ||
| 1651 | /// During a page fault, indicates that the page was rejected | ||
| 1652 | /// as a result of a signature check. | ||
| 1653 | CODESIGN_ERROR = 50, | ||
| 1654 | /// The requested property cannot be changed at this time. | ||
| 1655 | POLICY_STATIC = 51, | ||
| 1656 | /// The provided buffer is of insufficient size for the requested data. | ||
| 1657 | INSUFFICIENT_BUFFER_SIZE = 52, | ||
| 1658 | /// Denied by security policy | ||
| 1659 | DENIED = 53, | ||
| 1660 | /// The KC on which the function is operating is missing | ||
| 1661 | MISSING_KC = 54, | ||
| 1662 | /// The KC on which the function is operating is invalid | ||
| 1663 | INVALID_KC = 55, | ||
| 1664 | /// A search or query operation did not return a result | ||
| 1665 | NOT_FOUND = 56, | ||
| 1666 | _, | ||
| 1667 | }; | ||
| 1668 | 1020 | ||
| 1669 | pub const mach_msg_return_t = kern_return_t; | 1021 | pub const mach_msg_return_t = kern_return_t; |
| 1670 | 1022 |
src/link/MachO.zig+645-2| ... | @@ -3779,7 +3779,7 @@ pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { | ... | @@ -3779,7 +3779,7 @@ pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { |
| 3779 | pub fn ptraceAttach(self: *MachO, pid: std.posix.pid_t) !void { | 3779 | pub fn ptraceAttach(self: *MachO, pid: std.posix.pid_t) !void { |
| 3780 | if (!is_hot_update_compatible) return; | 3780 | if (!is_hot_update_compatible) return; |
| 3781 | 3781 | ||
| 3782 | const mach_task = try std.c.machTaskForPid(pid); | 3782 | const mach_task = try machTaskForPid(pid); |
| 3783 | log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task }); | 3783 | log.debug("Mach task for pid {d}: {any}", .{ pid, mach_task }); |
| 3784 | self.hot_state.mach_task = mach_task; | 3784 | self.hot_state.mach_task = mach_task; |
| 3785 | 3785 | ||
| ... | @@ -4058,7 +4058,7 @@ pub const LiteralPool = struct { | ... | @@ -4058,7 +4058,7 @@ pub const LiteralPool = struct { |
| 4058 | }; | 4058 | }; |
| 4059 | 4059 | ||
| 4060 | const HotUpdateState = struct { | 4060 | const HotUpdateState = struct { |
| 4061 | mach_task: ?std.c.MachTask = null, | 4061 | mach_task: ?MachTask = null, |
| 4062 | }; | 4062 | }; |
| 4063 | 4063 | ||
| 4064 | pub const SymtabCtx = struct { | 4064 | pub const SymtabCtx = struct { |
| ... | @@ -4562,3 +4562,646 @@ const UnwindInfo = @import("MachO/UnwindInfo.zig"); | ... | @@ -4562,3 +4562,646 @@ const UnwindInfo = @import("MachO/UnwindInfo.zig"); |
| 4562 | const WeakBind = bind.WeakBind; | 4562 | const WeakBind = bind.WeakBind; |
| 4563 | const ZigGotSection = synthetic.ZigGotSection; | 4563 | const ZigGotSection = synthetic.ZigGotSection; |
| 4564 | const ZigObject = @import("MachO/ZigObject.zig"); | 4564 | const ZigObject = @import("MachO/ZigObject.zig"); |
| 4565 | |||
| 4566 | pub const MachError = error{ | ||
| 4567 | /// Not enough permissions held to perform the requested kernel | ||
| 4568 | /// call. | ||
| 4569 | PermissionDenied, | ||
| 4570 | } || std.posix.UnexpectedError; | ||
| 4571 | |||
| 4572 | pub const MachTask = extern struct { | ||
| 4573 | port: std.c.mach_port_name_t, | ||
| 4574 | |||
| 4575 | pub fn isValid(self: MachTask) bool { | ||
| 4576 | return self.port != std.c.TASK_NULL; | ||
| 4577 | } | ||
| 4578 | |||
| 4579 | pub fn pidForTask(self: MachTask) MachError!std.c.pid_t { | ||
| 4580 | var pid: std.c.pid_t = undefined; | ||
| 4581 | switch (getKernError(std.c.pid_for_task(self.port, &pid))) { | ||
| 4582 | .SUCCESS => return pid, | ||
| 4583 | .FAILURE => return error.PermissionDenied, | ||
| 4584 | else => |err| return unexpectedKernError(err), | ||
| 4585 | } | ||
| 4586 | } | ||
| 4587 | |||
| 4588 | pub fn allocatePort(self: MachTask, right: std.c.MACH_PORT_RIGHT) MachError!MachTask { | ||
| 4589 | var out_port: std.c.mach_port_name_t = undefined; | ||
| 4590 | switch (getKernError(std.c.mach_port_allocate( | ||
| 4591 | self.port, | ||
| 4592 | @intFromEnum(right), | ||
| 4593 | &out_port, | ||
| 4594 | ))) { | ||
| 4595 | .SUCCESS => return .{ .port = out_port }, | ||
| 4596 | .FAILURE => return error.PermissionDenied, | ||
| 4597 | else => |err| return unexpectedKernError(err), | ||
| 4598 | } | ||
| 4599 | } | ||
| 4600 | |||
| 4601 | pub fn deallocatePort(self: MachTask, port: MachTask) void { | ||
| 4602 | _ = getKernError(std.c.mach_port_deallocate(self.port, port.port)); | ||
| 4603 | } | ||
| 4604 | |||
| 4605 | pub fn insertRight(self: MachTask, port: MachTask, msg: std.c.MACH_MSG_TYPE) !void { | ||
| 4606 | switch (getKernError(std.c.mach_port_insert_right( | ||
| 4607 | self.port, | ||
| 4608 | port.port, | ||
| 4609 | port.port, | ||
| 4610 | @intFromEnum(msg), | ||
| 4611 | ))) { | ||
| 4612 | .SUCCESS => return, | ||
| 4613 | .FAILURE => return error.PermissionDenied, | ||
| 4614 | else => |err| return unexpectedKernError(err), | ||
| 4615 | } | ||
| 4616 | } | ||
| 4617 | |||
| 4618 | pub const PortInfo = struct { | ||
| 4619 | mask: std.c.exception_mask_t, | ||
| 4620 | masks: [std.c.EXC.TYPES_COUNT]std.c.exception_mask_t, | ||
| 4621 | ports: [std.c.EXC.TYPES_COUNT]std.c.mach_port_t, | ||
| 4622 | behaviors: [std.c.EXC.TYPES_COUNT]std.c.exception_behavior_t, | ||
| 4623 | flavors: [std.c.EXC.TYPES_COUNT]std.c.thread_state_flavor_t, | ||
| 4624 | count: std.c.mach_msg_type_number_t, | ||
| 4625 | }; | ||
| 4626 | |||
| 4627 | pub fn getExceptionPorts(self: MachTask, mask: std.c.exception_mask_t) !PortInfo { | ||
| 4628 | var info: PortInfo = .{ | ||
| 4629 | .mask = mask, | ||
| 4630 | .masks = undefined, | ||
| 4631 | .ports = undefined, | ||
| 4632 | .behaviors = undefined, | ||
| 4633 | .flavors = undefined, | ||
| 4634 | .count = 0, | ||
| 4635 | }; | ||
| 4636 | info.count = info.ports.len / @sizeOf(std.c.mach_port_t); | ||
| 4637 | |||
| 4638 | switch (getKernError(std.c.task_get_exception_ports( | ||
| 4639 | self.port, | ||
| 4640 | info.mask, | ||
| 4641 | &info.masks, | ||
| 4642 | &info.count, | ||
| 4643 | &info.ports, | ||
| 4644 | &info.behaviors, | ||
| 4645 | &info.flavors, | ||
| 4646 | ))) { | ||
| 4647 | .SUCCESS => return info, | ||
| 4648 | .FAILURE => return error.PermissionDenied, | ||
| 4649 | else => |err| return unexpectedKernError(err), | ||
| 4650 | } | ||
| 4651 | } | ||
| 4652 | |||
| 4653 | pub fn setExceptionPorts( | ||
| 4654 | self: MachTask, | ||
| 4655 | mask: std.c.exception_mask_t, | ||
| 4656 | new_port: MachTask, | ||
| 4657 | behavior: std.c.exception_behavior_t, | ||
| 4658 | new_flavor: std.c.thread_state_flavor_t, | ||
| 4659 | ) !void { | ||
| 4660 | switch (getKernError(std.c.task_set_exception_ports( | ||
| 4661 | self.port, | ||
| 4662 | mask, | ||
| 4663 | new_port.port, | ||
| 4664 | behavior, | ||
| 4665 | new_flavor, | ||
| 4666 | ))) { | ||
| 4667 | .SUCCESS => return, | ||
| 4668 | .FAILURE => return error.PermissionDenied, | ||
| 4669 | else => |err| return unexpectedKernError(err), | ||
| 4670 | } | ||
| 4671 | } | ||
| 4672 | |||
| 4673 | pub const RegionInfo = struct { | ||
| 4674 | pub const Tag = enum { | ||
| 4675 | basic, | ||
| 4676 | extended, | ||
| 4677 | top, | ||
| 4678 | }; | ||
| 4679 | |||
| 4680 | base_addr: u64, | ||
| 4681 | tag: Tag, | ||
| 4682 | info: union { | ||
| 4683 | basic: std.c.vm_region_basic_info_64, | ||
| 4684 | extended: std.c.vm_region_extended_info, | ||
| 4685 | top: std.c.vm_region_top_info, | ||
| 4686 | }, | ||
| 4687 | }; | ||
| 4688 | |||
| 4689 | pub fn getRegionInfo( | ||
| 4690 | task: MachTask, | ||
| 4691 | address: u64, | ||
| 4692 | len: usize, | ||
| 4693 | tag: RegionInfo.Tag, | ||
| 4694 | ) MachError!RegionInfo { | ||
| 4695 | var info: RegionInfo = .{ | ||
| 4696 | .base_addr = address, | ||
| 4697 | .tag = tag, | ||
| 4698 | .info = undefined, | ||
| 4699 | }; | ||
| 4700 | switch (tag) { | ||
| 4701 | .basic => info.info = .{ .basic = undefined }, | ||
| 4702 | .extended => info.info = .{ .extended = undefined }, | ||
| 4703 | .top => info.info = .{ .top = undefined }, | ||
| 4704 | } | ||
| 4705 | var base_len: std.c.mach_vm_size_t = if (len == 1) 2 else len; | ||
| 4706 | var objname: std.c.mach_port_t = undefined; | ||
| 4707 | var count: std.c.mach_msg_type_number_t = switch (tag) { | ||
| 4708 | .basic => std.c.VM.REGION.BASIC_INFO_COUNT, | ||
| 4709 | .extended => std.c.VM.REGION.EXTENDED_INFO_COUNT, | ||
| 4710 | .top => std.c.VM.REGION.TOP_INFO_COUNT, | ||
| 4711 | }; | ||
| 4712 | switch (getKernError(std.c.mach_vm_region( | ||
| 4713 | task.port, | ||
| 4714 | &info.base_addr, | ||
| 4715 | &base_len, | ||
| 4716 | switch (tag) { | ||
| 4717 | .basic => std.c.VM.REGION.BASIC_INFO_64, | ||
| 4718 | .extended => std.c.VM.REGION.EXTENDED_INFO, | ||
| 4719 | .top => std.c.VM.REGION.TOP_INFO, | ||
| 4720 | }, | ||
| 4721 | switch (tag) { | ||
| 4722 | .basic => @as(std.c.vm_region_info_t, @ptrCast(&info.info.basic)), | ||
| 4723 | .extended => @as(std.c.vm_region_info_t, @ptrCast(&info.info.extended)), | ||
| 4724 | .top => @as(std.c.vm_region_info_t, @ptrCast(&info.info.top)), | ||
| 4725 | }, | ||
| 4726 | &count, | ||
| 4727 | &objname, | ||
| 4728 | ))) { | ||
| 4729 | .SUCCESS => return info, | ||
| 4730 | .FAILURE => return error.PermissionDenied, | ||
| 4731 | else => |err| return unexpectedKernError(err), | ||
| 4732 | } | ||
| 4733 | } | ||
| 4734 | |||
| 4735 | pub const RegionSubmapInfo = struct { | ||
| 4736 | pub const Tag = enum { | ||
| 4737 | short, | ||
| 4738 | full, | ||
| 4739 | }; | ||
| 4740 | |||
| 4741 | tag: Tag, | ||
| 4742 | base_addr: u64, | ||
| 4743 | info: union { | ||
| 4744 | short: std.c.vm_region_submap_short_info_64, | ||
| 4745 | full: std.c.vm_region_submap_info_64, | ||
| 4746 | }, | ||
| 4747 | }; | ||
| 4748 | |||
| 4749 | pub fn getRegionSubmapInfo( | ||
| 4750 | task: MachTask, | ||
| 4751 | address: u64, | ||
| 4752 | len: usize, | ||
| 4753 | nesting_depth: u32, | ||
| 4754 | tag: RegionSubmapInfo.Tag, | ||
| 4755 | ) MachError!RegionSubmapInfo { | ||
| 4756 | var info: RegionSubmapInfo = .{ | ||
| 4757 | .base_addr = address, | ||
| 4758 | .tag = tag, | ||
| 4759 | .info = undefined, | ||
| 4760 | }; | ||
| 4761 | switch (tag) { | ||
| 4762 | .short => info.info = .{ .short = undefined }, | ||
| 4763 | .full => info.info = .{ .full = undefined }, | ||
| 4764 | } | ||
| 4765 | var nesting = nesting_depth; | ||
| 4766 | var base_len: std.c.mach_vm_size_t = if (len == 1) 2 else len; | ||
| 4767 | var count: std.c.mach_msg_type_number_t = switch (tag) { | ||
| 4768 | .short => std.c.VM.REGION.SUBMAP_SHORT_INFO_COUNT_64, | ||
| 4769 | .full => std.c.VM.REGION.SUBMAP_INFO_COUNT_64, | ||
| 4770 | }; | ||
| 4771 | switch (getKernError(std.c.mach_vm_region_recurse( | ||
| 4772 | task.port, | ||
| 4773 | &info.base_addr, | ||
| 4774 | &base_len, | ||
| 4775 | &nesting, | ||
| 4776 | switch (tag) { | ||
| 4777 | .short => @as(std.c.vm_region_recurse_info_t, @ptrCast(&info.info.short)), | ||
| 4778 | .full => @as(std.c.vm_region_recurse_info_t, @ptrCast(&info.info.full)), | ||
| 4779 | }, | ||
| 4780 | &count, | ||
| 4781 | ))) { | ||
| 4782 | .SUCCESS => return info, | ||
| 4783 | .FAILURE => return error.PermissionDenied, | ||
| 4784 | else => |err| return unexpectedKernError(err), | ||
| 4785 | } | ||
| 4786 | } | ||
| 4787 | |||
| 4788 | pub fn getCurrProtection(task: MachTask, address: u64, len: usize) MachError!std.c.vm_prot_t { | ||
| 4789 | const info = try task.getRegionSubmapInfo(address, len, 0, .short); | ||
| 4790 | return info.info.short.protection; | ||
| 4791 | } | ||
| 4792 | |||
| 4793 | pub fn setMaxProtection(task: MachTask, address: u64, len: usize, prot: std.c.vm_prot_t) MachError!void { | ||
| 4794 | return task.setProtectionImpl(address, len, true, prot); | ||
| 4795 | } | ||
| 4796 | |||
| 4797 | pub fn setCurrProtection(task: MachTask, address: u64, len: usize, prot: std.c.vm_prot_t) MachError!void { | ||
| 4798 | return task.setProtectionImpl(address, len, false, prot); | ||
| 4799 | } | ||
| 4800 | |||
| 4801 | fn setProtectionImpl(task: MachTask, address: u64, len: usize, set_max: bool, prot: std.c.vm_prot_t) MachError!void { | ||
| 4802 | switch (getKernError(std.c.mach_vm_protect(task.port, address, len, @intFromBool(set_max), prot))) { | ||
| 4803 | .SUCCESS => return, | ||
| 4804 | .FAILURE => return error.PermissionDenied, | ||
| 4805 | else => |err| return unexpectedKernError(err), | ||
| 4806 | } | ||
| 4807 | } | ||
| 4808 | |||
| 4809 | /// Will write to VM even if current protection attributes specifically prohibit | ||
| 4810 | /// us from doing so, by temporarily setting protection level to a level with VM_PROT_COPY | ||
| 4811 | /// variant, and resetting after a successful or unsuccessful write. | ||
| 4812 | pub fn writeMemProtected(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize { | ||
| 4813 | const curr_prot = try task.getCurrProtection(address, buf.len); | ||
| 4814 | try task.setCurrProtection( | ||
| 4815 | address, | ||
| 4816 | buf.len, | ||
| 4817 | std.c.PROT.READ | std.c.PROT.WRITE | std.c.PROT.COPY, | ||
| 4818 | ); | ||
| 4819 | defer { | ||
| 4820 | task.setCurrProtection(address, buf.len, curr_prot) catch {}; | ||
| 4821 | } | ||
| 4822 | return task.writeMem(address, buf, arch); | ||
| 4823 | } | ||
| 4824 | |||
| 4825 | pub fn writeMem(task: MachTask, address: u64, buf: []const u8, arch: std.Target.Cpu.Arch) MachError!usize { | ||
| 4826 | const count = buf.len; | ||
| 4827 | var total_written: usize = 0; | ||
| 4828 | var curr_addr = address; | ||
| 4829 | const page_size = try MachTask.getPageSize(task); // TODO we probably can assume value here | ||
| 4830 | var out_buf = buf[0..]; | ||
| 4831 | |||
| 4832 | while (total_written < count) { | ||
| 4833 | const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_written); | ||
| 4834 | switch (getKernError(std.c.mach_vm_write( | ||
| 4835 | task.port, | ||
| 4836 | curr_addr, | ||
| 4837 | @intFromPtr(out_buf.ptr), | ||
| 4838 | @as(std.c.mach_msg_type_number_t, @intCast(curr_size)), | ||
| 4839 | ))) { | ||
| 4840 | .SUCCESS => {}, | ||
| 4841 | .FAILURE => return error.PermissionDenied, | ||
| 4842 | else => |err| return unexpectedKernError(err), | ||
| 4843 | } | ||
| 4844 | |||
| 4845 | switch (arch) { | ||
| 4846 | .aarch64 => { | ||
| 4847 | var mattr_value: std.c.vm_machine_attribute_val_t = std.c.MATTR.VAL_CACHE_FLUSH; | ||
| 4848 | switch (getKernError(std.c.vm_machine_attribute( | ||
| 4849 | task.port, | ||
| 4850 | curr_addr, | ||
| 4851 | curr_size, | ||
| 4852 | std.c.MATTR.CACHE, | ||
| 4853 | &mattr_value, | ||
| 4854 | ))) { | ||
| 4855 | .SUCCESS => {}, | ||
| 4856 | .FAILURE => return error.PermissionDenied, | ||
| 4857 | else => |err| return unexpectedKernError(err), | ||
| 4858 | } | ||
| 4859 | }, | ||
| 4860 | .x86_64 => {}, | ||
| 4861 | else => unreachable, | ||
| 4862 | } | ||
| 4863 | |||
| 4864 | out_buf = out_buf[curr_size..]; | ||
| 4865 | total_written += curr_size; | ||
| 4866 | curr_addr += curr_size; | ||
| 4867 | } | ||
| 4868 | |||
| 4869 | return total_written; | ||
| 4870 | } | ||
| 4871 | |||
| 4872 | pub fn readMem(task: MachTask, address: u64, buf: []u8) MachError!usize { | ||
| 4873 | const count = buf.len; | ||
| 4874 | var total_read: usize = 0; | ||
| 4875 | var curr_addr = address; | ||
| 4876 | const page_size = try MachTask.getPageSize(task); // TODO we probably can assume value here | ||
| 4877 | var out_buf = buf[0..]; | ||
| 4878 | |||
| 4879 | while (total_read < count) { | ||
| 4880 | const curr_size = maxBytesLeftInPage(page_size, curr_addr, count - total_read); | ||
| 4881 | var curr_bytes_read: std.c.mach_msg_type_number_t = 0; | ||
| 4882 | var vm_memory: std.c.vm_offset_t = undefined; | ||
| 4883 | switch (getKernError(std.c.mach_vm_read(task.port, curr_addr, curr_size, &vm_memory, &curr_bytes_read))) { | ||
| 4884 | .SUCCESS => {}, | ||
| 4885 | .FAILURE => return error.PermissionDenied, | ||
| 4886 | else => |err| return unexpectedKernError(err), | ||
| 4887 | } | ||
| 4888 | |||
| 4889 | @memcpy(out_buf[0..curr_bytes_read], @as([*]const u8, @ptrFromInt(vm_memory))); | ||
| 4890 | _ = std.c.vm_deallocate(std.c.mach_task_self(), vm_memory, curr_bytes_read); | ||
| 4891 | |||
| 4892 | out_buf = out_buf[curr_bytes_read..]; | ||
| 4893 | curr_addr += curr_bytes_read; | ||
| 4894 | total_read += curr_bytes_read; | ||
| 4895 | } | ||
| 4896 | |||
| 4897 | return total_read; | ||
| 4898 | } | ||
| 4899 | |||
| 4900 | fn maxBytesLeftInPage(page_size: usize, address: u64, count: usize) usize { | ||
| 4901 | var left = count; | ||
| 4902 | if (page_size > 0) { | ||
| 4903 | const page_offset = address % page_size; | ||
| 4904 | const bytes_left_in_page = page_size - page_offset; | ||
| 4905 | if (count > bytes_left_in_page) { | ||
| 4906 | left = bytes_left_in_page; | ||
| 4907 | } | ||
| 4908 | } | ||
| 4909 | return left; | ||
| 4910 | } | ||
| 4911 | |||
| 4912 | fn getPageSize(task: MachTask) MachError!usize { | ||
| 4913 | if (task.isValid()) { | ||
| 4914 | var info_count = std.c.TASK_VM_INFO_COUNT; | ||
| 4915 | var vm_info: std.c.task_vm_info_data_t = undefined; | ||
| 4916 | switch (getKernError(std.c.task_info( | ||
| 4917 | task.port, | ||
| 4918 | std.c.TASK_VM_INFO, | ||
| 4919 | @as(std.c.task_info_t, @ptrCast(&vm_info)), | ||
| 4920 | &info_count, | ||
| 4921 | ))) { | ||
| 4922 | .SUCCESS => return @as(usize, @intCast(vm_info.page_size)), | ||
| 4923 | else => {}, | ||
| 4924 | } | ||
| 4925 | } | ||
| 4926 | var page_size: std.c.vm_size_t = undefined; | ||
| 4927 | switch (getKernError(std.c._host_page_size(std.c.mach_host_self(), &page_size))) { | ||
| 4928 | .SUCCESS => return page_size, | ||
| 4929 | else => |err| return unexpectedKernError(err), | ||
| 4930 | } | ||
| 4931 | } | ||
| 4932 | |||
| 4933 | pub fn basicTaskInfo(task: MachTask) MachError!std.c.mach_task_basic_info { | ||
| 4934 | var info: std.c.mach_task_basic_info = undefined; | ||
| 4935 | var count = std.c.MACH_TASK_BASIC_INFO_COUNT; | ||
| 4936 | switch (getKernError(std.c.task_info( | ||
| 4937 | task.port, | ||
| 4938 | std.c.MACH_TASK_BASIC_INFO, | ||
| 4939 | @as(std.c.task_info_t, @ptrCast(&info)), | ||
| 4940 | &count, | ||
| 4941 | ))) { | ||
| 4942 | .SUCCESS => return info, | ||
| 4943 | else => |err| return unexpectedKernError(err), | ||
| 4944 | } | ||
| 4945 | } | ||
| 4946 | |||
| 4947 | pub fn @"resume"(task: MachTask) MachError!void { | ||
| 4948 | switch (getKernError(std.c.task_resume(task.port))) { | ||
| 4949 | .SUCCESS => {}, | ||
| 4950 | else => |err| return unexpectedKernError(err), | ||
| 4951 | } | ||
| 4952 | } | ||
| 4953 | |||
| 4954 | pub fn @"suspend"(task: MachTask) MachError!void { | ||
| 4955 | switch (getKernError(std.c.task_suspend(task.port))) { | ||
| 4956 | .SUCCESS => {}, | ||
| 4957 | else => |err| return unexpectedKernError(err), | ||
| 4958 | } | ||
| 4959 | } | ||
| 4960 | |||
| 4961 | const ThreadList = struct { | ||
| 4962 | buf: []MachThread, | ||
| 4963 | |||
| 4964 | pub fn deinit(list: ThreadList) void { | ||
| 4965 | const self_task = machTaskForSelf(); | ||
| 4966 | _ = std.c.vm_deallocate( | ||
| 4967 | self_task.port, | ||
| 4968 | @intFromPtr(list.buf.ptr), | ||
| 4969 | @as(std.c.vm_size_t, @intCast(list.buf.len * @sizeOf(std.c.mach_port_t))), | ||
| 4970 | ); | ||
| 4971 | } | ||
| 4972 | }; | ||
| 4973 | |||
| 4974 | pub fn getThreads(task: MachTask) MachError!ThreadList { | ||
| 4975 | var thread_list: std.c.mach_port_array_t = undefined; | ||
| 4976 | var thread_count: std.c.mach_msg_type_number_t = undefined; | ||
| 4977 | switch (getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) { | ||
| 4978 | .SUCCESS => return ThreadList{ .buf = @as([*]MachThread, @ptrCast(thread_list))[0..thread_count] }, | ||
| 4979 | else => |err| return unexpectedKernError(err), | ||
| 4980 | } | ||
| 4981 | } | ||
| 4982 | }; | ||
| 4983 | |||
| 4984 | pub const MachThread = extern struct { | ||
| 4985 | port: std.c.mach_port_t, | ||
| 4986 | |||
| 4987 | pub fn isValid(thread: MachThread) bool { | ||
| 4988 | return thread.port != std.c.THREAD_NULL; | ||
| 4989 | } | ||
| 4990 | |||
| 4991 | pub fn getBasicInfo(thread: MachThread) MachError!std.c.thread_basic_info { | ||
| 4992 | var info: std.c.thread_basic_info = undefined; | ||
| 4993 | var count = std.c.THREAD_BASIC_INFO_COUNT; | ||
| 4994 | switch (getKernError(std.c.thread_info( | ||
| 4995 | thread.port, | ||
| 4996 | std.c.THREAD_BASIC_INFO, | ||
| 4997 | @as(std.c.thread_info_t, @ptrCast(&info)), | ||
| 4998 | &count, | ||
| 4999 | ))) { | ||
| 5000 | .SUCCESS => return info, | ||
| 5001 | else => |err| return unexpectedKernError(err), | ||
| 5002 | } | ||
| 5003 | } | ||
| 5004 | |||
| 5005 | pub fn getIdentifierInfo(thread: MachThread) MachError!std.c.thread_identifier_info { | ||
| 5006 | var info: std.c.thread_identifier_info = undefined; | ||
| 5007 | var count = std.c.THREAD_IDENTIFIER_INFO_COUNT; | ||
| 5008 | switch (getKernError(std.c.thread_info( | ||
| 5009 | thread.port, | ||
| 5010 | std.c.THREAD_IDENTIFIER_INFO, | ||
| 5011 | @as(std.c.thread_info_t, @ptrCast(&info)), | ||
| 5012 | &count, | ||
| 5013 | ))) { | ||
| 5014 | .SUCCESS => return info, | ||
| 5015 | else => |err| return unexpectedKernError(err), | ||
| 5016 | } | ||
| 5017 | } | ||
| 5018 | }; | ||
| 5019 | |||
| 5020 | pub fn machTaskForPid(pid: std.c.pid_t) MachError!MachTask { | ||
| 5021 | var port: std.c.mach_port_name_t = undefined; | ||
| 5022 | switch (getKernError(std.c.task_for_pid(std.c.mach_task_self(), pid, &port))) { | ||
| 5023 | .SUCCESS => {}, | ||
| 5024 | .FAILURE => return error.PermissionDenied, | ||
| 5025 | else => |err| return unexpectedKernError(err), | ||
| 5026 | } | ||
| 5027 | return MachTask{ .port = port }; | ||
| 5028 | } | ||
| 5029 | |||
| 5030 | pub fn machTaskForSelf() MachTask { | ||
| 5031 | return .{ .port = std.c.mach_task_self() }; | ||
| 5032 | } | ||
| 5033 | |||
| 5034 | pub fn getKernError(err: std.c.kern_return_t) KernE { | ||
| 5035 | return @as(KernE, @enumFromInt(@as(u32, @truncate(@as(usize, @intCast(err)))))); | ||
| 5036 | } | ||
| 5037 | |||
| 5038 | pub fn unexpectedKernError(err: KernE) std.posix.UnexpectedError { | ||
| 5039 | if (std.posix.unexpected_error_tracing) { | ||
| 5040 | std.debug.print("unexpected error: {d}\n", .{@intFromEnum(err)}); | ||
| 5041 | std.debug.dumpCurrentStackTrace(null); | ||
| 5042 | } | ||
| 5043 | return error.Unexpected; | ||
| 5044 | } | ||
| 5045 | |||
| 5046 | /// Kernel return values | ||
| 5047 | pub const KernE = enum(u32) { | ||
| 5048 | SUCCESS = 0, | ||
| 5049 | /// Specified address is not currently valid | ||
| 5050 | INVALID_ADDRESS = 1, | ||
| 5051 | /// Specified memory is valid, but does not permit the | ||
| 5052 | /// required forms of access. | ||
| 5053 | PROTECTION_FAILURE = 2, | ||
| 5054 | /// The address range specified is already in use, or | ||
| 5055 | /// no address range of the size specified could be | ||
| 5056 | /// found. | ||
| 5057 | NO_SPACE = 3, | ||
| 5058 | /// The function requested was not applicable to this | ||
| 5059 | /// type of argument, or an argument is invalid | ||
| 5060 | INVALID_ARGUMENT = 4, | ||
| 5061 | /// The function could not be performed. A catch-all. | ||
| 5062 | FAILURE = 5, | ||
| 5063 | /// A system resource could not be allocated to fulfill | ||
| 5064 | /// this request. This failure may not be permanent. | ||
| 5065 | RESOURCE_SHORTAGE = 6, | ||
| 5066 | /// The task in question does not hold receive rights | ||
| 5067 | /// for the port argument. | ||
| 5068 | NOT_RECEIVER = 7, | ||
| 5069 | /// Bogus access restriction. | ||
| 5070 | NO_ACCESS = 8, | ||
| 5071 | /// During a page fault, the target address refers to a | ||
| 5072 | /// memory object that has been destroyed. This | ||
| 5073 | /// failure is permanent. | ||
| 5074 | MEMORY_FAILURE = 9, | ||
| 5075 | /// During a page fault, the memory object indicated | ||
| 5076 | /// that the data could not be returned. This failure | ||
| 5077 | /// may be temporary; future attempts to access this | ||
| 5078 | /// same data may succeed, as defined by the memory | ||
| 5079 | /// object. | ||
| 5080 | MEMORY_ERROR = 10, | ||
| 5081 | /// The receive right is already a member of the portset. | ||
| 5082 | ALREADY_IN_SET = 11, | ||
| 5083 | /// The receive right is not a member of a port set. | ||
| 5084 | NOT_IN_SET = 12, | ||
| 5085 | /// The name already denotes a right in the task. | ||
| 5086 | NAME_EXISTS = 13, | ||
| 5087 | /// The operation was aborted. Ipc code will | ||
| 5088 | /// catch this and reflect it as a message error. | ||
| 5089 | ABORTED = 14, | ||
| 5090 | /// The name doesn't denote a right in the task. | ||
| 5091 | INVALID_NAME = 15, | ||
| 5092 | /// Target task isn't an active task. | ||
| 5093 | INVALID_TASK = 16, | ||
| 5094 | /// The name denotes a right, but not an appropriate right. | ||
| 5095 | INVALID_RIGHT = 17, | ||
| 5096 | /// A blatant range error. | ||
| 5097 | INVALID_VALUE = 18, | ||
| 5098 | /// Operation would overflow limit on user-references. | ||
| 5099 | UREFS_OVERFLOW = 19, | ||
| 5100 | /// The supplied (port) capability is improper. | ||
| 5101 | INVALID_CAPABILITY = 20, | ||
| 5102 | /// The task already has send or receive rights | ||
| 5103 | /// for the port under another name. | ||
| 5104 | RIGHT_EXISTS = 21, | ||
| 5105 | /// Target host isn't actually a host. | ||
| 5106 | INVALID_HOST = 22, | ||
| 5107 | /// An attempt was made to supply "precious" data | ||
| 5108 | /// for memory that is already present in a | ||
| 5109 | /// memory object. | ||
| 5110 | MEMORY_PRESENT = 23, | ||
| 5111 | /// A page was requested of a memory manager via | ||
| 5112 | /// memory_object_data_request for an object using | ||
| 5113 | /// a MEMORY_OBJECT_COPY_CALL strategy, with the | ||
| 5114 | /// VM_PROT_WANTS_COPY flag being used to specify | ||
| 5115 | /// that the page desired is for a copy of the | ||
| 5116 | /// object, and the memory manager has detected | ||
| 5117 | /// the page was pushed into a copy of the object | ||
| 5118 | /// while the kernel was walking the shadow chain | ||
| 5119 | /// from the copy to the object. This error code | ||
| 5120 | /// is delivered via memory_object_data_error | ||
| 5121 | /// and is handled by the kernel (it forces the | ||
| 5122 | /// kernel to restart the fault). It will not be | ||
| 5123 | /// seen by users. | ||
| 5124 | MEMORY_DATA_MOVED = 24, | ||
| 5125 | /// A strategic copy was attempted of an object | ||
| 5126 | /// upon which a quicker copy is now possible. | ||
| 5127 | /// The caller should retry the copy using | ||
| 5128 | /// vm_object_copy_quickly. This error code | ||
| 5129 | /// is seen only by the kernel. | ||
| 5130 | MEMORY_RESTART_COPY = 25, | ||
| 5131 | /// An argument applied to assert processor set privilege | ||
| 5132 | /// was not a processor set control port. | ||
| 5133 | INVALID_PROCESSOR_SET = 26, | ||
| 5134 | /// The specified scheduling attributes exceed the thread's | ||
| 5135 | /// limits. | ||
| 5136 | POLICY_LIMIT = 27, | ||
| 5137 | /// The specified scheduling policy is not currently | ||
| 5138 | /// enabled for the processor set. | ||
| 5139 | INVALID_POLICY = 28, | ||
| 5140 | /// The external memory manager failed to initialize the | ||
| 5141 | /// memory object. | ||
| 5142 | INVALID_OBJECT = 29, | ||
| 5143 | /// A thread is attempting to wait for an event for which | ||
| 5144 | /// there is already a waiting thread. | ||
| 5145 | ALREADY_WAITING = 30, | ||
| 5146 | /// An attempt was made to destroy the default processor | ||
| 5147 | /// set. | ||
| 5148 | DEFAULT_SET = 31, | ||
| 5149 | /// An attempt was made to fetch an exception port that is | ||
| 5150 | /// protected, or to abort a thread while processing a | ||
| 5151 | /// protected exception. | ||
| 5152 | EXCEPTION_PROTECTED = 32, | ||
| 5153 | /// A ledger was required but not supplied. | ||
| 5154 | INVALID_LEDGER = 33, | ||
| 5155 | /// The port was not a memory cache control port. | ||
| 5156 | INVALID_MEMORY_CONTROL = 34, | ||
| 5157 | /// An argument supplied to assert security privilege | ||
| 5158 | /// was not a host security port. | ||
| 5159 | INVALID_SECURITY = 35, | ||
| 5160 | /// thread_depress_abort was called on a thread which | ||
| 5161 | /// was not currently depressed. | ||
| 5162 | NOT_DEPRESSED = 36, | ||
| 5163 | /// Object has been terminated and is no longer available | ||
| 5164 | TERMINATED = 37, | ||
| 5165 | /// Lock set has been destroyed and is no longer available. | ||
| 5166 | LOCK_SET_DESTROYED = 38, | ||
| 5167 | /// The thread holding the lock terminated before releasing | ||
| 5168 | /// the lock | ||
| 5169 | LOCK_UNSTABLE = 39, | ||
| 5170 | /// The lock is already owned by another thread | ||
| 5171 | LOCK_OWNED = 40, | ||
| 5172 | /// The lock is already owned by the calling thread | ||
| 5173 | LOCK_OWNED_SELF = 41, | ||
| 5174 | /// Semaphore has been destroyed and is no longer available. | ||
| 5175 | SEMAPHORE_DESTROYED = 42, | ||
| 5176 | /// Return from RPC indicating the target server was | ||
| 5177 | /// terminated before it successfully replied | ||
| 5178 | RPC_SERVER_TERMINATED = 43, | ||
| 5179 | /// Terminate an orphaned activation. | ||
| 5180 | RPC_TERMINATE_ORPHAN = 44, | ||
| 5181 | /// Allow an orphaned activation to continue executing. | ||
| 5182 | RPC_CONTINUE_ORPHAN = 45, | ||
| 5183 | /// Empty thread activation (No thread linked to it) | ||
| 5184 | NOT_SUPPORTED = 46, | ||
| 5185 | /// Remote node down or inaccessible. | ||
| 5186 | NODE_DOWN = 47, | ||
| 5187 | /// A signalled thread was not actually waiting. | ||
| 5188 | NOT_WAITING = 48, | ||
| 5189 | /// Some thread-oriented operation (semaphore_wait) timed out | ||
| 5190 | OPERATION_TIMED_OUT = 49, | ||
| 5191 | /// During a page fault, indicates that the page was rejected | ||
| 5192 | /// as a result of a signature check. | ||
| 5193 | CODESIGN_ERROR = 50, | ||
| 5194 | /// The requested property cannot be changed at this time. | ||
| 5195 | POLICY_STATIC = 51, | ||
| 5196 | /// The provided buffer is of insufficient size for the requested data. | ||
| 5197 | INSUFFICIENT_BUFFER_SIZE = 52, | ||
| 5198 | /// Denied by security policy | ||
| 5199 | DENIED = 53, | ||
| 5200 | /// The KC on which the function is operating is missing | ||
| 5201 | MISSING_KC = 54, | ||
| 5202 | /// The KC on which the function is operating is invalid | ||
| 5203 | INVALID_KC = 55, | ||
| 5204 | /// A search or query operation did not return a result | ||
| 5205 | NOT_FOUND = 56, | ||
| 5206 | _, | ||
| 5207 | }; |