diff options
Diffstat (limited to 'boot/fake_syscall_entry.S')
| -rw-r--r-- | boot/fake_syscall_entry.S | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/boot/fake_syscall_entry.S b/boot/fake_syscall_entry.S index bc175c1..8a3f8c8 100644 --- a/boot/fake_syscall_entry.S +++ b/boot/fake_syscall_entry.S @@ -1,34 +1,79 @@ .section .text .global fake_syscall_entry -.global fake_syscall_return +.global fake_syscall_start .extern fake_syscall_handler -fake_syscall_entry: - hlt; - -fake_syscall_return: +fake_syscall_start: cli -fake_syscall_swap: - mov %cs, %rax - pushq %rax - pushq %rdx - mov %ds, %rax - pushq %rax - sub $16, %rsp - sgdt (%rsp) - mov %rsp, (%rsi) mov %rdi, %rsp - lgdt (%rsp) - add $16, %rsp - movw (%rsp), %ds - movw (%rsp), %es - movw (%rsp), %fs - movw (%rsp), %gs - movw (%rsp), %ss + jmp .L_fake_syscall_return + +/* + SYSCALL STACK FRAME - FROM LOWER TO HIGHER ADDRESS + + 0 pad + 8 syscall_index + 16 parameters[0] + 24 parameters[1] + 32 parameters[2] + 40 parameters[3] + 48 parameters[4] + 56 parameters[5] + 64 state.rflags + 72 state.gdtr.base:2 state.gdtr.limit:6 + 80 state.gdtr.limit:2 [unused]:6 + 88 state.return_ds + 96 state.return_rip + 104 state.return_cs +*/ + +fake_syscall_entry: + sub $112, %rsp + mov %rax, 8(%rsp) + mov %rdi, 16(%rsp) + mov %rsi, 24(%rsp) + mov %rdx, 32(%rsp) + mov %r10, 40(%rsp) + mov %r8, 48(%rsp) + mov %r9, 56(%rsp) + + pushfq + pop %rdi + mov %rdi, 64(%rsp) + + sgdt 72(%rsp) + movw %ds, 88(%rsp) + mov %rcx, 96(%rsp) + movw %cs, 104(%rsp) + + mov %rsp, %rdi + call fake_syscall_handler + + push %rbp + mov %rsp, %rbp + add $64, %rsp + popfq + mov %rbp, %rsp + pop %rbp + +.L_fake_syscall_return: + lgdt 72(%rsp) + mov 88(%rsp), %rdi + mov %di, %ds + mov %di, %es + mov %di, %fs + mov %di, %gs + mov %di, %ss - add $8, %rsp + mov 16(%rsp), %rdi + mov 24(%rsp), %rsi + mov 32(%rsp), %rdx + mov 40(%rsp), %r10 + mov 48(%rsp), %r8 + mov 56(%rsp), %r9 + add $96, %rsp lretq |
