diff options
-rw-r--r-- | toolchain/uClibc/patches-0.9.31/901-MIPS-restore-INLINE_SYSCALL-macro.patch | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/toolchain/uClibc/patches-0.9.31/901-MIPS-restore-INLINE_SYSCALL-macro.patch b/toolchain/uClibc/patches-0.9.31/901-MIPS-restore-INLINE_SYSCALL-macro.patch new file mode 100644 index 0000000000..4ba09424b9 --- /dev/null +++ b/toolchain/uClibc/patches-0.9.31/901-MIPS-restore-INLINE_SYSCALL-macro.patch @@ -0,0 +1,110 @@ +From 911bf867eb82e28799e81578c50d82ee166cebb5 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos <juhosg@openwrt.org> +Date: Tue, 6 Apr 2010 17:25:56 +0200 +Subject: [PATCH] MIPS: restore INLINE_SYSCALL macro + +The MIPS specific INLINE_SYSCALL macro has been renamed to +INLINE_SYSCALL_NCS with: + + 763bbf9e9a27426c9be8322dca5ddf2cb4dbc464 + + syscall: unify part 2: NCS variety + + Declare common NCS (non-constant syscall) variants and convert the + existing ports over to this. + +This change breaks system calls. The code generated with using of the +new macro does not obey the restartable syscall convention used by the +linux kernel. When it tries to restart the syscall the errno value is +not being replaced by the syscall number. + +This causes weird behaviour of the 'ping' command in busybox for +example: + +root@OpenWrt:/# ping 192.168.1.254 +PING 192.168.1.254 (192.168.1.254): 56 data bytes +64 bytes from 192.168.1.254: seq=0 ttl=128 time=6.292 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=1 ttl=128 time=0.719 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=2 ttl=128 time=0.489 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=3 ttl=128 time=0.486 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=4 ttl=128 time=0.487 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=5 ttl=128 time=0.939 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=6 ttl=128 time=0.971 ms +ping: recvfrom: Function not implemented +64 bytes from 192.168.1.254: seq=7 ttl=128 time=0.488 ms +ping: recvfrom: Funct^C +--- 192.168.1.254 ping statistics --- +9 packets transmitted, 9 packets received, 0% packet loss +round-trip min/avg/max = 0.486/1.307/6.292 ms +root@OpenWrt:/# + +Here is the relevant assembler code parts of the 'recvfrom' function: + +with the current INLINE_SYSCALL_NCS: +00000000 <__GI_recvfrom>: + ... + 2c: 24021050 li v0,4176 + 30: 8fd1003c lw s1,60(s8) + 34: 8fd00038 lw s0,56(s8) + 38: 27bdffe0 addiu sp,sp,-32 + 3c: afb00010 sw s0,16(sp) + 40: afb10014 sw s1,20(sp) <-- wrong + 44: 0000000c syscall + 48: 27bd0020 addiu sp,sp,32 + ... + +with the old INLINE_SYSCALL: +00000000 <__libc_recvfrom>: + ... + 28: 8fd0003c lw s0,60(s8) + 2c: 8fc20038 lw v0,56(s8) + 30: 27bdffe0 addiu sp,sp,-32 + 34: afa20010 sw v0,16(sp) + 38: afb00014 sw s0,20(sp) + 3c: 24021050 li v0,4176 <-- good + 40: 0000000c syscall + 44: 27bd0020 addiu sp,sp,32 + ... + +Signed-off-by: Gabor Juhos <juhosg@openwrt.org> +Cc: Mike Frysinger <vapier@gentoo.org> +--- +Notes: + +The ideal solution would to fix the 'internal_syscall' macros to generate +correct code for the NCS case as well. However the INLINE_SYSCALL macro +generates smaller code if the syscall number is constant, so it is +useful in such cases. + +Additionally, the current INLINE_SYSCALL_NCS in the 'mips/bits/syscall.h' +is a duplicate of the one in the 'common/bits/syscalls-common.h' so it +should be removed anyway. +--- + libc/sysdeps/linux/mips/bits/syscalls.h | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h +index 28b0f91..944d038 100644 +--- a/libc/sysdeps/linux/mips/bits/syscalls.h ++++ b/libc/sysdeps/linux/mips/bits/syscalls.h +@@ -19,9 +19,9 @@ + + /* Define a macro which expands into the inline wrapper code for a system + call. */ +-#define INLINE_SYSCALL_NCS(name, nr, args...) \ ++#define INLINE_SYSCALL(name, nr, args...) \ + ({ INTERNAL_SYSCALL_DECL(err); \ +- long result_var = INTERNAL_SYSCALL_NCS (name, err, nr, args); \ ++ long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ + if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \ +-- +1.5.3.2 + |