this repo has no description
1
fork

Configure Feed

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

Some initial work on ptrace/SIGEXC support

+208 -21
+7 -1
src/kernel/emulation/linux/CMakeLists.txt
··· 15 15 16 16 17 17 include_directories(${CMAKE_SOURCE_DIR}/src/startup) 18 - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 18 + 19 + # include src/startup for rtsig.h 20 + include_directories(${CMAKE_CURRENT_SOURCE_DIR} 21 + ${CMAKE_BINARY_DIR}/src/startup 22 + ) 19 23 20 24 set(emulation_sources 21 25 elfcalls_wrapper.c ··· 132 136 signal/sigprocmask.c 133 137 signal/sig_restorer.S 134 138 signal/sigsuspend.c 139 + signal/sigexc.c 135 140 misc/ptrace.c 136 141 misc/getentropy.c 137 142 misc/syscall.c ··· 291 296 add_library(emulation OBJECT ${emulation_sources}) 292 297 add_library(emulation_dyld OBJECT ${emulation_sources}) 293 298 set_target_properties(emulation_dyld PROPERTIES COMPILE_FLAGS "-ffunction-sections -DVARIANT_DYLD") 299 + add_dependencies(emulation rtsig_h) 294 300 295 301 make_fat(emulation) 296 302 make_fat(emulation_dyld)
+2
src/kernel/emulation/linux/mach/mach_traps.c
··· 518 518 }; 519 519 // Sleep for 1ms 520 520 __linux_nanosleep(&tv, &tv); 521 + 522 + // TODO: we could implement this with yield_to() in LKM 521 523 return KERN_SUCCESS; 522 524 } 523 525
+13 -14
src/kernel/emulation/linux/process/wait4.c
··· 3 3 #include "../errno.h" 4 4 #include "../signal/duct_signals.h" 5 5 #include "../misc/ptrace.h" 6 + #include "../mach/lkm.h" 7 + #include "../../../../lkm/api.h" 6 8 #include <sys/signal.h> 7 9 #include <stddef.h> 8 10 #include <linux-syscalls/linux.h> ··· 39 41 signal = signum_linux_to_bsd(signal); 40 42 *status = (*status & 0x7f) | (signal << 8); 41 43 42 - switch (signal) 44 + if (lkm_call(NR_get_tracer, (void*)(long) ret) == getpid()) 43 45 { 44 - case SIGCONT: 45 - case SIGSTOP: 46 - case SIGTSTP: 47 - case SIGTTIN: 48 - case SIGTTOU: 49 - // It is standard behavior that these signals stop (resume) the process 50 - break; 51 - default: 52 - // We are probably ptracing the target process. 53 - // Allow the execution to continue so that the ptraced process can translate 54 - // the signal into a Mach message. 55 - sys_ptrace(PT_CONTINUE, ret, NULL, signal); 56 - goto restart; 46 + // We are ptracing the target process. 47 + // Allow the execution to continue so that the ptraced process can translate 48 + // the signal into a Mach message. 49 + if (signal == SIGSTOP) 50 + { 51 + // TODO: notify target process it has been SIGSTOP'ed via sigqueue 52 + } 53 + 54 + sys_ptrace(PT_CONTINUE, ret, NULL, signal); 55 + goto restart; 57 56 } 58 57 } 59 58
-1
src/kernel/emulation/linux/signal/duct_signals.h
··· 36 36 #define LINUX_SIGPWR 30 37 37 #define LINUX_SIGSYS 31 38 38 #define LINUX_SIGUNUSED 31 39 - #define LINUX_SIGRTMIN 32 40 39 #define LINUX_SA_NOCLDSTOP 0x00000001u 41 40 #define LINUX_SA_NOCLDWAIT 0x00000002u 42 41 #define LINUX_SA_SIGINFO 0x00000004u
+13 -5
src/kernel/emulation/linux/signal/sigaction.c
··· 4 4 #include "../simple.h" 5 5 #include <linux-syscalls/linux.h> 6 6 #include <stddef.h> 7 + #include "sigexc.h" 7 8 #include "../../../../../platform-include/sys/errno.h" 8 9 9 - static void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt); 10 10 static int sigflags_bsd_to_linux(int flags); 11 11 static int sigflags_linux_to_bsd(int flags); 12 12 extern void sig_restorer(void); ··· 17 17 18 18 // Libc uses only one trampoline 19 19 void (*sa_tramp)(void*, int, int, struct bsd_siginfo*, void*) = 0; 20 - static bsd_sig_handler* sig_handlers[32]; 20 + bsd_sig_handler* sig_handlers[32]; 21 + int sig_flags[32]; 22 + unsigned int sig_masks[32]; 21 23 22 24 long sys_sigaction(int signum, const struct bsd___sigaction* nsa, struct bsd_sigaction* osa) 23 25 { ··· 42 44 if (nsa != NULL) 43 45 { 44 46 sa_tramp = nsa->sa_tramp; 45 - if (nsa->sa_sigaction != SIG_DFL && nsa->sa_sigaction != SIG_IGN 47 + if (darling_am_i_ptraced()) 48 + { 49 + sa.sa_sigaction = &sigexc_handler; 50 + } 51 + else if (nsa->sa_sigaction != SIG_DFL && nsa->sa_sigaction != SIG_IGN 46 52 && nsa->sa_sigaction != SIG_ERR) 47 53 { 48 54 sa.sa_sigaction = &handler_linux_to_bsd; ··· 71 77 osa->sa_flags = sigflags_linux_to_bsd(olsa.sa_flags); 72 78 } 73 79 74 - if (nsa != NULL) 80 + if (nsa != NULL && ret >= 0) 75 81 { 76 82 // __simple_printf("Saving handler for signal %d: %d\n", linux_signum, nsa->sa_sigaction); 77 83 sig_handlers[linux_signum] = nsa->sa_sigaction; 84 + sig_flags[linux_signum] = sa.sa_flags; 85 + sig_masks[linux_signum] = sa.sa_mask; 78 86 } 79 87 80 88 return 0; ··· 120 128 #undef copyreg 121 129 } 122 130 123 - static void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt) 131 + void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt) 124 132 { 125 133 int bsd_signum; 126 134 struct bsd_siginfo binfo;
+6
src/kernel/emulation/linux/signal/sigaction.h
··· 51 51 union 52 52 { 53 53 int _pad[__SI_PAD_SIZE]; 54 + unsigned long si_value; 54 55 }; 55 56 }; 56 57 ··· 193 194 unsigned long uc_mcsize; 194 195 struct bsd_mcontext* uc_mcontext; 195 196 }; 197 + 198 + void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt); 199 + extern bsd_sig_handler* sig_handlers[32]; 200 + extern int sig_flags[32]; 201 + extern unsigned int sig_masks[32]; 196 202 197 203 #endif 198 204
+113
src/kernel/emulation/linux/signal/sigexc.c
··· 1 + #include "sigexc.h" 2 + #include "../base.h" 3 + #include <stddef.h> 4 + #include <linux-syscalls/linux.h> 5 + 6 + // Support for Darwin debugging. 7 + // Unlike other Unix-like systems, macOS doesn't use wait() to handle events in the debugged process. 8 + 9 + static bool am_i_ptraced = false; 10 + static void handle_rt_signal(int signum); 11 + extern void sig_restorer(void); 12 + void darling_sigexc_uninstall(void); 13 + void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt); 14 + 15 + void sigexc_setup(void) 16 + { 17 + // Setup handler for SIGNAL_SIGEXC_TOGGLE and SIGNAL_SIGEXC_THUPDATE 18 + handle_rt_signal(SIGNAL_SIGEXC_TOGGLE); 19 + handle_rt_signal(SIGNAL_SIGEXC_THUPDATE); 20 + } 21 + 22 + static void handle_rt_signal(int signum) 23 + { 24 + struct linux_sigaction sa; 25 + sa.sa_sigaction = sigrt_handler; 26 + sa.sa_mask = 0; 27 + sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART; 28 + sa.sa_restorer = sig_restorer; 29 + 30 + LINUX_SYSCALL(__NR_rt_sigaction, signum, 31 + &sa, NULL, 32 + sizeof(sa.sa_mask)); 33 + } 34 + 35 + bool darling_am_i_ptraced(void) 36 + { 37 + return am_i_ptraced; 38 + } 39 + 40 + void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt) 41 + { 42 + if (signum == SIGNAL_SIGEXC_TOGGLE) 43 + { 44 + if (info->si_value == SIGRT_MAGIC_ENABLE_SIGEXC) 45 + { 46 + am_i_ptraced = true; 47 + darling_sigexc_self(); 48 + } 49 + else if (info->si_value == SIGRT_MAGIC_DISABLE_SIGEXC) 50 + { 51 + am_i_ptraced = false; 52 + darling_sigexc_uninstall(); 53 + } 54 + } 55 + else if (signum == SIGNAL_SIGEXC_THUPDATE) 56 + { 57 + // TODO: Change how a pending signal is handled 58 + // Use TLS? 59 + if (!am_i_ptraced) 60 + return; 61 + } 62 + } 63 + 64 + void darling_sigexc_self(void) 65 + { 66 + // Make sigexc_handler the handler for all signals in the process 67 + for (int i = 1; i <= 31; i++) 68 + { 69 + struct linux_sigaction sa; 70 + sa.sa_sigaction = sigrt_handler; 71 + sa.sa_mask = sig_masks[i]; 72 + sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART; 73 + sa.sa_restorer = sig_restorer; 74 + 75 + LINUX_SYSCALL(__NR_rt_sigaction, i, 76 + &sa, NULL, 77 + sizeof(sa.sa_mask)); 78 + } 79 + } 80 + void darling_sigexc_uninstall(void) 81 + { 82 + for (int i = 1; i <= 31; i++) 83 + { 84 + struct linux_sigaction sa; 85 + 86 + if (sig_handlers[i] == SIG_DFL || sig_handlers[i] != SIG_IGN 87 + || sig_handlers[i] != SIG_ERR) 88 + { 89 + sa.sa_sigaction = (linux_sig_handler*) sig_handlers[i]; 90 + } 91 + else 92 + sa.sa_sigaction = &handler_linux_to_bsd; 93 + 94 + sa.sa_mask = sig_masks[i]; 95 + sa.sa_flags = sig_flags[i]; 96 + sa.sa_restorer = sig_restorer; 97 + 98 + LINUX_SYSCALL(__NR_rt_sigaction, i, 99 + &sa, NULL, 100 + sizeof(sa.sa_mask)); 101 + } 102 + } 103 + 104 + void sigexc_handler(int linux_signum, struct linux_siginfo* info, void* ctxt) 105 + { 106 + // SIGSEGV + SIGBUS -> EXC_BAD_ACCESS 107 + // SIGTRAP -> EXC_BREAKPOINT 108 + // * -> EXC_SOFTWARE with EXC_SOFT_SIGNAL (e.g. SIGSTOP 109 + if (darling_am_i_ptraced()) 110 + { 111 + } 112 + } 113 +
+25
src/kernel/emulation/linux/signal/sigexc.h
··· 1 + #ifndef _SIGEXC_H 2 + #define _SIGEXC_H 3 + #include <stdbool.h> 4 + #include "rtsig.h" 5 + #include "sigaction.h" 6 + 7 + #define SIGNAL_SIGEXC_TOGGLE LINUX_SIGRTMIN 8 + #define SIGNAL_SIGEXC_THUPDATE (LINUX_SIGRTMIN + 1) 9 + 10 + #define SIGRT_MAGIC_ENABLE_SIGEXC 0xdebdeb01 11 + #define SIGRT_MAGIC_DISABLE_SIGEXC 0xdebdeb00 12 + #define SIGRT_ 13 + 14 + // Initializes this module 15 + void sigexc_setup(void); 16 + 17 + // Is this process currently traced by a debugger? 18 + bool darling_am_i_ptraced(void); 19 + 20 + // for PT_SIGEXC to handle this operation synchronously 21 + void darling_sigexc_self(void); 22 + void sigexc_handler(int linux_signum, struct linux_siginfo* info, void* ctxt); 23 + 24 + #endif 25 +
+4
src/startup/CMakeLists.txt
··· 59 59 add_executable(print_wrapped_elf wrapgen/print_wrapped_elf.cpp) 60 60 endif (DEFINED WITH_PRINT_WRAPPED_ELF) 61 61 62 + add_executable(rtsig rtsig.c) 63 + add_custom_command(OUTPUT rtsig.h DEPENDS rtsig COMMAND ${CMAKE_CURRENT_BINARY_DIR}/rtsig rtsig.h COMMENT "Determining available RT signals") 64 + add_custom_target(rtsig_h DEPENDS rtsig.h) 65 +
+25
src/startup/rtsig.c
··· 1 + #include <signal.h> 2 + #include <stdio.h> 3 + 4 + // Determine RT signal ranges without polluting the build environment with Linux system headers 5 + int main(int argc, char** argv) 6 + { 7 + FILE* output = stdout; 8 + 9 + if (argc > 1) 10 + { 11 + output = fopen(argv[1], "w"); 12 + if (!output) 13 + { 14 + perror("fopen"); 15 + return 1; 16 + } 17 + } 18 + 19 + fprintf(output, "#define LINUX_SIGRTMIN %d\n", SIGRTMIN); 20 + fprintf(output, "#define LINUX_SIGRTMAX %d\n", SIGRTMAX); 21 + 22 + fclose(output); 23 + return 0; 24 + } 25 +