901-MIPS-restore-INLINE_SYSCALL-macro.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From 911bf867eb82e28799e81578c50d82ee166cebb5 Mon Sep 17 00:00:00 2001
  2. From: Gabor Juhos <[email protected]>
  3. Date: Tue, 6 Apr 2010 17:25:56 +0200
  4. Subject: [PATCH] MIPS: restore INLINE_SYSCALL macro
  5. The MIPS specific INLINE_SYSCALL macro has been renamed to
  6. INLINE_SYSCALL_NCS with:
  7. 763bbf9e9a27426c9be8322dca5ddf2cb4dbc464
  8. syscall: unify part 2: NCS variety
  9. Declare common NCS (non-constant syscall) variants and convert the
  10. existing ports over to this.
  11. This change breaks system calls. The code generated with using of the
  12. new macro does not obey the restartable syscall convention used by the
  13. linux kernel. When it tries to restart the syscall the errno value is
  14. not being replaced by the syscall number.
  15. This causes weird behaviour of the 'ping' command in busybox for
  16. example:
  17. root@OpenWrt:/# ping 192.168.1.254
  18. PING 192.168.1.254 (192.168.1.254): 56 data bytes
  19. 64 bytes from 192.168.1.254: seq=0 ttl=128 time=6.292 ms
  20. ping: recvfrom: Function not implemented
  21. 64 bytes from 192.168.1.254: seq=1 ttl=128 time=0.719 ms
  22. ping: recvfrom: Function not implemented
  23. 64 bytes from 192.168.1.254: seq=2 ttl=128 time=0.489 ms
  24. ping: recvfrom: Function not implemented
  25. 64 bytes from 192.168.1.254: seq=3 ttl=128 time=0.486 ms
  26. ping: recvfrom: Function not implemented
  27. 64 bytes from 192.168.1.254: seq=4 ttl=128 time=0.487 ms
  28. ping: recvfrom: Function not implemented
  29. 64 bytes from 192.168.1.254: seq=5 ttl=128 time=0.939 ms
  30. ping: recvfrom: Function not implemented
  31. 64 bytes from 192.168.1.254: seq=6 ttl=128 time=0.971 ms
  32. ping: recvfrom: Function not implemented
  33. 64 bytes from 192.168.1.254: seq=7 ttl=128 time=0.488 ms
  34. ping: recvfrom: Funct^C
  35. --- 192.168.1.254 ping statistics ---
  36. 9 packets transmitted, 9 packets received, 0% packet loss
  37. round-trip min/avg/max = 0.486/1.307/6.292 ms
  38. root@OpenWrt:/#
  39. Here is the relevant assembler code parts of the 'recvfrom' function:
  40. with the current INLINE_SYSCALL_NCS:
  41. 00000000 <__GI_recvfrom>:
  42. ...
  43. 2c: 24021050 li v0,4176
  44. 30: 8fd1003c lw s1,60(s8)
  45. 34: 8fd00038 lw s0,56(s8)
  46. 38: 27bdffe0 addiu sp,sp,-32
  47. 3c: afb00010 sw s0,16(sp)
  48. 40: afb10014 sw s1,20(sp) <-- wrong
  49. 44: 0000000c syscall
  50. 48: 27bd0020 addiu sp,sp,32
  51. ...
  52. with the old INLINE_SYSCALL:
  53. 00000000 <__libc_recvfrom>:
  54. ...
  55. 28: 8fd0003c lw s0,60(s8)
  56. 2c: 8fc20038 lw v0,56(s8)
  57. 30: 27bdffe0 addiu sp,sp,-32
  58. 34: afa20010 sw v0,16(sp)
  59. 38: afb00014 sw s0,20(sp)
  60. 3c: 24021050 li v0,4176 <-- good
  61. 40: 0000000c syscall
  62. 44: 27bd0020 addiu sp,sp,32
  63. ...
  64. Signed-off-by: Gabor Juhos <[email protected]>
  65. Cc: Mike Frysinger <[email protected]>
  66. ---
  67. Notes:
  68. The ideal solution would to fix the 'internal_syscall' macros to generate
  69. correct code for the NCS case as well. However the INLINE_SYSCALL macro
  70. generates smaller code if the syscall number is constant, so it is
  71. useful in such cases.
  72. Additionally, the current INLINE_SYSCALL_NCS in the 'mips/bits/syscall.h'
  73. is a duplicate of the one in the 'common/bits/syscalls-common.h' so it
  74. should be removed anyway.
  75. ---
  76. libc/sysdeps/linux/mips/bits/syscalls.h | 4 ++--
  77. 1 files changed, 2 insertions(+), 2 deletions(-)
  78. diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
  79. index 28b0f91..944d038 100644
  80. --- a/libc/sysdeps/linux/mips/bits/syscalls.h
  81. +++ b/libc/sysdeps/linux/mips/bits/syscalls.h
  82. @@ -19,9 +19,9 @@
  83. /* Define a macro which expands into the inline wrapper code for a system
  84. call. */
  85. -#define INLINE_SYSCALL_NCS(name, nr, args...) \
  86. +#define INLINE_SYSCALL(name, nr, args...) \
  87. ({ INTERNAL_SYSCALL_DECL(err); \
  88. - long result_var = INTERNAL_SYSCALL_NCS (name, err, nr, args); \
  89. + long result_var = INTERNAL_SYSCALL(name, err, nr, args); \
  90. if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \
  91. { \
  92. __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
  93. --
  94. 1.5.3.2