Skip to content

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

  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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information