linux-user: Untabify all safe-syscall.inc.S

Reviewed-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-11-23 11:44:55 +01:00
parent 212a33d3b0
commit b9d2af3c62
7 changed files with 396 additions and 396 deletions

View file

@ -10,66 +10,66 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, #function .type safe_syscall_base, #function
.type safe_syscall_start, #function .type safe_syscall_start, #function
.type safe_syscall_end, #function .type safe_syscall_end, #function
/* This is the entry point for making a system call. The calling /* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
safe_syscall_base: safe_syscall_base:
.cfi_startproc .cfi_startproc
/* The syscall calling convention isn't the same as the /* The syscall calling convention isn't the same as the
* C one: * C one:
* we enter with x0 == *signal_pending * we enter with x0 == *signal_pending
* x1 == syscall number * x1 == syscall number
* x2 ... x7, (stack) == syscall arguments * x2 ... x7, (stack) == syscall arguments
* and return the result in x0 * and return the result in x0
* and the syscall instruction needs * and the syscall instruction needs
* x8 == syscall number * x8 == syscall number
* x0 ... x6 == syscall arguments * x0 ... x6 == syscall arguments
* and returns the result in x0 * and returns the result in x0
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
*/ */
mov x9, x0 /* signal_pending pointer */ mov x9, x0 /* signal_pending pointer */
mov x8, x1 /* syscall number */ mov x8, x1 /* syscall number */
mov x0, x2 /* syscall arguments */ mov x0, x2 /* syscall arguments */
mov x1, x3 mov x1, x3
mov x2, x4 mov x2, x4
mov x3, x5 mov x3, x5
mov x4, x6 mov x4, x6
mov x5, x7 mov x5, x7
ldr x6, [sp] ldr x6, [sp]
/* This next sequence of code works in conjunction with the /* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
ldr w10, [x9] ldr w10, [x9]
cbnz w10, 0f cbnz w10, 0f
svc 0x0 svc 0x0
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
ret ret
0: 0:
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
mov x0, #-TARGET_ERESTARTSYS mov x0, #-TARGET_ERESTARTSYS
ret ret
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View file

@ -10,81 +10,81 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, %function .type safe_syscall_base, %function
.cfi_sections .debug_frame .cfi_sections .debug_frame
.text .text
.syntax unified .syntax unified
.arm .arm
.align 2 .align 2
/* This is the entry point for making a system call. The calling /* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
safe_syscall_base: safe_syscall_base:
.fnstart .fnstart
.cfi_startproc .cfi_startproc
mov r12, sp /* save entry stack */ mov r12, sp /* save entry stack */
push { r4, r5, r6, r7, r8, lr } push { r4, r5, r6, r7, r8, lr }
.save { r4, r5, r6, r7, r8, lr } .save { r4, r5, r6, r7, r8, lr }
.cfi_adjust_cfa_offset 24 .cfi_adjust_cfa_offset 24
.cfi_rel_offset r4, 0 .cfi_rel_offset r4, 0
.cfi_rel_offset r5, 4 .cfi_rel_offset r5, 4
.cfi_rel_offset r6, 8 .cfi_rel_offset r6, 8
.cfi_rel_offset r7, 12 .cfi_rel_offset r7, 12
.cfi_rel_offset r8, 16 .cfi_rel_offset r8, 16
.cfi_rel_offset lr, 20 .cfi_rel_offset lr, 20
/* The syscall calling convention isn't the same as the C one: /* The syscall calling convention isn't the same as the C one:
* we enter with r0 == *signal_pending * we enter with r0 == *signal_pending
* r1 == syscall number * r1 == syscall number
* r2, r3, [sp+0] ... [sp+12] == syscall arguments * r2, r3, [sp+0] ... [sp+12] == syscall arguments
* and return the result in r0 * and return the result in r0
* and the syscall instruction needs * and the syscall instruction needs
* r7 == syscall number * r7 == syscall number
* r0 ... r6 == syscall arguments * r0 ... r6 == syscall arguments
* and returns the result in r0 * and returns the result in r0
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
* Note the 16 bytes that we pushed to save registers. * Note the 16 bytes that we pushed to save registers.
*/ */
mov r8, r0 /* copy signal_pending */ mov r8, r0 /* copy signal_pending */
mov r7, r1 /* syscall number */ mov r7, r1 /* syscall number */
mov r0, r2 /* syscall args */ mov r0, r2 /* syscall args */
mov r1, r3 mov r1, r3
ldm r12, { r2, r3, r4, r5, r6 } ldm r12, { r2, r3, r4, r5, r6 }
/* This next sequence of code works in conjunction with the /* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
ldr r12, [r8] /* signal_pending */ ldr r12, [r8] /* signal_pending */
tst r12, r12 tst r12, r12
bne 1f bne 1f
swi 0 swi 0
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
pop { r4, r5, r6, r7, r8, pc } pop { r4, r5, r6, r7, r8, pc }
1: 1:
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
ldr r0, =-TARGET_ERESTARTSYS ldr r0, =-TARGET_ERESTARTSYS
pop { r4, r5, r6, r7, r8, pc } pop { r4, r5, r6, r7, r8, pc }
.fnend .fnend
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View file

