-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathapi_amd64.S
More file actions
80 lines (74 loc) · 1.94 KB
/
api_amd64.S
File metadata and controls
80 lines (74 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// UEFI Call Stub for x86_64
//
// Generic stub for calling any UEFI function via the Microsoft x64 ABI.
//
// Go signature: func callAsm(fn uintptr, args *uintptr, nargs uintptr) Status
// MS x64 entry:
// RCX = fn (function pointer to call)
// RDX = args (pointer to uintptr array of arguments)
// R8 = nargs (number of arguments, 0-N)
//
// MS x64 ABI register mapping for the callee:
// Args 1-4: RCX, RDX, R8, R9
// Args 5+: stack (after 32-byte shadow space)
// Return: RAX
// Stack: 16-byte aligned before CALL
//
.section .text.uefiCall,"ax"
.global uefiCall
uefiCall:
pushq %rbp
movq %rsp, %rbp
pushq %rsi
pushq %rdi
movq %rcx, %r10 // Save fn
movq %rdx, %rsi // Save args pointer
movq %r8, %rdi // Save nargs
// Calculate stack space: align16(32 + max(0, nargs-4) * 8)
// After 3 pushes, RSP is 16-byte aligned. Subtracting an aligned
// value keeps it aligned for the CALL instruction.
xorq %rax, %rax
cmpq $4, %rdi
jle 1f
movq %rdi, %rax
subq $4, %rax
1:
shlq $3, %rax // nStackArgs * 8
addq $47, %rax // + 32 (shadow) + 15 (round-up)
andq $-16, %rax // align to 16
subq %rax, %rsp
// Copy stack args: args[4..nargs-1] -> RSP+32+j*8
movq %rdi, %rcx
subq $4, %rcx
jle 2f
xorq %rax, %rax
3: movq 32(%rsi,%rax,8), %r11
movq %r11, 32(%rsp,%rax,8)
incq %rax
cmpq %rcx, %rax
jl 3b
2:
// Load register args
xorq %rcx, %rcx
xorq %rdx, %rdx
xorq %r8, %r8
xorq %r9, %r9
testq %rdi, %rdi
jz 4f
movq 0(%rsi), %rcx // args[0] -> RCX
cmpq $2, %rdi
jl 4f
movq 8(%rsi), %rdx // args[1] -> RDX
cmpq $3, %rdi
jl 4f
movq 16(%rsi), %r8 // args[2] -> R8
cmpq $4, %rdi
jl 4f
movq 24(%rsi), %r9 // args[3] -> R9
4:
callq *%r10
leaq -16(%rbp), %rsp
popq %rdi
popq %rsi
popq %rbp
retq