···1414 -DEMULATED_VERSION="Darwin Kernel Version 16.0.0")
151516161717-include_directories(${CMAKE_SOURCE_DIR}/src/startup)
1717+include_directories(${CMAKE_SOURCE_DIR}/src/libelfloader/native)
18181919# include src/startup for rtsig.h
2020include_directories(${CMAKE_CURRENT_SOURCE_DIR}
···11-#ifndef _ELFCALLS_H_
22-#define _ELFCALLS_H_
33-#include <stdint.h>
44-55-struct elf_calls
66-{
77- // ELF dynamic loader access
88- void* (*dlopen)(const char* name);
99- int (*dlclose)(void* lib);
1010- void* (*dlsym)(void* lib, const char* name);
1111- char* (*dlerror)(void);
1212-1313- // pthread wrapping
1414- void* (*darling_thread_create)(unsigned long stack_size, unsigned long pthobj_size,
1515- void* entry_point, uintptr_t arg3,
1616- uintptr_t arg4, uintptr_t arg5, uintptr_t arg6,
1717- int (*thread_self_trap)());
1818- int (*darling_thread_terminate)(void* stackaddr,
1919- unsigned long freesize, unsigned long pthobj_size);
2020- void* (*darling_thread_get_stack)(void);
2121-2222- // The same as above, except they abort() in case of failure
2323- void* (*dlopen_fatal)(const char* name);
2424- int (*dlclose_fatal)(void* lib);
2525- void* (*dlsym_fatal)(void* lib, const char* name);
2626-2727- // Get main executable's UUID (16 bytes)
2828- const uint8_t* (*exe_uuid)(void);
2929-3030- // Get data for TASK_DYLD_INFO (struct task_dyld_info)
3131- void (*dyld_info)(uintptr_t* all_image_location, __SIZE_TYPE__* all_image_length);
3232-3333- // POSIX semaphore APIs
3434- int (*get_errno)(void);
3535- int* (*sem_open)(const char* name, int oflag, unsigned short mode, unsigned int value);
3636- int (*sem_wait)(int* sem);
3737- int (*sem_trywait)(int* sem);
3838- int (*sem_post)(int* sem);
3939- int (*sem_close)(int* sem);
4040- int (*sem_unlink)(const char* name);
4141-4242- // POSIX SHM APIs
4343- int (*shm_open)(const char* name, int oflag, unsigned short mode);
4444- int (*shm_unlink)(const char* name);
4545-};
4646-4747-#endif
4848-
-87
src/startup/gdb.c
···11-/*
22-This file is part of Darling.
33-44-Copyright (C) 2016 Lubos Dolezel
55-66-Darling is free software: you can redistribute it and/or modify
77-it under the terms of the GNU General Public License as published by
88-the Free Software Foundation, either version 3 of the License, or
99-(at your option) any later version.
1010-1111-Darling is distributed in the hope that it will be useful,
1212-but WITHOUT ANY WARRANTY; without even the implied warranty of
1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414-GNU General Public License for more details.
1515-1616-You should have received a copy of the GNU General Public License
1717-along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818-*/
1919-2020-#include "gdb.h"
2121-#include <string.h>
2222-#include <stdio.h>
2323-2424-__attribute__ ((noinline))
2525-static void gdb_notifier(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]);
2626-static void dyld_notification_wrapper(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]);
2727-2828-static struct dyld_all_image_infos* orig_dyld_all_image_infos;
2929-3030-// This is the symbol GDB looks for
3131-struct dyld_all_image_infos _dyld_all_image_infos = {
3232- .version = 15,
3333- .infoArrayCount = 0,
3434- .infoArray = NULL,
3535- .notification = &gdb_notifier,
3636-};
3737-3838-void gdb_notifier(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[])
3939-{
4040- // GDB sets a breakpoint in this function
4141-}
4242-4343-struct jump
4444-{
4545-#ifdef __x86_64__
4646- uint16_t mov;
4747- void* addr;
4848- uint16_t jump;
4949-#elif __i386__
5050- uint8_t mov;
5151- void* addr;
5252- uint16_t jump;
5353-#endif
5454-} __attribute__ ((packed));
5555-5656-void setup_gdb_notifications(uintptr_t slide, uintptr_t addr)
5757-{
5858- orig_dyld_all_image_infos = (struct dyld_all_image_infos*)(addr + slide);
5959-6060- // dyld will later rebase the address in notification,
6161- // but at this point we must add slide manually.
6262- struct jump* jump = (struct jump*)(((uintptr_t)orig_dyld_all_image_infos->notification) + slide);
6363-6464- // Rewrite instructions in the notification function to redirect the call to us.
6565-#ifdef __x86_64__
6666- jump->mov = 0xb948; // movabs imm,%rcx
6767- jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding movabs
6868- jump->jump = 0xe1ff; // jmpq *%rcx
6969-#elif __i386__
7070- jump->mov = 0xb9; // mov imm,%ecx
7171- jump->addr = (void*) &dyld_notification_wrapper; // immediate for preceding mov
7272- jump->jump = 0xe1ff; // jmpl *%ecx
7373-#else
7474-# error TODO: Unsupported platform
7575-#endif
7676-}
7777-7878-void dyld_notification_wrapper(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[])
7979-{
8080- // Copy over all data from dyld's copy of the structure to the one GDB can find (ours)
8181- memcpy(&_dyld_all_image_infos, orig_dyld_all_image_infos, sizeof(_dyld_all_image_infos));
8282- _dyld_all_image_infos.notification = &gdb_notifier;
8383-8484- // printf("Got notification from dyld\n");
8585- gdb_notifier(mode, infoCount, info);
8686-}
8787-
-36
src/startup/gdb.h
···11-/*
22-This file is part of Darling.
33-44-Copyright (C) 2017 Lubos Dolezel
55-66-Darling is free software: you can redistribute it and/or modify
77-it under the terms of the GNU General Public License as published by
88-the Free Software Foundation, either version 3 of the License, or
99-(at your option) any later version.
1010-1111-Darling is distributed in the hope that it will be useful,
1212-but WITHOUT ANY WARRANTY; without even the implied warranty of
1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414-GNU General Public License for more details.
1515-1616-You should have received a copy of the GNU General Public License
1717-along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818-*/
1919-2020-#ifndef _GDB_H_
2121-#define _GDB_H_
2222-#include <mach-o/dyld_images.h>
2323-#include <stdint.h>
2424-2525-#ifdef __cplusplus
2626-extern "C" {
2727-#endif
2828-2929-void setup_gdb_notifications(uintptr_t slide, uintptr_t addr);
3030-3131-#ifdef __cplusplus
3232-}
3333-#endif
3434-3535-#endif
3636-
-281
src/startup/threads.c
···11-/*
22-This file is part of Darling.
33-44-Copyright (C) 2015 Lubos Dolezel
55-66-Darling is free software: you can redistribute it and/or modify
77-it under the terms of the GNU General Public License as published by
88-the Free Software Foundation, either version 3 of the License, or
99-(at your option) any later version.
1010-1111-Darling is distributed in the hope that it will be useful,
1212-but WITHOUT ANY WARRANTY; without even the implied warranty of
1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414-GNU General Public License for more details.
1515-1616-You should have received a copy of the GNU General Public License
1717-along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818-*/
1919-2020-#include "threads.h"
2121-#include <pthread.h>
2222-#include <sys/mman.h>
2323-#include <semaphore.h>
2424-#include <string.h>
2525-#include <stdbool.h>
2626-#include <stdlib.h>
2727-#include <signal.h>
2828-#include <unistd.h>
2929-#include <sys/syscall.h>
3030-3131-// The point of this file is build macOS threads on top of native libc's threads,
3232-// otherwise it would not be possible to make native calls from these threads.
3333-3434-typedef void (*thread_ep)(void**, int, ...);
3535-struct arg_struct
3636-{
3737- thread_ep entry_point;
3838- uintptr_t arg3;
3939- uintptr_t arg4;
4040- uintptr_t arg5;
4141- uintptr_t arg6;
4242- union
4343- {
4444- int (*thread_self_trap)();
4545- int port;
4646- };
4747- unsigned long pth_obj_size;
4848- void* pth;
4949-};
5050-struct reaper_item
5151-{
5252- struct reaper_item* next;
5353- pthread_t thread;
5454- void* stack;
5555- size_t stacksize;
5656-};
5757-5858-static void* darling_thread_entry(void* p);
5959-static void start_reaper();
6060-6161-static sem_t reaper_sem;
6262-static pthread_mutex_t reaper_mutex = PTHREAD_MUTEX_INITIALIZER;
6363-static struct reaper_item *reaper_items_front = NULL, *reaper_items_end = NULL;
6464-static void reaper_item_push(struct reaper_item* item);
6565-static struct reaper_item* reaper_item_pop(void);
6666-6767-#ifndef PTHREAD_STACK_MIN
6868-# define PTHREAD_STACK_MIN 16384
6969-#endif
7070-7171-void* __darling_thread_create(unsigned long stack_size, unsigned long pth_obj_size,
7272- void* entry_point, uintptr_t arg3,
7373- uintptr_t arg4, uintptr_t arg5, uintptr_t arg6,
7474- int (*thread_self_trap)())
7575-{
7676- static pthread_once_t reaper_once = PTHREAD_ONCE_INIT;
7777-7878- struct arg_struct args = { (thread_ep) entry_point, arg3,
7979- arg4, arg5, arg6, thread_self_trap, pth_obj_size, NULL };
8080- pthread_attr_t attr;
8181- pthread_t nativeLibcThread;
8282- void* pth;
8383-8484- pthread_once(&reaper_once, start_reaper);
8585-8686- pthread_attr_init(&attr);
8787- //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
8888- // pthread_attr_setstacksize(&attr, stack_size);
8989-9090- pth = mmap(NULL, stack_size + pth_obj_size + 0x1000, PROT_READ | PROT_WRITE,
9191- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
9292-9393- // pthread_attr_setstack is buggy. The documentation states we should provide the lowest
9494- // address of the stack, yet some versions regard it as the highest address instead.
9595- // Therefore it's better to just make the pthread stack as small as possible and then switch
9696- // to our own stack instead.
9797- //pthread_attr_setstack(&attr, ((char*)pth) + pth_obj_size, stack_size - pth_obj_size - 0x1000);
9898-9999- // std::cout << "Allocated stack at " << pth << ", size " << stack_size << std::endl;
100100- pth = ((char*) pth) + stack_size + 0x1000;
101101- pthread_attr_setstacksize(&attr, 4096);
102102-103103- args.pth = pth;
104104- pthread_create(&nativeLibcThread, &attr, darling_thread_entry, &args);
105105- pthread_attr_destroy(&attr);
106106-107107- while (args.pth != NULL)
108108- sched_yield();
109109-110110- return pth;
111111-}
112112-113113-static void* darling_thread_entry(void* p)
114114-{
115115- struct arg_struct* in_args = (struct arg_struct*) p;
116116- struct arg_struct args;
117117-118118- memcpy(&args, in_args, sizeof(args));
119119-120120- args.port = args.thread_self_trap();
121121- in_args->pth = NULL;
122122-123123-#ifdef __x86_64__
124124- __asm__ __volatile__ (
125125- "movq %1, %%rdi\n"
126126- "movq %%rdi, %%rsp\n"
127127- "movq 40(%0), %%rsi\n"
128128- "movq 8(%0), %%rdx\n"
129129- "testq %%rdx, %%rdx\n"
130130- "jnz 1f\n"
131131- "movq %%rsp, %%rdx\n" // wqthread hack: if 3rd arg is null, we pass sp
132132- "1:\n"
133133- "movq 16(%0), %%rcx\n"
134134- "movq 24(%0), %%r8\n"
135135- "movq 32(%0), %%r9\n"
136136- "movq %%rdi, 56(%0)\n"
137137- "movq (%0), %%rax\n"
138138- "andq $-0x10, %%rsp\n"
139139- "pushq $0\n"
140140- "pushq $0\n"
141141- "jmpq *%%rax\n"
142142- :: "a" (&args), "di" (args.pth));
143143-#elif defined(__i386__) // args in eax, ebx, ecx, edx, edi, esi
144144- __asm__ __volatile__ (
145145- "movl (%0), %%eax\n"
146146- "movl (%1), %%esp\n"
147147- "pushl %%eax\n" // address to be jumped to
148148- "movl %1, 28(%0)\n"
149149- "movl %1, %%eax\n" // 1st arg
150150- "movl 20(%0), %%ebx\n" // 2nd arg
151151- "movl 8(%0), %%edx\n" // 4th arg
152152- "movl 12(%0), %%edi\n" // 5th arg
153153- "movl 16(%0), %%esi\n" // 6th arg
154154- "movl 4(%0), %%ecx\n" // 3rd arg
155155- "testl %%ecx, %%ecx\n" // FIXME: clobbered ecx!
156156- "jnz 1f\n"
157157- "movl %%esp, %%ecx\n"
158158- "1:\n"
159159- "ret\n" // Jump to the address pushed at the beginning
160160- :: "c" (&args), "d" (args.pth));
161161-#endif
162162- return NULL;
163163-}
164164-165165-int __darling_thread_terminate(void* stackaddr,
166166- unsigned long freesize, unsigned long pthobj_size)
167167-{
168168- if (getpid() == syscall(SYS_gettid))
169169- {
170170- // dispatch_main() calls pthread_exit(NULL) on the main thread,
171171- // which turns the our process into a zombie.
172172- // Let's just hang around forever.
173173- sigset_t mask;
174174- memset(&mask, 0, sizeof(mask));
175175-176176- while (1)
177177- sigsuspend(&mask);
178178- }
179179-180180- struct reaper_item* item = (struct reaper_item*) malloc(sizeof(struct reaper_item));
181181- item->thread = pthread_self();
182182- item->stack = stackaddr;
183183- item->stacksize = freesize;
184184- reaper_item_push(item);
185185-186186- sem_post(&reaper_sem);
187187-188188- pthread_exit(NULL);
189189-190190- __builtin_unreachable();
191191-}
192192-193193-void* __darling_thread_get_stack(void)
194194-{
195195- pthread_attr_t attr;
196196- void* stackaddr;
197197- size_t stacksize;
198198-199199- pthread_getattr_np(pthread_self(), &attr);
200200- pthread_attr_getstack(&attr, &stackaddr, &stacksize);
201201-202202- return ((char*)stackaddr) + stacksize - 0x2000;
203203-}
204204-205205-static void* reaper_entry(void* unused)
206206-{
207207- while (true)
208208- {
209209- struct reaper_item* item;
210210-211211- sem_wait(&reaper_sem);
212212-213213- item = reaper_item_pop();
214214- if (!item)
215215- continue; // Should not happen!
216216-217217- // std::cout << "Reaping thread " << (void*)item.thread << "; Free stack at " << item.stack << ", " << item.stacksize << " bytes\n";
218218-219219- // Wait for thread to terminate
220220- pthread_join(item->thread, NULL);
221221-222222- // Free its stack in the extended range requested by Darwin's libc
223223- munmap(item->stack, item->stacksize);
224224-225225- free(item);
226226- }
227227-}
228228-229229-static void start_reaper()
230230-{
231231- pthread_attr_t attr;
232232- pthread_t thread;
233233-234234- pthread_attr_init(&attr);
235235- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
236236-237237- sem_init(&reaper_sem, 0, 0);
238238- pthread_create(&thread, &attr, reaper_entry, NULL);
239239- pthread_attr_destroy(&attr);
240240-}
241241-242242-static void reaper_item_push(struct reaper_item* item)
243243-{
244244- pthread_mutex_lock(&reaper_mutex);
245245-246246- item->next = NULL;
247247- if (reaper_items_end != NULL)
248248- {
249249- reaper_items_end->next = item;
250250- reaper_items_end = item;
251251- }
252252- else
253253- {
254254- reaper_items_front = reaper_items_end = item;
255255- }
256256-257257- pthread_mutex_unlock(&reaper_mutex);
258258-}
259259-260260-static struct reaper_item* reaper_item_pop(void)
261261-{
262262- struct reaper_item* e;
263263- pthread_mutex_lock(&reaper_mutex);
264264-265265- if (reaper_items_front != NULL)
266266- {
267267- e = reaper_items_front;
268268-269269- if (reaper_items_front == reaper_items_end)
270270- reaper_items_front = reaper_items_end = NULL; // The list is now empty
271271- else
272272- reaper_items_front = e->next;
273273- }
274274- else
275275- e = NULL;
276276-277277- pthread_mutex_unlock(&reaper_mutex);
278278-279279- return e;
280280-}
281281-
-41
src/startup/threads.h
···11-/*
22-This file is part of Darling.
33-44-Copyright (C) 2015 Lubos Dolezel
55-66-Darling is free software: you can redistribute it and/or modify
77-it under the terms of the GNU General Public License as published by
88-the Free Software Foundation, either version 3 of the License, or
99-(at your option) any later version.
1010-1111-Darling is distributed in the hope that it will be useful,
1212-but WITHOUT ANY WARRANTY; without even the implied warranty of
1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414-GNU General Public License for more details.
1515-1616-You should have received a copy of the GNU General Public License
1717-along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818-*/
1919-2020-#ifndef DYLD_THREADS_H
2121-#define DYLD_THREADS_H
2222-#include <stdint.h>
2323-2424-#ifdef __cplusplus
2525-extern "C" {
2626-#endif
2727-2828-void* __darling_thread_create(unsigned long stack_size, unsigned long pthobj_size,
2929- void* entry_point, uintptr_t arg3,
3030- uintptr_t arg4, uintptr_t arg5, uintptr_t arg6,
3131- int (*thread_self_trap)());
3232-int __darling_thread_terminate(void* stackaddr,
3333- unsigned long freesize, unsigned long pthobj_size);
3434-void* __darling_thread_get_stack(void);
3535-3636-#ifdef __cplusplus
3737-}
3838-#endif
3939-4040-#endif
4141-