@ -10,91 +10,91 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, @function .type safe_syscall_base, @function
/* This is the entry point for making a system call. The calling /* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
safe_syscall_base: safe_syscall_base:
.cfi_startproc .cfi_startproc
push %ebp push %ebp
.cfi_adjust_cfa_offset 4 .cfi_adjust_cfa_offset 4
.cfi_rel_offset ebp, 0 .cfi_rel_offset ebp, 0
push %esi push %esi
.cfi_adjust_cfa_offset 4 .cfi_adjust_cfa_offset 4
.cfi_rel_offset esi, 0 .cfi_rel_offset esi, 0
push %edi push %edi
.cfi_adjust_cfa_offset 4 .cfi_adjust_cfa_offset 4
.cfi_rel_offset edi, 0 .cfi_rel_offset edi, 0
push %ebx push %ebx
.cfi_adjust_cfa_offset 4 .cfi_adjust_cfa_offset 4
.cfi_rel_offset ebx, 0 .cfi_rel_offset ebx, 0
/* The syscall calling convention isn't the same as the C one: /* The syscall calling convention isn't the same as the C one:
* we enter with 0(%esp) == return address * we enter with 0(%esp) == return address
* 4(%esp) == *signal_pending * 4(%esp) == *signal_pending
* 8(%esp) == syscall number * 8(%esp) == syscall number
* 12(%esp) ... 32(%esp) == syscall arguments * 12(%esp) ... 32(%esp) == syscall arguments
* and return the result in eax * and return the result in eax
* and the syscall instruction needs * and the syscall instruction needs
* eax == syscall number * eax == syscall number
* ebx, ecx, edx, esi, edi, ebp == syscall arguments * ebx, ecx, edx, esi, edi, ebp == syscall arguments
* and returns the result in eax * and returns the result in eax
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
* Note the 16 bytes that we pushed to save registers. * Note the 16 bytes that we pushed to save registers.
*/ */
mov 12+16(%esp), %ebx /* the syscall arguments */ mov 12+16(%esp), %ebx /* the syscall arguments */
mov 16+16(%esp), %ecx mov 16+16(%esp), %ecx
mov 20+16(%esp), %edx mov 20+16(%esp), %edx
mov 24+16(%esp), %esi mov 24+16(%esp), %esi
mov 28+16(%esp), %edi mov 28+16(%esp), %edi
mov 32+16(%esp), %ebp mov 32+16(%esp), %ebp
/* This next sequence of code works in conjunction with the /* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
mov 4+16(%esp), %eax /* signal_pending */ mov 4+16(%esp), %eax /* signal_pending */
cmpl $0, (%eax) cmpl $0, (%eax)
jnz 1f jnz 1f
mov 8+16(%esp), %eax /* syscall number */ mov 8+16(%esp), %eax /* syscall number */
int $0x80 int $0x80
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
pop %ebx pop %ebx
.cfi_remember_state .cfi_remember_state
.cfi_adjust_cfa_offset -4 .cfi_adjust_cfa_offset -4
.cfi_restore ebx .cfi_restore ebx
pop %edi pop %edi
.cfi_adjust_cfa_offset -4 .cfi_adjust_cfa_offset -4
.cfi_restore edi .cfi_restore edi
pop %esi pop %esi
.cfi_adjust_cfa_offset -4 .cfi_adjust_cfa_offset -4
.cfi_restore esi .cfi_restore esi
pop %ebp pop %ebp
.cfi_adjust_cfa_offset -4 .cfi_adjust_cfa_offset -4
.cfi_restore ebp .cfi_restore ebp
ret ret
1: 1:
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
.cfi_restore_state .cfi_restore_state
mov $-TARGET_ERESTARTSYS, %eax mov $-TARGET_ERESTARTSYS, %eax
jmp safe_syscall_end jmp safe_syscall_end
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View file

