1/*
2 * Generic syscall call.
3 * Upon entry:
4 *	%eax: system call number  - caller save
5 *	%ebx: arg0 to system call -   callee save
6 *	%ecx: arg1                - caller save
7 *	%edx: arg2                - caller save
8 *	%esi: arg3                -   callee save
9 *	%edi: arg4                -   callee save
10 *	%ebp: arg5                -   callee save
11 */
12
13#include <private/bionic_asm.h>
14
15ENTRY(syscall)
16    # Push the callee save registers.
17    push    %ebx
18    .cfi_adjust_cfa_offset 4
19    .cfi_rel_offset ebx, 0
20    push    %esi
21    .cfi_adjust_cfa_offset 4
22    .cfi_rel_offset esi, 0
23    push    %edi
24    .cfi_adjust_cfa_offset 4
25    .cfi_rel_offset edi, 0
26    push    %ebp
27    .cfi_adjust_cfa_offset 4
28    .cfi_rel_offset ebp, 0
29
30    # Get and save the system call entry address.
31    call    __kernel_syscall
32    push    %eax
33    .cfi_adjust_cfa_offset 4
34    .cfi_rel_offset eax, 0
35
36    # Load all the arguments from the calling frame.
37    # (Not all will be valid, depending on the syscall.)
38    mov     24(%esp),%eax
39    mov     28(%esp),%ebx
40    mov     32(%esp),%ecx
41    mov     36(%esp),%edx
42    mov     40(%esp),%esi
43    mov     44(%esp),%edi
44    mov     48(%esp),%ebp
45
46    # Make the system call.
47    call    *(%esp)
48    addl    $4, %esp
49
50    # Error?
51    cmpl    $-MAX_ERRNO, %eax
52    jb      1f
53    # Yes, so set errno.
54    negl    %eax
55    pushl   %eax
56    call    __set_errno_internal
57    addl    $4, %esp
581:
59    # Restore the callee save registers.
60    pop    %ebp
61    .cfi_adjust_cfa_offset -4
62    .cfi_restore ebp
63    pop    %edi
64    .cfi_adjust_cfa_offset -4
65    .cfi_restore edi
66    pop    %esi
67    .cfi_adjust_cfa_offset -4
68    .cfi_restore esi
69    pop    %ebx
70    .cfi_adjust_cfa_offset -4
71    .cfi_restore ebx
72    ret
73END(syscall)
74