this repo has no description
1
fork

Configure Feed

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

Merge pull request #1401 from darlinghq/mldr_thread_entry_rework

Rewrite darling_thread_entry Inline Assembly

authored by

CuriousTommy and committed by
GitHub
82525f6d 98c5c8ab

+67 -37
+1 -1
src/startup/CMakeLists.txt
··· 9 9 10 10 enable_language(C ASM) 11 11 12 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -ggdb -O0") 12 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -ggdb -O0") 13 13 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 14 14 #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Ttext-segment,0x400000 -Wl,-Tbss,0x410000 -Wl,-Tdata,0x420000") 15 15 add_definitions(-DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -D_GNU_SOURCE -DMLDR_BUILD)
+66 -36
src/startup/mldr/elfcalls/threads.c
··· 77 77 78 78 #define DEFAULT_DTHREAD_GUARD_SIZE 0x1000 79 79 80 + static inline void *align_16(uintptr_t ptr) { 81 + return (void *) ((uintptr_t) ptr & ~(uintptr_t) 15); 82 + } 83 + 80 84 static dthread_t dthread_structure_init(dthread_t dthread, size_t guard_size, void* stack_addr, size_t stack_size, void* base_addr, size_t total_size) { 81 85 // the pthread signature is the address of the pthread XORed with the "pointer munge" token passed in by the kernel 82 86 // since the LKM doesn't pass in a token, it's always zero, so the signature is equal to just the address ··· 250 254 return NULL; 251 255 } 252 256 257 + void *stack_ptr = align_16(args.stack_addr); 258 + 259 + // No additional function calls should occur beyond this point. Otherwise, we will risk our 260 + // registers being call-clobbered. I recommend reading the following doc for more details: 261 + // https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html 262 + #if __x86_64__ 263 + register void* arg1 asm("rdi") = args.pth; 264 + register int arg2 asm("esi") = args.port; 265 + register uintptr_t arg3 asm("rdx") = args.real_entry_point; 266 + register uintptr_t arg4 asm("rcx") = args.arg1; 267 + register uintptr_t arg5 asm("r8") = args.arg2; 268 + register uintptr_t arg6 asm("r9") = args.arg3; 269 + #elif __i386__ 270 + uintptr_t arg3 = args.real_entry_point; 271 + #endif 272 + 273 + if (arg3 == 0) { 274 + arg3 = (long) args.stack_bottom; 275 + } 276 + 253 277 #ifdef __x86_64__ 254 - __asm__ __volatile__ ( 255 - "movq %1, %%rdi\n" 256 - "movq 80(%0), %%rsp\n" 257 - "movq 40(%0), %%rsi\n" 258 - "movq 8(%0), %%rdx\n" 259 - "testq %%rdx, %%rdx\n" 260 - "jnz 1f\n" 261 - "movq 72(%0), %%rdx\n" // wqthread hack: if 3rd arg is null, we pass the stack bottom 262 - "1:\n" 263 - "movq 16(%0), %%rcx\n" 264 - "movq 24(%0), %%r8\n" 265 - "movq 32(%0), %%r9\n" 266 - "movq %%rdi, 56(%0)\n" 267 - "movq (%0), %%rax\n" 268 - "andq $-0x10, %%rsp\n" 269 - "pushq $0\n" 270 - "pushq $0\n" 271 - "jmpq *%%rax\n" 272 - :: "a" (&args), "di" (args.pth)); 278 + asm volatile( 279 + // Zero out the frame base register. 280 + "xorq %%rbp, %%rbp\n" 281 + // Switch to the new stack. 282 + "movq %[stack_ptr], %%rsp\n" 283 + // Push a fake return address. 284 + "pushq $0\n" 285 + // Jump to the entry point. 286 + "jmp *%[entry_point]" :: 287 + 288 + // Function arguments 289 + "r"(arg1),"r"(arg2),"r"(arg3),"r"(arg4),"r"(arg5),"r"(arg6), 290 + 291 + [entry_point] "r"(args.entry_point), 292 + [stack_ptr] "r"(stack_ptr) 293 + ); 273 294 #elif defined(__i386__) // args in eax, ebx, ecx, edx, edi, esi 274 295 __asm__ __volatile__ ( 275 - "movl (%0), %%eax\n" 276 - "movl 40(%0), %%esp\n" 277 - "pushl %%eax\n" // address to be jumped to 278 - "movl %1, 28(%0)\n" 279 - "movl %1, %%eax\n" // 1st arg 280 - "movl 20(%0), %%ebx\n" // 2nd arg 281 - "movl 8(%0), %%edx\n" // 4th arg 282 - "movl 12(%0), %%edi\n" // 5th arg 283 - "movl 16(%0), %%esi\n" // 6th arg 284 - "movl 4(%0), %%ecx\n" // 3rd arg 285 - "testl %%ecx, %%ecx\n" // FIXME: clobbered ecx! 286 - "jnz 1f\n" 287 - "movl 36(%0), %%ecx\n" // if the 3rd argument is null, pass the stack bottom 288 - "1:\n" 289 - "ret\n" // Jump to the address pushed at the beginning 290 - :: "c" (&args), "d" (args.pth)); 296 + // Zero out the frame base register. 297 + "xorl %%ebp, %%ebp\n" 298 + // Switch to the new stack. 299 + "movl %[stack_ptr], %%esp\n" 300 + // Make sure stack is 16 aligned (before we push the fake return address) 301 + "sub $8, %%esp\n" 302 + // Unlike x86_64, all function arguments must be stored in the stack 303 + "pushl 16(%[args])\n" // 6th argument | args.arg3 304 + "pushl 12(%[args])\n" // 5th argument | args.arg2 305 + "pushl 8(%[args])\n" // 4th argument | args.arg1 306 + "pushl %[arg3]\n" // 3rd argument | args3 307 + "pushl 20(%[args])\n" // 2nd argument | args.port 308 + "pushl 28(%[args])\n" // 1st argument | args.pth 309 + // Push a fake return address. 310 + "pushl $0\n" 311 + // Jump to the entry point. 312 + "jmp *%[entry_point]" :: 313 + 314 + // Function arguments to push to the stack. 315 + [args] "r"(&args), [arg3]"r"(arg3), 316 + 317 + [entry_point] "r"(args.entry_point), 318 + [stack_ptr] "r"(stack_ptr) 319 + ); 291 320 #else 292 - #error Not implemented 321 + #error Not implemented 322 + // args.entry_point(args.pth, args.port, args.real_entry_point, args.arg1, args.arg2, args.arg3); 293 323 #endif 294 324 __builtin_unreachable(); 295 325 }