this repo has no description
1
fork

Configure Feed

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

Working TLS, dropped dependency on NASM

+478 -442
+1 -1
src/libc/CMakeLists.txt
··· 25 25 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w ") 26 26 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/weak_reference.h") 27 27 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0") # development flags 28 - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,--version-script=${DARLING_TOP_DIRECTORY}/darwin.map") 28 + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,--version-script=${DARLING_TOP_DIRECTORY}/darwin.map -Bsymbolic-functions") 29 29 30 30 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/fbsdcompat") 31 31 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/pthreads")
+1 -1
src/libc/i386/pthreads/pthread_getspecific.s
··· 28 28 .globl _pthread_getspecific 29 29 _pthread_getspecific: 30 30 movl 4(%esp),%eax 31 - movl %gs:(,%eax,4),%eax 31 + movl %fs:(,%eax,4),%eax 32 32 ret
+1 -1
src/libc/i386/pthreads/pthread_self.s
··· 27 27 .align 2, 0x90 28 28 .globl _pthread_self 29 29 _pthread_self: 30 - movl %gs:0,%eax 30 + movl %fs:0,%eax 31 31 ret
+10
src/libc/pthreads/pthread_tsd.c
··· 1 + // Modified by Lubos Dolezel for Darling 1 2 /* 2 3 * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. 3 4 * ··· 252 253 253 254 } 254 255 256 + #ifdef DARLING 257 + 258 + // Needed for Darling libdyld 259 + 260 + int __darwin_pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) __attribute__((weak, alias("pthread_key_create"))); 261 + int __darwin_pthread_key_delete(pthread_key_t key) __attribute__((weak, alias("pthread_key_delete"))); 262 + int __darwin_pthread_setspecific(pthread_key_t key, const void *value) __attribute__((weak, alias("pthread_setspecific"))); 263 + #endif 264 +
+8 -5
src/libdyld/CMakeLists.txt
··· 3 3 cmake_minimum_required(VERSION 2.4.0) 4 4 5 5 # set(CMAKE_ASM_NASM_OBJECT_FORMAT "elf") # TODO: for 32bit 6 - # enable_language(ASM_NASM) 6 + enable_language(ASM) 7 7 8 8 if(COMMAND cmake_policy) 9 9 cmake_policy(SET CMP0003 NEW) 10 10 endif(COMMAND cmake_policy) 11 11 12 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -ggdb") 12 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -ggdb -O2") 13 13 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/darwin.map") 14 14 15 15 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) ··· 42 42 set(dyld_SRCS ${dyld_SRCS} 43 43 UndefinedFunction.cpp 44 44 Trampoline.cpp 45 - trampoline_helper.nasm 46 - dyld_stub_binder.nasm 47 - tls_helper.nasm 45 + x86-64/dyld_stub_binder.S 46 + x86-64/trampoline_helper.S 47 + x86-64/tls_helper.S 48 + i386/dyld_stub_binder.S 49 + i386/trampoline_helper.S 50 + i386/tls_helper.S 48 51 TLS.cpp 49 52 ) 50 53
+16 -19
src/libdyld/TLS.cpp
··· 26 26 #include "trace.h" 27 27 #include "mutex.h" 28 28 29 + extern "C" { 30 + int __darwin_pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 31 + int __darwin_pthread_key_delete(pthread_key_t key); 32 + int __darwin_pthread_setspecific(pthread_key_t key, const void *value); 33 + } 34 + 29 35 static void TLSRunDestructors(void* p); 30 36 31 37 static std::map<void*, Darling::ImageData*> m_images; 32 38 static std::map<pthread_key_t, Darling::ImageData*> m_imagesKey; 33 39 static Darling::Mutex m_imagesMutex; 34 40 35 - // Maybe not a nice solution, we could implement TLS completely on our own via the fs/gs register 36 - static __thread Darling::ThreadData m_tlsData[1024]; // 1024 = PTHREAD_KEYS_MAX 37 - 38 41 // Used for a thread-local list of destructor-object pairs (DestructorLinkedListElement) 39 42 static pthread_key_t m_keyDestructors; 40 43 41 - __attribute__((constructor)) 42 - static void TLSSetupDestructors() 44 + static void TLSSetupDestructors() 43 45 { 44 - pthread_key_create(&m_keyDestructors, TLSRunDestructors); 46 + __darwin_pthread_key_create(&m_keyDestructors, TLSRunDestructors); 45 47 } 46 48 47 49 static void TLSRunDestructors(void* p) ··· 64 66 while (dlist != nullptr); 65 67 } 66 68 67 - void* Darling::TLSGetNative() 68 - { 69 - return m_tlsData; 70 - } 71 - 72 69 void Darling::TLSSetup(void* imageKey, std::vector<tlv_descriptor*>& descriptors, std::vector<void*>& initializers, void* start, uintptr_t length) 73 70 { 74 71 Darling::MutexLock _l(&m_imagesMutex); 75 72 pthread_key_t key; 76 73 ImageData* id; 74 + pthread_once_t once; 75 + 76 + pthread_once(&once, TLSSetupDestructors); 77 77 78 78 auto it = m_images.find(imageKey); 79 79 assert (it == m_images.end()); 80 80 81 - pthread_key_create(&key, (void (*)(void *)) Darling::TLSTeardownThread); 81 + __darwin_pthread_key_create(&key, (void (*)(void *)) Darling::TLSTeardownThread); 82 82 83 83 m_images[imageKey] = id = new ImageData{ key, start, length, initializers }; 84 84 m_imagesKey[key] = id; ··· 106 106 // TODO: What to do with live objects with C++11 destructors? Does Apple's dyld handle this? 107 107 108 108 m_imagesKey.erase(key); 109 - pthread_key_delete(key); 109 + __darwin_pthread_key_delete(key); 110 110 111 111 delete it->second; 112 112 m_images.erase(it); ··· 127 127 Darling::ImageData* id = m_imagesKey[key]; 128 128 char* data; 129 129 130 - assert(!m_tlsData[key]); 131 - 132 130 // Allocate a new block for TLS variables 133 - m_tlsData[key] = data = new char[id->length]; 131 + data = new char[id->length]; 134 132 135 133 // Copy the initial variable values into the new block 136 134 memcpy(data, id->start, id->length); ··· 144 142 } 145 143 146 144 // Delete the data upon thread exit 147 - pthread_setspecific(key, data); 145 + __darwin_pthread_setspecific(key, data); 148 146 149 147 LOG << "TLS data allocated at " << (void*)data << std::endl; 150 - LOG << "Pointer written at " << &m_tlsData[key] << std::endl; 151 148 152 149 return data; 153 150 } ··· 173 170 d->first = d; 174 171 } 175 172 176 - pthread_setspecific(m_keyDestructors, d); 173 + __darwin_pthread_setspecific(m_keyDestructors, d); 177 174 } 178 175 179 176 void* Darling::TLSBootstrap(tlv_descriptor* desc)
-3
src/libdyld/TLS.h
··· 56 56 // Called by pthread upon thread destruction 57 57 void TLSTeardownThread(ThreadData data); 58 58 59 - // Fast-path helper for darling_tls_get_addr() 60 - void* TLSGetNative() asm("darling_tls_get_native"); 61 - 62 59 // Called by darling_tls_get_addr() when the variable is accessed for the first time - slow path 63 60 void* TLSAllocate(pthread_key_t key) asm("darling_tls_allocate"); 64 61
+2
src/libdyld/darwin.map
··· 32 32 dyld_image_path_containing_address; 33 33 _dyld_find_unwind_sections; 34 34 _dyld_fork_child; 35 + _tlv_bootstrap; 36 + _tlv_atexit; 35 37 }; 36 38
-75
src/libdyld/dyld_stub_binder.nasm
··· 1 - section .note.GNU-stack noalloc noexec nowrite progbits 2 - 3 - extern reg_saveall 4 - extern reg_restoreall 5 - extern dyld_stub_binder_fixup ; void* dyld_stub_binder_fixup(void* cache, uintptr_t index) 6 - extern _GLOBAL_OFFSET_TABLE_ 7 - global dyld_stub_binder 8 - 9 - ; Stub identifier is pushed first 10 - ; then the code pushes a pointer to cache 11 - 12 - %ifidn __OUTPUT_FORMAT__, elf64 13 - 14 - BITS 64 15 - section text 16 - 17 - dyld_stub_binder: 18 - 19 - call reg_saveall WRT ..plt ; 224 bytes 20 - mov rdi, [rsp+224] ; cache 21 - mov rsi, [rsp+224+8] ; offset 22 - sub rsp, 8 ; maintain 16-byte stack alignment 23 - 24 - call dyld_stub_binder_fixup WRT ..plt 25 - 26 - add rsp, 8 ; maintain 16-byte stack alignment 27 - 28 - mov [rsp+224], rax 29 - call reg_restoreall WRT ..plt 30 - 31 - mov r11, [rsp] 32 - add rsp, 16 ; remove arguments to dyld_stub_binder 33 - jmp r11 34 - 35 - %elifidn __OUTPUT_FORMAT__, elf 36 - 37 - BITS 32 38 - section text 39 - 40 - dyld_stub_binder: 41 - 42 - push ebx 43 - 44 - call .get_GOT 45 - .get_GOT: 46 - pop ebx 47 - add ebx, _GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 48 - 49 - push eax 50 - call reg_saveall WRT ..plt ; 32 bytes 51 - mov eax, [esp+32+4] ; cache 52 - mov ecx, [esp+32+4+4] ; offset 53 - push ecx 54 - push eax 55 - 56 - call dyld_stub_binder_fixup WRT ..plt 57 - add esp, 8 58 - 59 - mov [esp+32+4], eax ; save the real addr somewhere 60 - call reg_restoreall WRT ..plt 61 - 62 - mov eax, [esp+4] ; restore the real addr 63 - 64 - pop ebx 65 - add esp, 8 ; remove arguments to dyld_stub_binder THIS SHOULDN'T WORK! 66 - 67 - jmp eax 68 - 69 - %else 70 - 71 - %error "Unsupported platform" 72 - 73 - %endif 74 - 75 -
+39
src/libdyld/i386/dyld_stub_binder.S
··· 1 + .text 2 + .globl dyld_stub_binder 3 + 4 + #ifdef __i386__ 5 + 6 + dyld_stub_binder: 7 + 8 + pushl %ebx 9 + 10 + calll 1f 11 + 1: 12 + popl %ebx 13 + 2: 14 + addl $_GLOBAL_OFFSET_TABLE_+(2b-1b), %ebx 15 + 16 + pushl %eax 17 + call reg_saveall@PLT // 32 bytes 18 + movl 32+4(%esp), %eax // cache 19 + movl 32+8(%esp), %ecx // offset 20 + pushl %ecx 21 + pushl %eax 22 + 23 + call dyld_stub_binder_fixup@PLT 24 + addl $8, %esp 25 + 26 + movl %eax, 32+4(%esp) // save the real addr somewhere 27 + call reg_restoreall@PLT 28 + 29 + movl 4(%esp), %eax // restore the real addr 30 + 31 + popl %ebx 32 + addl $8, %esp // remove arguments to dyld_stub_binder THIS SHOULDN'T WORK! 33 + 34 + jmpl *%eax 35 + 36 + #endif 37 + 38 + .section ".note.GNU-stack","",@progbits 39 +
+59
src/libdyld/i386/tls_helper.S
··· 1 + // 2 + // This file is part of Darling. 3 + // 4 + // Copyright (C) 2013 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 + .text 21 + .globl darling_tls_get_addr 22 + .hidden darling_tls_get_addr 23 + 24 + #ifdef __i386__ 25 + 26 + // Argument is in %eax 27 + darling_tls_get_addr: 28 + 29 + movl 4(%eax), %ecx 30 + movl %fs:0x0(,%ecx,4),%ecx 31 + 32 + testl %ecx, %ecx 33 + jz .Lslow_path 34 + 35 + addl 8(%eax), %ecx // add the offset 36 + 37 + ret 38 + 39 + .Lslow_path: 40 + pushl %ebx 41 + calll 1f 42 + 1: 43 + popl %ebx 44 + 2: 45 + addl $_GLOBAL_OFFSET_TABLE_+(2b-1b), %ebx 46 + 47 + pushl 4(%eax) // pass the pthread_key 48 + call darling_tls_allocate@PLT 49 + addl $4, %esp // remove the argument 50 + 51 + addl 8(%eax), %ecx // add the offset 52 + 53 + popl %ebx 54 + ret 55 + 56 + #endif 57 + 58 + .section ".note.GNU-stack","",@progbits 59 +
+107
src/libdyld/i386/trampoline_helper.S
··· 1 + // 2 + // This file is part of Darling. 3 + // 4 + // Copyright (C) 2012 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 + .globl trampoline_start 20 + .globl trampoline_end 21 + .globl reg_saveall 22 + .globl reg_restoreall 23 + .hidden trampoline_start 24 + .hidden trampoline_end 25 + .hidden reg_saveall 26 + .hidden reg_restoreall 27 + 28 + #ifdef __i386__ 29 + 30 + #define SavedRegLen 32 31 + 32 + reg_saveall: // 24 bytes on stack 33 + popl %eax 34 + 35 + pushl %ebx 36 + pushl %ecx 37 + pushl %edx 38 + pushl %esi 39 + pushl %edi 40 + subl 8, %esp 41 + fstpl (%esp) 42 + 43 + jmpl *%eax 44 + 45 + reg_restoreall: 46 + popl %ebx 47 + movl -4+SavedRegLen(%esp), %eax 48 + mov %ebx, -4+SavedRegLen(%esp) 49 + 50 + fldl (%esp) 51 + addl $8, %esp 52 + popl %edi 53 + popl %esi 54 + popl %edx 55 + popl %ecx 56 + popl %ebx 57 + 58 + ret 59 + 60 + trampoline_start: 61 + pushl %eax 62 + movl 0xa0a1a2a3, %eax // call reg_saveall 63 + calll *%eax 64 + 65 + pushl %esp 66 + pushl 0x12345678 // index in entry table 67 + movl 0xb0b1b2b3, %eax 68 + calll *%eax // call print function 69 + addl $8, %esp 70 + 71 + movl %eax, -8(%esp) 72 + movl 0xc0c1c2c3, %eax // call reg_restoreall 73 + calll *%eax 74 + 75 + // we cannot use IP-relative lea on 32bit x86 76 + calll .Lget_eip 77 + .Lget_eip: 78 + popl %eax 79 + addl $0xD, %eax // this gives us the address of after_jump 80 + movl %eax, (%esp) 81 + movl -8-SavedRegLen(%esp), %eax 82 + 83 + jmpl *%eax // call the real function 84 + 85 + .align 2 86 + after_jump: 87 + pushl %eax 88 + movl 0xa0a1a2a3, %eax 89 + calll *%eax // call reg_saveall 90 + pushl %esp 91 + pushl 0x12345678 // index in entry table 92 + movl 0xb9b9b9b9, %eax // print function 2 93 + calll *%eax 94 + addl $8, %esp 95 + 96 + movl %eax, -8(%esp) // real return address 97 + movl 0xc0c1c2c3, %eax 98 + calll *%eax // call reg_restoreall 99 + 100 + movl -8-SavedRegLen, %ecx 101 + jmpl *%ecx // return to the original caller 102 + trampoline_end: 103 + nop 104 + 105 + #endif 106 + 107 + .section ".note.GNU-stack","",@progbits
-128
src/libdyld/tls_helper.nasm
··· 1 - ; 2 - ; This file is part of Darling. 3 - ; 4 - ; Copyright (C) 2013 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 - 21 - section .note.GNU-stack noalloc noexec nowrite progbits 22 - 23 - extern darling_tls_get_native 24 - extern darling_tls_allocate 25 - extern _GLOBAL_OFFSET_TABLE_ 26 - 27 - global darling_tls_get_addr 28 - 29 - %ifidn __OUTPUT_FORMAT__, elf64 30 - 31 - BITS 64 32 - section text 33 - 34 - darling_tls_get_addr: 35 - push rdi 36 - call darling_tls_get_native WRT ..plt ; fast three-instruction function 37 - 38 - mov rdi, [rsp] 39 - mov rdi, [rdi+8] 40 - mov rax, [rax+rdi*8] 41 - pop rdi 42 - 43 - test rax, rax 44 - jz slow_path 45 - 46 - add rax, [rdi+16] ; add the variable offset 47 - ret 48 - 49 - slow_path: 50 - enter 592, 0 51 - 52 - ; Do a register full-save, because the caller assumes that no registers 53 - ; except for rax/rdi will be modified 54 - mov [rbp-8], rdi 55 - mov [rbp-16], rsi 56 - mov [rbp-24], rdx 57 - mov [rbp-32], rcx 58 - mov [rbp-40], r8 59 - mov [rbp-48], r9 60 - mov [rbp-56], r10 61 - mov [rbp-64], r11 62 - fxsave [rbp-592] 63 - 64 - mov rdi, [rdi+8] ; pass the pthread_key 65 - call darling_tls_allocate WRT ..plt 66 - 67 - fxrstor [rbp-592] 68 - mov r11, [rbp-64] 69 - mov r10, [rbp-56] 70 - mov r9, [rbp-48] 71 - mov r8, [rbp-40] 72 - mov rcx, [rbp-32] 73 - mov rdx, [rbp-24] 74 - mov rsi, [rbp-16] 75 - mov rdi, [rbp-8] 76 - 77 - add rax, [rdi+16] ; add the variable offset 78 - leave 79 - ret 80 - 81 - %elifidn __OUTPUT_FORMAT__, elf 82 - 83 - BITS 32 84 - section text 85 - 86 - darling_tls_get_addr: 87 - 88 - push ebx 89 - call .get_GOT 90 - .get_GOT: 91 - pop ebx 92 - add ebx, _GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 93 - 94 - mov ecx, eax ; eax will get destroyed 95 - push ecx 96 - call darling_tls_get_native WRT ..plt ; fast three-instruction function 97 - 98 - mov ecx, [esp] 99 - mov ecx, [ecx+4] ; add the pthread key 100 - mov eax, [eax+ecx*4] ; read the value at the key 101 - 102 - test eax, eax 103 - jz slow_path 104 - 105 - pop ecx 106 - add eax, [ecx+8] ; add the offset 107 - 108 - pop ebx 109 - ret 110 - 111 - slow_path: 112 - mov ecx, [esp] 113 - push dword [ecx+4] ; pass the pthread_key 114 - call darling_tls_allocate WRT ..plt 115 - pop ecx 116 - pop ecx 117 - 118 - add eax, [ecx+8] ; add the offset 119 - 120 - pop ebx 121 - ret 122 - 123 - %else 124 - 125 - %error "Unsupported platform" 126 - 127 - %endif 128 -
-208
src/libdyld/trampoline_helper.nasm
··· 1 - ; 2 - ; This file is part of Darling. 3 - ; 4 - ; Copyright (C) 2012 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 - section .note.GNU-stack noalloc noexec nowrite progbits 20 - 21 - global trampoline_start 22 - global trampoline_end 23 - global reg_saveall 24 - global reg_restoreall 25 - 26 - %ifidn __OUTPUT_FORMAT__, elf64 27 - 28 - BITS 64 29 - section text 30 - 31 - reg_saveall: ; 192 bytes on stack 32 - pop r10 ; remove retaddr from stack 33 - push rax 34 - push rbx 35 - push rdi 36 - push rsi 37 - push rdx 38 - push rcx 39 - push r8 40 - push r9 41 - push r12 42 - push r13 43 - push r14 44 - push r15 45 - sub rsp, 128 ; 8*16 46 - movdqu [rsp], xmm0 47 - movdqu [rsp+16], xmm1 48 - movdqu [rsp+32], xmm2 49 - movdqu [rsp+48], xmm3 50 - movdqu [rsp+64], xmm4 51 - movdqu [rsp+80], xmm5 52 - movdqu [rsp+96], xmm6 53 - movdqu [rsp+112], xmm7 54 - jmp r10 55 - 56 - reg_restoreall: 57 - pop r10 ; remove retaddr from stack 58 - movdqu xmm7, [rsp+112] 59 - movdqu xmm6, [rsp+96] 60 - movdqu xmm5, [rsp+80] 61 - movdqu xmm4, [rsp+64] 62 - movdqu xmm3, [rsp+48] 63 - movdqu xmm2, [rsp+32] 64 - movdqu xmm1, [rsp+16] 65 - movdqu xmm0, [rsp] 66 - add rsp, 128 67 - pop r15 68 - pop r14 69 - pop r13 70 - pop r12 71 - pop r9 72 - pop r8 73 - pop rcx 74 - pop rdx 75 - pop rsi 76 - pop rdi 77 - pop rbx 78 - pop rax 79 - jmp r10 80 - 81 - ; This is duplicated for every mapped function 82 - trampoline_start: 83 - mov r10, qword 0xb0b1b2b3b4b5b6 84 - call r10 ; call reg_saveall 85 - 86 - mov rdi, 0x123456 ; index in entry table 87 - mov rsi, rsp 88 - mov rcx, qword 0xaabbccddeeff ; print function (saves orig ret address) 89 - 90 - ;sub rsp, 8 ; align stack to 16 91 - call rcx 92 - ;add rsp, 8 93 - 94 - mov r11, rax ; save the right addr 95 - 96 - mov r10, qword 0xc0c1c2c3c4c5c6 ; call reg_restoreall 97 - call r10 98 - 99 - ; rewrite return address 100 - lea r10, [rel after_jump] 101 - mov [rsp], r10; second print function 102 - jmp r11 ; jump to the real function 103 - 104 - ALIGN 2 105 - after_jump: 106 - 107 - mov r10, qword 0xb0b1b2b3b4b5b6 108 - call r10 ; call reg_saveall 109 - 110 - mov rdi, 0x123456 111 - mov rsi, rsp 112 - mov rcx, qword 0xa0a1a2a3a4a5a6 ; retval print function (returns orig ret address) 113 - 114 - ;sub rsp, 8 ; align stack to 16 115 - call rcx 116 - ;add rsp, 8 117 - 118 - mov r11, rax 119 - 120 - mov r10, qword 0xc0c1c2c3c4c5c6 ; call reg_restoreall 121 - call r10 122 - jmp r11 ; now we "return" to the original function 123 - trampoline_end: 124 - nop 125 - %elifidn __OUTPUT_FORMAT__, elf 126 - 127 - BITS 32 128 - section text 129 - 130 - %define SavedRegLen 32 131 - 132 - reg_saveall: ; 24 bytes on stack 133 - pop eax 134 - 135 - push ebx 136 - push ecx 137 - push edx 138 - push esi 139 - push edi 140 - sub esp, 8 141 - fstp qword [esp] 142 - 143 - jmp eax 144 - 145 - reg_restoreall: 146 - pop ebx 147 - mov eax, [esp+SavedRegLen-4] 148 - mov [esp+SavedRegLen-4], ebx 149 - 150 - fld qword [esp] 151 - add esp, 8 152 - pop edi 153 - pop esi 154 - pop edx 155 - pop ecx 156 - pop ebx 157 - 158 - ret 159 - 160 - trampoline_start: 161 - push eax 162 - mov eax, 0xa0a1a2a3 ; call reg_saveall 163 - call eax 164 - 165 - push esp 166 - push 0x12345678 ; index in entry table 167 - mov eax, 0xb0b1b2b3 168 - call eax ; call print function 169 - add esp, 8 170 - 171 - mov [esp-8], eax 172 - mov eax, 0xc0c1c2c3 ; call reg_restoreall 173 - call eax 174 - 175 - ; we cannot use IP-relative lea on 32bit x86 176 - call get_eip 177 - get_eip: 178 - pop eax 179 - add eax, 0xD ; this gives us the address of after_jump 180 - mov [esp], eax 181 - mov eax, [esp-SavedRegLen-8] 182 - 183 - jmp eax ; call the real function 184 - 185 - ALIGN 2 186 - after_jump: 187 - push eax 188 - mov eax, 0xa0a1a2a3 189 - call eax ; call reg_saveall 190 - push esp 191 - push 0x12345678 ; index in entry table 192 - mov eax, 0xb9b9b9b9 ; print function 2 193 - call eax 194 - add esp, 8 195 - 196 - mov [esp-8], eax ; real return address 197 - mov eax, 0xc0c1c2c3 198 - call eax ; call reg_restoreall 199 - 200 - mov ecx, [esp-SavedRegLen-8] 201 - jmp ecx ; return to the original caller 202 - trampoline_end: 203 - nop 204 - %else 205 - 206 - %error "Unsupported platform" 207 - 208 - %endif
+30
src/libdyld/x86-64/dyld_stub_binder.S
··· 1 + .text 2 + .globl dyld_stub_binder 3 + 4 + #ifdef __x86_64__ 5 + 6 + // Stub identifier is pushed first 7 + // then the code pushes a pointer to cache 8 + 9 + dyld_stub_binder: 10 + 11 + call reg_saveall@PLT // 224 bytes 12 + movq 224(%rsp), %rdi // cache 13 + movq 224+8(%rsp), %rsi // offset 14 + subq $8, %rsp // maintain 16-byte stack alignment 15 + 16 + call dyld_stub_binder_fixup@PLT 17 + 18 + addq $8, %rsp // maintain 16-byte stack alignment 19 + 20 + movq %rax, 224(%rsp) 21 + call reg_restoreall@PLT 22 + 23 + movq (%rsp), %r11 24 + addq $16, %rsp // remove arguments to dyld_stub_binder 25 + jmpq *%r11 26 + 27 + #endif 28 + 29 + .section ".note.GNU-stack","",@progbits 30 +
+74
src/libdyld/x86-64/tls_helper.S
··· 1 + // 2 + // This file is part of Darling. 3 + // 4 + // Copyright (C) 2013 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 + 21 + .text 22 + .globl darling_tls_get_addr 23 + .hidden darling_tls_get_addr 24 + 25 + #ifdef __x86_64__ 26 + 27 + darling_tls_get_addr: 28 + movq 8(%rdi), %rax 29 + 30 + // %gs on x86-64, %fs on i386 31 + movq %gs:0x0(,%rax,8),%rax 32 + 33 + testq %rax, %rax 34 + jz .Lslow_path 35 + 36 + addq 16(%rdi), %rax // add the variable offset 37 + ret 38 + 39 + .Lslow_path: 40 + enter $592, $0 41 + 42 + // Do a register full-save, because the caller assumes that no registers 43 + // except for rax/rdi will be modified 44 + movq %rdi, -8(%rbp) 45 + movq %rsi, -16(%rbp) 46 + movq %rdx, -24(%rbp) 47 + movq %rcx, -32(%rbp) 48 + movq %r8, -40(%rbp) 49 + movq %r9, -48(%rbp) 50 + movq %r10,-56(%rbp) 51 + movq %r11,-64(%rbp) 52 + fxsave -592(%rbp) 53 + 54 + movq 8(%rdi), %rdi // pass the pthread_key 55 + call darling_tls_allocate@PLT 56 + 57 + fxrstor -592(%rbp) 58 + movq -64(%rbp), %r11 59 + movq -56(%rbp), %r10 60 + movq -48(%rbp), %r9 61 + movq -40(%rbp), %r8 62 + movq -32(%rbp), %rcx 63 + movq -24(%rbp), %rdx 64 + movq -16(%rbp), %rsi 65 + movq -8(%rbp), %rdi 66 + 67 + addq 16(%rdi), %rax // add the variable offset 68 + leave 69 + ret 70 + 71 + #endif 72 + 73 + .section ".note.GNU-stack","",@progbits 74 +
+129
src/libdyld/x86-64/trampoline_helper.S
··· 1 + // 2 + // This file is part of Darling. 3 + // 4 + // Copyright (C) 2012 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 + .text 20 + .globl trampoline_start 21 + .globl trampoline_end 22 + .globl reg_saveall 23 + .globl reg_restoreall 24 + .hidden trampoline_start 25 + .hidden trampoline_end 26 + .hidden reg_saveall 27 + .hidden reg_restoreall 28 + 29 + #ifdef __x86_64__ 30 + 31 + reg_saveall: // 192 bytes on stack 32 + popq %r10 // remove retaddr from stack 33 + pushq %rax 34 + pushq %rbx 35 + pushq %rdi 36 + pushq %rsi 37 + pushq %rdx 38 + pushq %rcx 39 + pushq %r8 40 + pushq %r9 41 + pushq %r12 42 + pushq %r13 43 + pushq %r14 44 + pushq %r15 45 + subq $128, %rsp // 8*16 46 + movdqu %xmm0, (%rsp) 47 + movdqu %xmm1, 16(%rsp) 48 + movdqu %xmm2, 32(%rsp) 49 + movdqu %xmm3, 48(%rsp) 50 + movdqu %xmm4, 64(%rsp) 51 + movdqu %xmm5, 80(%rsp) 52 + movdqu %xmm6, 96(%rsp) 53 + movdqu %xmm7, 112(%rsp) 54 + jmpq *%r10 55 + 56 + reg_restoreall: 57 + popq %r10 // remove retaddr from stack 58 + movdqu 112(%rsp), %xmm7 59 + movdqu 96(%rsp), %xmm6 60 + movdqu 80(%rsp), %xmm5 61 + movdqu 64(%rsp), %xmm4 62 + movdqu 48(%rsp), %xmm3 63 + movdqu 32(%rsp), %xmm2 64 + movdqu 16(%rsp), %xmm1 65 + movdqu (%rsp), %xmm0 66 + addq $128, %rsp 67 + popq %r15 68 + popq %r14 69 + popq %r13 70 + popq %r12 71 + popq %r9 72 + popq %r8 73 + popq %rcx 74 + popq %rdx 75 + popq %rsi 76 + popq %rdi 77 + popq %rbx 78 + popq %rax 79 + jmpq *%r10 80 + 81 + // This is duplicated for every mapped function 82 + trampoline_start: 83 + movq 0xb0b1b2b3b4b5b6, %r10 84 + callq *%r10 // call reg_saveall 85 + 86 + movq 0x123456, %rdi // index in entry table 87 + movq %rsp, %rsi 88 + movq 0xaabbccddeeff, %rcx // print function (saves orig ret address) 89 + 90 + //sub rsp, 8 ; align stack to 16 91 + callq *%rcx 92 + //add rsp, 8 93 + 94 + movq %rax, %r11 // save the right addr 95 + 96 + movq 0xc0c1c2c3c4c5c6, %r10 // call reg_restoreall 97 + callq *%r10 98 + 99 + // rewrite return address 100 + leaq 1f(%rip), %r10 101 + movq %r10, (%rsp) // second print function 102 + jmpq *%r11 // jump to the real function 103 + 104 + .align 2 105 + 1: 106 + 107 + movq 0xb0b1b2b3b4b5b6, %r10 108 + callq *%r10 // call reg_saveall 109 + 110 + movq 0x123456, %rdi 111 + movq %rsp, %rsi 112 + movq 0xa0a1a2a3a4a5a6, %rcx // retval print function (returns orig ret address) 113 + 114 + // sub rsp, 8 ; align stack to 16 115 + callq *%rcx 116 + // add rsp, 8 117 + 118 + movq %rax, %r11 119 + 120 + movq 0xc0c1c2c3c4c5c6, %r10 // call reg_restoreall 121 + callq *%r10 122 + jmpq *%r11 // now we "return" to the original function 123 + trampoline_end: 124 + nop 125 + 126 + #endif 127 + 128 + .section ".note.GNU-stack","",@progbits 129 +
+1 -1
src/libsystem/CMakeLists.txt
··· 39 39 add_library(system SHARED ${libsystem_sources}) 40 40 target_link_libraries(system system_malloc system_c system_kernel keymgr 41 41 system_m system_info system_notify unwind libdispatch_shared objc launch 42 - removefile system_copyfile) 42 + removefile system_copyfile dyld) 43 43 44 44 install(TARGETS system DESTINATION lib${SUFFIX}/darling) 45 45