@ -10,87 +10,87 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, @function .type safe_syscall_base, @function
.text .text
/* This is the entry point for making a system call. The calling /* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
#if _CALL_ELF == 2 #if _CALL_ELF == 2
safe_syscall_base: safe_syscall_base:
.cfi_startproc .cfi_startproc
.localentry safe_syscall_base,0 .localentry safe_syscall_base,0
#else #else
.section ".opd","aw" .section ".opd","aw"
.align 3 .align 3
safe_syscall_base: safe_syscall_base:
.quad .L.safe_syscall_base,.TOC.@tocbase,0 .quad .L.safe_syscall_base,.TOC.@tocbase,0
.previous .previous
.L.safe_syscall_base: .L.safe_syscall_base:
.cfi_startproc .cfi_startproc
#endif #endif
/* We enter with r3 == *signal_pending /* We enter with r3 == *signal_pending
* r4 == syscall number * r4 == syscall number
* r5 ... r10 == syscall arguments * r5 ... r10 == syscall arguments
* and return the result in r3 * and return the result in r3
* and the syscall instruction needs * and the syscall instruction needs
* r0 == syscall number * r0 == syscall number
* r3 ... r8 == syscall arguments * r3 ... r8 == syscall arguments
* and returns the result in r3 * and returns the result in r3
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
*/ */
std 14, 16(1) /* Preserve r14 in SP+16 */ std 14, 16(1) /* Preserve r14 in SP+16 */
.cfi_offset 14, 16 .cfi_offset 14, 16
mr 14, 3 /* signal_pending */ mr 14, 3 /* signal_pending */
mr 0, 4 /* syscall number */ mr 0, 4 /* syscall number */
mr 3, 5 /* syscall arguments */ mr 3, 5 /* syscall arguments */
mr 4, 6 mr 4, 6
mr 5, 7 mr 5, 7
mr 6, 8 mr 6, 8
mr 7, 9 mr 7, 9
mr 8, 10 mr 8, 10
/* This next sequence of code works in conjunction with the /* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
lwz 12, 0(14) lwz 12, 0(14)
cmpwi 0, 12, 0 cmpwi 0, 12, 0
bne- 0f bne- 0f
sc sc
safe_syscall_end: safe_syscall_end:
/* code path when we did execute the syscall */ /* code path when we did execute the syscall */
ld 14, 16(1) /* restore r14 to its original value */ ld 14, 16(1) /* restore r14 to its original value */
bnslr+ bnslr+
/* syscall failed; return negative errno */ /* syscall failed; return negative errno */
neg 3, 3 neg 3, 3
blr blr
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
0: addi 3, 0, -TARGET_ERESTARTSYS 0: addi 3, 0, -TARGET_ERESTARTSYS
ld 14, 16(1) /* restore r14 to its original value */ ld 14, 16(1) /* restore r14 to its original value */
blr blr
.cfi_endproc .cfi_endproc
#if _CALL_ELF == 2 #if _CALL_ELF == 2
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base
#else #else
.size safe_syscall_base, .-.L.safe_syscall_base .size safe_syscall_base, .-.L.safe_syscall_base
.size .L.safe_syscall_base, .-.L.safe_syscall_base .size .L.safe_syscall_base, .-.L.safe_syscall_base
#endif #endif

