From 8504c3b4d833a77dc3384a0af36a85aeb36d9dcc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 31 Jan 2006 00:29:30 +0000 Subject: John Bowler writes in Bug 385: This patch changes all cases where the ARM assembler mov pc,rx instructions are used to ensure that the thumb/arm interwork change of process more works - in essence mov pc,rx needs to become bx rc. The ldr pc or ldm rx, {pc} instructions are not changed - this is fine on ARM >=v5 but will fail to restore thumb mode on ARM v4T, i.e. this code will not provide support for thumb on ARM v4T. One mov pc is left in resolve.S, this is fixed in a different patch - thumb-resolve.patch The changes are protected by __THUMB_INTERWORK__ - the original mov instruction will work on newer architectures and is required on arch v4 (not v4t) and earlier - those which did not support thumb - so this is safe. See gcc lib1asmfuncs for a more exact test. --- libc/sysdeps/linux/arm/clone.S | 6 +++++- libc/sysdeps/linux/arm/vfork.S | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'libc/sysdeps/linux') diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S index 6672c7d6e..98b1296c0 100644 --- a/libc/sysdeps/linux/arm/clone.S +++ b/libc/sysdeps/linux/arm/clone.S @@ -52,7 +52,11 @@ clone: DO_CALL (clone) movs a1, a1 blt __error - movne pc, lr +#if defined(__THUMB_INTERWORK__) + bxne lr +#else + movne pc, lr +#endif @ pick the function arg and call address off the stack and execute ldr r0, [sp, #4] diff --git a/libc/sysdeps/linux/arm/vfork.S b/libc/sysdeps/linux/arm/vfork.S index e13636940..486a7e8e4 100644 --- a/libc/sysdeps/linux/arm/vfork.S +++ b/libc/sysdeps/linux/arm/vfork.S @@ -26,7 +26,11 @@ __vfork: #ifdef __NR_vfork DO_CALL (vfork) cmn r0, #4096 +#if defined(__THUMB_INTERWORK__) + bxcc lr +#else movcc pc, lr +#endif /* Check if vfork even exists. */ ldr r1, =-ENOSYS @@ -39,7 +43,11 @@ __vfork: cmn r0, #4096 /* Syscall worked. Return to child/parent */ +#if defined(__THUMB_INTERWORK__) + bxcc lr +#else movcc pc, lr +#endif __error: b __syscall_error -- cgit v1.2.3