diff options
Diffstat (limited to 'ports/sysdeps/unix/sysv/linux/arm/vfork.S')
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/arm/vfork.S | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/arm/vfork.S b/ports/sysdeps/unix/sysv/linux/arm/vfork.S index a02065898..e63690eec 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/vfork.S +++ b/ports/sysdeps/unix/sysv/linux/arm/vfork.S @@ -33,7 +33,28 @@ ENTRY (__vfork) #ifdef SAVE_PID SAVE_PID #endif - DO_CALL (vfork, 0) +#ifdef __ARM_EABI__ + /* The DO_CALL macro saves r7 on the stack, to enable generation + of ARM unwind info. Since the stack is initially shared between + parent and child of vfork, that saved value could be corrupted. + To avoid this problem, we save r7 into ip as well, and restore + from there. */ + mov ip, r7 + cfi_register (r7, ip) + .fnstart + str r7, [sp, #-4]! + cfi_adjust_cfa_offset (4) + .save { r7 } + ldr r7, =SYS_ify (vfork) + swi 0x0 + .fnend + add sp, sp, #4 + cfi_adjust_cfa_offset (-4) + mov r7, ip + cfi_restore (r7); +#else + swi SYS_ify(vfork) +#endif #ifdef RESTORE_PID RESTORE_PID #endif |