qapi: allow unions to contain further unions
[qemu/armbru.git] / common-user / host / ppc / safe-syscall.inc.S
blob0851f6c0b8d1c0359a4635862f60c3b0e2f46c54
1 /*
2  * safe-syscall.inc.S : host-specific assembly fragment
3  * to handle signals occurring at the same time as system calls.
4  * This is intended to be included by common-user/safe-syscall.S
5  *
6  * Copyright (C) 2022 Linaro, Ltd.
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2 or later.
9  * See the COPYING file in the top-level directory.
10  */
13  * Standardize on the _CALL_FOO symbols used by GCC:
14  * Apple XCode does not define _CALL_DARWIN.
15  * Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit).
16  */
17 #if !defined(_CALL_SYSV) && \
18     !defined(_CALL_DARWIN) && \
19     !defined(_CALL_AIX) && \
20     !defined(_CALL_ELF)
21 # if defined(__APPLE__)
22 #  define _CALL_DARWIN
23 # elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32
24 #  define _CALL_SYSV
25 # else
26 #  error "Unknown ABI"
27 # endif
28 #endif 
30 #ifndef _CALL_SYSV
31 # error "Unsupported ABI"
32 #endif
35         .global safe_syscall_base
36         .global safe_syscall_start
37         .global safe_syscall_end
38         .type   safe_syscall_base, @function
40         .text
42         /*
43          * This is the entry point for making a system call. The calling
44          * convention here is that of a C varargs function with the
45          * first argument an 'int *' to the signal_pending flag, the
46          * second one the system call number (as a 'long'), and all further
47          * arguments being syscall arguments (also 'long').
48          */
49 safe_syscall_base:
50         .cfi_startproc
51         stwu    1, -8(1)
52         .cfi_def_cfa_offset 8
53         stw     30, 4(1)
54         .cfi_offset 30, -4
56         /*
57          * We enter with r3 == &signal_pending
58          *               r4 == syscall number
59          *               r5 ... r10 == syscall arguments
60          *               and return the result in r3
61          * and the syscall instruction needs
62          *               r0 == syscall number
63          *               r3 ... r8 == syscall arguments
64          *               and returns the result in r3
65          * Shuffle everything around appropriately.
66          */
67         mr      30, 3           /* signal_pending */
68         mr      0, 4            /* syscall number */
69         mr      3, 5            /* syscall arguments */
70         mr      4, 6
71         mr      5, 7
72         mr      6, 8
73         mr      7, 9
74         mr      8, 10
76         /*
77          * This next sequence of code works in conjunction with the
78          * rewind_if_safe_syscall_function(). If a signal is taken
79          * and the interrupted PC is anywhere between 'safe_syscall_start'
80          * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
81          * The code sequence must therefore be able to cope with this, and
82          * the syscall instruction must be the final one in the sequence.
83          */
84 safe_syscall_start:
85         /* if signal_pending is non-zero, don't do the call */
86         lwz     12, 0(30)
87         cmpwi   0, 12, 0
88         bne-    2f
89         sc
90 safe_syscall_end:
91         /* code path when we did execute the syscall */
92         lwz     30, 4(1)        /* restore r30 */
93         addi    1, 1, 8         /* restore stack */
94         .cfi_restore 30
95         .cfi_def_cfa_offset 0
96         bnslr+                  /* return on success */
97         b       safe_syscall_set_errno_tail
99         /* code path when we didn't execute the syscall */
100 2:      lwz     30, 4(1)
101         addi    1, 1, 8
102         addi    3, 0, QEMU_ERESTARTSYS
103         b       safe_syscall_set_errno_tail
105         .cfi_endproc
107         .size   safe_syscall_base, .-safe_syscall_base