this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Initial Darling xtrace code

+770 -2
+18
platform-include/mach/i386/syscall_sw.h
··· 95 95 * Macro to generate Mach call stubs in libc: 96 96 */ 97 97 98 + #ifndef DARLING 98 99 #define kernel_trap(trap_name,trap_number,number_args) \ 99 100 LEAF(_##trap_name,0) ;\ 100 101 movl $##trap_number, %eax ;\ 101 102 call __sysenter_trap ;\ 102 103 END(_##trap_name) 104 + #else 105 + #define kernel_trap(trap_name,trap_number,number_args) \ 106 + LEAF(_##trap_name,0) ;\ 107 + movl $##trap_number, %eax ;\ 108 + call __darling_mach_syscall ;\ 109 + END(_##trap_name) 110 + 111 + #endif /* DARLING */ 103 112 104 113 #endif /* !KERNEL */ 105 114 ··· 121 130 * macro above, we negate those numbers here for the 64-bit 122 131 * code path. 123 132 */ 133 + #ifndef DARLING 124 134 #define kernel_trap(trap_name,trap_number,number_args) \ 125 135 LEAF(_##trap_name,0) ;\ 126 136 movq %rcx, %r10 ;\ 127 137 movl $ SYSCALL_CONSTRUCT_MACH(-##trap_number), %eax ;\ 128 138 syscall ;\ 129 139 END(_##trap_name) 140 + #else 141 + #define kernel_trap(trap_name,trap_number,number_args) \ 142 + LEAF(_##trap_name,0) ;\ 143 + movl $##trap_number, %eax ;\ 144 + call __darling_mach_syscall;\ 145 + END(_##trap_name) 146 + 147 + #endif 130 148 131 149 #endif /* !KERNEL */ 132 150
+179
platform-include/mach/syscall_sw.h
··· 1 + /* 2 + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 3 + * 4 + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 + * 6 + * This file contains Original Code and/or Modifications of Original Code 7 + * as defined in and that are subject to the Apple Public Source License 8 + * Version 2.0 (the 'License'). You may not use this file except in 9 + * compliance with the License. The rights granted to you under the License 10 + * may not be used to create, or enable the creation or redistribution of, 11 + * unlawful or unlicensed copies of an Apple operating system, or to 12 + * circumvent, violate, or enable the circumvention or violation of, any 13 + * terms of an Apple operating system software license agreement. 14 + * 15 + * Please obtain a copy of the License at 16 + * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 + * 18 + * The Original Code and all software distributed under the License are 19 + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 + * Please see the License for the specific language governing rights and 24 + * limitations under the License. 25 + * 26 + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 + */ 28 + /* 29 + * @OSF_COPYRIGHT@ 30 + */ 31 + /* 32 + * Mach Operating System 33 + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University 34 + * All Rights Reserved. 35 + * 36 + * Permission to use, copy, modify and distribute this software and its 37 + * documentation is hereby granted, provided that both the copyright 38 + * notice and this permission notice appear in all copies of the 39 + * software, derivative works or modified versions, and any portions 40 + * thereof, and that both notices appear in supporting documentation. 41 + * 42 + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 + * 46 + * Carnegie Mellon requests users of this software to return to 47 + * 48 + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 + * School of Computer Science 50 + * Carnegie Mellon University 51 + * Pittsburgh PA 15213-3890 52 + * 53 + * any improvements or extensions that they make and grant Carnegie Mellon 54 + * the rights to redistribute these changes. 55 + */ 56 + 57 + #ifdef PRIVATE 58 + 59 + #ifndef _MACH_SYSCALL_SW_H_ 60 + #define _MACH_SYSCALL_SW_H_ 61 + 62 + /* 63 + * The machine-dependent "syscall_sw.h" file should 64 + * define a macro for 65 + * kernel_trap(trap_name, trap_number, arg_count) 66 + * which will expand into assembly code for the 67 + * trap. 68 + * 69 + * N.B.: When adding calls, do not put spaces in the macros. 70 + */ 71 + 72 + #include <mach/machine/syscall_sw.h> 73 + 74 + /* 75 + * These trap numbers should be taken from the 76 + * table in <kern/syscall_sw.c>. 77 + */ 78 + 79 + /* 80 + * i386 and x86_64 just load of the stack or use 81 + * registers in order; no munging is required, 82 + * and number of args is ignored. ARM loads args 83 + * into registers beyond r3, unlike the normal 84 + * procedure call standard; we pad for 64-bit args. 85 + */ 86 + kernel_trap(_kernelrpc_mach_vm_allocate_trap,-10,5) /* 4 args, +1 for mach_vm_size_t */ 87 + kernel_trap(_kernelrpc_mach_vm_purgable_control_trap,-11,5) /* 4 args, +1 for mach_vm_offset_t */ 88 + kernel_trap(_kernelrpc_mach_vm_deallocate_trap,-12,5) /* 3 args, +2 for mach_vm_size_t and mach_vm_address_t */ 89 + kernel_trap(_kernelrpc_mach_vm_protect_trap,-14,7) /* 5 args, +2 for mach_vm_address_t and mach_vm_size_t */ 90 + kernel_trap(_kernelrpc_mach_vm_map_trap,-15,9) 91 + kernel_trap(_kernelrpc_mach_port_allocate_trap,-16,3) 92 + kernel_trap(_kernelrpc_mach_port_destroy_trap,-17,2) 93 + kernel_trap(_kernelrpc_mach_port_deallocate_trap,-18,2) 94 + kernel_trap(_kernelrpc_mach_port_mod_refs_trap,-19,4) 95 + kernel_trap(_kernelrpc_mach_port_move_member_trap,-20,3) 96 + kernel_trap(_kernelrpc_mach_port_insert_right_trap,-21,4) 97 + kernel_trap(_kernelrpc_mach_port_insert_member_trap,-22,3) 98 + kernel_trap(_kernelrpc_mach_port_extract_member_trap,-23,3) 99 + kernel_trap(_kernelrpc_mach_port_construct_trap,-24,5) 100 + kernel_trap(_kernelrpc_mach_port_destruct_trap,-25,5) 101 + 102 + kernel_trap(mach_reply_port,-26,0) 103 + kernel_trap(thread_self_trap,-27,0) 104 + kernel_trap(task_self_trap,-28,0) 105 + kernel_trap(host_self_trap,-29,0) 106 + 107 + kernel_trap(mach_msg_trap,-31,7) 108 + kernel_trap(mach_msg_overwrite_trap,-32,9) 109 + kernel_trap(semaphore_signal_trap, -33, 1) 110 + kernel_trap(semaphore_signal_all_trap, -34, 1) 111 + kernel_trap(semaphore_signal_thread_trap, -35, 2) 112 + kernel_trap(semaphore_wait_trap,-36,1) 113 + kernel_trap(semaphore_wait_signal_trap,-37,2) 114 + kernel_trap(semaphore_timedwait_trap,-38,3) 115 + kernel_trap(semaphore_timedwait_signal_trap,-39,4) 116 + 117 + kernel_trap(_kernelrpc_mach_port_guard_trap,-41,5) 118 + kernel_trap(_kernelrpc_mach_port_unguard_trap,-42,4) 119 + kernel_trap(mach_generate_activity_id, -43, 3) 120 + 121 + kernel_trap(task_name_for_pid,-44,3) 122 + kernel_trap(task_for_pid,-45,3) 123 + kernel_trap(pid_for_task,-46,2) 124 + 125 + #if defined(__LP64__) 126 + kernel_trap(macx_swapon,-48, 4) 127 + kernel_trap(macx_swapoff,-49, 2) 128 + #else /* __LP64__ */ 129 + kernel_trap(macx_swapon,-48, 5) 130 + kernel_trap(macx_swapoff,-49, 3) 131 + #endif /* __LP64__ */ 132 + kernel_trap(macx_triggers,-51, 4) 133 + kernel_trap(macx_backing_store_suspend,-52, 1) 134 + kernel_trap(macx_backing_store_recovery,-53, 1) 135 + 136 + /* These are currently used by pthreads even on LP64 */ 137 + /* But as soon as that is fixed - they will go away there */ 138 + kernel_trap(swtch_pri,-59,1) 139 + kernel_trap(swtch,-60,0) 140 + 141 + kernel_trap(syscall_thread_switch,-61,3) 142 + kernel_trap(clock_sleep_trap,-62,5) 143 + 144 + /* voucher traps */ 145 + kernel_trap(host_create_mach_voucher_trap,-70,4) 146 + /* mach_voucher_extract_attr_content */ 147 + kernel_trap(mach_voucher_extract_attr_recipe_trap,-72,4) 148 + /* mach_voucher_extract_all_attr_recipes */ 149 + /* mach_voucher_attr_command */ 150 + /* mach_voucher_debug_info */ 151 + 152 + kernel_trap(mach_timebase_info_trap,-89,1) 153 + 154 + #if defined(__LP64__) 155 + /* unit64_t arguments passed in one register in LP64 */ 156 + kernel_trap(mach_wait_until,-90,1) 157 + #else /* __LP64__ */ 158 + kernel_trap(mach_wait_until,-90,2) 159 + #endif /* __LP64__ */ 160 + 161 + kernel_trap(mk_timer_create,-91,0) 162 + kernel_trap(mk_timer_destroy,-92,1) 163 + 164 + #if defined(__LP64__) 165 + /* unit64_t arguments passed in one register in LP64 */ 166 + kernel_trap(mk_timer_arm,-93,2) 167 + #else /* __LP64__ */ 168 + kernel_trap(mk_timer_arm,-93,3) 169 + #endif /* __LP64__ */ 170 + 171 + kernel_trap(mk_timer_cancel,-94,2) 172 + 173 + /* 174 + * N.B: Trap #-100 is in use by IOTrap.s in the IOKit Framework 175 + * (iokit_user_client_trap) 176 + */ 177 + #endif /* _MACH_SYSCALL_SW_H_ */ 178 + 179 + #endif /* PRIVATE */
+1
src/CMakeLists.txt
··· 99 99 add_subdirectory(libresolv) 100 100 add_subdirectory(libstdcxx) 101 101 add_subdirectory(libffi) 102 + add_subdirectory(xtrace) 102 103 add_subdirectory(dyld-apple) 103 104 add_subdirectory(external/objc4/runtime) 104 105 add_subdirectory(external/syslog/libsystem_asl.tproj)
+1
src/kernel/emulation/linux/misc/thread_selfid.c
··· 3 3 #include "../errno.h" 4 4 #include <linux-syscalls/linux.h> 5 5 6 + VISIBLE // made visible for xtrace 6 7 long sys_thread_selfid(void) 7 8 { 8 9 int ret;
+29 -2
src/kernel/mach_server/client/darling_mach_syscall.S
··· 9 9 jnl Lpositive 10 10 negl %eax 11 11 Lpositive: 12 + Lentry_hook: 13 + .space 13, 0x90 12 14 movq ___mach_syscall_table@GOTPCREL(%rip), %r10 13 15 movq (%r10,%rax,8), %r10 14 16 test %r10, %r10 ··· 20 22 pushq %r11 21 23 call *%r10 22 24 addq $16, %rsp 25 + .std_ret: 26 + Lexit_hook: 27 + .space 13, 0x90 23 28 ret 24 29 .no_sys: 25 30 movq %rax, %rdi 26 31 call ___unknown_mach_syscall 27 - ret 32 + jmp .std_ret 33 + 34 + .section __DATA,__data 35 + .globl __darling_mach_syscall_entry 36 + .globl __darling_mach_syscall_exit 37 + __darling_mach_syscall_entry: 38 + .quad Lentry_hook 39 + __darling_mach_syscall_exit: 40 + .quad Lexit_hook 28 41 29 42 #elif defined(__i386__) 30 43 ··· 37 50 jnl Lpositive 38 51 negl %eax 39 52 Lpositive: 53 + Lentry_hook: 54 + .space 6, 0x90 40 55 calll 1f 41 56 1: 42 57 popl %ecx ··· 56 71 subl $24, %esp 57 72 call *%eax 58 73 addl $24, %esp 74 + .std_ret: 75 + Lexit_hook: 76 + .space 6, 0x90 59 77 ret 60 78 .no_sys: 61 79 pushl %ecx 62 80 call ___unknown_mach_syscall 63 81 addl $4, %esp 64 - ret 82 + jmp .std_ret 65 83 66 84 .section __IMPORT,__pointers,non_lazy_symbol_pointers 67 85 L___mach_syscall_table$non_lazy_ptr: 68 86 .indirect_symbol ___mach_syscall_table 69 87 .long 0 88 + 89 + .section __DATA,__data 90 + .globl __darling_mach_syscall_entry 91 + .globl __darling_mach_syscall_exit 92 + __darling_mach_syscall_entry: 93 + .long Lentry_hook 94 + __darling_mach_syscall_exit: 95 + .long Lexit_hook 96 + 70 97 71 98 .subsections_via_symbols 72 99
+22
src/xtrace/CMakeLists.txt
··· 1 + project(xtrace) 2 + 3 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc") 4 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -fno-exceptions -fno-rtti -std=c++11") 5 + 6 + include(darling_lib) 7 + 8 + set(xtrace_sources 9 + xtracelib.c 10 + simple.c 11 + trampoline.S 12 + mach_trace.cpp 13 + ) 14 + 15 + set(DYLIB_INSTALL_NAME "/usr/lib/darling/libxtrace.dylib") 16 + add_darling_library(xtracelib SHARED ${xtrace_sources}) 17 + set_target_properties(xtracelib PROPERTIES OUTPUT_NAME "xtrace") 18 + target_link_libraries(xtracelib system) 19 + 20 + install(TARGETS xtracelib DESTINATION libexec/darling/usr/lib/darling) 21 + install(FILES xtrace DESTINATION libexec/darling/usr/bin) 22 +
+153
src/xtrace/mach_trace.cpp
··· 1 + #include "simple.h" 2 + #include <unistd.h> 3 + #include <pthread.h> 4 + #include "xtracelib.h" 5 + 6 + _Thread_local int mach_call_nr = -1; 7 + 8 + static void print_kern_return(char* buf, uintptr_t rv); 9 + static void print_port_return(char* buf, uintptr_t rv); 10 + static void print_int_return(char* buf, uintptr_t rv); 11 + static void print_empty(char* buf, void* args[]); 12 + 13 + static const struct calldef mach_defs[128] = { 14 + [10] = { "_kernelrpc_mach_vm_allocate_trap", NULL, print_kern_return }, 15 + [12] = { "_kernelrpc_mach_vm_deallocate_trap", NULL, print_kern_return }, 16 + [14] = { "_kernelrpc_mach_vm_protect_trap", NULL, print_kern_return }, 17 + [15] = { "_kernelrpc_mach_vm_map_trap", NULL, print_kern_return }, 18 + [16] = { "_kernelrpc_mach_port_allocate_trap", NULL, print_kern_return }, 19 + [17] = { "_kernelrpc_mach_port_destroy_trap", NULL, print_kern_return }, 20 + [18] = { "_kernelrpc_mach_port_deallocate_trap", [](char* buf, void* args[]) { __simple_sprintf(buf, "task=%d, name=%d", args[0], args[1]); }, print_kern_return }, 21 + [19] = { "_kernelrpc_mach_port_mod_refs_trap", NULL, print_kern_return }, 22 + [20] = { "_kernelrpc_mach_port_move_member_trap", NULL, print_kern_return }, 23 + [21] = { "_kernelrpc_mach_port_insert_right_trap", NULL, print_kern_return }, 24 + [22] = { "_kernelrpc_mach_port_insert_member_trap", NULL, print_kern_return }, 25 + [23] = { "_kernelrpc_mach_port_extract_member_trap", NULL, print_kern_return }, 26 + [24] = { "_kernelrpc_mach_port_construct_trap", NULL, print_kern_return }, 27 + [25] = { "_kernelrpc_mach_port_destruct_trap", NULL, print_kern_return }, 28 + [26] = { "mach_reply_port", print_empty, print_port_return }, 29 + [27] = { "thread_self_trap", print_empty, print_port_return }, 30 + [28] = { "task_self_trap", print_empty, print_port_return }, 31 + [29] = { "host_self_trap", print_empty, print_port_return }, 32 + [31] = { "mach_msg_trap", NULL, print_kern_return }, 33 + [32] = { "mach_msg_overwrite_trap", NULL, print_kern_return }, 34 + [33] = { "semaphore_signal_trap", NULL, print_kern_return }, 35 + [34] = { "semaphore_signal_all_trap", NULL, print_kern_return }, 36 + [35] = { "semaphore_signal_thread_trap", NULL, print_kern_return }, 37 + [36] = { "semaphore_wait_trap", NULL, print_kern_return }, 38 + [37] = { "semaphore_wait_signal_trap", NULL, print_kern_return }, 39 + [38] = { "semaphore_timedwait_trap", NULL, print_kern_return }, 40 + [39] = { "semaphore_timedwait_signal_trap", NULL, print_kern_return }, 41 + [41] = { "_kernelrpc_mach_port_guard_trap", NULL, print_kern_return }, 42 + [42] = { "_kernelrpc_mach_port_unguard_trap", NULL, print_kern_return }, 43 + [43] = { "mach_generate_activity_id", NULL, print_kern_return }, 44 + [44] = { "task_name_for_pid", NULL, print_kern_return }, 45 + [45] = { "task_for_pid", NULL, print_port_return }, 46 + [46] = { "pid_for_task", NULL, print_int_return }, 47 + [48] = { "macx_swapon", NULL, print_kern_return }, 48 + [49] = { "macx_swapoff", NULL, print_kern_return }, 49 + [51] = { "macx_triggers", NULL, print_kern_return }, 50 + [52] = { "macx_backing_store_suspend", NULL, print_kern_return }, 51 + [53] = { "macx_backing_store_recovery", NULL, print_kern_return }, 52 + [59] = { "swtch_pri", NULL, print_kern_return }, 53 + [60] = { "swtch", NULL, print_kern_return }, 54 + [61] = { "syscall_thread_switch", NULL, print_kern_return }, 55 + [62] = { "clock_sleep_trap", NULL, print_kern_return }, 56 + [89] = { "mach_timebase_info_trap", NULL, print_kern_return }, 57 + [90] = { "mach_wait_until", NULL, print_kern_return }, 58 + [91] = { "mk_timer_create", print_empty, print_port_return }, 59 + [92] = { "mk_timer_destroy", NULL, print_kern_return }, 60 + [93] = { "mk_timer_arm", NULL, print_kern_return }, 61 + [94] = { "mk_timer_cancel", NULL, print_kern_return }, 62 + }; 63 + 64 + static const char* kern_return_values[] = { 65 + "KERN_SUCCESS", 66 + "KERN_INVALID_ADDRESS", 67 + "KERN_PROTECTION_FAILURE", 68 + "KERN_NO_SPACE", 69 + "KERN_INVALID_ARGUMENT", 70 + "KERN_FAILURE", 71 + "KERN_RESOURCE_SHORTAGE", 72 + "KERN_NOT_RECEIVER", 73 + "KERN_NO_ACCESS", 74 + "KERN_MEMORY_FAILURE", 75 + "KERN_MEMORY_ERROR", 76 + "KERN_ALREADY_IN_SET", 77 + "KERN_NOT_IN_SET", 78 + "KERN_NAME_EXISTS", 79 + "KERN_ABORTED", 80 + "KERN_INVALID_NAME", 81 + "KERN_INVALID_TASK", 82 + "KERN_INVALID_RIGHT", 83 + "KERN_INVALID_VALUE", 84 + "KERN_UREFS_OVERFLOW", 85 + "KERN_INVALID_CAPABILITY", 86 + "KERN_RIGHT_EXISTS", 87 + "KERN_INVALID_HOST", 88 + "KERN_MEMORY_PRESENT", 89 + "KERN_MEMORY_DATA_MOVED", 90 + "KERN_MEMORY_RESTART_COPY", 91 + "KERN_INVALID_PROCESSOR_SET", 92 + "KERN_POLICY_LIMIT", 93 + "KERN_INVALID_POLICY", 94 + "KERN_INVALID_OBJECT", 95 + "KERN_ALREADY_WAITING", 96 + "KERN_DEFAULT_SET", 97 + "KERN_EXCEPTION_PROTECTED", 98 + "KERN_INVALID_LEDGER", 99 + "KERN_INVALID_MEMORY_CONTROL", 100 + "KERN_INVALID_SECURITY", 101 + "KERN_NOT_DEPRESSED", 102 + "KERN_TERMINATED", 103 + "KERN_LOCK_SET_DESTROYED", 104 + "KERN_LOCK_UNSTABLE", 105 + "KERN_LOCK_OWNED", 106 + "KERN_LOCK_OWNED_SELF", 107 + "KERN_SEMAPHORE_DESTROYED", 108 + "KERN_RPC_SERVER_TERMINATED", 109 + "KERN_RPC_TERMINATE_ORPHAN", 110 + "KERN_RPC_CONTINUE_ORPHAN", 111 + "KERN_NOT_SUPPORTED", 112 + "KERN_NODE_DOWN", 113 + "KERN_NOT_WAITING", 114 + "KERN_OPERATION_TIMED_OUT", 115 + "KERN_CODESIGN_ERROR", 116 + "KERN_POLICY_STATIC", 117 + "KERN_INSUFFICIENT_BUFFER_SIZE", 118 + }; 119 + 120 + extern "C" 121 + void darling_mach_syscall_entry_print(int nr, void* args[]) 122 + { 123 + mach_call_nr = nr; 124 + handle_generic_entry(mach_defs, "mach", mach_call_nr, args); 125 + } 126 + 127 + extern "C" 128 + void darling_mach_syscall_exit_print(uintptr_t retval) 129 + { 130 + handle_generic_exit(mach_defs, "mach", mach_call_nr, retval); 131 + mach_call_nr = -1; 132 + } 133 + 134 + static void print_kern_return(char* buf, uintptr_t rv) 135 + { 136 + __simple_sprintf(buf, kern_return_values[rv]); 137 + } 138 + 139 + static void print_port_return(char* buf, uintptr_t rv) 140 + { 141 + __simple_sprintf(buf, "port right %d", rv); 142 + } 143 + 144 + static void print_int_return(char* buf, uintptr_t rv) 145 + { 146 + __simple_sprintf(buf, "%d", rv); 147 + } 148 + 149 + static void print_empty(char* buf, void* args[]) 150 + { 151 + *buf = 0; 152 + } 153 +
+195
src/xtrace/simple.c
··· 1 + #include "simple.h" 2 + #include <stdarg.h> 3 + #include <stddef.h> 4 + #include <unistd.h> 5 + 6 + void __simple_vsprintf(char* buf, const char* format, va_list vl); 7 + extern char* memchr(char* buf, int c, __SIZE_TYPE__ n); 8 + 9 + int __simple_strlen(const char* text) 10 + { 11 + int len = 0; 12 + while (*text++) 13 + len++; 14 + return len; 15 + } 16 + 17 + static inline int abs(int n) 18 + { 19 + return (n < 0) ? -n : n; 20 + } 21 + 22 + void __simple_vsprintf(char* buf, const char* format, va_list vl) 23 + { 24 + while (*format) 25 + { 26 + if (*format == '%') 27 + { 28 + format++; 29 + if (!*format) 30 + break; 31 + 32 + switch (*format) 33 + { 34 + case '%': 35 + *buf++ = '%'; 36 + break; 37 + case 's': 38 + { 39 + const char* str = va_arg(vl, const char*); 40 + if (!str) 41 + str = "(null)"; 42 + 43 + while (*str) 44 + { 45 + *buf++ = *str; 46 + str++; 47 + } 48 + break; 49 + } 50 + case 'd': 51 + { 52 + int num = va_arg(vl, int); 53 + char temp[16]; 54 + int count = 0; 55 + 56 + if (num < 0) 57 + *buf++ = '-'; 58 + 59 + do 60 + { 61 + temp[count++] = '0' + abs(num % 10); 62 + num /= 10; 63 + } 64 + while (num > 0); 65 + 66 + while (count--) 67 + *buf++ = temp[count]; 68 + 69 + break; 70 + } 71 + case 'p': 72 + case 'x': 73 + { 74 + unsigned long num = va_arg(vl, unsigned long); 75 + char temp[40]; 76 + int count = 0; 77 + 78 + if (*format == 'p') 79 + { 80 + *buf++ = '0'; 81 + *buf++ = 'x'; 82 + } 83 + 84 + do 85 + { 86 + int c = (num % 16); 87 + 88 + if (c < 10) 89 + temp[count++] = '0' + c; 90 + else 91 + temp[count++] = 'A' + (c - 10); 92 + num /= 16; 93 + } 94 + while (num > 0); 95 + 96 + while (count--) 97 + *buf++ = temp[count]; 98 + 99 + break; 100 + 101 + } 102 + } 103 + 104 + format++; 105 + } 106 + else 107 + { 108 + *buf++ = *format; 109 + format++; 110 + } 111 + } 112 + 113 + *buf = 0; 114 + } 115 + 116 + __attribute__ ((visibility ("default"))) 117 + void __simple_printf(const char* format, ...) 118 + { 119 + char buffer[512]; 120 + va_list vl; 121 + 122 + va_start(vl, format); 123 + __simple_vsprintf(buffer, format, vl); 124 + va_end(vl); 125 + 126 + write(2, buffer, __simple_strlen(buffer)); 127 + } 128 + 129 + void __simple_sprintf(char *buffer, const char* format, ...) 130 + { 131 + va_list vl; 132 + 133 + va_start(vl, format); 134 + __simple_vsprintf(buffer, format, vl); 135 + va_end(vl); 136 + } 137 + 138 + #ifdef isdigit 139 + #undef isdigit 140 + #endif 141 + 142 + static int isdigit(char c) 143 + { 144 + return c >= '0' && c <= '9'; 145 + } 146 + static int isdigit16(char c) 147 + { 148 + if (isdigit(c)) 149 + return 1; 150 + if (c >= 'a' && c <= 'f') 151 + return 1; 152 + if (c >= 'A' && c <= 'F') 153 + return 1; 154 + return 0; 155 + } 156 + 157 + unsigned long long __simple_atoi(const char* str, const char** endp) 158 + { 159 + unsigned long long value = 0; 160 + 161 + while (isdigit(*str)) 162 + { 163 + value *= 10; 164 + value += *str - '0'; 165 + str++; 166 + } 167 + if (endp) 168 + *endp = str; 169 + 170 + return value; 171 + } 172 + 173 + unsigned long long __simple_atoi16(const char* str, const char** endp) 174 + { 175 + unsigned long long value = 0; 176 + 177 + while (isdigit16(*str)) 178 + { 179 + value *= 16; 180 + 181 + if (*str >= '0' && *str <= '9') 182 + value += *str - '0'; 183 + else if (*str >= 'a' && *str <= 'f') 184 + value += 10 + (*str - 'a'); 185 + else if (*str >= 'A' && *str < 'F') 186 + value += 10 + (*str - 'A'); 187 + 188 + str++; 189 + } 190 + if (endp) 191 + *endp = str; 192 + 193 + return value; 194 + } 195 +
+20
src/xtrace/simple.h
··· 1 + #ifndef LINUX_DEBUG_H 2 + #define LINUX_DEBUG_H 3 + 4 + #ifdef __cplusplus 5 + extern "C" { 6 + #endif 7 + 8 + void __simple_printf(const char* format, ...); 9 + void __simple_sprintf(char *buffer, const char* format, ...); 10 + int __simple_strlen(const char* str); 11 + 12 + unsigned long long __simple_atoi(const char* str, const char** endp); 13 + unsigned long long __simple_atoi16(const char* str, const char** endp); 14 + 15 + #ifdef __cplusplus 16 + } 17 + #endif 18 + 19 + #endif 20 +
+37
src/xtrace/trampoline.S
··· 1 + .macro trampoline_enter 2 + push %r9 3 + push %r8 4 + push %rcx 5 + push %rdx 6 + push %rsi 7 + push %rdi 8 + push %rax 9 + movq %rax, %rdi 10 + leaq 8(%rsp), %rsi 11 + .endmacro 12 + 13 + .macro trampoline_leave 14 + pop %rax 15 + pop %rdi 16 + pop %rsi 17 + pop %rdx 18 + pop %rcx 19 + pop %r8 20 + pop %r9 21 + .endmacro 22 + 23 + .private_extern _darling_mach_syscall_entry_trampoline 24 + _darling_mach_syscall_entry_trampoline: 25 + trampoline_enter 26 + call _darling_mach_syscall_entry_print 27 + trampoline_leave 28 + ret 29 + 30 + .private_extern _darling_mach_syscall_exit_trampoline 31 + _darling_mach_syscall_exit_trampoline: 32 + trampoline_enter 33 + call _darling_mach_syscall_exit_print 34 + trampoline_leave 35 + ret 36 + 37 +
+5
src/xtrace/xtrace
··· 1 + #!/bin/sh 2 + 3 + export DYLD_INSERT_LIBRARIES="/usr/lib/darling/libxtrace.dylib" 4 + exec "$@" 5 +
+86
src/xtrace/xtracelib.c
··· 1 + #include <unistd.h> 2 + #include <sys/mman.h> 3 + #include <stdint.h> 4 + #include <pthread.h> 5 + #include <string.h> 6 + #include "simple.h" 7 + #include "xtracelib.h" 8 + 9 + // Defined in assembly 10 + extern void darling_mach_syscall_entry_trampoline(void); 11 + extern void darling_mach_syscall_exit_trampoline(void); 12 + extern int sys_thread_selfid(void); 13 + 14 + #ifdef __x86_64__ 15 + struct hook 16 + { 17 + uint8_t movabs[2]; 18 + uint64_t addr; 19 + uint8_t call[3]; 20 + } 21 + __attribute__((packed)); 22 + #endif 23 + 24 + // Defined in libsystem_kernel 25 + extern struct hook* _darling_mach_syscall_entry; 26 + extern struct hook* _darling_mach_syscall_exit; 27 + 28 + __attribute__((constructor)) 29 + void xtrace_setup() 30 + { 31 + uintptr_t area = (uintptr_t)_darling_mach_syscall_entry; 32 + 33 + // __asm__("int3"); 34 + area &= ~(4096-1); 35 + 36 + mprotect((void*) area, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); 37 + 38 + _darling_mach_syscall_entry->movabs[0] = 0x49; 39 + _darling_mach_syscall_entry->movabs[1] = 0xbc; 40 + _darling_mach_syscall_entry->call[0] = 0x41; 41 + _darling_mach_syscall_entry->call[1] = 0xff; 42 + _darling_mach_syscall_entry->call[2] = 0xd4; 43 + 44 + _darling_mach_syscall_exit->movabs[0] = 0x49; 45 + _darling_mach_syscall_exit->movabs[1] = 0xbc; 46 + _darling_mach_syscall_exit->call[0] = 0x41; 47 + _darling_mach_syscall_exit->call[1] = 0xff; 48 + _darling_mach_syscall_exit->call[2] = 0xd4; 49 + 50 + _darling_mach_syscall_entry->addr = (uint64_t)darling_mach_syscall_entry_trampoline; 51 + _darling_mach_syscall_exit->addr = (uint64_t)darling_mach_syscall_exit_trampoline; 52 + 53 + mprotect((void*) area, 4096, PROT_READ | PROT_EXEC); 54 + } 55 + 56 + void handle_generic_entry(const struct calldef* defs, const char* type, int nr, void* args[]) 57 + { 58 + if (defs[nr].name != NULL) 59 + { 60 + char args_buf[4096]; 61 + if (defs[nr].print_args != NULL) 62 + defs[nr].print_args(args_buf, &args[1]); // because args[0] contains %rax 63 + else 64 + strcpy(args_buf, "..."); 65 + __simple_printf("[%d] %s (%s)\n", sys_thread_selfid(), defs[nr].name, args_buf); 66 + } 67 + else 68 + __simple_printf("[%d] %s %d (...)\n", sys_thread_selfid(), type, nr); 69 + } 70 + 71 + 72 + void handle_generic_exit(const struct calldef* defs, const char* type, int nr, uintptr_t retval) 73 + { 74 + if (defs[nr].name != NULL) 75 + { 76 + char args_buf[4096]; 77 + if (defs[nr].print_retval != NULL) 78 + defs[nr].print_retval(args_buf, retval); 79 + else 80 + __simple_sprintf(args_buf, "0x%x\n", retval); 81 + __simple_printf("[%d]\t%s () -> %s\n", sys_thread_selfid(), defs[nr].name, args_buf); 82 + } 83 + else 84 + __simple_printf("[%d]\t%s %d () -> 0x%x\n", sys_thread_selfid(), type, nr, retval); 85 + } 86 +
+24
src/xtrace/xtracelib.h
··· 1 + #ifndef _XTRACELIB_H_ 2 + #define _XTRACELIB_H_ 3 + #include <stdint.h> 4 + 5 + struct calldef 6 + { 7 + const char* name; 8 + void (*print_args)(char*, void* args[]); 9 + void (*print_retval)(char*, uintptr_t rv); 10 + }; 11 + 12 + #ifdef __cplusplus 13 + extern "C" { 14 + #endif 15 + 16 + void handle_generic_entry(const struct calldef* defs, const char* type, int nr, void* args[]); 17 + void handle_generic_exit(const struct calldef* defs, const char* type, int nr, uintptr_t retval); 18 + 19 + #ifdef __cplusplus 20 + } 21 + #endif 22 + 23 + #endif 24 +