uClibc: add a whole bunch of mips64 related fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 41570
This commit is contained in:
parent
a44b4e3ffb
commit
ded4c0675d
@ -21,11 +21,9 @@ Cc: Anthony G. Basile <blueness@gentoo.org>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
---
|
||||
|
||||
diff --git a/Rules.mak b/Rules.mak
|
||||
index 792b794..889108e 100644
|
||||
--- a/Rules.mak
|
||||
+++ b/Rules.mak
|
||||
@@ -138,13 +138,19 @@ export MAJOR_VERSION MINOR_VERSION SUBLEVEL VERSION ABI_VERSION LC_ALL
|
||||
@@ -118,13 +118,19 @@ export MAJOR_VERSION MINOR_VERSION SUBLE
|
||||
LIBC := libc
|
||||
SHARED_LIBNAME := $(LIBC).so.$(ABI_VERSION)
|
||||
UBACKTRACE_DSO := libubacktrace.so.$(ABI_VERSION)
|
||||
@ -48,5 +46,3 @@ index 792b794..889108e 100644
|
||||
UCLIBC_LDSO := $(UCLIBC_LDSO_NAME).so.$(ABI_VERSION)
|
||||
NONSHARED_LIBNAME := uclibc_nonshared.a
|
||||
libc := $(top_builddir)lib/$(SHARED_LIBNAME)
|
||||
--
|
||||
cgit v0.9.1
|
285
toolchain/uClibc/patches-0.9.33.2/610-mips64_syscall_fix.patch
Normal file
285
toolchain/uClibc/patches-0.9.33.2/610-mips64_syscall_fix.patch
Normal file
@ -0,0 +1,285 @@
|
||||
commit e5cde2eb0ed7df9416fdd6070af07c8448c72a30
|
||||
Author: Steve Ellcey <sellcey@mips.com>
|
||||
Date: Wed Feb 12 11:01:35 2014 -0800
|
||||
|
||||
mips: Remove duplicate macro definitions
|
||||
|
||||
The INLINE_SYSCALL, INTERNAL_SYSCALL*, and internal_syscall* macros
|
||||
are defined for MIPS in both libc/sysdeps/linux/mips/sysdep.h and
|
||||
libc/sysdeps/linux/mips/bits/syscalls.h. The macros are the same
|
||||
in both cases except that syscalls.h defines internal_syscalls[567]
|
||||
the same for N32 and N64 ABIs and has a different definition for O32.
|
||||
I believe that is correct. The sysdep.h header uses the O32 versions
|
||||
for N32 and has different definitions for N64. I think that is wrong
|
||||
and that N32 and N64 should share the same definition (modulo the
|
||||
type 'long' vs. 'long long' for the arguments. This setup (from
|
||||
sysdep.h) now agrees with what glibc has.
|
||||
|
||||
I am not positive about which header (sysdep.h vs syscalls.h) is
|
||||
really the right one to have these definitions in but using sysdep.h
|
||||
seems to work for all my builds.
|
||||
|
||||
Signed-off-by: Steve Ellcey <sellcey@mips.com>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
--- a/libc/sysdeps/linux/mips/sysdep.h
|
||||
+++ b/libc/sysdeps/linux/mips/sysdep.h
|
||||
@@ -133,258 +133,6 @@ L(syse1):
|
||||
|
||||
#else /* ! __ASSEMBLER__ */
|
||||
|
||||
-/* Define a macro which expands into the inline wrapper code for a system
|
||||
- call. */
|
||||
-#undef INLINE_SYSCALL
|
||||
-#define INLINE_SYSCALL(name, nr, args...) \
|
||||
- ({ INTERNAL_SYSCALL_DECL(err); \
|
||||
- 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)); \
|
||||
- result_var = -1L; \
|
||||
- } \
|
||||
- result_var; })
|
||||
-
|
||||
-#undef INTERNAL_SYSCALL_DECL
|
||||
-#define INTERNAL_SYSCALL_DECL(err) long err
|
||||
-
|
||||
-#undef INTERNAL_SYSCALL_ERROR_P
|
||||
-#define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
|
||||
-
|
||||
-#undef INTERNAL_SYSCALL_ERRNO
|
||||
-#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
|
||||
-
|
||||
-#undef INTERNAL_SYSCALL
|
||||
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
|
||||
- internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \
|
||||
- "i" (SYS_ify (name)), err, args)
|
||||
-
|
||||
-#undef INTERNAL_SYSCALL_NCS
|
||||
-#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
|
||||
- internal_syscall##nr (= number, , "r" (__v0), err, args)
|
||||
-#undef internal_syscall0
|
||||
-#define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a3 __asm__("$7"); \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- ".set reorder" \
|
||||
- : "=r" (__v0), "=r" (__a3) \
|
||||
- : input \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall1
|
||||
-#define internal_syscall1(ncs_init, cs_init, input, err, arg1) \
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a3 __asm__("$7"); \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- ".set reorder" \
|
||||
- : "=r" (__v0), "=r" (__a3) \
|
||||
- : input, "r" (__a0) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall2
|
||||
-#define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a3 __asm__("$7"); \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "=r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall3
|
||||
-#define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a2 __asm__("$6") = (long) arg3; \
|
||||
- register long __a3 __asm__("$7"); \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "=r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1), "r" (__a2) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall4
|
||||
-#define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a2 __asm__("$6") = (long) arg3; \
|
||||
- register long __a3 __asm__("$7") = (long) arg4; \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "+r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1), "r" (__a2) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-/* We need to use a frame pointer for the functions in which we
|
||||
- adjust $sp around the syscall, or debug information and unwind
|
||||
- information will be $sp relative and thus wrong during the syscall. As
|
||||
- of GCC 3.4.3, this is sufficient. */
|
||||
-#define FORCE_FRAME_POINTER alloca (4)
|
||||
-
|
||||
-#undef internal_syscall5
|
||||
-#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- FORCE_FRAME_POINTER; \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a2 __asm__("$6") = (long) arg3; \
|
||||
- register long __a3 __asm__("$7") = (long) arg4; \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- "subu\t$29, 32\n\t" \
|
||||
- "sw\t%6, 16($29)\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- "addiu\t$29, 32\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "+r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
|
||||
- "r" ((long)arg5) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall6
|
||||
-#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- FORCE_FRAME_POINTER; \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a2 __asm__("$6") = (long) arg3; \
|
||||
- register long __a3 __asm__("$7") = (long) arg4; \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- "subu\t$29, 32\n\t" \
|
||||
- "sw\t%6, 16($29)\n\t" \
|
||||
- "sw\t%7, 20($29)\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- "addiu\t$29, 32\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "+r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
|
||||
- "r" ((long)arg5), "r" ((long)arg6) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef internal_syscall7
|
||||
-#define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
|
||||
-({ \
|
||||
- long _sys_result; \
|
||||
- \
|
||||
- FORCE_FRAME_POINTER; \
|
||||
- { \
|
||||
- register long __v0 __asm__("$2") ncs_init; \
|
||||
- register long __a0 __asm__("$4") = (long) arg1; \
|
||||
- register long __a1 __asm__("$5") = (long) arg2; \
|
||||
- register long __a2 __asm__("$6") = (long) arg3; \
|
||||
- register long __a3 __asm__("$7") = (long) arg4; \
|
||||
- __asm__ __volatile__ ( \
|
||||
- ".set\tnoreorder\n\t" \
|
||||
- "subu\t$29, 32\n\t" \
|
||||
- "sw\t%6, 16($29)\n\t" \
|
||||
- "sw\t%7, 20($29)\n\t" \
|
||||
- "sw\t%8, 24($29)\n\t" \
|
||||
- cs_init \
|
||||
- "syscall\n\t" \
|
||||
- "addiu\t$29, 32\n\t" \
|
||||
- ".set\treorder" \
|
||||
- : "=r" (__v0), "+r" (__a3) \
|
||||
- : input, "r" (__a0), "r" (__a1), "r" (__a2), \
|
||||
- "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
|
||||
- : __SYSCALL_CLOBBERS); \
|
||||
- err = __a3; \
|
||||
- _sys_result = __v0; \
|
||||
- } \
|
||||
- _sys_result; \
|
||||
-})
|
||||
-
|
||||
-#undef __SYSCALL_CLOBBERS
|
||||
-#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
|
||||
- "$14", "$15", "$24", "$25", "memory"
|
||||
-
|
||||
/* Pointer mangling is not yet supported for MIPS. */
|
||||
#define PTR_MANGLE(var) (void) (var)
|
||||
#define PTR_DEMANGLE(var) (void) (var)
|
@ -0,0 +1,99 @@
|
||||
commit 2952c70804b48bb5c87eea21df5e401969dc4ec1
|
||||
Author: Kevin Cernekee <cernekee@gmail.com>
|
||||
Date: Tue Jun 5 15:05:20 2012 -0700
|
||||
|
||||
MIPS: Use $a0 instead of $v0 for __syscall_error() argument
|
||||
|
||||
$a0 is saved across _dl_runtime_resolve(); $v0 is not. Unfortunately,
|
||||
__syscall_error() uses $v0 for its argument, not $a0 as is the MIPS ABI
|
||||
standard. This means that if lazy binding was used for __syscall_error(),
|
||||
the errno value in $v0 could get corrupted.
|
||||
|
||||
The problem can be easily seen in testcases where syscalls in librt fail;
|
||||
when librt tries to call __syscall_error() in libc, the argument gets
|
||||
lost and errno gets set to a bogus value:
|
||||
|
||||
# ./tst-mqueue1 ; echo $?
|
||||
mq_receive on O_WRONLY mqd_t did not fail with EBADF: Unknown error 2004684208
|
||||
1
|
||||
# ./tst-mqueue2 ; echo $?
|
||||
mq_timedreceive with too small msg_len did not fail with EMSGSIZE: Unknown error 1997360560
|
||||
1
|
||||
# ./tst-mqueue4 ; echo $?
|
||||
mq_timedsend did not fail with ETIMEDOUT: Unknown error 2008747440
|
||||
1
|
||||
|
||||
When _dl_runtime_resolve() was taken out of the equation, the same test
|
||||
cases passed:
|
||||
|
||||
# LD_BIND_NOW=y ./tst-mqueue1 ; echo $?
|
||||
0
|
||||
# LD_BIND_NOW=y ./tst-mqueue2 ; echo $?
|
||||
0
|
||||
# LD_BIND_NOW=y ./tst-mqueue4 ; echo $?
|
||||
0
|
||||
|
||||
Changing __syscall_error() to look at $a0 instead of $v0 fixed the
|
||||
problem.
|
||||
|
||||
(Note that there is also a "__syscall_error.c" file which presumably
|
||||
uses the standard C calling conventions, but I do not think it is used
|
||||
on MIPS.)
|
||||
|
||||
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
commit 3c58d95d918c7e2fda374c37a52f81b34b81e4ca
|
||||
Author: Kevin Cernekee <cernekee@gmail.com>
|
||||
Date: Tue Jun 5 15:05:19 2012 -0700
|
||||
|
||||
MIPS: Convert __syscall_error() callers to use $a0 for argument
|
||||
|
||||
Some callers passed the first argument in $v0, while others used $a0.
|
||||
Change the callers to use $a0 consistently.
|
||||
|
||||
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
--- a/libc/sysdeps/linux/mips/vfork.S
|
||||
+++ b/libc/sysdeps/linux/mips/vfork.S
|
||||
@@ -84,6 +84,7 @@ NESTED(__vfork,FRAMESZ,sp)
|
||||
|
||||
/* Something bad happened -- no child created. */
|
||||
L(error):
|
||||
+ move a0, v0
|
||||
#ifdef __PIC__
|
||||
PTR_LA t9, __syscall_error
|
||||
RESTORE_GP64
|
||||
--- a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
|
||||
+++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
|
||||
@@ -31,7 +31,7 @@
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
- 99: \
|
||||
+ 99: move a0, v0; \
|
||||
PTR_LA t9,__syscall_error; \
|
||||
/* manual cpreturn. */ \
|
||||
REG_L gp, STKOFF_GP(sp); \
|
||||
--- a/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
+++ b/libpthread/linuxthreads/sysdeps/unix/sysv/linux/mips/vfork.S
|
||||
@@ -80,6 +80,7 @@ NESTED(__vfork,FRAMESZ,sp)
|
||||
|
||||
/* Something bad happened -- no child created. */
|
||||
L(error):
|
||||
+ move a0, v0
|
||||
#ifdef __PIC__
|
||||
PTR_LA t9, __syscall_error
|
||||
RESTORE_GP64
|
||||
--- a/libc/sysdeps/linux/mips/syscall_error.S
|
||||
+++ b/libc/sysdeps/linux/mips/syscall_error.S
|
||||
@@ -43,7 +43,7 @@ ENTRY(__syscall_error)
|
||||
#ifdef __PIC__
|
||||
SAVE_GP(GPOFF)
|
||||
#endif
|
||||
- REG_S v0, V0OFF(sp)
|
||||
+ REG_S a0, V0OFF(sp)
|
||||
REG_S ra, RAOFF(sp)
|
||||
|
||||
/* Find our per-thread errno address */
|
@ -0,0 +1,29 @@
|
||||
commit 052bcf13afb067cafac5e7f4fc21fbad2b34b11f
|
||||
Author: Waldemar Brodkorb <wbx@openadk.org>
|
||||
Date: Wed Nov 27 09:55:51 2013 +0100
|
||||
|
||||
Fix for SIGBUS error on MIPS64 with N64 ABI
|
||||
|
||||
When accessing errno, a per thread variable, from _stdio_init
|
||||
a SIGBUS error happens. This change fixes the wrong relocation
|
||||
and debug output.
|
||||
|
||||
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
--- a/ldso/ldso/mips/elfinterp.c
|
||||
+++ b/ldso/ldso/mips/elfinterp.c
|
||||
@@ -259,11 +259,11 @@ int _dl_parse_relocation_information(str
|
||||
case R_MIPS_TLS_TPREL32:
|
||||
case R_MIPS_TLS_TPREL64:
|
||||
CHECK_STATIC_TLS((struct link_map *)tls_tpnt);
|
||||
- *(ElfW(Word) *)reloc_addr +=
|
||||
+ *(ElfW(Addr) *)reloc_addr +=
|
||||
TLS_TPREL_VALUE (tls_tpnt, symbol_addr);
|
||||
#ifdef __SUPPORT_LD_DEBUG__
|
||||
_dl_dprintf(2, "TLS_TPREL : %s, %x, %x\n",
|
||||
- symname, old_val, *((unsigned int *)reloc_addr));
|
||||
+ symname, old_val, *((unsigned long *)reloc_addr));
|
||||
#endif
|
||||
break;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
--- a/ldso/ldso/mips/elfinterp.c
|
||||
+++ b/ldso/ldso/mips/elfinterp.c
|
||||
@@ -239,7 +239,7 @@ int _dl_parse_relocation_information(str
|
||||
case R_MIPS_TLS_DTPMOD64:
|
||||
case R_MIPS_TLS_DTPMOD32:
|
||||
if (tls_tpnt)
|
||||
- *(ElfW(Word) *)reloc_addr = tls_tpnt->l_tls_modid;
|
||||
+ *(ElfW(Addr) *)reloc_addr = tls_tpnt->l_tls_modid;
|
||||
#ifdef __SUPPORT_LD_DEBUG__
|
||||
_dl_dprintf(2, "TLS_DTPMOD : %s, %d, %d\n",
|
||||
symname, old_val, *((unsigned int *)reloc_addr));
|
||||
@@ -248,7 +248,7 @@ int _dl_parse_relocation_information(str
|
||||
|
||||
case R_MIPS_TLS_DTPREL64:
|
||||
case R_MIPS_TLS_DTPREL32:
|
||||
- *(ElfW(Word) *)reloc_addr +=
|
||||
+ *(ElfW(Addr) *)reloc_addr +=
|
||||
TLS_DTPREL_VALUE (symbol_addr);
|
||||
#ifdef __SUPPORT_LD_DEBUG__
|
||||
_dl_dprintf(2, "TLS_DTPREL : %s, %x, %x\n",
|
@ -0,0 +1,99 @@
|
||||
commit 70a04a287a2875c82e6822c36e071afba5b63a62
|
||||
Author: Waldemar Brodkorb <wbx@openadk.org>
|
||||
Date: Wed Jan 29 18:58:56 2014 +0100
|
||||
|
||||
libc: mips: Fix setjmp/longjmp for MIPS64 N64 ABI
|
||||
|
||||
When booting a Linux system with qemu-system-mips64 the execution
|
||||
of $(pwd) in the ash shell triggers a segmentation fault. Ash uses
|
||||
setjmp/longjmp for exception handling.
|
||||
|
||||
After looking at the glibc implementation,
|
||||
I found some differences, with this patch tries to resolve.
|
||||
Now the system boots up fine and no segmentation faults occur.
|
||||
|
||||
The global pointer should be restored and the types for the
|
||||
register values should be wide enough.
|
||||
|
||||
See:
|
||||
http://www.cygwin.com/ml/libc-alpha/2003-03/msg00363.html
|
||||
|
||||
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
--- a/libc/sysdeps/linux/mips/bits/setjmp.h
|
||||
+++ b/libc/sysdeps/linux/mips/bits/setjmp.h
|
||||
@@ -26,13 +26,19 @@
|
||||
|
||||
#include <sgidefs.h>
|
||||
|
||||
+#if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
+#define ptrsize void *
|
||||
+#else
|
||||
+#define ptrsize long long
|
||||
+#endif
|
||||
+
|
||||
typedef struct
|
||||
{
|
||||
/* Program counter. */
|
||||
- void * __pc;
|
||||
+ ptrsize __pc;
|
||||
|
||||
/* Stack pointer. */
|
||||
- void * __sp;
|
||||
+ ptrsize __sp;
|
||||
|
||||
/* Callee-saved registers s0 through s7. */
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
@@ -42,10 +48,10 @@ typedef struct
|
||||
#endif
|
||||
|
||||
/* The frame pointer. */
|
||||
- void * __fp;
|
||||
+ ptrsize __fp;
|
||||
|
||||
/* The global pointer. */
|
||||
- void * __gp;
|
||||
+ ptrsize __gp;
|
||||
|
||||
/* Floating point status register. */
|
||||
int __fpc_csr;
|
||||
--- a/libc/sysdeps/linux/mips/setjmp.S
|
||||
+++ b/libc/sysdeps/linux/mips/setjmp.S
|
||||
@@ -53,6 +53,7 @@ __sigsetjmp:
|
||||
PTR_LA t9, __sigsetjmp_aux
|
||||
#if _MIPS_SIM != _MIPS_SIM_ABI32
|
||||
.cpreturn
|
||||
+ move a4, gp
|
||||
#endif
|
||||
jr t9
|
||||
#else
|
||||
--- a/libc/sysdeps/linux/mips/setjmp_aux.c
|
||||
+++ b/libc/sysdeps/linux/mips/setjmp_aux.c
|
||||
@@ -31,7 +31,7 @@ extern int __sigjmp_save (sigjmp_buf, in
|
||||
|
||||
int
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
-__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp)
|
||||
+__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp, long long gp)
|
||||
#else /* O32 || N32 */
|
||||
__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
|
||||
#endif /* O32 || N32 */
|
||||
@@ -65,14 +65,14 @@ __sigsetjmp_aux (jmp_buf env, int savema
|
||||
#endif
|
||||
|
||||
/* .. and the stack pointer; */
|
||||
- env[0].__jmpbuf[0].__sp = (void *) sp;
|
||||
+ env[0].__jmpbuf[0].__sp = (ptrsize) sp;
|
||||
|
||||
/* .. and the FP; it'll be in s8. */
|
||||
- env[0].__jmpbuf[0].__fp = (void *) fp;
|
||||
+ env[0].__jmpbuf[0].__fp = (ptrsize) fp;
|
||||
|
||||
/* .. and the GP; */
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
- __asm__ __volatile__ ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
|
||||
+ env[0].__jmpbuf[0].__gp = (ptrsize) gp;
|
||||
#else
|
||||
__asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
|
||||
#endif
|
@ -0,0 +1,58 @@
|
||||
commit b97b4b698b023f75b54f987859c856ab4861ea00
|
||||
Author: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
|
||||
Date: Thu Jan 2 15:02:12 2014 +0000
|
||||
|
||||
siginfo.h: __SIGEV_PAD_SIZE takes __WORDSIZE into account
|
||||
|
||||
Make __SIGEV_PAD_SIZE to take __WORDSIZE into account for alpha, mips
|
||||
and ia64 arches.
|
||||
|
||||
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
|
||||
--- a/libc/sysdeps/linux/alpha/bits/siginfo.h
|
||||
+++ b/libc/sysdeps/linux/alpha/bits/siginfo.h
|
||||
@@ -258,7 +258,11 @@ enum
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
# define __SIGEV_MAX_SIZE 64
|
||||
-# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
+# if __WORDSIZE == 64
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
+# else
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
|
||||
+# endif
|
||||
|
||||
typedef struct sigevent
|
||||
{
|
||||
--- a/libc/sysdeps/linux/ia64/bits/siginfo.h
|
||||
+++ b/libc/sysdeps/linux/ia64/bits/siginfo.h
|
||||
@@ -298,7 +298,11 @@ enum
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
# define __SIGEV_MAX_SIZE 64
|
||||
-# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
+# if __WORDSIZE == 64
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
+# else
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
|
||||
+# endif
|
||||
|
||||
typedef struct sigevent
|
||||
{
|
||||
--- a/libc/sysdeps/linux/mips/bits/siginfo.h
|
||||
+++ b/libc/sysdeps/linux/mips/bits/siginfo.h
|
||||
@@ -265,8 +265,11 @@ enum
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
# define __SIGEV_MAX_SIZE 64
|
||||
-# define __SIGEV_HEAD_SIZE (sizeof(long) + 2*sizeof(int))
|
||||
-# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE - __SIGEV_HEAD_SIZE) / sizeof (int))
|
||||
+# if __WORDSIZE == 64
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 4)
|
||||
+# else
|
||||
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
|
||||
+# endif
|
||||
|
||||
/* Forward declaration of the `pthread_attr_t' type. */
|
||||
struct __pthread_attr_s;
|
123
toolchain/uClibc/patches-0.9.33.2/616-mips_fix_stat_time.patch
Normal file
123
toolchain/uClibc/patches-0.9.33.2/616-mips_fix_stat_time.patch
Normal file
@ -0,0 +1,123 @@
|
||||
--- a/libc/sysdeps/linux/common/xstatconv.c
|
||||
+++ b/libc/sysdeps/linux/common/xstatconv.c
|
||||
@@ -39,9 +39,12 @@ void __xstat_conv(struct kernel_stat *kb
|
||||
buf->st_size = kbuf->st_size;
|
||||
buf->st_blksize = kbuf->st_blksize;
|
||||
buf->st_blocks = kbuf->st_blocks;
|
||||
- buf->st_atim = kbuf->st_atim;
|
||||
- buf->st_mtim = kbuf->st_mtim;
|
||||
- buf->st_ctim = kbuf->st_ctim;
|
||||
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
|
||||
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_sec;
|
||||
}
|
||||
|
||||
void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
|
||||
@@ -58,9 +61,12 @@ void __xstat32_conv(struct kernel_stat64
|
||||
buf->st_size = kbuf->st_size;
|
||||
buf->st_blksize = kbuf->st_blksize;
|
||||
buf->st_blocks = kbuf->st_blocks;
|
||||
- buf->st_atim = kbuf->st_atim;
|
||||
- buf->st_mtim = kbuf->st_mtim;
|
||||
- buf->st_ctim = kbuf->st_ctim;
|
||||
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
|
||||
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_sec;
|
||||
}
|
||||
|
||||
#ifdef __UCLIBC_HAS_LFS__
|
||||
@@ -82,9 +88,12 @@ void __xstat64_conv(struct kernel_stat64
|
||||
buf->st_size = kbuf->st_size;
|
||||
buf->st_blksize = kbuf->st_blksize;
|
||||
buf->st_blocks = kbuf->st_blocks;
|
||||
- buf->st_atim = kbuf->st_atim;
|
||||
- buf->st_mtim = kbuf->st_mtim;
|
||||
- buf->st_ctim = kbuf->st_ctim;
|
||||
+ buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_atim.tv_nsec = kbuf->st_atim.tv_sec;
|
||||
+ buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_sec;
|
||||
+ buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
|
||||
+ buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_sec;
|
||||
}
|
||||
|
||||
#endif /* __UCLIBC_HAS_LFS__ */
|
||||
--- a/libc/sysdeps/linux/mips/bits/kernel_stat.h
|
||||
+++ b/libc/sysdeps/linux/mips/bits/kernel_stat.h
|
||||
@@ -8,6 +8,18 @@
|
||||
#include <sgidefs.h>
|
||||
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
+typedef struct {
|
||||
+ unsigned int tv_sec;
|
||||
+ unsigned int tv_nsec;
|
||||
+} __ktimespec_t;
|
||||
+#else
|
||||
+typedef struct {
|
||||
+ time_t tv_sec;
|
||||
+ unsigned long tv_nsec;
|
||||
+} __ktimespec_t;
|
||||
+#endif
|
||||
+
|
||||
+#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
|
||||
struct kernel_stat {
|
||||
__kernel_dev_t st_dev;
|
||||
@@ -20,9 +32,9 @@ struct kernel_stat {
|
||||
__kernel_dev_t st_rdev;
|
||||
unsigned int st_pad2[3];
|
||||
__kernel_off_t st_size;
|
||||
- struct timespec st_atim;
|
||||
- struct timespec st_mtim;
|
||||
- struct timespec st_ctim;
|
||||
+ __ktimespec_t st_atim;
|
||||
+ __ktimespec_t st_mtim;
|
||||
+ __ktimespec_t st_ctim;
|
||||
unsigned int st_blksize;
|
||||
unsigned int reserved3;
|
||||
unsigned long st_blocks;
|
||||
@@ -41,9 +53,9 @@ struct kernel_stat {
|
||||
unsigned int st_rdev;
|
||||
unsigned int st_pad2[3];
|
||||
unsigned long long st_size;
|
||||
- struct timespec st_atim;
|
||||
- struct timespec st_mtim;
|
||||
- struct timespec st_ctim;
|
||||
+ __ktimespec_t st_atim;
|
||||
+ __ktimespec_t st_mtim;
|
||||
+ __ktimespec_t st_ctim;
|
||||
unsigned int st_blksize;
|
||||
unsigned int reserved3;
|
||||
unsigned long long st_blocks;
|
||||
@@ -62,9 +74,9 @@ struct kernel_stat {
|
||||
long st_pad2[2];
|
||||
__kernel_off_t st_size;
|
||||
long st_pad3;
|
||||
- struct timespec st_atim;
|
||||
- struct timespec st_mtim;
|
||||
- struct timespec st_ctim;
|
||||
+ __ktimespec_t st_atim;
|
||||
+ __ktimespec_t st_mtim;
|
||||
+ __ktimespec_t st_ctim;
|
||||
long st_blksize;
|
||||
long st_blocks;
|
||||
long st_pad4[14];
|
||||
@@ -81,9 +93,9 @@ struct kernel_stat64 {
|
||||
unsigned long st_rdev;
|
||||
unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */
|
||||
long long st_size;
|
||||
- struct timespec st_atim;
|
||||
- struct timespec st_mtim;
|
||||
- struct timespec st_ctim;
|
||||
+ __ktimespec_t st_atim;
|
||||
+ __ktimespec_t st_mtim;
|
||||
+ __ktimespec_t st_ctim;
|
||||
unsigned long st_blksize;
|
||||
unsigned long st_pad2;
|
||||
long long st_blocks;
|
@ -0,0 +1,58 @@
|
||||
--- a/libc/sysdeps/linux/mips/bits/setjmp.h
|
||||
+++ b/libc/sysdeps/linux/mips/bits/setjmp.h
|
||||
@@ -27,18 +27,18 @@
|
||||
#include <sgidefs.h>
|
||||
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
-#define ptrsize void *
|
||||
+#define __setjmp_ptr void *
|
||||
#else
|
||||
-#define ptrsize long long
|
||||
+#define __setjmp_ptr long long
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Program counter. */
|
||||
- ptrsize __pc;
|
||||
+ __setjmp_ptr __pc;
|
||||
|
||||
/* Stack pointer. */
|
||||
- ptrsize __sp;
|
||||
+ __setjmp_ptr __sp;
|
||||
|
||||
/* Callee-saved registers s0 through s7. */
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
@@ -48,10 +48,10 @@ typedef struct
|
||||
#endif
|
||||
|
||||
/* The frame pointer. */
|
||||
- ptrsize __fp;
|
||||
+ __setjmp_ptr __fp;
|
||||
|
||||
/* The global pointer. */
|
||||
- ptrsize __gp;
|
||||
+ __setjmp_ptr __gp;
|
||||
|
||||
/* Floating point status register. */
|
||||
int __fpc_csr;
|
||||
--- a/libc/sysdeps/linux/mips/setjmp_aux.c
|
||||
+++ b/libc/sysdeps/linux/mips/setjmp_aux.c
|
||||
@@ -65,14 +65,14 @@ __sigsetjmp_aux (jmp_buf env, int savema
|
||||
#endif
|
||||
|
||||
/* .. and the stack pointer; */
|
||||
- env[0].__jmpbuf[0].__sp = (ptrsize) sp;
|
||||
+ env[0].__jmpbuf[0].__sp = (__setjmp_ptr) sp;
|
||||
|
||||
/* .. and the FP; it'll be in s8. */
|
||||
- env[0].__jmpbuf[0].__fp = (ptrsize) fp;
|
||||
+ env[0].__jmpbuf[0].__fp = (__setjmp_ptr) fp;
|
||||
|
||||
/* .. and the GP; */
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
- env[0].__jmpbuf[0].__gp = (ptrsize) gp;
|
||||
+ env[0].__jmpbuf[0].__gp = (__setjmp_ptr) gp;
|
||||
#else
|
||||
__asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
|
||||
#endif
|
@ -0,0 +1,36 @@
|
||||
--- a/libc/sysdeps/linux/mips/sysdep.h
|
||||
+++ b/libc/sysdeps/linux/mips/sysdep.h
|
||||
@@ -96,7 +96,8 @@
|
||||
backwards into the previous fn. */
|
||||
|
||||
#ifdef __PIC__
|
||||
-#define PSEUDO(name, syscall_name, args) \
|
||||
+# if _MIPS_SIM == _ABIO32
|
||||
+# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
99: move a0, v0; \
|
||||
la t9,__syscall_error; \
|
||||
@@ -109,6 +110,23 @@
|
||||
.set reorder; \
|
||||
bne a3, zero, 99b; \
|
||||
L(syse1):
|
||||
+# else
|
||||
+# define PSEUDO(name, syscall_name, args) \
|
||||
+ .align 2; \
|
||||
+ 99: \
|
||||
+ .set noat; \
|
||||
+ .cpsetup t9, $1, name; \
|
||||
+ .set at; \
|
||||
+ move a0, v0; \
|
||||
+ dla t9,__syscall_error; \
|
||||
+ .cpreturn; \
|
||||
+ jr t9; \
|
||||
+ ENTRY(name) \
|
||||
+ li v0, SYS_ify(syscall_name); \
|
||||
+ syscall; \
|
||||
+ bne a3, zero, 99b; \
|
||||
+L(syse1):
|
||||
+# endif
|
||||
#else
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
.set noreorder; \
|
@ -0,0 +1,195 @@
|
||||
--- a/extra/Configs/Config.in
|
||||
+++ b/extra/Configs/Config.in
|
||||
@@ -235,6 +235,7 @@ config TARGET_SUBARCH
|
||||
default "i486" if CONFIG_486
|
||||
default "i586" if CONFIG_586 || CONFIG_586MMX
|
||||
default "i686" if TARGET_ARCH = "i386"
|
||||
+ default "mips64" if CONFIG_MIPS_N64_ABI
|
||||
default ""
|
||||
|
||||
source "extra/Configs/Config.in.arch"
|
||||
--- /dev/null
|
||||
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
|
||||
@@ -0,0 +1,182 @@
|
||||
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library. If not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <sysdep.h>
|
||||
+#include <tls.h>
|
||||
+#ifndef __ASSEMBLER__
|
||||
+# include <pthreadP.h>
|
||||
+#endif
|
||||
+#include <sys/asm.h>
|
||||
+
|
||||
+/* Gas will put the initial save of $gp into the CIE, because it appears to
|
||||
+ happen before any instructions. So we use cfi_same_value instead of
|
||||
+ cfi_restore. */
|
||||
+
|
||||
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
|
||||
+
|
||||
+#ifdef __PIC__
|
||||
+# undef PSEUDO
|
||||
+# define PSEUDO(name, syscall_name, args) \
|
||||
+ .align 2; \
|
||||
+ L(pseudo_start): \
|
||||
+ cfi_startproc; \
|
||||
+ cfi_adjust_cfa_offset (STKSPACE); \
|
||||
+ cfi_rel_offset (gp, STKOFF_GP); \
|
||||
+ 99: move a0, v0; \
|
||||
+ PTR_LA t9,__syscall_error; \
|
||||
+ /* manual cpreturn */ \
|
||||
+ REG_L gp, STKOFF_GP(sp); \
|
||||
+ cfi_same_value (gp); \
|
||||
+ RESTORESTK; \
|
||||
+ jr t9; \
|
||||
+ .type __##syscall_name##_nocancel, @function; \
|
||||
+ .globl __##syscall_name##_nocancel; \
|
||||
+ __##syscall_name##_nocancel: \
|
||||
+ SAVESTK; \
|
||||
+ .cpsetup t9, STKOFF_GP, name; \
|
||||
+ cfi_rel_offset (gp, STKOFF_GP); \
|
||||
+ li v0, SYS_ify(syscall_name); \
|
||||
+ syscall; \
|
||||
+ bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
+ /* manual cpreturn */ \
|
||||
+ REG_L gp, STKOFF_GP(sp); \
|
||||
+ cfi_same_value (gp); \
|
||||
+ RESTORESTK; \
|
||||
+ ret; \
|
||||
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
+ ENTRY (name) \
|
||||
+ SAVESTK; \
|
||||
+ .cpsetup t9, STKOFF_GP, name; \
|
||||
+ cfi_rel_offset (gp, STKOFF_GP); \
|
||||
+ SINGLE_THREAD_P(v1); \
|
||||
+ bne zero, v1, L(pseudo_cancel); \
|
||||
+ .set noreorder; \
|
||||
+ li v0, SYS_ify(syscall_name); \
|
||||
+ syscall; \
|
||||
+ .set reorder; \
|
||||
+ bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
+ /* manual cpreturn */ \
|
||||
+ REG_L gp, STKOFF_GP(sp); \
|
||||
+ cfi_same_value (gp); \
|
||||
+ RESTORESTK; \
|
||||
+ ret; \
|
||||
+ L(pseudo_cancel): \
|
||||
+ cfi_adjust_cfa_offset (STKSPACE); \
|
||||
+ cfi_rel_offset (gp, STKOFF_GP); \
|
||||
+ REG_S ra, STKOFF_RA(sp); \
|
||||
+ cfi_rel_offset (ra, STKOFF_RA); \
|
||||
+ PUSHARGS_##args; /* save syscall args */ \
|
||||
+ CENABLE; \
|
||||
+ REG_S v0, STKOFF_SVMSK(sp); /* save mask */ \
|
||||
+ POPARGS_##args; /* restore syscall args */ \
|
||||
+ .set noreorder; \
|
||||
+ li v0, SYS_ify (syscall_name); \
|
||||
+ syscall; \
|
||||
+ .set reorder; \
|
||||
+ REG_S v0, STKOFF_SC_V0(sp); /* save syscall result */ \
|
||||
+ REG_S a3, STKOFF_SC_ERR(sp); /* save syscall error flag */ \
|
||||
+ REG_L a0, STKOFF_SVMSK(sp); /* pass mask as arg1 */ \
|
||||
+ CDISABLE; \
|
||||
+ REG_L a3, STKOFF_SC_ERR(sp); /* restore syscall error flag */ \
|
||||
+ REG_L ra, STKOFF_RA(sp); /* restore return address */ \
|
||||
+ REG_L v0, STKOFF_SC_V0(sp); /* restore syscall result */ \
|
||||
+ bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
+ /* manual cpreturn */ \
|
||||
+ REG_L gp, STKOFF_GP(sp); \
|
||||
+ cfi_same_value (gp); \
|
||||
+ RESTORESTK; \
|
||||
+ L(pseudo_end):
|
||||
+
|
||||
+
|
||||
+# undef PSEUDO_END
|
||||
+# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+# define PUSHARGS_0 /* nothing to do */
|
||||
+# define PUSHARGS_1 PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
|
||||
+# define PUSHARGS_2 PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
|
||||
+# define PUSHARGS_3 PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
|
||||
+# define PUSHARGS_4 PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
|
||||
+# define PUSHARGS_5 PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a3, STKOFF_A4);
|
||||
+# define PUSHARGS_6 PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a3, STKOFF_A5);
|
||||
+
|
||||
+# define POPARGS_0 /* nothing to do */
|
||||
+# define POPARGS_1 POPARGS_0 REG_L a0, STKOFF_A0(sp);
|
||||
+# define POPARGS_2 POPARGS_1 REG_L a1, STKOFF_A1(sp);
|
||||
+# define POPARGS_3 POPARGS_2 REG_L a2, STKOFF_A2(sp);
|
||||
+# define POPARGS_4 POPARGS_3 REG_L a3, STKOFF_A3(sp);
|
||||
+# define POPARGS_5 POPARGS_4 REG_L a4, STKOFF_A4(sp);
|
||||
+# define POPARGS_6 POPARGS_5 REG_L a5, STKOFF_A5(sp);
|
||||
+
|
||||
+/* Save an even number of slots. Should be 0 if an even number of slots
|
||||
+ are used below, or SZREG if an odd number are used. */
|
||||
+# define STK_PAD SZREG
|
||||
+
|
||||
+/* Place values that we are more likely to use later in this sequence, i.e.
|
||||
+ closer to the SP at function entry. If you do that, the are more
|
||||
+ likely to already be in your d-cache. */
|
||||
+# define STKOFF_A5 (STK_PAD)
|
||||
+# define STKOFF_A4 (STKOFF_A5 + SZREG)
|
||||
+# define STKOFF_A3 (STKOFF_A4 + SZREG)
|
||||
+# define STKOFF_A2 (STKOFF_A3 + SZREG) /* MT and more args. */
|
||||
+# define STKOFF_A1 (STKOFF_A2 + SZREG) /* MT and 2 args. */
|
||||
+# define STKOFF_A0 (STKOFF_A1 + SZREG) /* MT and 1 arg. */
|
||||
+# define STKOFF_RA (STKOFF_A0 + SZREG) /* Used if MT. */
|
||||
+# define STKOFF_SC_V0 (STKOFF_RA + SZREG) /* Used if MT. */
|
||||
+# define STKOFF_SC_ERR (STKOFF_SC_V0 + SZREG) /* Used if MT. */
|
||||
+# define STKOFF_SVMSK (STKOFF_SC_ERR + SZREG) /* Used if MT. */
|
||||
+# define STKOFF_GP (STKOFF_SVMSK + SZREG) /* Always used. */
|
||||
+
|
||||
+# define STKSPACE (STKOFF_GP + SZREG)
|
||||
+# define SAVESTK PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
|
||||
+# define RESTORESTK PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
|
||||
+
|
||||
+# ifdef IS_IN_libpthread
|
||||
+# define CENABLE PTR_LA t9, __pthread_enable_asynccancel; jalr t9
|
||||
+# define CDISABLE PTR_LA t9, __pthread_disable_asynccancel; jalr t9
|
||||
+# elif defined IS_IN_librt
|
||||
+# define CENABLE PTR_LA t9, __librt_enable_asynccancel; jalr t9
|
||||
+# define CDISABLE PTR_LA t9, __librt_disable_asynccancel; jalr t9
|
||||
+# else
|
||||
+# define CENABLE PTR_LA t9, __libc_enable_asynccancel; jalr t9
|
||||
+# define CDISABLE PTR_LA t9, __libc_disable_asynccancel; jalr t9
|
||||
+# endif
|
||||
+
|
||||
+# ifndef __ASSEMBLER__
|
||||
+# define SINGLE_THREAD_P \
|
||||
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
+ header.multiple_threads) \
|
||||
+ == 0, 1)
|
||||
+# else
|
||||
+# define SINGLE_THREAD_P(reg) \
|
||||
+ READ_THREAD_POINTER(reg); \
|
||||
+ lw reg, MULTIPLE_THREADS_OFFSET(reg)
|
||||
+#endif
|
||||
+
|
||||
+#elif !defined __ASSEMBLER__
|
||||
+
|
||||
+# define SINGLE_THREAD_P 1
|
||||
+# define NO_CANCELLATION 1
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#ifndef __ASSEMBLER__
|
||||
+# define RTLD_SINGLE_THREAD_P \
|
||||
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
+ header.multiple_threads) == 0, 1)
|
||||
+#endif
|
@ -15,11 +15,9 @@ Reviewed-by: Markos Chandras <markos.chandras@imgtec.com>
|
||||
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
||||
---
|
||||
|
||||
diff --git a/Rules.mak b/Rules.mak
|
||||
index 889108e..be53d81 100644
|
||||
--- a/Rules.mak
|
||||
+++ b/Rules.mak
|
||||
@@ -141,7 +141,7 @@ UBACKTRACE_DSO := libubacktrace.so.$(ABI_VERSION)
|
||||
@@ -121,7 +121,7 @@ UBACKTRACE_DSO := libubacktrace.so.$(ABI
|
||||
|
||||
UCLIBC_LDSO_NAME := ld-uClibc
|
||||
ARCH_NATIVE_BIT := 32
|
||||
@ -28,5 +26,3 @@ index 889108e..be53d81 100644
|
||||
UCLIBC_LDSO_NAME := ld64-uClibc
|
||||
ARCH_NATIVE_BIT := 64
|
||||
else
|
||||
--
|
||||
cgit v0.9.1
|
||||
|
Loading…
Reference in New Issue
Block a user