this repo has no description
1
fork

Configure Feed

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

Progress on reworking elfcalls access, build currently broken

+27 -975
+3 -3
cmake/wrap_elf.cmake
··· 6 6 OUTPUT 7 7 ${CMAKE_CURRENT_BINARY_DIR}/${name}.c 8 8 COMMAND 9 - ${CMAKE_BINARY_DIR}/src/startup/wrapgen 9 + ${CMAKE_BINARY_DIR}/src/libelfloader/wrapgen 10 10 ${elfname} 11 11 ${CMAKE_CURRENT_BINARY_DIR}/${name}.c 12 12 DEPENDS ··· 14 14 ) 15 15 16 16 set(DYLIB_INSTALL_NAME "/usr/lib/native/lib${name}.dylib") 17 - include_directories(${CMAKE_SOURCE_DIR}/src/startup) 17 + include_directories(${CMAKE_SOURCE_DIR}/src/libelfloader/native) 18 18 add_darling_library(${name} SHARED ${CMAKE_CURRENT_BINARY_DIR}/${name}.c) 19 - target_link_libraries(${name} PRIVATE system) 19 + target_link_libraries(${name} PRIVATE system elfloader) 20 20 make_fat(${name}) 21 21 install(TARGETS ${name} DESTINATION libexec/darling/usr/lib/native) 22 22 endfunction(wrap_elf)
+1
src/CMakeLists.txt
··· 43 43 #add_subdirectory(libmach-o) 44 44 #add_subdirectory(libdyld) 45 45 add_subdirectory(libelfloader/native) 46 + add_subdirectory(libelfloader/wrapgen) 46 47 add_subdirectory(startup) 47 48 48 49 add_definitions(
+1 -1
src/kernel/emulation/linux/CMakeLists.txt
··· 14 14 -DEMULATED_VERSION="Darwin Kernel Version 16.0.0") 15 15 16 16 17 - include_directories(${CMAKE_SOURCE_DIR}/src/startup) 17 + include_directories(${CMAKE_SOURCE_DIR}/src/libelfloader/native) 18 18 19 19 # include src/startup for rtsig.h 20 20 include_directories(${CMAKE_CURRENT_SOURCE_DIR}
-1
src/kernel/emulation/linux/bsdthread/bsdthread_create.c
··· 6 6 #include <stddef.h> 7 7 #include <stdint.h> 8 8 #include "../../../../../platform-include/sys/mman.h" 9 - #include "../../../../startup/threads.h" 10 9 #include "../../../../../platform-include/sys/errno.h" 11 10 #include "../mman/mman.h" 12 11 #include "../simple.h"
-1
src/kernel/emulation/linux/bsdthread/workq_kernreturn.c
··· 4 4 #include "../base.h" 5 5 #include "../errno.h" 6 6 #include "../../../../../platform-include/sys/errno.h" 7 - #include "../../../../startup/threads.h" 8 7 #include <linux-syscalls/linux.h> 9 8 #include <stddef.h> 10 9 #include <pthread/tsd_private.h>
-5
src/kernel/emulation/linux/elfcalls_wrapper.c
··· 43 43 return _elfcalls->dlclose(module); 44 44 } 45 45 46 - const uint8_t* get_exe_uuid(void) 47 - { 48 - return _elfcalls->exe_uuid(); 49 - } 50 -
-1
src/kernel/emulation/linux/elfcalls_wrapper.h
··· 23 23 24 24 void* __darling_thread_get_stack(void); 25 25 26 - const uint8_t* get_exe_uuid(void); 27 26 28 27 #ifdef __cplusplus 29 28 }
-3
src/kernel/emulation/linux/mach/lkm.c
··· 7 7 #include <unistd.h> 8 8 #include <sys/resource.h> 9 9 #include "../../libsyscall/wrappers/_libkernel_init.h" 10 - #include <elfcalls.h> 11 - 12 - extern struct elf_calls* _elfcalls; 13 10 14 11 extern int __real_ioctl(int fd, int cmd, void* arg); 15 12 extern int sys_open(const char*, int, int);
+4 -1
src/kernel/emulation/linux/misc/proc_info.c
··· 104 104 } 105 105 } 106 106 107 + static char fakeuuid[16]; 108 + 107 109 static long _proc_pidonfo_uniqinfo(int32_t pid, void* buffer, int32_t bufsize) 108 110 { 109 111 #ifndef VARIANT_DYLD ··· 120 122 121 123 memset(buffer, 0, bufsize); 122 124 123 - memcpy(info->p_uuid, get_exe_uuid(), sizeof(info->p_uuid)); 125 + #warning Get UUID from kernel 126 + memcpy(info->p_uuid, fakeuuid, sizeof(info->p_uuid)); 124 127 125 128 ////////////////////////// 126 129 // Read info for pid //
-2
src/kernel/libsyscall/CMakeLists.txt
··· 10 10 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../iokit") 11 11 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/os") 12 12 include_directories("${CMAKE_SOURCE_DIR}/platform-include") 13 - include_directories("${CMAKE_SOURCE_DIR}/src/startup") # for elfcalls.h 14 13 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../libc/include") 15 14 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../duct/include") 16 15 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/wrappers/libproc") ··· 72 71 set(syscall_sources 73 72 mach/mach_traps.S 74 73 os/alloc_once.c 75 - wrappers/elfcalls_setup.c 76 74 wrappers/libproc/libproc.c 77 75 wrappers/libproc/proc_listpidspath.c 78 76
-2
src/kernel/libsyscall/wrappers/_libkernel_init.c
··· 27 27 */ 28 28 29 29 #include "_libkernel_init.h" 30 - #include "elfcalls_setup.h" 31 30 32 31 extern int mach_init(void); 33 32 extern void sigexc_setup(void); ··· 49 48 _dlsym = fns->dlsym; 50 49 } 51 50 52 - setup_elfcalls(apple); 53 51 mach_init(); 54 52 sigexc_setup(); 55 53 }
-24
src/kernel/libsyscall/wrappers/elfcalls_setup.c
··· 1 - #include <stdint.h> 2 - #include <stddef.h> 3 - #include "elfcalls_setup.h" 4 - #include <elfcalls.h> 5 - 6 - extern int strncmp(const char *s1, const char *s2, __SIZE_TYPE__ n); 7 - extern unsigned long long __simple_atoi16(const char* str, const char** endp); 8 - 9 - __attribute__((visibility("default"))) 10 - struct elf_calls* _elfcalls; 11 - 12 - void setup_elfcalls(const char** apple) 13 - { 14 - int i; 15 - for (i = 0; apple[i] != NULL; i++) 16 - { 17 - if (strncmp(apple[i], "elf_calls=", 10) == 0) 18 - { 19 - uintptr_t table = (uintptr_t) __simple_atoi16(apple[i] + 12, NULL); 20 - _elfcalls = (struct elf_calls*) table; 21 - } 22 - } 23 - } 24 -
-7
src/kernel/libsyscall/wrappers/elfcalls_setup.h
··· 1 - #ifndef _KERNEL_ELFCALLS_H 2 - #define _KERNEL_ELFCALLS_H 3 - 4 - void setup_elfcalls(const char** apple); 5 - 6 - #endif 7 -
+3 -2
src/libelfloader/loader.c
··· 73 73 static const char SYSTEM_ROOT[] = "/Volumes/SystemRoot"; 74 74 75 75 static jmp_buf jmpbuf; 76 - static struct elf_calls elfcalls; 76 + struct elf_calls* _elfcalls; 77 77 78 78 #ifndef TEST 79 79 __attribute__((constructor)) 80 80 static void runDummy(void) 81 81 { 82 + _elfcalls = (struct elf_calls*) malloc(sizeof(struct elf_calls)); 82 83 run(DUMMY_PATH); 83 84 } 84 85 #endif ··· 119 120 stack[pos++] = 3; // argc 120 121 stack[pos++] = (unsigned long) "elfloader_dummy"; 121 122 122 - snprintf(pointer1, sizeof(pointer1), "%lx", (unsigned long) &elfcalls); 123 + snprintf(pointer1, sizeof(pointer1), "%lx", (unsigned long) _elfcalls); 123 124 stack[pos++] = (unsigned long) pointer1; 124 125 125 126 snprintf(pointer2, sizeof(pointer2), "%lx", (unsigned long) loader_return);
+3
src/libelfloader/loader.h
··· 19 19 20 20 #ifndef _LOADER_H 21 21 #define _LOADER_H 22 + #include "native/elfcalls.h" 23 + 24 + extern struct elf_calls* _elfcalls; 22 25 23 26 #endif 24 27
+12
src/libelfloader/wrapgen/CMakeLists.txt
··· 1 + project(wrapgen) 2 + 3 + cmake_minimum_required(VERSION 2.4.0) 4 + 5 + if(COMMAND cmake_policy) 6 + cmake_policy(SET CMP0003 NEW) 7 + cmake_policy(SET CMP0005 NEW) 8 + endif(COMMAND cmake_policy) 9 + 10 + add_executable(wrapgen wrapgen.cpp) 11 + target_link_libraries(wrapgen dl) 12 +
-24
src/startup/32in64.h
··· 1 - #ifndef _32IN64_H 2 - #define _32IN64_H 3 - 4 - #ifdef __x86_64__ 5 - 6 - // Jump to a 32-bit address through segment number 0x23 (32-bit). The 64-bit segment is 0x33. 7 - // Set DS to 0x2B. 8 - #define _64TO32_WITH_STACK(sp, addr) __asm__ volatile("movq %1, %%rsp;" \ 9 - "subq $12, %%rsp;" \ 10 - /*"movq %0, %%rax;"*/ \ 11 - "movl %0, 8(%%rsp);" \ 12 - "movl $0x23, 4(%%rsp);" \ 13 - "leaq 1f, %%rax;" \ 14 - "movl %%eax, (%%rsp);" \ 15 - "lret;" \ 16 - ".code32;\n" \ 17 - "1: push $0x2b;" \ 18 - "pop %%ds;" \ 19 - "ret;" \ 20 - :: "r"((uint32_t)addr), "r"(sp) : "rax") 21 - 22 - #endif 23 - #endif 24 -
-3
src/startup/CMakeLists.txt
··· 20 20 21 21 include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 22 22 23 - add_executable(wrapgen wrapgen/wrapgen.cpp) 24 - target_link_libraries(wrapgen dl) 25 - 26 23 install(TARGETS darling DESTINATION bin 27 24 PERMISSIONS 28 25 OWNER_READ OWNER_WRITE OWNER_EXECUTE
-146
src/startup/commpage.c
··· 1 - #include "commpage.h" 2 - #include <sys/mman.h> 3 - #include <stdio.h> 4 - #include <errno.h> 5 - #include <string.h> 6 - #include <stdlib.h> 7 - #include <cpuid.h> 8 - #include <unistd.h> 9 - #include <sys/sysinfo.h> 10 - 11 - // Include commpage definitions 12 - #define PRIVATE 13 - #include "../../kernel-include/i386/cpu_capabilities.h" 14 - 15 - static const char* SIGNATURE32 = "commpage 32-bit"; 16 - static const char* SIGNATURE64 = "commpage 64-bit"; 17 - 18 - static uint64_t get_cpu_caps(void); 19 - 20 - #define CGET(p) (commpage + ((p)-_COMM_PAGE_START_ADDRESS)) 21 - 22 - void commpage_setup(bool _64bit) 23 - { 24 - uint8_t* commpage; 25 - uint64_t* cpu_caps64; 26 - uint32_t* cpu_caps; 27 - uint16_t* version; 28 - char* signature; 29 - uint64_t my_caps; 30 - uint8_t *ncpus, *nactivecpus; 31 - uint8_t *physcpus, *logcpus; 32 - struct sysinfo si; 33 - 34 - commpage = (uint8_t*) mmap((void*)(_64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS), 35 - _64bit ? _COMM_PAGE64_AREA_LENGTH : _COMM_PAGE32_AREA_LENGTH, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 36 - if (commpage == MAP_FAILED) 37 - { 38 - fprintf(stderr, "Cannot mmap commpage: %s\n", strerror(errno)); 39 - exit(1); 40 - } 41 - 42 - signature = (char*)CGET(_COMM_PAGE_SIGNATURE); 43 - version = (uint16_t*)CGET(_COMM_PAGE_VERSION); 44 - cpu_caps64 = (uint64_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES64); 45 - cpu_caps = (uint32_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES); 46 - 47 - strcpy(signature, _64bit ? SIGNATURE64 : SIGNATURE32); 48 - *version = _COMM_PAGE_THIS_VERSION; 49 - 50 - ncpus = (uint8_t*)CGET(_COMM_PAGE_NCPUS); 51 - *ncpus = sysconf(_SC_NPROCESSORS_CONF); 52 - 53 - nactivecpus = (uint8_t*)CGET(_COMM_PAGE_ACTIVE_CPUS); 54 - *nactivecpus = sysconf(_SC_NPROCESSORS_ONLN); 55 - 56 - // Better imprecise information than no information 57 - physcpus = (uint8_t*)CGET(_COMM_PAGE_PHYSICAL_CPUS); 58 - logcpus = (uint8_t*)CGET(_COMM_PAGE_LOGICAL_CPUS); 59 - *physcpus = *logcpus = *ncpus; 60 - 61 - my_caps = get_cpu_caps(); 62 - if (*ncpus == 1) 63 - my_caps |= kUP; 64 - 65 - *cpu_caps = (uint32_t) my_caps; 66 - *cpu_caps64 = my_caps; 67 - 68 - if (sysinfo(&si) == 0) 69 - { 70 - uint64_t* memsize = (uint64_t*)CGET(_COMM_PAGE_MEMORY_SIZE); 71 - *memsize = si.totalram * si.mem_unit; 72 - } 73 - } 74 - 75 - uint64_t get_cpu_caps(void) 76 - { 77 - uint64_t caps = 0; 78 - 79 - { 80 - union cpu_flags1 eax; 81 - union cpu_flags2 ecx; 82 - union cpu_flags3 edx; 83 - uint32_t ebx; 84 - 85 - eax.reg = ecx.reg = edx.reg = 0; 86 - __cpuid(1, eax.reg, ebx, ecx.reg, edx.reg); 87 - 88 - if (ecx.mmx) 89 - caps |= kHasMMX; 90 - if (ecx.sse) 91 - caps |= kHasSSE; 92 - if (ecx.sse2) 93 - caps |= kHasSSE2; 94 - if (edx.sse3) 95 - caps |= kHasSSE3; 96 - if (ecx.ia64) 97 - caps |= k64Bit; 98 - if (edx.ssse3) 99 - caps |= kHasSupplementalSSE3; 100 - if (edx.sse41) 101 - caps |= kHasSSE4_1; 102 - if (edx.sse42) 103 - caps |= kHasSSE4_2; 104 - if (edx.aes) 105 - caps |= kHasAES; 106 - if (edx.avx) 107 - caps |= kHasAVX1_0; 108 - if (edx.rdrnd) 109 - caps |= kHasRDRAND; 110 - if (edx.fma) 111 - caps |= kHasFMA; 112 - if (edx.f16c) 113 - caps |= kHasF16C; 114 - } 115 - { 116 - union cpu_flags4 ebx; 117 - union cpu_flags5 ecx; 118 - uint32_t edx = 0, eax = 7; 119 - 120 - __cpuid(7, eax, ebx.reg, ecx.reg, edx); 121 - 122 - if (ebx.erms) 123 - caps |= kHasENFSTRG; 124 - if (ebx.avx2) 125 - caps |= kHasAVX2_0; 126 - if (ebx.bmi1) 127 - caps |= kHasBMI1; 128 - if (ebx.bmi2) 129 - caps |= kHasBMI2; 130 - if (ebx.rtm) 131 - caps |= kHasRTM; 132 - if (ebx.hle) 133 - caps |= kHasHLE; 134 - if (ebx.rdseed) 135 - caps |= kHasRDSEED; 136 - if (ebx.adx) 137 - caps |= kHasADX; 138 - if (ebx.mpx) 139 - caps |= kHasMPX; 140 - if (ebx.sgx) 141 - caps |= kHasSGX; 142 - } 143 - 144 - return caps; 145 - } 146 -
-154
src/startup/commpage.h
··· 1 - #ifndef _COMMPAGE_H 2 - #define _COMMPAGE_H 3 - #include <stdbool.h> 4 - #include <stdint.h> 5 - 6 - #ifdef __cplusplus 7 - extern "C" { 8 - #endif 9 - 10 - void commpage_setup(bool _64bit); 11 - 12 - union cpu_flags1 { 13 - struct { 14 - uint8_t step: 4; 15 - uint8_t model: 4; 16 - uint8_t family: 4; 17 - uint8_t type: 2; 18 - uint8_t pad1: 2; 19 - uint8_t emodel: 4; 20 - uint8_t efamily: 8; 21 - uint8_t pad2: 4; 22 - }; 23 - uint32_t reg; 24 - }; 25 - 26 - union cpu_flags2 { 27 - struct { 28 - uint8_t fpu: 1; 29 - uint8_t vme: 1; 30 - uint8_t de: 1; 31 - uint8_t pse: 1; 32 - uint8_t tsc: 1; 33 - uint8_t msr: 1; 34 - uint8_t pae: 1; 35 - uint8_t mce: 1; 36 - uint8_t cx8: 1; 37 - uint8_t apic: 1; 38 - uint8_t reserved1: 1; 39 - uint8_t sep: 1; 40 - uint8_t mtrr: 1; 41 - uint8_t pge: 1; 42 - uint8_t mca: 1; 43 - uint8_t cmov: 1; 44 - uint8_t pat: 1; 45 - uint8_t pse36: 1; 46 - uint8_t psn: 1; 47 - uint8_t clfsh: 1; 48 - uint8_t reserved2: 1; 49 - uint8_t ds: 1; 50 - uint8_t acpi: 1; 51 - uint8_t mmx: 1; 52 - uint8_t fxsr: 1; 53 - uint8_t sse: 1; 54 - uint8_t sse2: 1; 55 - uint8_t ss: 1; 56 - uint8_t htt: 1; 57 - uint8_t tm: 1; 58 - uint8_t ia64: 1; 59 - uint8_t pbe: 1; 60 - }; 61 - uint32_t reg; 62 - }; 63 - 64 - union cpu_flags3 { 65 - struct { 66 - uint32_t sse3: 1; 67 - uint32_t pclmulqdq: 1; 68 - uint32_t dtes64: 1; 69 - uint32_t monitor: 1; 70 - uint32_t dscpl: 1; 71 - uint32_t vmx: 1; 72 - uint32_t smx: 1; 73 - uint32_t est: 1; 74 - uint32_t tm2: 1; 75 - uint32_t ssse3: 1; 76 - uint32_t cntxid: 1; 77 - uint32_t sdbg: 1; 78 - uint32_t fma: 1; 79 - uint32_t cx16: 1; 80 - uint32_t xtpr: 1; 81 - uint32_t pdcm: 1; 82 - uint32_t reserved1: 1; 83 - uint32_t pcid: 1; 84 - uint32_t dca: 1; 85 - uint32_t sse41: 1; 86 - uint32_t sse42: 1; 87 - uint32_t x2apic: 1; 88 - uint32_t movbe: 1; 89 - uint32_t popcnt: 1; 90 - uint32_t tscdadline: 1; 91 - uint32_t aes: 1; 92 - uint32_t xsave: 1; 93 - uint32_t osxsave: 1; 94 - uint32_t avx: 1; 95 - uint32_t f16c: 1; 96 - uint32_t rdrnd: 1; 97 - uint32_t hypervisor: 1; 98 - }; 99 - uint32_t reg; 100 - }; 101 - 102 - union cpu_flags4 { 103 - struct { 104 - uint8_t fsgsbase: 1; 105 - uint8_t ia32tscadjust: 1; 106 - uint8_t sgx: 1; 107 - uint8_t bmi1: 1; 108 - uint8_t hle: 1; 109 - uint8_t avx2: 1; 110 - uint8_t reserved1: 1; 111 - uint8_t smep: 1; 112 - uint8_t bmi2: 1; 113 - uint8_t erms: 1; 114 - uint8_t invpcid: 1; 115 - uint8_t rtm: 1; 116 - uint8_t pqm: 1; 117 - uint8_t fpucsdsdeprecated: 1; 118 - uint8_t mpx: 1; 119 - uint8_t pqe: 1; 120 - uint8_t avx512f: 1; 121 - uint8_t avx512dq: 1; 122 - uint8_t rdseed: 1; 123 - uint8_t adx: 1; 124 - uint8_t smap: 1; 125 - uint8_t avx512ifma: 1; 126 - uint8_t pcommit: 1; 127 - uint8_t clflushopt: 1; 128 - uint8_t clwb: 1; 129 - uint8_t intelproctrace: 1; 130 - uint8_t avx512pf: 1; 131 - uint8_t avx512er: 1; 132 - uint8_t avx512cd: 1; 133 - uint8_t sha: 1; 134 - uint8_t avx512bw: 1; 135 - uint8_t avx512vl: 1; 136 - }; 137 - uint32_t reg; 138 - }; 139 - 140 - union cpu_flags5 { 141 - struct { 142 - uint8_t prefetchwt1: 1; 143 - uint8_t avx512vbmi: 1; 144 - uint32_t reserved: 30; 145 - }; 146 - uint32_t reg; 147 - }; 148 - 149 - #ifdef __cplusplus 150 - } 151 - #endif 152 - 153 - #endif 154 -
-102
src/startup/elfcalls.c
··· 1 - #include <dlfcn.h> 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - #include <errno.h> 5 - #include <semaphore.h> 6 - #include <sys/mman.h> 7 - #include "elfcalls.h" 8 - #include "threads.h" 9 - 10 - extern uint8_t exe_uuid[16]; 11 - extern uintptr_t dyld_all_image_location; 12 - extern size_t dyld_all_image_size; 13 - 14 - static void* dlopen_simple(const char* name) 15 - { 16 - return dlopen(name, RTLD_LAZY); 17 - } 18 - 19 - static void* dlopen_fatal(const char* name) 20 - { 21 - void* rv = dlopen_simple(name); 22 - if (!rv) 23 - { 24 - fprintf(stderr, "Cannot load %s (ELF): %s\n", name, dlerror()); 25 - abort(); 26 - } 27 - return rv; 28 - } 29 - 30 - static void* dlsym_fatal(void* handle, const char* sym) 31 - { 32 - void* addr = dlsym(handle, sym); 33 - if (!addr) 34 - { 35 - fprintf(stderr, "Failed to lookup symbol %s (ELF): %s\n", sym, dlerror()); 36 - abort(); 37 - } 38 - return addr; 39 - } 40 - 41 - static int dlclose_fatal(void* handle) 42 - { 43 - if (dlclose(handle) != 0) 44 - { 45 - fprintf(stderr, "Cannot dlclose library (ELF): %s\n", dlerror()); 46 - abort(); 47 - } 48 - return 0; 49 - } 50 - 51 - static const uint8_t* get_exe_uuid(void) 52 - { 53 - return exe_uuid; 54 - } 55 - 56 - static void get_dyld_info(uintptr_t* all_image_location, size_t* all_image_length) 57 - { 58 - *all_image_location = dyld_all_image_location; 59 - *all_image_length = dyld_all_image_size; 60 - } 61 - 62 - static int get_errno(void) 63 - { 64 - return errno; 65 - } 66 - 67 - char* elfcalls_make(void) 68 - { 69 - static char param[32]; 70 - static struct elf_calls calls; 71 - 72 - calls.dlopen = dlopen_simple; 73 - calls.dlclose = dlclose; 74 - calls.dlsym = dlsym; 75 - calls.dlerror = dlerror; 76 - 77 - calls.dlopen_fatal = dlopen_fatal; 78 - calls.dlsym_fatal = dlsym_fatal; 79 - calls.dlclose_fatal = dlclose_fatal; 80 - 81 - calls.darling_thread_create = __darling_thread_create; 82 - calls.darling_thread_terminate = __darling_thread_terminate; 83 - calls.darling_thread_get_stack = __darling_thread_get_stack; 84 - 85 - calls.exe_uuid = get_exe_uuid; 86 - calls.dyld_info = get_dyld_info; 87 - 88 - calls.get_errno = get_errno; 89 - *((void**)&calls.sem_open) = sem_open; 90 - *((void**)&calls.sem_wait) = sem_wait; 91 - *((void**)&calls.sem_trywait) = sem_trywait; 92 - *((void**)&calls.sem_post) = sem_post; 93 - *((void**)&calls.sem_close) = sem_close; 94 - *((void**)&calls.sem_unlink) = sem_unlink; 95 - 96 - *((void**)&calls.shm_open) = shm_open; 97 - *((void**)&calls.shm_unlink) = shm_unlink; 98 - 99 - sprintf(param, "elf_calls=%p", &calls); 100 - return param; 101 - } 102 -
-48
src/startup/elfcalls.h
··· 1 - #ifndef _ELFCALLS_H_ 2 - #define _ELFCALLS_H_ 3 - #include <stdint.h> 4 - 5 - struct elf_calls 6 - { 7 - // ELF dynamic loader access 8 - void* (*dlopen)(const char* name); 9 - int (*dlclose)(void* lib); 10 - void* (*dlsym)(void* lib, const char* name); 11 - char* (*dlerror)(void); 12 - 13 - // pthread wrapping 14 - void* (*darling_thread_create)(unsigned long stack_size, unsigned long pthobj_size, 15 - void* entry_point, uintptr_t arg3, 16 - uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, 17 - int (*thread_self_trap)()); 18 - int (*darling_thread_terminate)(void* stackaddr, 19 - unsigned long freesize, unsigned long pthobj_size); 20 - void* (*darling_thread_get_stack)(void); 21 - 22 - // The same as above, except they abort() in case of failure 23 - void* (*dlopen_fatal)(const char* name); 24 - int (*dlclose_fatal)(void* lib); 25 - void* (*dlsym_fatal)(void* lib, const char* name); 26 - 27 - // Get main executable's UUID (16 bytes) 28 - const uint8_t* (*exe_uuid)(void); 29 - 30 - // Get data for TASK_DYLD_INFO (struct task_dyld_info) 31 - void (*dyld_info)(uintptr_t* all_image_location, __SIZE_TYPE__* all_image_length); 32 - 33 - // POSIX semaphore APIs 34 - int (*get_errno)(void); 35 - int* (*sem_open)(const char* name, int oflag, unsigned short mode, unsigned int value); 36 - int (*sem_wait)(int* sem); 37 - int (*sem_trywait)(int* sem); 38 - int (*sem_post)(int* sem); 39 - int (*sem_close)(int* sem); 40 - int (*sem_unlink)(const char* name); 41 - 42 - // POSIX SHM APIs 43 - int (*shm_open)(const char* name, int oflag, unsigned short mode); 44 - int (*shm_unlink)(const char* name); 45 - }; 46 - 47 - #endif 48 -
-87
src/startup/gdb.c
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2016 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #include "gdb.h" 21 - #include <string.h> 22 - #include <stdio.h> 23 - 24 - __attribute__ ((noinline)) 25 - static void gdb_notifier(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]); 26 - static void dyld_notification_wrapper(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]); 27 - 28 - static struct dyld_all_image_infos* orig_dyld_all_image_infos; 29 - 30 - // This is the symbol GDB looks for 31 - struct dyld_all_image_infos _dyld_all_image_infos = { 32 - .version = 15, 33 - .infoArrayCount = 0, 34 - .infoArray = NULL, 35 - .notification = &gdb_notifier, 36 - }; 37 - 38 - void gdb_notifier(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]) 39 - { 40 - // GDB sets a breakpoint in this function 41 - } 42 - 43 - struct jump 44 - { 45 - #ifdef __x86_64__ 46 - uint16_t mov; 47 - void* addr; 48 - uint16_t jump; 49 - #elif __i386__ 50 - uint8_t mov; 51 - void* addr; 52 - uint16_t jump; 53 - #endif 54 - } __attribute__ ((packed)); 55 - 56 - void setup_gdb_notifications(uintptr_t slide, uintptr_t addr) 57 - { 58 - orig_dyld_all_image_infos = (struct dyld_all_image_infos*)(addr + slide); 59 - 60 - // dyld will later rebase the address in notification, 61 - // but at this point we must add slide manually. 62 - struct jump* jump = (struct jump*)(((uintptr_t)orig_dyld_all_image_infos->notification) + slide); 63 - 64 - // Rewrite instructions in the notification function to redirect the call to us. 65 - #ifdef __x86_64__ 66 - jump->mov = 0xb948; // movabs imm,%rcx 67 - jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding movabs 68 - jump->jump = 0xe1ff; // jmpq *%rcx 69 - #elif __i386__ 70 - jump->mov = 0xb9; // mov imm,%ecx 71 - jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding mov 72 - jump->jump = 0xe1ff; // jmpl *%ecx 73 - #else 74 - # error TODO: Unsupported platform 75 - #endif 76 - } 77 - 78 - void dyld_notification_wrapper(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]) 79 - { 80 - // Copy over all data from dyld's copy of the structure to the one GDB can find (ours) 81 - memcpy(&_dyld_all_image_infos, orig_dyld_all_image_infos, sizeof(_dyld_all_image_infos)); 82 - _dyld_all_image_infos.notification = &gdb_notifier; 83 - 84 - // printf("Got notification from dyld\n"); 85 - gdb_notifier(mode, infoCount, info); 86 - } 87 -
-36
src/startup/gdb.h
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2017 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #ifndef _GDB_H_ 21 - #define _GDB_H_ 22 - #include <mach-o/dyld_images.h> 23 - #include <stdint.h> 24 - 25 - #ifdef __cplusplus 26 - extern "C" { 27 - #endif 28 - 29 - void setup_gdb_notifications(uintptr_t slide, uintptr_t addr); 30 - 31 - #ifdef __cplusplus 32 - } 33 - #endif 34 - 35 - #endif 36 -
-281
src/startup/threads.c
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2015 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #include "threads.h" 21 - #include <pthread.h> 22 - #include <sys/mman.h> 23 - #include <semaphore.h> 24 - #include <string.h> 25 - #include <stdbool.h> 26 - #include <stdlib.h> 27 - #include <signal.h> 28 - #include <unistd.h> 29 - #include <sys/syscall.h> 30 - 31 - // The point of this file is build macOS threads on top of native libc's threads, 32 - // otherwise it would not be possible to make native calls from these threads. 33 - 34 - typedef void (*thread_ep)(void**, int, ...); 35 - struct arg_struct 36 - { 37 - thread_ep entry_point; 38 - uintptr_t arg3; 39 - uintptr_t arg4; 40 - uintptr_t arg5; 41 - uintptr_t arg6; 42 - union 43 - { 44 - int (*thread_self_trap)(); 45 - int port; 46 - }; 47 - unsigned long pth_obj_size; 48 - void* pth; 49 - }; 50 - struct reaper_item 51 - { 52 - struct reaper_item* next; 53 - pthread_t thread; 54 - void* stack; 55 - size_t stacksize; 56 - }; 57 - 58 - static void* darling_thread_entry(void* p); 59 - static void start_reaper(); 60 - 61 - static sem_t reaper_sem; 62 - static pthread_mutex_t reaper_mutex = PTHREAD_MUTEX_INITIALIZER; 63 - static struct reaper_item *reaper_items_front = NULL, *reaper_items_end = NULL; 64 - static void reaper_item_push(struct reaper_item* item); 65 - static struct reaper_item* reaper_item_pop(void); 66 - 67 - #ifndef PTHREAD_STACK_MIN 68 - # define PTHREAD_STACK_MIN 16384 69 - #endif 70 - 71 - void* __darling_thread_create(unsigned long stack_size, unsigned long pth_obj_size, 72 - void* entry_point, uintptr_t arg3, 73 - uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, 74 - int (*thread_self_trap)()) 75 - { 76 - static pthread_once_t reaper_once = PTHREAD_ONCE_INIT; 77 - 78 - struct arg_struct args = { (thread_ep) entry_point, arg3, 79 - arg4, arg5, arg6, thread_self_trap, pth_obj_size, NULL }; 80 - pthread_attr_t attr; 81 - pthread_t nativeLibcThread; 82 - void* pth; 83 - 84 - pthread_once(&reaper_once, start_reaper); 85 - 86 - pthread_attr_init(&attr); 87 - //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 88 - // pthread_attr_setstacksize(&attr, stack_size); 89 - 90 - pth = mmap(NULL, stack_size + pth_obj_size + 0x1000, PROT_READ | PROT_WRITE, 91 - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 92 - 93 - // pthread_attr_setstack is buggy. The documentation states we should provide the lowest 94 - // address of the stack, yet some versions regard it as the highest address instead. 95 - // Therefore it's better to just make the pthread stack as small as possible and then switch 96 - // to our own stack instead. 97 - //pthread_attr_setstack(&attr, ((char*)pth) + pth_obj_size, stack_size - pth_obj_size - 0x1000); 98 - 99 - // std::cout << "Allocated stack at " << pth << ", size " << stack_size << std::endl; 100 - pth = ((char*) pth) + stack_size + 0x1000; 101 - pthread_attr_setstacksize(&attr, 4096); 102 - 103 - args.pth = pth; 104 - pthread_create(&nativeLibcThread, &attr, darling_thread_entry, &args); 105 - pthread_attr_destroy(&attr); 106 - 107 - while (args.pth != NULL) 108 - sched_yield(); 109 - 110 - return pth; 111 - } 112 - 113 - static void* darling_thread_entry(void* p) 114 - { 115 - struct arg_struct* in_args = (struct arg_struct*) p; 116 - struct arg_struct args; 117 - 118 - memcpy(&args, in_args, sizeof(args)); 119 - 120 - args.port = args.thread_self_trap(); 121 - in_args->pth = NULL; 122 - 123 - #ifdef __x86_64__ 124 - __asm__ __volatile__ ( 125 - "movq %1, %%rdi\n" 126 - "movq %%rdi, %%rsp\n" 127 - "movq 40(%0), %%rsi\n" 128 - "movq 8(%0), %%rdx\n" 129 - "testq %%rdx, %%rdx\n" 130 - "jnz 1f\n" 131 - "movq %%rsp, %%rdx\n" // wqthread hack: if 3rd arg is null, we pass sp 132 - "1:\n" 133 - "movq 16(%0), %%rcx\n" 134 - "movq 24(%0), %%r8\n" 135 - "movq 32(%0), %%r9\n" 136 - "movq %%rdi, 56(%0)\n" 137 - "movq (%0), %%rax\n" 138 - "andq $-0x10, %%rsp\n" 139 - "pushq $0\n" 140 - "pushq $0\n" 141 - "jmpq *%%rax\n" 142 - :: "a" (&args), "di" (args.pth)); 143 - #elif defined(__i386__) // args in eax, ebx, ecx, edx, edi, esi 144 - __asm__ __volatile__ ( 145 - "movl (%0), %%eax\n" 146 - "movl (%1), %%esp\n" 147 - "pushl %%eax\n" // address to be jumped to 148 - "movl %1, 28(%0)\n" 149 - "movl %1, %%eax\n" // 1st arg 150 - "movl 20(%0), %%ebx\n" // 2nd arg 151 - "movl 8(%0), %%edx\n" // 4th arg 152 - "movl 12(%0), %%edi\n" // 5th arg 153 - "movl 16(%0), %%esi\n" // 6th arg 154 - "movl 4(%0), %%ecx\n" // 3rd arg 155 - "testl %%ecx, %%ecx\n" // FIXME: clobbered ecx! 156 - "jnz 1f\n" 157 - "movl %%esp, %%ecx\n" 158 - "1:\n" 159 - "ret\n" // Jump to the address pushed at the beginning 160 - :: "c" (&args), "d" (args.pth)); 161 - #endif 162 - return NULL; 163 - } 164 - 165 - int __darling_thread_terminate(void* stackaddr, 166 - unsigned long freesize, unsigned long pthobj_size) 167 - { 168 - if (getpid() == syscall(SYS_gettid)) 169 - { 170 - // dispatch_main() calls pthread_exit(NULL) on the main thread, 171 - // which turns the our process into a zombie. 172 - // Let's just hang around forever. 173 - sigset_t mask; 174 - memset(&mask, 0, sizeof(mask)); 175 - 176 - while (1) 177 - sigsuspend(&mask); 178 - } 179 - 180 - struct reaper_item* item = (struct reaper_item*) malloc(sizeof(struct reaper_item)); 181 - item->thread = pthread_self(); 182 - item->stack = stackaddr; 183 - item->stacksize = freesize; 184 - reaper_item_push(item); 185 - 186 - sem_post(&reaper_sem); 187 - 188 - pthread_exit(NULL); 189 - 190 - __builtin_unreachable(); 191 - } 192 - 193 - void* __darling_thread_get_stack(void) 194 - { 195 - pthread_attr_t attr; 196 - void* stackaddr; 197 - size_t stacksize; 198 - 199 - pthread_getattr_np(pthread_self(), &attr); 200 - pthread_attr_getstack(&attr, &stackaddr, &stacksize); 201 - 202 - return ((char*)stackaddr) + stacksize - 0x2000; 203 - } 204 - 205 - static void* reaper_entry(void* unused) 206 - { 207 - while (true) 208 - { 209 - struct reaper_item* item; 210 - 211 - sem_wait(&reaper_sem); 212 - 213 - item = reaper_item_pop(); 214 - if (!item) 215 - continue; // Should not happen! 216 - 217 - // std::cout << "Reaping thread " << (void*)item.thread << "; Free stack at " << item.stack << ", " << item.stacksize << " bytes\n"; 218 - 219 - // Wait for thread to terminate 220 - pthread_join(item->thread, NULL); 221 - 222 - // Free its stack in the extended range requested by Darwin's libc 223 - munmap(item->stack, item->stacksize); 224 - 225 - free(item); 226 - } 227 - } 228 - 229 - static void start_reaper() 230 - { 231 - pthread_attr_t attr; 232 - pthread_t thread; 233 - 234 - pthread_attr_init(&attr); 235 - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 236 - 237 - sem_init(&reaper_sem, 0, 0); 238 - pthread_create(&thread, &attr, reaper_entry, NULL); 239 - pthread_attr_destroy(&attr); 240 - } 241 - 242 - static void reaper_item_push(struct reaper_item* item) 243 - { 244 - pthread_mutex_lock(&reaper_mutex); 245 - 246 - item->next = NULL; 247 - if (reaper_items_end != NULL) 248 - { 249 - reaper_items_end->next = item; 250 - reaper_items_end = item; 251 - } 252 - else 253 - { 254 - reaper_items_front = reaper_items_end = item; 255 - } 256 - 257 - pthread_mutex_unlock(&reaper_mutex); 258 - } 259 - 260 - static struct reaper_item* reaper_item_pop(void) 261 - { 262 - struct reaper_item* e; 263 - pthread_mutex_lock(&reaper_mutex); 264 - 265 - if (reaper_items_front != NULL) 266 - { 267 - e = reaper_items_front; 268 - 269 - if (reaper_items_front == reaper_items_end) 270 - reaper_items_front = reaper_items_end = NULL; // The list is now empty 271 - else 272 - reaper_items_front = e->next; 273 - } 274 - else 275 - e = NULL; 276 - 277 - pthread_mutex_unlock(&reaper_mutex); 278 - 279 - return e; 280 - } 281 -
-41
src/startup/threads.h
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2015 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #ifndef DYLD_THREADS_H 21 - #define DYLD_THREADS_H 22 - #include <stdint.h> 23 - 24 - #ifdef __cplusplus 25 - extern "C" { 26 - #endif 27 - 28 - void* __darling_thread_create(unsigned long stack_size, unsigned long pthobj_size, 29 - void* entry_point, uintptr_t arg3, 30 - uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, 31 - int (*thread_self_trap)()); 32 - int __darling_thread_terminate(void* stackaddr, 33 - unsigned long freesize, unsigned long pthobj_size); 34 - void* __darling_thread_get_stack(void); 35 - 36 - #ifdef __cplusplus 37 - } 38 - #endif 39 - 40 - #endif 41 -
src/startup/wrapgen/print_wrapped_elf.cpp src/libelfloader/wrapgen/print_wrapped_elf.cpp
src/startup/wrapgen/produce_stubs_example.h src/libelfloader/wrapgen/produce_stubs_example.h
src/startup/wrapgen/stubgen32.cpp src/libelfloader/wrapgen/stubgen32.cpp
src/startup/wrapgen/wrapgen.cpp src/libelfloader/wrapgen/wrapgen.cpp