diff options
| author | Khem Raj <kraj@mvista.com> | 2008-07-10 01:09:10 +0000 |
|---|---|---|
| committer | Khem Raj <kraj@mvista.com> | 2008-07-10 01:09:10 +0000 |
| commit | 5b18ea5152ec1b318620face2c17e1af7635f2d5 (patch) | |
| tree | bcc74f77ad49b2e34f63a826039fe925221ee5f6 /libc/sysdeps/linux/arm/bits/syscalls.h | |
| parent | e3c51bfa967f849292c220b4ae7f19089682f59b (diff) | |
| download | uClibc-alpine-5b18ea5152ec1b318620face2c17e1af7635f2d5.tar.bz2 uClibc-alpine-5b18ea5152ec1b318620face2c17e1af7635f2d5.tar.xz | |
Do not use push/pop in inline asm. It breaks unwinding
Diffstat (limited to 'libc/sysdeps/linux/arm/bits/syscalls.h')
| -rw-r--r-- | libc/sysdeps/linux/arm/bits/syscalls.h | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/libc/sysdeps/linux/arm/bits/syscalls.h b/libc/sysdeps/linux/arm/bits/syscalls.h index af6cf843d..85c6cbd55 100644 --- a/libc/sysdeps/linux/arm/bits/syscalls.h +++ b/libc/sysdeps/linux/arm/bits/syscalls.h @@ -137,17 +137,21 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (int) __sys_result; }) #endif #else /* !defined(__thumb__) */ - +/* We can't use push/pop inside the asm because that breaks + unwinding (ie. thread cancellation). + */ #define INTERNAL_SYSCALL(name, err, nr, args...) \ ({ unsigned int __sys_result; \ { \ + int _sys_buf[2]; \ register int _a1 __asm__ ("a1"); \ + register int *_v3 asm ("v3") = _sys_buf; \ + *_v3 = (int) (SYS_ify(name)); \ LOAD_ARGS_##nr (args) \ - register int _v3 __asm__ ("v3") = (int) (SYS_ify(name)); \ - __asm__ __volatile__ ("push {r7}\n" \ - "\tmov r7, v3\n" \ - "\tswi 0 @ syscall " #name "\n" \ - "\tpop {r7}" \ + asm volatile ("str r7, [v3, #4]\n" \ + "\tldr r7, [v3]\n" \ + "\tswi 0 @ syscall " #name "\n" \ + "\tldr r7, [v3, #4]" \ : "=r" (_a1) \ : "r" (_v3) ASM_ARGS_##nr \ : "memory"); \ |