View file

@ -10,68 +10,68 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, @function .type safe_syscall_base, @function
.type safe_syscall_start, @function .type safe_syscall_start, @function
.type safe_syscall_end, @function .type safe_syscall_end, @function
/* /*
* This is the entry point for making a system call. The calling * This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
safe_syscall_base: safe_syscall_base:
.cfi_startproc .cfi_startproc
/* /*
* The syscall calling convention is nearly the same as C: * The syscall calling convention is nearly the same as C:
* we enter with a0 == *signal_pending * we enter with a0 == *signal_pending
* a1 == syscall number * a1 == syscall number
* a2 ... a7 == syscall arguments * a2 ... a7 == syscall arguments
* and return the result in a0 * and return the result in a0
* and the syscall instruction needs * and the syscall instruction needs
* a7 == syscall number * a7 == syscall number
* a0 ... a5 == syscall arguments * a0 ... a5 == syscall arguments
* and returns the result in a0 * and returns the result in a0
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
*/ */
mv t0, a0 /* signal_pending pointer */ mv t0, a0 /* signal_pending pointer */
mv t1, a1 /* syscall number */ mv t1, a1 /* syscall number */
mv a0, a2 /* syscall arguments */ mv a0, a2 /* syscall arguments */
mv a1, a3 mv a1, a3
mv a2, a4 mv a2, a4
mv a3, a5 mv a3, a5
mv a4, a6 mv a4, a6
mv a5, a7 mv a5, a7
mv a7, t1 mv a7, t1
/* /*
* This next sequence of code works in conjunction with the * This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* If signal_pending is non-zero, don't do the call */ /* If signal_pending is non-zero, don't do the call */
lw t1, 0(t0) lw t1, 0(t0)
bnez t1, 0f bnez t1, 0f
scall scall
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
ret ret
0: 0:
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
li a0, -TARGET_ERESTARTSYS li a0, -TARGET_ERESTARTSYS
ret ret
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View file

