uClibc: add a whole bunch of mips64 related fixes

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 41570
v19.07.3_mercusys_ac12_duma
Felix Fietkau 10 years ago
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

@ -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;

@ -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…
Cancel
Save