f48b9aeb4539daadc29ae9de913acc65944c721a
[packages/trusty/cirros-testvm.git] / cirros-testvm / src-cirros / buildroot-2015.05 / package / uclibc / 0.9.33.2 / 0024-MIPS-Use-a0-instead-of-v0-for-__syscall_error-argume.patch
1 From c8f9e946bc2a0a42e84b5f97f272932de6485b54 Mon Sep 17 00:00:00 2001
2 From: Kevin Cernekee <cernekee@gmail.com>
3 Date: Tue, 5 Jun 2012 15:05:20 -0700
4 Subject: [PATCH] MIPS: Use $a0 instead of $v0 for __syscall_error() argument
5
6 $a0 is saved across _dl_runtime_resolve(); $v0 is not.  Unfortunately,
7 __syscall_error() uses $v0 for its argument, not $a0 as is the MIPS ABI
8 standard.  This means that if lazy binding was used for __syscall_error(),
9 the errno value in $v0 could get corrupted.
10
11 The problem can be easily seen in testcases where syscalls in librt fail;
12 when librt tries to call __syscall_error() in libc, the argument gets
13 lost and errno gets set to a bogus value:
14
15     # ./tst-mqueue1 ; echo $?
16     mq_receive on O_WRONLY mqd_t did not fail with EBADF: Unknown error 2004684208
17     1
18     # ./tst-mqueue2 ; echo $?
19     mq_timedreceive with too small msg_len did not fail with EMSGSIZE: Unknown error 1997360560
20     1
21     # ./tst-mqueue4 ; echo $?
22     mq_timedsend did not fail with ETIMEDOUT: Unknown error 2008747440
23     1
24
25 When _dl_runtime_resolve() was taken out of the equation, the same test
26 cases passed:
27
28     # LD_BIND_NOW=y ./tst-mqueue1 ; echo $?
29     0
30     # LD_BIND_NOW=y ./tst-mqueue2 ; echo $?
31     0
32     # LD_BIND_NOW=y ./tst-mqueue4 ; echo $?
33     0
34
35 Changing __syscall_error() to look at $a0 instead of $v0 fixed the
36 problem.
37
38 (Note that there is also a "__syscall_error.c" file which presumably
39 uses the standard C calling conventions, but I do not think it is used
40 on MIPS.)
41
42 Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
43 Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
44 ---
45  libc/sysdeps/linux/mips/syscall_error.S |    2 +-
46  1 file changed, 1 insertion(+), 1 deletion(-)
47
48 diff --git a/libc/sysdeps/linux/mips/syscall_error.S b/libc/sysdeps/linux/mips/syscall_error.S
49 index 51a8efa..0cc20da 100644
50 --- a/libc/sysdeps/linux/mips/syscall_error.S
51 +++ b/libc/sysdeps/linux/mips/syscall_error.S
52 @@ -43,7 +43,7 @@ ENTRY(__syscall_error)
53  #ifdef __PIC__
54         SAVE_GP(GPOFF)
55  #endif
56 -       REG_S   v0, V0OFF(sp)
57 +       REG_S   a0, V0OFF(sp)
58         REG_S   ra, RAOFF(sp)
59  
60         /* Find our per-thread errno address  */
61 -- 
62 1.7.10.4
63