PowerPC host code is broken on Darwin
Host environment
- Operating system: macOS 10.5 / 10.6
- Architecture: PowerPC
- QEMU version: 7.x and later
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
- 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.