1/*
2 * Copyright 2019, J��r��me Duval, jerome.duval@gmail.com.
3 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include <asm_defs.h>
8
9
10call_stub:
11	// push arguments on the stack
12	push	%r9
13	push	%r8
14	push	%rcx
15	push	%rdx
16	push	%rsi
17	push	%rdi
18	// pointer to ourself
19	lea		call_stub(%rip), %rdi
20	// pointer to first argument
21	mov		%rsp, %rsi
22
23	// call the wrapper function
24	movq	(call_stub_callback_address - call_stub)(%rdi), %rax
25	call	*%rax
26				// returns a pointer to the actual function
27	// restore arguments before calling
28	pop		%rdi
29	pop		%rsi
30	pop		%rdx
31	pop		%rcx
32	pop		%r8
33	pop		%r9
34	jmp		*%rax
35
36.align 8
37call_stub_callback_address:
38	.long	0
39call_stub_end:
40
41
42// size_t arch_call_stub_size();
43FUNCTION(arch_call_stub_size):
44	movq	$(call_stub_end - call_stub), %rax
45	ret
46FUNCTION_END(arch_call_stub_size)
47
48
49// void arch_init_call_stub(void* stub,
50//		void* (*callback)(const void* stub, const void* args),
51//		void* function);
52FUNCTION(arch_init_call_stub):
53	push	%rbp
54	movq	%rsp, %rbp
55
56	push	%rsi
57	push	%rdi
58
59	// copy the stub
60	movq	$(call_stub_end - call_stub), %rdx
61	lea		call_stub(%rip), %rsi
62	call	memcpy@plt
63
64	// set the callback address in the stub
65	pop		%rdi
66	pop		%rsi
67	movq	%rsi, (call_stub_callback_address - call_stub)(%rdi)
68
69	movq	%rbp, %rsp
70	pop		%rbp
71	ret
72FUNCTION_END(arch_init_call_stub)
73