this repo has no description
1
fork

Configure Feed

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

More changes to get more parts of LLDB working

The most important changes to this source tree (not including changes
to darlingserver) are signal handling for the new S2C signal and the
client-side implementions of S2C mprotect and mmaping a file descriptor.

+79 -9
+1 -4
src/kernel/emulation/linux/mach/mach_traps.c
··· 287 287 int prot = 0; 288 288 int ret; 289 289 290 - // mach_vm_protect() on a remote process is not trivial to implement 291 - // in a LKM. We simulate success. At the same time, we allow mach_vm_write() 292 - // to work even if the target page is R/O (like ptrace(POKE_DATA)). 293 290 if (target != 0 && target != mach_task_self()) 294 - return KERN_SUCCESS; 291 + return MACH_SEND_INVALID_DEST; 295 292 296 293 if (new_protection & VM_PROT_READ) 297 294 prot |= PROT_READ;
+1 -1
src/kernel/emulation/linux/process/execve.c
··· 205 205 206 206 linux_sigset_t set; 207 207 set = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 208 - //set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 208 + set |= (1ull << (SIGNAL_S2C-1)); 209 209 210 210 // darlingserver needs to know whether the execve completes successfully or not. 211 211 // since pidfds don't notify on execve, we have to use a pipe with close-on-exec
+53 -2
src/kernel/emulation/linux/resources/dserver-rpc-defs.h
··· 11 11 #include "../elfcalls_wrapper.h" 12 12 #include "../simple.h" 13 13 #include "../signal/sigprocmask.h" 14 + #include "../unistd/close.h" 14 15 15 16 #include <darlingserver/rpc-supplement.h> 17 + 18 + #include <rtsig.h> 16 19 17 20 #ifndef DSERVER_RPC_HOOKS_ARCHITECTURE 18 21 #define DSERVER_RPC_HOOKS_ARCHITECTURE 1 ··· 111 114 .errno_result = 0, 112 115 }; 113 116 117 + if (mmap_call->fd == 0) { 118 + dserver_rpc_hooks_cmsghdr_t* reply_cmsg = DSERVER_RPC_HOOKS_CMSG_FIRSTHDR(out_message); 119 + if (!reply_cmsg || reply_cmsg->cmsg_level != DSERVER_RPC_HOOKS_SOL_SOCKET || reply_cmsg->cmsg_type != DSERVER_RPC_HOOKS_SCM_RIGHTS || reply_cmsg->cmsg_len != DSERVER_RPC_HOOKS_CMSG_LEN(sizeof(int))) { 120 + __simple_printf("Bad S2C call: no FD, but expected one"); 121 + __simple_abort(); 122 + } 123 + dserver_rpc_hooks_memcpy(&mmap_call->fd, DSERVER_RPC_HOOKS_CMSG_DATA(reply_cmsg), sizeof(int)); 124 + } else if (mmap_call->fd != -1) { 125 + __simple_printf("Bad S2C call: invalid FD number"); 126 + __simple_abort(); 127 + } 128 + 114 129 #ifdef __NR_mmap2 115 130 call_ret = (void*)LINUX_SYSCALL(__NR_mmap2, mmap_call->address, mmap_call->length, mmap_call->protection, mmap_call->flags, mmap_call->fd, mmap_call->offset / 4096); 116 131 #else 117 132 call_ret = (void*)LINUX_SYSCALL(__NR_mmap, mmap_call->address, mmap_call->length, mmap_call->protection, mmap_call->flags, mmap_call->fd, mmap_call->offset); 118 133 #endif 134 + 135 + if (mmap_call->fd >= 0) { 136 + close_internal(mmap_call->fd); 137 + } 119 138 120 139 if ((unsigned long)call_ret > (unsigned long)-4096) { 121 140 // this is actually an errno ··· 167 186 } 168 187 } break; 169 188 189 + case dserver_s2c_msgnum_mprotect: { 190 + dserver_s2c_call_mprotect_t* mprotect_call = out_message->msg_iov->iov_base; 191 + int call_ret; 192 + dserver_s2c_reply_mprotect_t reply = { 193 + .header.call_number = 0x52cca11, 194 + .header.pid = dserver_rpc_hooks_get_pid(), 195 + .header.tid = dserver_rpc_hooks_get_tid(), 196 + .header.architecture = dserver_rpc_hooks_get_architecture(), 197 + .header.s2c_number = dserver_s2c_msgnum_mprotect, 198 + .return_value = 0, 199 + .errno_result = 0, 200 + }; 201 + 202 + call_ret = LINUX_SYSCALL3(__NR_mprotect, mprotect_call->address, mprotect_call->length, mprotect_call->protection); 203 + 204 + if (call_ret < 0) { 205 + reply.return_value = -1; 206 + reply.errno_result = -call_ret; 207 + } else { 208 + reply.return_value = call_ret; 209 + } 210 + 211 + #ifdef __NR_socketcall 212 + ret = LINUX_SYSCALL(__NR_socketcall, LINUX_SYS_SENDTO, ((long[6]) { socket, &reply, sizeof(reply), 0, dserver_rpc_hooks_get_server_address(), dserver_rpc_hooks_get_server_address_length() })); 213 + #else 214 + ret = LINUX_SYSCALL(__NR_sendto, socket, &reply, sizeof(reply), 0, dserver_rpc_hooks_get_server_address(), dserver_rpc_hooks_get_server_address_length()); 215 + #endif 216 + if (ret < 0) { 217 + return ret; 218 + } 219 + } break; 220 + 170 221 default: 171 222 __simple_printf("Invalid S2C call number: %d", callhdr->s2c_number); 172 223 __simple_abort(); ··· 196 247 #define dserver_rpc_hooks_atomic_save_t sigset_t 197 248 198 249 static void dserver_rpc_hooks_atomic_begin(dserver_rpc_hooks_atomic_save_t* atomic_save) { 199 - // see sys_disable_threadsignal() 200 - sigset_t set = ~0; 250 + // block standard unix signals (not real-time signals, though) 251 + sigset_t set = 0x7fffffff; 201 252 sys_sigprocmask(SIG_BLOCK, &set, atomic_save); 202 253 }; 203 254
+15 -2
src/kernel/emulation/linux/signal/sigexc.c
··· 69 69 void sigexc_setup1(void) 70 70 { 71 71 handle_rt_signal(SIGNAL_SIGEXC_SUSPEND); 72 + handle_rt_signal(SIGNAL_S2C); 72 73 } 73 74 74 75 void sigexc_setup2(void) 75 76 { 76 77 linux_sigset_t set; 77 78 set = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 78 - //set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 79 + set |= (1ull << (SIGNAL_S2C-1)); 79 80 80 81 LINUX_SYSCALL(__NR_rt_sigprocmask, 1 /* LINUX_SIG_UNBLOCK */, 81 82 &set, NULL, sizeof(linux_sigset_t)); ··· 96 97 struct linux_sigaction sa; 97 98 98 99 sa.sa_sigaction = (linux_sig_handler*)sigrt_handler; 99 - sa.sa_mask = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 100 + sa.sa_mask = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)) | (1ull << (signum-1)); 100 101 sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK; 101 102 sa.sa_restorer = sig_restorer; 102 103 ··· 147 148 { 148 149 dserver_rpc_interrupt_enter(); 149 150 151 + if (signum == SIGNAL_SIGEXC_SUSPEND) { 150 152 #if defined(__x86_64__) 151 153 x86_thread_state64_t tstate; 152 154 x86_float_state64_t fstate; ··· 167 169 } 168 170 169 171 state_from_kernel(ctxt, &tstate, &fstate); 172 + } else if (signum == SIGNAL_S2C) { 173 + __simple_kprintf("sigexc: sigrt_handler S2C"); 174 + 175 + int ret = dserver_rpc_s2c_perform(); 176 + if (ret < 0) { 177 + __simple_printf("dserver_rpc_s2c_perform failed internally: %d", ret); 178 + __simple_abort(); 179 + } 180 + } else { 181 + __simple_printf("Unknown/unrecognized real-time signal: %d", signum); 182 + } 170 183 171 184 dserver_rpc_interrupt_exit(); 172 185 }
+1
src/kernel/emulation/linux/signal/sigexc.h
··· 7 7 // NOTE: Keep these definitions up to date with lkm/darling/binfmt.c! 8 8 // Uses one of the below magic values to toggle the debugging state 9 9 #define SIGNAL_SIGEXC_SUSPEND LINUX_SIGRTMIN 10 + #define SIGNAL_S2C (LINUX_SIGRTMIN + 1) 10 11 11 12 void sigexc_setup(void); 12 13
+4
src/startup/mldr/CMakeLists.txt
··· 13 13 add_dependencies(mldr_dserver_rpc generate_dserver_rpc_wrappers) 14 14 15 15 target_compile_options(mldr_dserver_rpc PRIVATE -include ${CMAKE_CURRENT_SOURCE_DIR}/resources/dserver-rpc-defs.h) 16 + add_dependencies(mldr_dserver_rpc rtsig_h) 17 + target_include_directories(mldr_dserver_rpc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..) 16 18 17 19 set(mldr_sources 18 20 mldr.c ··· 42 44 target_compile_options(mldr32_dserver_rpc PRIVATE -include ${CMAKE_CURRENT_SOURCE_DIR}/resources/dserver-rpc-defs.h) 43 45 target_compile_options(mldr32_dserver_rpc PRIVATE -m32) 44 46 target_link_options(mldr32_dserver_rpc PRIVATE -m32) 47 + add_dependencies(mldr32_dserver_rpc rtsig_h) 48 + target_include_directories(mldr32_dserver_rpc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..) 45 49 46 50 add_executable(mldr32 ${mldr_sources}) 47 51 target_compile_options(mldr32 PRIVATE -m32)
+4
src/startup/mldr/resources/dserver-rpc-defs.h
··· 10 10 11 11 #include <darlingserver/rpc-supplement.h> 12 12 13 + #include <rtsig.h> 14 + 13 15 #define dserver_rpc_hooks_msghdr_t struct msghdr 14 16 #define dserver_rpc_hooks_iovec_t struct iovec 15 17 #define dserver_rpc_hooks_cmsghdr_t struct cmsghdr ··· 91 93 static void dserver_rpc_hooks_atomic_begin(dserver_rpc_hooks_atomic_save_t* atomic_save) { 92 94 sigset_t set; 93 95 sigfillset(&set); 96 + sigdelset(&set, LINUX_SIGRTMIN); 97 + sigdelset(&set, LINUX_SIGRTMIN + 1); 94 98 pthread_sigmask(SIG_BLOCK, &set, atomic_save); 95 99 }; 96 100