syscall: 0.401 instruction: 0.321 runtime: 0.278 PowerPC host code is broken on Darwin Description of problem: Existing code is just wrong for Darwin ppc, it won’t compile. Assembler syntax needs to be fixed and likely adjusted to correct ABI. Steps to reproduce: 1. Run the build of qemu on Darwin ppc, see it fail. Additional information: This is a patch I used earlier to fix the build (together with few minor unrelated to powerpc fixes): ``` --- common-user/host/ppc/safe-syscall.inc.S.orig 2022-04-20 03:10:27.000000000 +0800 +++ common-user/host/ppc/safe-syscall.inc.S 2023-08-18 18:08:15.000000000 +0800 @@ -25,17 +25,11 @@ # else # error "Unknown ABI" # endif -#endif - -#ifndef _CALL_SYSV -# error "Unsupported ABI" #endif - .global safe_syscall_base .global safe_syscall_start .global safe_syscall_end - .type safe_syscall_base, @function .text @@ -47,11 +41,8 @@ * arguments being syscall arguments (also 'long'). */ safe_syscall_base: - .cfi_startproc - stwu 1, -8(1) - .cfi_def_cfa_offset 8 - stw 30, 4(1) - .cfi_offset 30, -4 + stwu r1, -8(r1) + stw r30, 4(r1) /* * We enter with r3 == &signal_pending @@ -64,14 +55,14 @@ * and returns the result in r3 * Shuffle everything around appropriately. */ - mr 30, 3 /* signal_pending */ - mr 0, 4 /* syscall number */ - mr 3, 5 /* syscall arguments */ - mr 4, 6 - mr 5, 7 - mr 6, 8 - mr 7, 9 - mr 8, 10 + mr r30, r3 /* signal_pending */ + mr r0, r4 /* syscall number */ + mr r3, r5 /* syscall arguments */ + mr r4, r6 + mr r5, r7 + mr r6, r8 + mr r7, r9 + mr r8, r10 /* * This next sequence of code works in conjunction with the @@ -83,25 +74,22 @@ */ safe_syscall_start: /* if signal_pending is non-zero, don't do the call */ - lwz 12, 0(30) - cmpwi 0, 12, 0 + lwz r12, 0(r30) + cmpwi cr0, r12, 0 bne- 2f sc safe_syscall_end: /* code path when we did execute the syscall */ - lwz 30, 4(1) /* restore r30 */ - addi 1, 1, 8 /* restore stack */ - .cfi_restore 30 - .cfi_def_cfa_offset 0 + lwz r30, 4(r1) /* restore r30 */ + addi r1, r1, 8 /* restore stack */ + bnslr+ /* return on success */ b safe_syscall_set_errno_tail /* code path when we didn't execute the syscall */ -2: lwz 30, 4(1) - addi 1, 1, 8 - addi 3, 0, QEMU_ERESTARTSYS +2: lwz r30, 4(r1) + addi r1, r1, 8 + addi r3, 0, QEMU_ERESTARTSYS b safe_syscall_set_errno_tail - .cfi_endproc - .size safe_syscall_base, .-safe_syscall_base --- common-user/host/ppc64/safe-syscall.inc.S.orig 2022-04-20 03:10:27.000000000 +0800 +++ common-user/host/ppc64/safe-syscall.inc.S 2022-05-31 13:23:21.000000000 +0800 @@ -13,7 +13,6 @@ .global safe_syscall_base .global safe_syscall_start .global safe_syscall_end - .type safe_syscall_base, @function .text @@ -23,19 +22,10 @@ * second one the system call number (as a 'long'), and all further * arguments being syscall arguments (also 'long'). */ -#if _CALL_ELF == 2 -safe_syscall_base: - .cfi_startproc - .localentry safe_syscall_base,0 -#else - .section ".opd","aw" + .align 3 safe_syscall_base: - .quad .L.safe_syscall_base,.TOC.@tocbase,0 - .previous -.L.safe_syscall_base: - .cfi_startproc -#endif + /* We enter with r3 == &signal_pending * r4 == syscall number * r5 ... r10 == syscall arguments @@ -46,16 +36,15 @@ * and returns the result in r3 * Shuffle everything around appropriately. */ - std 14, 16(1) /* Preserve r14 in SP+16 */ - .cfi_offset 14, 16 - mr 14, 3 /* signal_pending */ - mr 0, 4 /* syscall number */ - mr 3, 5 /* syscall arguments */ - mr 4, 6 - mr 5, 7 - mr 6, 8 - mr 7, 9 - mr 8, 10 + std r14, 16(r1) /* Preserve r14 in SP+16 */ + mr r14, r3 /* signal_pending */ + mr r0, r4 /* syscall number */ + mr r3, r5 /* syscall arguments */ + mr r4, r6 + mr r5, r7 + mr r6, r8 + mr r7, r9 + mr r8, r10 /* This next sequence of code works in conjunction with the * rewind_if_safe_syscall_function(). If a signal is taken @@ -66,29 +55,20 @@ */ safe_syscall_start: /* if signal_pending is non-zero, don't do the call */ - lwz 12, 0(14) - cmpwi 0, 12, 0 + ld r12, 0(r14) + cmpdi cr0, r12, 0 bne- 2f sc safe_syscall_end: /* code path when we did execute the syscall */ - ld 14, 16(1) /* restore r14 */ + ld r14, 16(r1) /* restore r14 */ bso- 1f blr /* code path when we didn't execute the syscall */ -2: ld 14, 16(1) /* restore r14 */ - addi 3, 0, QEMU_ERESTARTSYS +2: ld r14, 16(r1) /* restore r14 */ + addi r3, 0, QEMU_ERESTARTSYS /* code path setting errno */ 1: b safe_syscall_set_errno_tail nop /* per abi, for the linker to modify */ - - .cfi_endproc - -#if _CALL_ELF == 2 - .size safe_syscall_base, .-safe_syscall_base -#else - .size safe_syscall_base, .-.L.safe_syscall_base - .size .L.safe_syscall_base, .-.L.safe_syscall_base -#endif ``` (Obviously, it is not made in a portable way – that was not needed at the time.) Unfortunately, while build itself worked, the binary crashed on launch. So something is not quite right, maybe with ABI compliance.