···2626#include "trace.h"
2727#include "mutex.h"
28282929+extern "C" {
3030+int __darwin_pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
3131+int __darwin_pthread_key_delete(pthread_key_t key);
3232+int __darwin_pthread_setspecific(pthread_key_t key, const void *value);
3333+}
3434+2935static void TLSRunDestructors(void* p);
30363137static std::map<void*, Darling::ImageData*> m_images;
3238static std::map<pthread_key_t, Darling::ImageData*> m_imagesKey;
3339static Darling::Mutex m_imagesMutex;
34403535-// Maybe not a nice solution, we could implement TLS completely on our own via the fs/gs register
3636-static __thread Darling::ThreadData m_tlsData[1024]; // 1024 = PTHREAD_KEYS_MAX
3737-3841// Used for a thread-local list of destructor-object pairs (DestructorLinkedListElement)
3942static pthread_key_t m_keyDestructors;
40434141-__attribute__((constructor))
4242- static void TLSSetupDestructors()
4444+static void TLSSetupDestructors()
4345{
4444- pthread_key_create(&m_keyDestructors, TLSRunDestructors);
4646+ __darwin_pthread_key_create(&m_keyDestructors, TLSRunDestructors);
4547}
46484749static void TLSRunDestructors(void* p)
···6466 while (dlist != nullptr);
6567}
66686767-void* Darling::TLSGetNative()
6868-{
6969- return m_tlsData;
7070-}
7171-7269void Darling::TLSSetup(void* imageKey, std::vector<tlv_descriptor*>& descriptors, std::vector<void*>& initializers, void* start, uintptr_t length)
7370{
7471 Darling::MutexLock _l(&m_imagesMutex);
7572 pthread_key_t key;
7673 ImageData* id;
7474+ pthread_once_t once;
7575+7676+ pthread_once(&once, TLSSetupDestructors);
77777878 auto it = m_images.find(imageKey);
7979 assert (it == m_images.end());
80808181- pthread_key_create(&key, (void (*)(void *)) Darling::TLSTeardownThread);
8181+ __darwin_pthread_key_create(&key, (void (*)(void *)) Darling::TLSTeardownThread);
82828383 m_images[imageKey] = id = new ImageData{ key, start, length, initializers };
8484 m_imagesKey[key] = id;
···106106 // TODO: What to do with live objects with C++11 destructors? Does Apple's dyld handle this?
107107108108 m_imagesKey.erase(key);
109109- pthread_key_delete(key);
109109+ __darwin_pthread_key_delete(key);
110110111111 delete it->second;
112112 m_images.erase(it);
···127127 Darling::ImageData* id = m_imagesKey[key];
128128 char* data;
129129130130- assert(!m_tlsData[key]);
131131-132130 // Allocate a new block for TLS variables
133133- m_tlsData[key] = data = new char[id->length];
131131+ data = new char[id->length];
134132135133 // Copy the initial variable values into the new block
136134 memcpy(data, id->start, id->length);
···144142 }
145143146144 // Delete the data upon thread exit
147147- pthread_setspecific(key, data);
145145+ __darwin_pthread_setspecific(key, data);
148146149147 LOG << "TLS data allocated at " << (void*)data << std::endl;
150150- LOG << "Pointer written at " << &m_tlsData[key] << std::endl;
151148152149 return data;
153150}
···173170 d->first = d;
174171 }
175172176176- pthread_setspecific(m_keyDestructors, d);
173173+ __darwin_pthread_setspecific(m_keyDestructors, d);
177174}
178175179176void* Darling::TLSBootstrap(tlv_descriptor* desc)
-3
src/libdyld/TLS.h
···5656 // Called by pthread upon thread destruction
5757 void TLSTeardownThread(ThreadData data);
58585959- // Fast-path helper for darling_tls_get_addr()
6060- void* TLSGetNative() asm("darling_tls_get_native");
6161-6259 // Called by darling_tls_get_addr() when the variable is accessed for the first time - slow path
6360 void* TLSAllocate(pthread_key_t key) asm("darling_tls_allocate");
6461
···11+//
22+// This file is part of Darling.
33+//
44+// Copyright (C) 2013 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+.text
2121+.globl darling_tls_get_addr
2222+.hidden darling_tls_get_addr
2323+2424+#ifdef __i386__
2525+2626+// Argument is in %eax
2727+darling_tls_get_addr:
2828+2929+ movl 4(%eax), %ecx
3030+ movl %fs:0x0(,%ecx,4),%ecx
3131+3232+ testl %ecx, %ecx
3333+ jz .Lslow_path
3434+3535+ addl 8(%eax), %ecx // add the offset
3636+3737+ ret
3838+3939+.Lslow_path:
4040+ pushl %ebx
4141+ calll 1f
4242+1:
4343+ popl %ebx
4444+2:
4545+ addl $_GLOBAL_OFFSET_TABLE_+(2b-1b), %ebx
4646+4747+ pushl 4(%eax) // pass the pthread_key
4848+ call darling_tls_allocate@PLT
4949+ addl $4, %esp // remove the argument
5050+5151+ addl 8(%eax), %ecx // add the offset
5252+5353+ popl %ebx
5454+ ret
5555+5656+#endif
5757+5858+.section ".note.GNU-stack","",@progbits
5959+
+107
src/libdyld/i386/trampoline_helper.S
···11+//
22+// This file is part of Darling.
33+//
44+// Copyright (C) 2012 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+.globl trampoline_start
2020+.globl trampoline_end
2121+.globl reg_saveall
2222+.globl reg_restoreall
2323+.hidden trampoline_start
2424+.hidden trampoline_end
2525+.hidden reg_saveall
2626+.hidden reg_restoreall
2727+2828+#ifdef __i386__
2929+3030+#define SavedRegLen 32
3131+3232+reg_saveall: // 24 bytes on stack
3333+ popl %eax
3434+3535+ pushl %ebx
3636+ pushl %ecx
3737+ pushl %edx
3838+ pushl %esi
3939+ pushl %edi
4040+ subl 8, %esp
4141+ fstpl (%esp)
4242+4343+ jmpl *%eax
4444+4545+reg_restoreall:
4646+ popl %ebx
4747+ movl -4+SavedRegLen(%esp), %eax
4848+ mov %ebx, -4+SavedRegLen(%esp)
4949+5050+ fldl (%esp)
5151+ addl $8, %esp
5252+ popl %edi
5353+ popl %esi
5454+ popl %edx
5555+ popl %ecx
5656+ popl %ebx
5757+5858+ ret
5959+6060+trampoline_start:
6161+ pushl %eax
6262+ movl 0xa0a1a2a3, %eax // call reg_saveall
6363+ calll *%eax
6464+6565+ pushl %esp
6666+ pushl 0x12345678 // index in entry table
6767+ movl 0xb0b1b2b3, %eax
6868+ calll *%eax // call print function
6969+ addl $8, %esp
7070+7171+ movl %eax, -8(%esp)
7272+ movl 0xc0c1c2c3, %eax // call reg_restoreall
7373+ calll *%eax
7474+7575+ // we cannot use IP-relative lea on 32bit x86
7676+ calll .Lget_eip
7777+.Lget_eip:
7878+ popl %eax
7979+ addl $0xD, %eax // this gives us the address of after_jump
8080+ movl %eax, (%esp)
8181+ movl -8-SavedRegLen(%esp), %eax
8282+8383+ jmpl *%eax // call the real function
8484+8585+.align 2
8686+after_jump:
8787+ pushl %eax
8888+ movl 0xa0a1a2a3, %eax
8989+ calll *%eax // call reg_saveall
9090+ pushl %esp
9191+ pushl 0x12345678 // index in entry table
9292+ movl 0xb9b9b9b9, %eax // print function 2
9393+ calll *%eax
9494+ addl $8, %esp
9595+9696+ movl %eax, -8(%esp) // real return address
9797+ movl 0xc0c1c2c3, %eax
9898+ calll *%eax // call reg_restoreall
9999+100100+ movl -8-SavedRegLen, %ecx
101101+ jmpl *%ecx // return to the original caller
102102+trampoline_end:
103103+ nop
104104+105105+#endif
106106+107107+.section ".note.GNU-stack","",@progbits
-128
src/libdyld/tls_helper.nasm
···11-;
22-; This file is part of Darling.
33-;
44-; Copyright (C) 2013 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-2121-section .note.GNU-stack noalloc noexec nowrite progbits
2222-2323-extern darling_tls_get_native
2424-extern darling_tls_allocate
2525-extern _GLOBAL_OFFSET_TABLE_
2626-2727-global darling_tls_get_addr
2828-2929-%ifidn __OUTPUT_FORMAT__, elf64
3030-3131-BITS 64
3232-section text
3333-3434-darling_tls_get_addr:
3535- push rdi
3636- call darling_tls_get_native WRT ..plt ; fast three-instruction function
3737-3838- mov rdi, [rsp]
3939- mov rdi, [rdi+8]
4040- mov rax, [rax+rdi*8]
4141- pop rdi
4242-4343- test rax, rax
4444- jz slow_path
4545-4646- add rax, [rdi+16] ; add the variable offset
4747- ret
4848-4949-slow_path:
5050- enter 592, 0
5151-5252- ; Do a register full-save, because the caller assumes that no registers
5353- ; except for rax/rdi will be modified
5454- mov [rbp-8], rdi
5555- mov [rbp-16], rsi
5656- mov [rbp-24], rdx
5757- mov [rbp-32], rcx
5858- mov [rbp-40], r8
5959- mov [rbp-48], r9
6060- mov [rbp-56], r10
6161- mov [rbp-64], r11
6262- fxsave [rbp-592]
6363-6464- mov rdi, [rdi+8] ; pass the pthread_key
6565- call darling_tls_allocate WRT ..plt
6666-6767- fxrstor [rbp-592]
6868- mov r11, [rbp-64]
6969- mov r10, [rbp-56]
7070- mov r9, [rbp-48]
7171- mov r8, [rbp-40]
7272- mov rcx, [rbp-32]
7373- mov rdx, [rbp-24]
7474- mov rsi, [rbp-16]
7575- mov rdi, [rbp-8]
7676-7777- add rax, [rdi+16] ; add the variable offset
7878- leave
7979- ret
8080-8181-%elifidn __OUTPUT_FORMAT__, elf
8282-8383-BITS 32
8484-section text
8585-8686-darling_tls_get_addr:
8787-8888- push ebx
8989- call .get_GOT
9090-.get_GOT:
9191- pop ebx
9292- add ebx, _GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
9393-9494- mov ecx, eax ; eax will get destroyed
9595- push ecx
9696- call darling_tls_get_native WRT ..plt ; fast three-instruction function
9797-9898- mov ecx, [esp]
9999- mov ecx, [ecx+4] ; add the pthread key
100100- mov eax, [eax+ecx*4] ; read the value at the key
101101-102102- test eax, eax
103103- jz slow_path
104104-105105- pop ecx
106106- add eax, [ecx+8] ; add the offset
107107-108108- pop ebx
109109- ret
110110-111111-slow_path:
112112- mov ecx, [esp]
113113- push dword [ecx+4] ; pass the pthread_key
114114- call darling_tls_allocate WRT ..plt
115115- pop ecx
116116- pop ecx
117117-118118- add eax, [ecx+8] ; add the offset
119119-120120- pop ebx
121121- ret
122122-123123-%else
124124-125125-%error "Unsupported platform"
126126-127127-%endif
128128-
-208
src/libdyld/trampoline_helper.nasm
···11-;
22-; This file is part of Darling.
33-;
44-; Copyright (C) 2012 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-section .note.GNU-stack noalloc noexec nowrite progbits
2020-2121-global trampoline_start
2222-global trampoline_end
2323-global reg_saveall
2424-global reg_restoreall
2525-2626-%ifidn __OUTPUT_FORMAT__, elf64
2727-2828-BITS 64
2929-section text
3030-3131-reg_saveall: ; 192 bytes on stack
3232- pop r10 ; remove retaddr from stack
3333- push rax
3434- push rbx
3535- push rdi
3636- push rsi
3737- push rdx
3838- push rcx
3939- push r8
4040- push r9
4141- push r12
4242- push r13
4343- push r14
4444- push r15
4545- sub rsp, 128 ; 8*16
4646- movdqu [rsp], xmm0
4747- movdqu [rsp+16], xmm1
4848- movdqu [rsp+32], xmm2
4949- movdqu [rsp+48], xmm3
5050- movdqu [rsp+64], xmm4
5151- movdqu [rsp+80], xmm5
5252- movdqu [rsp+96], xmm6
5353- movdqu [rsp+112], xmm7
5454- jmp r10
5555-5656-reg_restoreall:
5757- pop r10 ; remove retaddr from stack
5858- movdqu xmm7, [rsp+112]
5959- movdqu xmm6, [rsp+96]
6060- movdqu xmm5, [rsp+80]
6161- movdqu xmm4, [rsp+64]
6262- movdqu xmm3, [rsp+48]
6363- movdqu xmm2, [rsp+32]
6464- movdqu xmm1, [rsp+16]
6565- movdqu xmm0, [rsp]
6666- add rsp, 128
6767- pop r15
6868- pop r14
6969- pop r13
7070- pop r12
7171- pop r9
7272- pop r8
7373- pop rcx
7474- pop rdx
7575- pop rsi
7676- pop rdi
7777- pop rbx
7878- pop rax
7979- jmp r10
8080-8181-; This is duplicated for every mapped function
8282-trampoline_start:
8383- mov r10, qword 0xb0b1b2b3b4b5b6
8484- call r10 ; call reg_saveall
8585-8686- mov rdi, 0x123456 ; index in entry table
8787- mov rsi, rsp
8888- mov rcx, qword 0xaabbccddeeff ; print function (saves orig ret address)
8989-9090- ;sub rsp, 8 ; align stack to 16
9191- call rcx
9292- ;add rsp, 8
9393-9494- mov r11, rax ; save the right addr
9595-9696- mov r10, qword 0xc0c1c2c3c4c5c6 ; call reg_restoreall
9797- call r10
9898-9999- ; rewrite return address
100100- lea r10, [rel after_jump]
101101- mov [rsp], r10; second print function
102102- jmp r11 ; jump to the real function
103103-104104-ALIGN 2
105105-after_jump:
106106-107107- mov r10, qword 0xb0b1b2b3b4b5b6
108108- call r10 ; call reg_saveall
109109-110110- mov rdi, 0x123456
111111- mov rsi, rsp
112112- mov rcx, qword 0xa0a1a2a3a4a5a6 ; retval print function (returns orig ret address)
113113-114114- ;sub rsp, 8 ; align stack to 16
115115- call rcx
116116- ;add rsp, 8
117117-118118- mov r11, rax
119119-120120- mov r10, qword 0xc0c1c2c3c4c5c6 ; call reg_restoreall
121121- call r10
122122- jmp r11 ; now we "return" to the original function
123123-trampoline_end:
124124- nop
125125-%elifidn __OUTPUT_FORMAT__, elf
126126-127127-BITS 32
128128-section text
129129-130130-%define SavedRegLen 32
131131-132132-reg_saveall: ; 24 bytes on stack
133133- pop eax
134134-135135- push ebx
136136- push ecx
137137- push edx
138138- push esi
139139- push edi
140140- sub esp, 8
141141- fstp qword [esp]
142142-143143- jmp eax
144144-145145-reg_restoreall:
146146- pop ebx
147147- mov eax, [esp+SavedRegLen-4]
148148- mov [esp+SavedRegLen-4], ebx
149149-150150- fld qword [esp]
151151- add esp, 8
152152- pop edi
153153- pop esi
154154- pop edx
155155- pop ecx
156156- pop ebx
157157-158158- ret
159159-160160-trampoline_start:
161161- push eax
162162- mov eax, 0xa0a1a2a3 ; call reg_saveall
163163- call eax
164164-165165- push esp
166166- push 0x12345678 ; index in entry table
167167- mov eax, 0xb0b1b2b3
168168- call eax ; call print function
169169- add esp, 8
170170-171171- mov [esp-8], eax
172172- mov eax, 0xc0c1c2c3 ; call reg_restoreall
173173- call eax
174174-175175- ; we cannot use IP-relative lea on 32bit x86
176176- call get_eip
177177-get_eip:
178178- pop eax
179179- add eax, 0xD ; this gives us the address of after_jump
180180- mov [esp], eax
181181- mov eax, [esp-SavedRegLen-8]
182182-183183- jmp eax ; call the real function
184184-185185-ALIGN 2
186186-after_jump:
187187- push eax
188188- mov eax, 0xa0a1a2a3
189189- call eax ; call reg_saveall
190190- push esp
191191- push 0x12345678 ; index in entry table
192192- mov eax, 0xb9b9b9b9 ; print function 2
193193- call eax
194194- add esp, 8
195195-196196- mov [esp-8], eax ; real return address
197197- mov eax, 0xc0c1c2c3
198198- call eax ; call reg_restoreall
199199-200200- mov ecx, [esp-SavedRegLen-8]
201201- jmp ecx ; return to the original caller
202202-trampoline_end:
203203- nop
204204-%else
205205-206206-%error "Unsupported platform"
207207-208208-%endif
···11+//
22+// This file is part of Darling.
33+//
44+// Copyright (C) 2013 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+2121+.text
2222+.globl darling_tls_get_addr
2323+.hidden darling_tls_get_addr
2424+2525+#ifdef __x86_64__
2626+2727+darling_tls_get_addr:
2828+ movq 8(%rdi), %rax
2929+3030+ // %gs on x86-64, %fs on i386
3131+ movq %gs:0x0(,%rax,8),%rax
3232+3333+ testq %rax, %rax
3434+ jz .Lslow_path
3535+3636+ addq 16(%rdi), %rax // add the variable offset
3737+ ret
3838+3939+.Lslow_path:
4040+ enter $592, $0
4141+4242+ // Do a register full-save, because the caller assumes that no registers
4343+ // except for rax/rdi will be modified
4444+ movq %rdi, -8(%rbp)
4545+ movq %rsi, -16(%rbp)
4646+ movq %rdx, -24(%rbp)
4747+ movq %rcx, -32(%rbp)
4848+ movq %r8, -40(%rbp)
4949+ movq %r9, -48(%rbp)
5050+ movq %r10,-56(%rbp)
5151+ movq %r11,-64(%rbp)
5252+ fxsave -592(%rbp)
5353+5454+ movq 8(%rdi), %rdi // pass the pthread_key
5555+ call darling_tls_allocate@PLT
5656+5757+ fxrstor -592(%rbp)
5858+ movq -64(%rbp), %r11
5959+ movq -56(%rbp), %r10
6060+ movq -48(%rbp), %r9
6161+ movq -40(%rbp), %r8
6262+ movq -32(%rbp), %rcx
6363+ movq -24(%rbp), %rdx
6464+ movq -16(%rbp), %rsi
6565+ movq -8(%rbp), %rdi
6666+6767+ addq 16(%rdi), %rax // add the variable offset
6868+ leave
6969+ ret
7070+7171+#endif
7272+7373+.section ".note.GNU-stack","",@progbits
7474+
+129
src/libdyld/x86-64/trampoline_helper.S
···11+//
22+// This file is part of Darling.
33+//
44+// Copyright (C) 2012 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+.text
2020+.globl trampoline_start
2121+.globl trampoline_end
2222+.globl reg_saveall
2323+.globl reg_restoreall
2424+.hidden trampoline_start
2525+.hidden trampoline_end
2626+.hidden reg_saveall
2727+.hidden reg_restoreall
2828+2929+#ifdef __x86_64__
3030+3131+reg_saveall: // 192 bytes on stack
3232+ popq %r10 // remove retaddr from stack
3333+ pushq %rax
3434+ pushq %rbx
3535+ pushq %rdi
3636+ pushq %rsi
3737+ pushq %rdx
3838+ pushq %rcx
3939+ pushq %r8
4040+ pushq %r9
4141+ pushq %r12
4242+ pushq %r13
4343+ pushq %r14
4444+ pushq %r15
4545+ subq $128, %rsp // 8*16
4646+ movdqu %xmm0, (%rsp)
4747+ movdqu %xmm1, 16(%rsp)
4848+ movdqu %xmm2, 32(%rsp)
4949+ movdqu %xmm3, 48(%rsp)
5050+ movdqu %xmm4, 64(%rsp)
5151+ movdqu %xmm5, 80(%rsp)
5252+ movdqu %xmm6, 96(%rsp)
5353+ movdqu %xmm7, 112(%rsp)
5454+ jmpq *%r10
5555+5656+reg_restoreall:
5757+ popq %r10 // remove retaddr from stack
5858+ movdqu 112(%rsp), %xmm7
5959+ movdqu 96(%rsp), %xmm6
6060+ movdqu 80(%rsp), %xmm5
6161+ movdqu 64(%rsp), %xmm4
6262+ movdqu 48(%rsp), %xmm3
6363+ movdqu 32(%rsp), %xmm2
6464+ movdqu 16(%rsp), %xmm1
6565+ movdqu (%rsp), %xmm0
6666+ addq $128, %rsp
6767+ popq %r15
6868+ popq %r14
6969+ popq %r13
7070+ popq %r12
7171+ popq %r9
7272+ popq %r8
7373+ popq %rcx
7474+ popq %rdx
7575+ popq %rsi
7676+ popq %rdi
7777+ popq %rbx
7878+ popq %rax
7979+ jmpq *%r10
8080+8181+// This is duplicated for every mapped function
8282+trampoline_start:
8383+ movq 0xb0b1b2b3b4b5b6, %r10
8484+ callq *%r10 // call reg_saveall
8585+8686+ movq 0x123456, %rdi // index in entry table
8787+ movq %rsp, %rsi
8888+ movq 0xaabbccddeeff, %rcx // print function (saves orig ret address)
8989+9090+ //sub rsp, 8 ; align stack to 16
9191+ callq *%rcx
9292+ //add rsp, 8
9393+9494+ movq %rax, %r11 // save the right addr
9595+9696+ movq 0xc0c1c2c3c4c5c6, %r10 // call reg_restoreall
9797+ callq *%r10
9898+9999+ // rewrite return address
100100+ leaq 1f(%rip), %r10
101101+ movq %r10, (%rsp) // second print function
102102+ jmpq *%r11 // jump to the real function
103103+104104+.align 2
105105+1:
106106+107107+ movq 0xb0b1b2b3b4b5b6, %r10
108108+ callq *%r10 // call reg_saveall
109109+110110+ movq 0x123456, %rdi
111111+ movq %rsp, %rsi
112112+ movq 0xa0a1a2a3a4a5a6, %rcx // retval print function (returns orig ret address)
113113+114114+ // sub rsp, 8 ; align stack to 16
115115+ callq *%rcx
116116+ // add rsp, 8
117117+118118+ movq %rax, %r11
119119+120120+ movq 0xc0c1c2c3c4c5c6, %r10 // call reg_restoreall
121121+ callq *%r10
122122+ jmpq *%r11 // now we "return" to the original function
123123+trampoline_end:
124124+ nop
125125+126126+#endif
127127+128128+.section ".note.GNU-stack","",@progbits
129129+