aboutsummaryrefslogtreecommitdiff
path: root/libc/arch-x86/bionic/syscall.S
blob: 12402aca4da6a138d737bfb3afa3e0daa02c8c04 (plain)
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
/*
 * Generic syscall call.
 * Upon entry:
 *	%eax: system call number  - caller save
 *	%ebx: arg0 to system call -   callee save
 *	%ecx: arg1                - caller save
 *	%edx: arg2                - caller save
 *	%esi: arg3                -   callee save
 *	%edi: arg4                -   callee save
 *	%ebp: arg5                -   callee save
 */

#include <private/bionic_asm.h>

ENTRY(syscall)
    # Push the callee save registers.
    push    %ebx
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset ebx, 0
    push    %esi
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset esi, 0
    push    %edi
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset edi, 0
    push    %ebp
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset ebp, 0

    # Get and save the system call entry address.
    call    __kernel_syscall
    push    %eax
    .cfi_adjust_cfa_offset 4
    .cfi_rel_offset eax, 0

    # Load all the arguments from the calling frame.
    # (Not all will be valid, depending on the syscall.)
    mov     24(%esp),%eax
    mov     28(%esp),%ebx
    mov     32(%esp),%ecx
    mov     36(%esp),%edx
    mov     40(%esp),%esi
    mov     44(%esp),%edi
    mov     48(%esp),%ebp

    # Make the system call.
    call    *(%esp)
    addl    $4, %esp

    # Error?
    cmpl    $-MAX_ERRNO, %eax
    jb      1f
    # Yes, so set errno.
    negl    %eax
    pushl   %eax
    call    __set_errno_internal
    addl    $4, %esp
1:
    # Restore the callee save registers.
    pop    %ebp
    .cfi_adjust_cfa_offset -4
    .cfi_restore ebp
    pop    %edi
    .cfi_adjust_cfa_offset -4
    .cfi_restore edi
    pop    %esi
    .cfi_adjust_cfa_offset -4
    .cfi_restore esi
    pop    %ebx
    .cfi_adjust_cfa_offset -4
    .cfi_restore ebx
    ret
END(syscall)