@ -10,81 +10,81 @@
* See the COPYING file in the top-level directory. * See the COPYING file in the top-level directory.
*/ */
.global safe_syscall_base .global safe_syscall_base
.global safe_syscall_start .global safe_syscall_start
.global safe_syscall_end .global safe_syscall_end
.type safe_syscall_base, @function .type safe_syscall_base, @function
/* This is the entry point for making a system call. The calling /* This is the entry point for making a system call. The calling
* convention here is that of a C varargs function with the * convention here is that of a C varargs function with the
* first argument an 'int *' to the signal_pending flag, the * first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further * second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long'). * arguments being syscall arguments (also 'long').
* We return a long which is the syscall's return value, which * We return a long which is the syscall's return value, which
* may be negative-errno on failure. Conversion to the * may be negative-errno on failure. Conversion to the
* -1-and-errno-set convention is done by the calling wrapper. * -1-and-errno-set convention is done by the calling wrapper.
*/ */
safe_syscall_base: safe_syscall_base:
.cfi_startproc .cfi_startproc
stmg %r6,%r15,48(%r15) /* save all call-saved registers */ stmg %r6,%r15,48(%r15) /* save all call-saved registers */
.cfi_offset %r15,-40 .cfi_offset %r15,-40
.cfi_offset %r14,-48 .cfi_offset %r14,-48
.cfi_offset %r13,-56 .cfi_offset %r13,-56
.cfi_offset %r12,-64 .cfi_offset %r12,-64
.cfi_offset %r11,-72 .cfi_offset %r11,-72
.cfi_offset %r10,-80 .cfi_offset %r10,-80
.cfi_offset %r9,-88 .cfi_offset %r9,-88
.cfi_offset %r8,-96 .cfi_offset %r8,-96
.cfi_offset %r7,-104 .cfi_offset %r7,-104
.cfi_offset %r6,-112 .cfi_offset %r6,-112
lgr %r1,%r15 lgr %r1,%r15
lg %r0,8(%r15) /* load eos */ lg %r0,8(%r15) /* load eos */
aghi %r15,-160 aghi %r15,-160
.cfi_adjust_cfa_offset 160 .cfi_adjust_cfa_offset 160
stg %r1,0(%r15) /* store back chain */ stg %r1,0(%r15) /* store back chain */
stg %r0,8(%r15) /* store eos */ stg %r0,8(%r15) /* store eos */
/* The syscall calling convention isn't the same as the /* The syscall calling convention isn't the same as the
* C one: * C one:
* we enter with r2 == *signal_pending * we enter with r2 == *signal_pending
* r3 == syscall number * r3 == syscall number
* r4, r5, r6, (stack) == syscall arguments * r4, r5, r6, (stack) == syscall arguments
* and return the result in r2 * and return the result in r2
* and the syscall instruction needs * and the syscall instruction needs
* r1 == syscall number * r1 == syscall number
* r2 ... r7 == syscall arguments * r2 ... r7 == syscall arguments
* and returns the result in r2 * and returns the result in r2
* Shuffle everything around appropriately. * Shuffle everything around appropriately.
*/ */
lgr %r8,%r2 /* signal_pending pointer */ lgr %r8,%r2 /* signal_pending pointer */
lgr %r1,%r3 /* syscall number */ lgr %r1,%r3 /* syscall number */
lgr %r2,%r4 /* syscall args */ lgr %r2,%r4 /* syscall args */
lgr %r3,%r5 lgr %r3,%r5
lgr %r4,%r6 lgr %r4,%r6
lmg %r5,%r7,320(%r15) lmg %r5,%r7,320(%r15)
/* This next sequence of code works in conjunction with the /* This next sequence of code works in conjunction with the
* rewind_if_safe_syscall_function(). If a signal is taken * rewind_if_safe_syscall_function(). If a signal is taken
* and the interrupted PC is anywhere between 'safe_syscall_start' * and the interrupted PC is anywhere between 'safe_syscall_start'
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'. * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
* The code sequence must therefore be able to cope with this, and * The code sequence must therefore be able to cope with this, and
* the syscall instruction must be the final one in the sequence. * the syscall instruction must be the final one in the sequence.
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
icm %r0,15,0(%r8) icm %r0,15,0(%r8)
jne 2f jne 2f
svc 0 svc 0
safe_syscall_end: safe_syscall_end:
1: lg %r15,0(%r15) /* load back chain */ 1: lg %r15,0(%r15) /* load back chain */
.cfi_remember_state .cfi_remember_state
.cfi_adjust_cfa_offset -160 .cfi_adjust_cfa_offset -160
lmg %r6,%r15,48(%r15) /* load saved registers */ lmg %r6,%r15,48(%r15) /* load saved registers */
br %r14 br %r14
.cfi_restore_state .cfi_restore_state
2: lghi %r2, -TARGET_ERESTARTSYS 2: lghi %r2, -TARGET_ERESTARTSYS
j 1b j 1b
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View file

@ -67,7 +67,7 @@ safe_syscall_base:
*/ */
safe_syscall_start: safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */ /* if signal_pending is non-zero, don't do the call */
cmpl $0, (%rbp) cmpl $0, (%rbp)
jnz 1f jnz 1f
syscall syscall
safe_syscall_end: safe_syscall_end: