| #include "uml-config.h" |
| #include "as-layout.h" |
| |
| .globl syscall_stub |
| .section .__syscall_stub, "x" |
| syscall_stub: |
| syscall |
| /* We don't have 64-bit constants, so this constructs the address |
| * we need. |
| */ |
| movq $(ASM_STUB_DATA >> 32), %rbx |
| salq $32, %rbx |
| movq $(ASM_STUB_DATA & 0xffffffff), %rcx |
| or %rcx, %rbx |
| movq %rax, (%rbx) |
| int3 |
| |
| .globl batch_syscall_stub |
| batch_syscall_stub: |
| mov $(ASM_STUB_DATA >> 32), %rbx |
| sal $32, %rbx |
| mov $(ASM_STUB_DATA & 0xffffffff), %rax |
| or %rax, %rbx |
| /* load pointer to first operation */ |
| mov %rbx, %rsp |
| add $0x10, %rsp |
| again: |
| /* load length of additional data */ |
| mov 0x0(%rsp), %rax |
| |
| /* if(length == 0) : end of list */ |
| /* write possible 0 to header */ |
| mov %rax, 8(%rbx) |
| cmp $0, %rax |
| jz done |
| |
| /* save current pointer */ |
| mov %rsp, 8(%rbx) |
| |
| /* skip additional data */ |
| add %rax, %rsp |
| |
| /* load syscall-# */ |
| pop %rax |
| |
| /* load syscall params */ |
| pop %rdi |
| pop %rsi |
| pop %rdx |
| pop %r10 |
| pop %r8 |
| pop %r9 |
| |
| /* execute syscall */ |
| syscall |
| |
| /* check return value */ |
| pop %rcx |
| cmp %rcx, %rax |
| je again |
| |
| done: |
| /* save return value */ |
| mov %rax, (%rbx) |
| |
| /* stop */ |
| int3 |