···6666 else
6767 {
6868 // This triggers darling_sigexc_self() in the remote process.
6969- linux_sigqueue(pid, SIGNAL_SIGEXC_TOGGLE, SIGRT_MAGIC_ENABLE_SIGEXC);
6969+ ret = linux_sigqueue(pid, SIGNAL_SIGEXC_TOGGLE, SIGRT_MAGIC_ENABLE_SIGEXC);
7070+7171+ if (ret < 0)
7272+ ret = errno_linux_to_bsd(ret);
7373+ // This doesn't work if the process is stopped, e.g. when spawning a stopped
7474+ // process via posix_spawn(). So now we have to resume the process so that
7575+ // it gets the RT signal above and triggers a fake SIGSTOP on its own.
7676+ // int pstate = lkm_call(NR_pid_get_state, (void*)(long) pid);
7777+ // if (pstate & 4 /* __TASK_STOPPED */)
7878+ // sys_kill(pid, SIGCONT, 1);
7079 }
71807281 cmd = "PT_ATTACHEXC";
···151160 }
152161 }
153162163163+ char buf[128];
154164 if (cmd != NULL)
155155- __simple_printf("ptrace() req=%s, ret=%d\n", cmd, ret);
165165+ __simple_sprintf(buf, "ptrace() req=%s, ret=%d\n", cmd, ret);
156166 else
157157- __simple_printf("ptrace() req=%d\n", request);
167167+ __simple_sprintf(buf, "ptrace() req=%d\n", request);
168168+ lkm_call(0x1028, buf);
158169159170 return ret;
160171}
···4040static void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx);
4141#endif
42424343-void sigexc_setup(void)
4343+char xyzbuf[128];
4444+void sigexc_setup1(void)
4445{
4646+ lkm_call(0x1028, "sigexc_setup1()");
4547 // Setup handler for SIGNAL_SIGEXC_TOGGLE and SIGNAL_SIGEXC_THUPDATE
4648 handle_rt_signal(SIGNAL_SIGEXC_TOGGLE);
4749 handle_rt_signal(SIGNAL_SIGEXC_THUPDATE);
5050+}
5151+5252+void sigexc_setup2(void)
5353+{
5454+ lkm_call(0x1028, xyzbuf);
5555+ lkm_call(0x1028, "sigexc_setup2()\n");
5656+5757+ linux_sigset_t set;
5858+ set = (1ull << (SIGNAL_SIGEXC_TOGGLE-1));
5959+ set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1));
6060+6161+ LINUX_SYSCALL(__NR_rt_sigprocmask, 1 /* LINUX_SIG_UNBLOCK */,
6262+ &set, NULL, sizeof(linux_sigset_t));
48634964 // If we have a tracer (i.e. we are a new process after execve),
5065 // enable sigexc handling and send SIGTRAP to self to allow
5166 // the debugger to handle this situation.
5252- if (lkm_call(NR_get_tracer, NULL) != 0)
6767+ if (!am_i_ptraced && lkm_call(NR_get_tracer, NULL) != 0)
5368 {
5469 __simple_printf("the predecessor is traced\n");
5570 darling_sigexc_self();
···5772 }
5873}
59747575+void sigexc_setup(void)
7676+{
7777+ sigexc_setup1();
7878+ if (lkm_call(NR_started_suspended, 0))
7979+ {
8080+ // sigsuspend until resumed or debugger attached
8181+ linux_sigset_t set = -1ll;
8282+ set &= ~(1ull << (LINUX_SIGCONT-1));
8383+ set &= ~(1ull << (SIGNAL_SIGEXC_TOGGLE-1));
8484+ set &= ~(1ull << (SIGNAL_SIGEXC_THUPDATE-1));
8585+8686+ LINUX_SYSCALL(__NR_rt_sigsuspend, &set, 8);
8787+ }
8888+ sigexc_setup2();
8989+}
9090+6091static void handle_rt_signal(int signum)
6192{
6262- struct linux_sigaction sa;
9393+ int rv;
9494+ struct linux_sigaction sa;
9595+6396 sa.sa_sigaction = sigrt_handler;
6497 sa.sa_mask = 0;
6598 sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART;
6699 sa.sa_restorer = sig_restorer;
671006868- LINUX_SYSCALL(__NR_rt_sigaction, signum,
101101+ rv = LINUX_SYSCALL(__NR_rt_sigaction, signum,
69102 &sa, NULL,
70103 sizeof(sa.sa_mask));
104104+105105+ //char buf[128];
106106+ __simple_sprintf(xyzbuf, "Setting handler for RT signal %d: %d", signum, rv);
107107+ //lkm_call(0x1028, buf);
71108}
7210973110bool darling_am_i_ptraced(void)
···7711478115void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt)
79116{
8080- __simple_printf("sigrt_handler signum=%d\n", signum);
117117+ char buf[128];
118118+ __simple_sprintf(buf, "sigrt_handler signum=%d, si_value=%x\n", signum, info->si_value);
119119+ lkm_call(0x1028, buf);
81120 if (signum == SIGNAL_SIGEXC_TOGGLE)
82121 {
8383- if (info->si_value == SIGRT_MAGIC_ENABLE_SIGEXC)
122122+ if (((uint32_t) info->si_value) == SIGRT_MAGIC_ENABLE_SIGEXC)
84123 {
85124 darling_sigexc_self();
8612587126 // Stop on attach
88127 sigexc_handler(LINUX_SIGSTOP, NULL, NULL);
89128 }
9090- else if (info->si_value == SIGRT_MAGIC_DISABLE_SIGEXC)
129129+ else if (((uint32_t) info->si_value) == SIGRT_MAGIC_DISABLE_SIGEXC)
91130 {
92131 darling_sigexc_uninstall();
93132 }
···121160{
122161 am_i_ptraced = true;
123162124124- __simple_printf("darling_sigexc_self()\n");
163163+ lkm_call(0x1028, "darling_sigexc_self()\n");
125164 // Make sigexc_handler the handler for all signals in the process
126165 for (int i = 1; i <= 31; i++)
127166 {
167167+ if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL)
168168+ continue;
169169+128170 struct linux_sigaction sa;
129171 sa.sa_sigaction = (linux_sig_handler*) sigexc_handler;
130130- sa.sa_mask = 0xffffffff; // all other standard Unix signals should be blocked while the handler is run
172172+ sa.sa_mask = 0x7fffffff; // all other standard Unix signals should be blocked while the handler is run
131173 sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK;
132174 sa.sa_restorer = sig_restorer;
133175···150192 __simple_printf("darling_sigexc_uninstall()\n");
151193 for (int i = 1; i <= 31; i++)
152194 {
195195+ if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL)
196196+ continue;
197197+153198 struct linux_sigaction sa;
154199155200 if (sig_handlers[i] == SIG_DFL || sig_handlers[i] != SIG_IGN
···201246202247void sigexc_handler(int linux_signum, struct linux_siginfo* info, struct linux_ucontext* ctxt)
203248{
204204- __simple_printf("sigexc_handler(%d)\n", linux_signum);
249249+ char buf[128];
250250+ __simple_sprintf(buf, "sigexc_handler(%d, %p)\n", linux_signum, info);
251251+ lkm_call(0x1028, buf);
252252+205253 if (!darling_am_i_ptraced())
206254 {
207255 __simple_printf("NOT TRACED!\n");
···234282235283 switch (bsd_signum)
236284 {
237237- case SIGSEGV:
238238- mach_exception = EXC_BAD_ACCESS;
239239- codes[0] = EXC_I386_GPFLT;
240240- break;
241241- case SIGBUS:
242242- mach_exception = EXC_BAD_ACCESS;
243243- codes[0] = EXC_I386_ALIGNFLT;
244244- break;
245245- case SIGTRAP:
246246- mach_exception = EXC_BREAKPOINT;
247247- codes[0] = EXC_I386_BPT;
248248- break;
249249- case SIGILL:
250250- mach_exception = EXC_BAD_INSTRUCTION;
251251- codes[0] = EXC_I386_INVOP;
252252- break;
253253- case SIGFPE:
254254- mach_exception = EXC_ARITHMETIC;
255255- codes[0] = info->si_code;
256256- break;
285285+ // Only real exceptions produced by the CPU get translated to these
286286+ // Mach exceptions. The rest comes as EXC_SOFTWARE.
287287+ if (info != NULL && info->si_code == 0x80 /* SI_KERNEL */)
288288+ {
289289+ case SIGSEGV:
290290+ mach_exception = EXC_BAD_ACCESS;
291291+ codes[0] = EXC_I386_GPFLT;
292292+ break;
293293+ case SIGBUS:
294294+ mach_exception = EXC_BAD_ACCESS;
295295+ codes[0] = EXC_I386_ALIGNFLT;
296296+ break;
297297+ case SIGILL:
298298+ mach_exception = EXC_BAD_INSTRUCTION;
299299+ codes[0] = EXC_I386_INVOP;
300300+ break;
301301+ case SIGFPE:
302302+ mach_exception = EXC_ARITHMETIC;
303303+ codes[0] = info->si_code;
304304+ break;
305305+ case SIGTRAP:
306306+ mach_exception = EXC_BREAKPOINT;
307307+ codes[0] = EXC_I386_BPT;
308308+ break;
309309+ }
257310 default:
258311 mach_exception = EXC_SOFTWARE;
259312 codes[0] = EXC_SOFT_SIGNAL;
+4-2
src/kernel/emulation/linux/signal/sigexc.h
···1313#define SIGRT_MAGIC_ENABLE_SIGEXC 0xdebdeb01
1414#define SIGRT_MAGIC_DISABLE_SIGEXC 0xdebdeb00
15151616-// Initializes this module
1717-void sigexc_setup(void);
1616+// Initializes this module (before opening LKM)
1717+void sigexc_setup1(void);
1818+// Finish initialization (after opening LKM)
1919+void sigexc_setup2(void);
18201921// Is this process currently traced by a debugger?
2022bool darling_am_i_ptraced(void);