summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorCarmelo Amoroso <carmelo.amoroso@st.com>2007-11-20 09:39:52 +0000
committerCarmelo Amoroso <carmelo.amoroso@st.com>2007-11-20 09:39:52 +0000
commit328ff172e62af6a0a982bee615b3af61a82ccd62 (patch)
tree508d4719b2de1be043d2aa961759b851ef49fb91 /libc/sysdeps/linux
parent414d8e5f2a73aff8e9404684571a65f85b27bf89 (diff)
downloaduClibc-alpine-328ff172e62af6a0a982bee615b3af61a82ccd62.tar.bz2
uClibc-alpine-328ff172e62af6a0a982bee615b3af61a82ccd62.tar.xz
Push latest libc SH4 specific implementations
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/sh/Makefile.arch4
-rw-r--r--libc/sysdeps/linux/sh/bits/atomic.h512
-rw-r--r--libc/sysdeps/linux/sh/bits/fcntl.h2
-rw-r--r--libc/sysdeps/linux/sh/bits/syscalls.h2
-rw-r--r--libc/sysdeps/linux/sh/bits/uClibc_arch_features.h2
-rw-r--r--libc/sysdeps/linux/sh/clone.S123
-rw-r--r--libc/sysdeps/linux/sh/crti.S1
-rw-r--r--libc/sysdeps/linux/sh/pread_write.c60
-rw-r--r--libc/sysdeps/linux/sh/sys/procfs.h19
-rw-r--r--libc/sysdeps/linux/sh/sys/ucontext.h16
-rw-r--r--libc/sysdeps/linux/sh/sys/user.h56
-rw-r--r--libc/sysdeps/linux/sh/syscall_error.S4
12 files changed, 400 insertions, 401 deletions
diff --git a/libc/sysdeps/linux/sh/Makefile.arch b/libc/sysdeps/linux/sh/Makefile.arch
index 77ad570d6..de066758e 100644
--- a/libc/sysdeps/linux/sh/Makefile.arch
+++ b/libc/sysdeps/linux/sh/Makefile.arch
@@ -7,8 +7,8 @@
#
CSRC := \
- mmap.c pipe.c __init_brk.c brk.c sbrk.c syscall.c pread_write.c
+ mmap.c pipe.c __init_brk.c brk.c sbrk.c syscall.c pread_write.c longjmp.c
-SSRC := setjmp.S __longjmp.S vfork.S clone.S ___fpscr_values.S
+SSRC := setjmp.S __longjmp.S ___fpscr_values.S
include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
diff --git a/libc/sysdeps/linux/sh/bits/atomic.h b/libc/sysdeps/linux/sh/bits/atomic.h
index a0e5918f0..dd6e5f97d 100644
--- a/libc/sysdeps/linux/sh/bits/atomic.h
+++ b/libc/sysdeps/linux/sh/bits/atomic.h
@@ -54,6 +54,10 @@ typedef uintmax_t uatomic_max_t;
Japan. http://lc.linux.or.jp/lc2002/papers/niibe0919h.pdf (in
Japanese).
+ Niibe Yutaka, "gUSA: User Space Atomicity with Little Kernel
+ Modification", LinuxTag 2003, Rome.
+ http://www.semmel.ch/Linuxtag-DVD/talks/170/paper.html (in English).
+
B.N. Bershad, D. Redell, and J. Ellis, "Fast Mutual Exclusion for
Uniprocessors", Proceedings of the Fifth Architectural Support for
Programming Languages and Operating Systems (ASPLOS), pp. 223-233,
@@ -65,355 +69,225 @@ typedef uintmax_t uatomic_max_t;
r1: saved stack pointer
*/
-#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
- ({ __typeof (*(mem)) __result; \
+/* Avoid having lots of different versions of compare and exchange,
+ by having this one complicated version. Parameters:
+ bwl: b, w or l for 8, 16 and 32 bit versions.
+ version: val or bool, depending on whether the result is the
+ previous value or a bool indicating whether the transfer
+ did happen (note this needs inverting before being
+ returned in atomic_compare_and_exchange_bool).
+*/
+
+#define __arch_compare_and_exchange_n(mem, newval, oldval, bwl, version) \
+ ({ signed long __result; \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
nop\n\
mov r15,r1\n\
mov #-8,r15\n\
- 0: mov.b @%1,%0\n\
+ 0: mov." #bwl " @%1,%0\n\
cmp/eq %0,%3\n\
bf 1f\n\
- mov.b %2,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
- : "r0", "r1", "t", "memory"); \
+ mov." #bwl " %2,@%1\n\
+ 1: mov r1,r15\n\
+ .ifeqs \"bool\",\"" #version "\"\n\
+ movt %0\n\
+ .endif\n" \
+ : "=&r" (__result) \
+ : "r" (mem), "r" (newval), "r" (oldval) \
+ : "r0", "r1", "t", "memory"); \
__result; })
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ __arch_compare_and_exchange_n(mem, newval, (int8_t)(oldval), b, val)
+
#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
- ({ __typeof (*(mem)) __result; \
- __asm __volatile ("\
+ __arch_compare_and_exchange_n(mem, newval, (int16_t)(oldval), w, val)
+
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ __arch_compare_and_exchange_n(mem, newval, (int32_t)(oldval), l, val)
+
+/* XXX We do not really need 64-bit compare-and-exchange. At least
+ not in the moment. Using it would mean causing portability
+ problems since not many other 32-bit architectures have support for
+ such an operation. So don't define any code for now. */
+
+# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+/* For "bool" routines, return if the exchange did NOT occur */
+
+#define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
+ (! __arch_compare_and_exchange_n(mem, newval, (int8_t)(oldval), b, bool))
+
+#define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
+ (! __arch_compare_and_exchange_n(mem, newval, (int16_t)(oldval), w, bool))
+
+#define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
+ (! __arch_compare_and_exchange_n(mem, newval, (int32_t)(oldval), l, bool))
+
+# define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
+ (abort (), 0)
+
+/* Similar to the above, have one template which can be used in a
+ number of places. This version returns both the old and the new
+ values of the location. Parameters:
+ bwl: b, w or l for 8, 16 and 32 bit versions.
+ oper: The instruction to perform on the old value.
+ Note old is not sign extended, so should be an unsigned long.
+*/
+
+#define __arch_operate_old_new_n(mem, value, old, new, bwl, oper) \
+ (void) ({ __asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
- nop\n\
mov r15,r1\n\
+ nop\n\
mov #-8,r15\n\
- 0: mov.w @%1,%0\n\
- cmp/eq %0,%3\n\
- bf 1f\n\
- mov.w %2,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
- : "r0", "r1", "t", "memory"); \
- __result; })
+ 0: mov." #bwl " @%2,%0\n\
+ mov %0,%1\n\
+ " #oper " %3,%1\n\
+ mov." #bwl " %1,@%2\n\
+ 1: mov r1,r15" \
+ : "=&r" (old), "=&r"(new) \
+ : "r" (mem), "r" (value) \
+ : "r0", "r1", "memory"); \
+ })
-#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
- ({ __typeof (*(mem)) __result; \
+#define __arch_exchange_and_add_8_int(mem, value) \
+ ({ int32_t __value = (value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, b, add); \
+ __old; })
+
+#define __arch_exchange_and_add_16_int(mem, value) \
+ ({ int32_t __value = (value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, w, add); \
+ __old; })
+
+#define __arch_exchange_and_add_32_int(mem, value) \
+ ({ int32_t __value = (value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, l, add); \
+ __old; })
+
+#define __arch_exchange_and_add_64_int(mem, value) \
+ (abort (), 0)
+
+#define atomic_exchange_and_add(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value)
+
+
+/* Again, another template. We get a slight optimisation when the old value
+ does not need to be returned. Parameters:
+ bwl: b, w or l for 8, 16 and 32 bit versions.
+ oper: The instruction to perform on the old value.
+*/
+
+#define __arch_operate_new_n(mem, value, bwl, oper) \
+ ({ int32_t __value = (value), __new; \
__asm __volatile ("\
.align 2\n\
mova 1f,r0\n\
- nop\n\
mov r15,r1\n\
- mov #-8,r15\n\
- 0: mov.l @%1,%0\n\
- cmp/eq %0,%3\n\
- bf 1f\n\
- mov.l %2,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
- : "r0", "r1", "t", "memory"); \
- __result; })
+ mov #-6,r15\n\
+ 0: mov." #bwl " @%1,%0\n\
+ " #oper " %2,%0\n\
+ mov." #bwl " %0,@%1\n\
+ 1: mov r1,r15" \
+ : "=&r" (__new) \
+ : "r" (mem), "r" (__value) \
+ : "r0", "r1", "memory"); \
+ __new; \
+ })
-/* XXX We do not really need 64-bit compare-and-exchange. At least
- not in the moment. Using it would mean causing portability
- problems since not many other 32-bit architectures have support for
- such an operation. So don't define any code for now. */
+#define __arch_add_8_int(mem, value) \
+ __arch_operate_new_n(mem, value, b, add)
-# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
- (abort (), (__typeof (*mem)) 0)
+#define __arch_add_16_int(mem, value) \
+ __arch_operate_new_n(mem, value, w, add)
-#define atomic_exchange_and_add(mem, value) \
- ({ __typeof (*(mem)) __result, __tmp, __value = (value); \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.b @%2,%0\n\
- add %0,%1\n\
- mov.b %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.w @%2,%0\n\
- add %0,%1\n\
- mov.w %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.l @%2,%0\n\
- add %0,%1\n\
- mov.l %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "memory"); \
- else \
- { \
- __typeof (mem) memp = (mem); \
- do \
- __result = *memp; \
- while (__arch_compare_and_exchange_val_64_acq \
- (memp, __result + __value, __result) == __result); \
- (void) __value; \
- } \
- __result; })
+#define __arch_add_32_int(mem, value) \
+ __arch_operate_new_n(mem, value, l, add)
+
+#define __arch_add_64_int(mem, value) \
+ (abort (), 0)
#define atomic_add(mem, value) \
- (void) ({ __typeof (*(mem)) __tmp, __value = (value); \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.b @%1,r2\n\
- add r2,%0\n\
- mov.b %0,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__tmp) : "r" (mem), "0" (__value) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.w @%1,r2\n\
- add r2,%0\n\
- mov.w %0,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__tmp) : "r" (mem), "0" (__value) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.l @%1,r2\n\
- add r2,%0\n\
- mov.l %0,@%1\n\
- 1: mov r1,r15"\
- : "=&r" (__tmp) : "r" (mem), "0" (__value) \
- : "r0", "r1", "r2", "memory"); \
- else \
- { \
- __typeof (*(mem)) oldval; \
- __typeof (mem) memp = (mem); \
- do \
- oldval = *memp; \
- while (__arch_compare_and_exchange_val_64_acq \
- (memp, oldval + __value, oldval) == oldval); \
- (void) __value; \
- } \
- })
+ ((void) __atomic_val_bysize (__arch_add, int, mem, value))
+
+
+#define __arch_add_negative_8_int(mem, value) \
+ (__arch_operate_new_n(mem, value, b, add) < 0)
+
+#define __arch_add_negative_16_int(mem, value) \
+ (__arch_operate_new_n(mem, value, w, add) < 0)
+
+#define __arch_add_negative_32_int(mem, value) \
+ (__arch_operate_new_n(mem, value, l, add) < 0)
+
+#define __arch_add_negative_64_int(mem, value) \
+ (abort (), 0)
#define atomic_add_negative(mem, value) \
- ({ unsigned char __result; \
- __typeof (*(mem)) __tmp, __value = (value); \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.b @%2,r2\n\
- add r2,%1\n\
- mov.b %1,@%2\n\
- 1: mov r1,r15\n\
- shal %1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.w @%2,r2\n\
- add r2,%1\n\
- mov.w %1,@%2\n\
- 1: mov r1,r15\n\
- shal %1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.l @%2,r2\n\
- add r2,%1\n\
- mov.l %1,@%2\n\
- 1: mov r1,r15\n\
- shal %1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else \
- abort (); \
- __result; })
+ __atomic_bool_bysize (__arch_add_negative, int, mem, value)
+
+
+#define __arch_add_zero_8_int(mem, value) \
+ (__arch_operate_new_n(mem, value, b, add) == 0)
+
+#define __arch_add_zero_16_int(mem, value) \
+ (__arch_operate_new_n(mem, value, w, add) == 0)
+
+#define __arch_add_zero_32_int(mem, value) \
+ (__arch_operate_new_n(mem, value, l, add) == 0)
+
+#define __arch_add_zero_64_int(mem, value) \
+ (abort (), 0)
#define atomic_add_zero(mem, value) \
- ({ unsigned char __result; \
- __typeof (*(mem)) __tmp, __value = (value); \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.b @%2,r2\n\
- add r2,%1\n\
- mov.b %1,@%2\n\
- 1: mov r1,r15\n\
- tst %1,%1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.w @%2,r2\n\
- add r2,%1\n\
- mov.w %1,@%2\n\
- 1: mov r1,r15\n\
- tst %1,%1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.l @%2,r2\n\
- add r2,%1\n\
- mov.l %1,@%2\n\
- 1: mov r1,r15\n\
- tst %1,%1\n\
- movt %0"\
- : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \
- : "r0", "r1", "r2", "t", "memory"); \
- else \
- abort (); \
- __result; })
+ __atomic_bool_bysize (__arch_add_zero, int, mem, value)
+
#define atomic_increment_and_test(mem) atomic_add_zero((mem), 1)
#define atomic_decrement_and_test(mem) atomic_add_zero((mem), -1)
-#define atomic_bit_set(mem, bit) \
- (void) ({ unsigned int __mask = 1 << (bit); \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.b @%0,r2\n\
- or %1,r2\n\
- mov.b r2,@%0\n\
- 1: mov r1,r15"\
- : : "r" (mem), "r" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.w @%0,r2\n\
- or %1,r2\n\
- mov.w r2,@%0\n\
- 1: mov r1,r15"\
- : : "r" (mem), "r" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- mov r15,r1\n\
- mov #-6,r15\n\
- 0: mov.l @%0,r2\n\
- or %1,r2\n\
- mov.l r2,@%0\n\
- 1: mov r1,r15"\
- : : "r" (mem), "r" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else \
- abort (); \
- })
-
-#define atomic_bit_test_set(mem, bit) \
- ({ unsigned int __mask = 1 << (bit); \
- unsigned int __result = __mask; \
- if (sizeof (*(mem)) == 1) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- nop\n\
- mov r15,r1\n\
- mov #-8,r15\n\
- 0: mov.b @%2,r2\n\
- or r2,%1\n\
- and r2,%0\n\
- mov.b %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__mask) \
- : "r" (mem), "0" (__result), "1" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 2) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- nop\n\
- mov r15,r1\n\
- mov #-8,r15\n\
- 0: mov.w @%2,r2\n\
- or r2,%1\n\
- and r2,%0\n\
- mov.w %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__mask) \
- : "r" (mem), "0" (__result), "1" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else if (sizeof (*(mem)) == 4) \
- __asm __volatile ("\
- .align 2\n\
- mova 1f,r0\n\
- nop\n\
- mov r15,r1\n\
- mov #-8,r15\n\
- 0: mov.l @%2,r2\n\
- or r2,%1\n\
- and r2,%0\n\
- mov.l %1,@%2\n\
- 1: mov r1,r15"\
- : "=&r" (__result), "=&r" (__mask) \
- : "r" (mem), "0" (__result), "1" (__mask) \
- : "r0", "r1", "r2", "memory"); \
- else \
- abort (); \
- __result; })
+
+#define __arch_bit_set_8_int(mem, value) \
+ __arch_operate_new_n(mem, 1<<(value), b, or)
+
+#define __arch_bit_set_16_int(mem, value) \
+ __arch_operate_new_n(mem, 1<<(value), w, or)
+
+#define __arch_bit_set_32_int(mem, value) \
+ __arch_operate_new_n(mem, 1<<(value), l, or)
+
+#define __arch_bit_set_64_int(mem, value) \
+ (abort (), 0)
+
+#define __arch_add_64_int(mem, value) \
+ (abort (), 0)
+
+#define atomic_bit_set(mem, value) \
+ ((void) __atomic_val_bysize (__arch_bit_set, int, mem, value))
+
+
+#define __arch_bit_test_set_8_int(mem, value) \
+ ({ int32_t __value = 1<<(value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, b, or); \
+ __old & __value; })
+
+#define __arch_bit_test_set_16_int(mem, value) \
+ ({ int32_t __value = 1<<(value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, w, or); \
+ __old & __value; })
+
+#define __arch_bit_test_set_32_int(mem, value) \
+ ({ int32_t __value = 1<<(value), __new, __old; \
+ __arch_operate_old_new_n((mem), __value, __old, __new, l, or); \
+ __old & __value; })
+
+#define __arch_bit_test_set_64_int(mem, value) \
+ (abort (), 0)
+
+#define atomic_bit_test_set(mem, value) \
+ __atomic_val_bysize (__arch_bit_test_set, int, mem, value)
diff --git a/libc/sysdeps/linux/sh/bits/fcntl.h b/libc/sysdeps/linux/sh/bits/fcntl.h
index 10286a88d..ce8b623c6 100644
--- a/libc/sysdeps/linux/sh/bits/fcntl.h
+++ b/libc/sysdeps/linux/sh/bits/fcntl.h
@@ -24,7 +24,7 @@
#include <sys/types.h>
#ifdef __USE_GNU
-# include <bits/uio.h>
+# include <sys/uio.h>
#endif
diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h
index 234f80653..2a26d9684 100644
--- a/libc/sysdeps/linux/sh/bits/syscalls.h
+++ b/libc/sysdeps/linux/sh/bits/syscalls.h
@@ -4,6 +4,8 @@
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
+#include <bits/sysnum.h>
+
/* The Linux kernel uses different trap numbers on sh-2. */
#ifdef __CONFIG_SH2__
# define __SH_SYSCALL_TRAP_BASE 0x20
diff --git a/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h b/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h
index e2b480e75..f6b027b95 100644
--- a/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h
@@ -22,7 +22,7 @@
#undef __UCLIBC_BROKEN_CREATE_MODULE__
/* does your target have to worry about older [gs]etrlimit() ? */
-#define __UCLIBC_HANDLE_OLDER_RLIMIT__
+#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
/* does your target prefix all symbols with an _ ? */
#define __UCLIBC_NO_UNDERSCORES__
diff --git a/libc/sysdeps/linux/sh/clone.S b/libc/sysdeps/linux/sh/clone.S
index dec05a2c7..4d933a573 100644
--- a/libc/sysdeps/linux/sh/clone.S
+++ b/libc/sysdeps/linux/sh/clone.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2003, 2004 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
@@ -21,93 +21,93 @@
#include <features.h>
#include <asm/unistd.h>
+#include <sysdep.h>
#define _ERRNO_H 1
#include <bits/errno.h>
-#define _SYSCALL_H
-#include <bits/sysnum.h>
-
-
-#ifdef __HAVE_SHARED__
-#define PLTJMP(_x) _x##@PLT
-#else
-#define PLTJMP(_x) _x
+#ifdef RESET_PID
+#include <tcb-offsets.h>
#endif
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ pid_t *ptid, void *tls, pid_t *ctid); */
-
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
-
- .text
-
-.text
-.align 4
-.type clone,@function
-.globl clone;
-clone:
+ .text
+ENTRY(__clone)
/* sanity check arguments. */
tst r4, r4
bt 0f
tst r5, r5
bf/s 1f
- mov #+__NR_clone, r3
-0:
- bra __syscall_error
- mov #-EINVAL, r4
-
+ mov #+SYS_ify(clone), r3
+0:
+ bra .Lsyscall_error
+ mov #-EINVAL,r0
1:
/* insert the args onto the new stack */
mov.l r7, @-r5
/* save the function pointer as the 0th element */
mov.l r4, @-r5
-
+
/* do the system call */
mov r6, r4
- trapa #(__SH_SYSCALL_TRAP_BASE + 2)
+ mov.l @r15, r6
+ mov.l @(8,r15), r7
+ mov.l @(4,r15), r0
+ trapa #0x15
mov r0, r1
-#ifdef __CONFIG_SH2__
-// 12 arithmetic shifts for the crappy sh2, because shad doesn't exist!
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
- shar r1
-#else
mov #-12, r2
shad r2, r1
-#endif
not r1, r1 // r1=0 means r0 = -1 to -4095
tst r1, r1 // i.e. error in linux
- bf/s 2f
- tst r0, r0
- bra __syscall_error
- mov r0, r4
-
-2:
- bt 3f
+ bf .Lclone_end
+.Lsyscall_error:
+ SYSCALL_ERROR_HANDLER
+.Lclone_end:
+ tst r0, r0
+ bt 2f
+.Lpseudo_end:
rts
nop
+2:
+ /* terminate the stack frame */
+ mov #0, r14
+#ifdef RESET_PID
+ mov r4, r0
+ shlr16 r0
+ tst #1, r0 // CLONE_THREAD = (1 << 16)
+ bf/s 4f
+ mov r4, r0
+ /* new pid */
+ shlr8 r0
+ tst #1, r0 // CLONE_VM = (1 << 8)
+ bf/s 3f
+ mov #-1, r0
+ mov #+SYS_ify(getpid), r3
+ trapa #0x15
3:
+ stc gbr, r1
+ mov.w .Lpidoff, r2
+ add r1, r2
+ mov.l r0, @r2
+ mov.w .Ltidoff, r2
+ add r1, r2
+ mov.l r0, @r2
+4:
+#endif
/* thread starts */
mov.l @r15, r1
jsr @r1
mov.l @(4,r15), r4
/* we are done, passing the return value through r0 */
- mov.l .L1, r1
-#ifdef __HAVE_SHARED__
+ mov.l .L3, r1
+#ifdef SHARED
mov.l r12, @-r15
sts.l pr, @-r15
mov r0, r4
- mova .LG, r0 /* .LG from syscall_error.S */
+ mova .LG, r0
mov.l .LG, r12
add r0, r12
- mova .L1, r0
+ mova .L3, r0
add r0, r1
jsr @r1
nop
@@ -119,8 +119,17 @@ clone:
mov r0, r4
#endif
.align 2
-.L1:
- .long PLTJMP( HIDDEN_JUMPTARGET(_exit))
-.size clone,.-clone;
+.LG:
+ .long _GLOBAL_OFFSET_TABLE_
+.L3:
+ .long PLTJMP(C_SYMBOL_NAME(_exit))
+#ifdef RESET_PID
+.Lpidoff:
+ .word PID - TLS_PRE_TCB_SIZE
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+#endif
+
+PSEUDO_END (__clone)
-#include "syscall_error.S"
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/linux/sh/crti.S b/libc/sysdeps/linux/sh/crti.S
index 43ba28583..37b833825 100644
--- a/libc/sysdeps/linux/sh/crti.S
+++ b/libc/sysdeps/linux/sh/crti.S
@@ -1,3 +1,4 @@
+#include <features.h>
.file "crti.S"
.text
diff --git a/libc/sysdeps/linux/sh/pread_write.c b/libc/sysdeps/linux/sh/pread_write.c
index 9cc4bbf97..ab44204b0 100644
--- a/libc/sysdeps/linux/sh/pread_write.c
+++ b/libc/sysdeps/linux/sh/pread_write.c
@@ -12,10 +12,17 @@
* from GNU libc 2.2.5, but reworked considerably...
*/
-#include <sys/syscall.h>
+#include "../common/syscalls.h"
#include <unistd.h>
#include <stdint.h>
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <sysdep-cancel.h>
+#else
+#define SINGLE_THREAD_P 1
+#endif
+
+
#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
# ifdef __NR_pread
# error "__NR_pread and __NR_pread64 both defined???"
@@ -31,7 +38,15 @@ static inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
{
- return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR((off_t)0,offset)));
+ if (SINGLE_THREAD_P)
+ return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset)));
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ ssize_t result = __syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset));
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
+#endif
}
weak_alias(__libc_pread,pread)
@@ -39,9 +54,18 @@ weak_alias(__libc_pread,pread)
extern __typeof(pread64) __libc_pread64;
ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
{
- uint32_t low = offset & 0xffffffff;
- uint32_t high = offset >> 32;
- return(__syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+
+ if (SINGLE_THREAD_P)
+ return __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low));
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ ssize_t result = __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low));
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
+#endif
}
weak_alias(__libc_pread64,pread64)
# endif /* __UCLIBC_HAS_LFS__ */
@@ -64,7 +88,16 @@ static inline _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
{
- return(__syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR((off_t)0,offset)));
+ if (SINGLE_THREAD_P)
+ return __syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset));
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ ssize_t result = __syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset));
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
+#endif
+
}
weak_alias(__libc_pwrite,pwrite)
@@ -72,9 +105,18 @@ weak_alias(__libc_pwrite,pwrite)
extern __typeof(pwrite64) __libc_pwrite64;
ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
{
- uint32_t low = offset & 0xffffffff;
- uint32_t high = offset >> 32;
- return(__syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+
+ if (SINGLE_THREAD_P)
+ return __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low));
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ int oldtype = LIBC_CANCEL_ASYNC ();
+ ssize_t result = __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low));
+ LIBC_CANCEL_RESET (oldtype);
+ return result;
+#endif
}
weak_alias(__libc_pwrite64,pwrite64)
# endif /* __UCLIBC_HAS_LFS__ */
diff --git a/libc/sysdeps/linux/sh/sys/procfs.h b/libc/sysdeps/linux/sh/sys/procfs.h
index 76dd2bbeb..e58d824e2 100644
--- a/libc/sysdeps/linux/sh/sys/procfs.h
+++ b/libc/sysdeps/linux/sh/sys/procfs.h
@@ -29,10 +29,19 @@
#include <sys/types.h>
#include <sys/ucontext.h>
#include <sys/user.h>
-#include <asm/elf.h>
__BEGIN_DECLS
+/*
+ * ELF register definitions...
+ */
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpu_struct elf_fpregset_t;
+
struct elf_siginfo
{
int si_signo; /* Signal number. */
@@ -88,8 +97,8 @@ struct elf_prpsinfo
char pr_zomb; /* Zombie. */
char pr_nice; /* Nice val. */
unsigned long int pr_flag; /* Flags. */
- long pr_uid;
- long pr_gid;
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
int pr_pid, pr_ppid, pr_pgrp, pr_sid;
/* Lots missing */
char pr_fname[16]; /* Filename of executable. */
@@ -101,8 +110,8 @@ struct elf_prpsinfo
typedef void *psaddr_t;
/* Register sets. Linux has different names. */
-typedef gregset_t prgregset_t;
-typedef fpregset_t prfpregset_t;
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
/* We don't have any differences between processes and threads,
therefore habe only ine PID type. */
diff --git a/libc/sysdeps/linux/sh/sys/ucontext.h b/libc/sysdeps/linux/sh/sys/ucontext.h
index 78729c48f..e909f35bb 100644
--- a/libc/sysdeps/linux/sh/sys/ucontext.h
+++ b/libc/sysdeps/linux/sh/sys/ucontext.h
@@ -87,13 +87,25 @@ typedef freg_t fpregset_t[NFPREG];
/* Context to describe whole processor state. */
typedef struct
{
+ unsigned int oldmask;
+
+ /* CPU registers */
gregset_t gregs;
+ unsigned int pc;
+ unsigned int pr;
+ unsigned int sr;
+ unsigned int gbr;
+ unsigned int mach;
+ unsigned int macl;
+
+#ifdef __CONFIG_SH4__
+ /* FPU registers */
fpregset_t fpregs;
fpregset_t xfpregs;
unsigned int fpscr;
unsigned int fpul;
- unsigned int macl;
- unsigned int mach;
+ unsigned int ownedfp;
+#endif
} mcontext_t;
/* Userlevel context. */
diff --git a/libc/sysdeps/linux/sh/sys/user.h b/libc/sysdeps/linux/sh/sys/user.h
index 7f31bb62d..b1adc13b7 100644
--- a/libc/sysdeps/linux/sh/sys/user.h
+++ b/libc/sysdeps/linux/sh/sys/user.h
@@ -19,10 +19,60 @@
#ifndef _SYS_USER_H
#define _SYS_USER_H 1
-#include <features.h>
+#include <unistd.h>
+#include <asm/ptrace.h>
-#include <asm/user.h>
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd). The file contents are as follows:
+ *
+ * upage: 1 page consisting of a user struct that tells gdb
+ * what is present in the file. Directly after this is a
+ * copy of the task_struct, which is currently not used by gdb,
+ * but it may come in handy at some point. All of the registers
+ * are stored as part of the upage. The upage should always be
+ * only one page long.
+ * data: The data segment follows next. We use current->end_text to
+ * current->brk to pick up all of the user variables, plus any memory
+ * that may have been sbrk'ed. No attempt is made to determine if a
+ * page is demand-zero or if a page is totally unused, we just cover
+ * the entire range. All of the addresses are rounded in such a way
+ * that an integral number of pages is written.
+ * stack: We need the stack information in order to get a meaningful
+ * backtrace. We need to write the data from usp to
+ * current->start_stack, so we round each of these in order to be able
+ * to write an integer number of pages.
+ */
-#undef start_thread
+struct user_fpu_struct {
+ unsigned long fp_regs[16];
+ unsigned long xfp_regs[16];
+ unsigned long fpscr;
+ unsigned long fpul;
+};
+
+struct user {
+ struct pt_regs regs; /* entire machine state */
+ struct user_fpu_struct fpu; /* Math Co-processor registers */
+ int u_fpvalid; /* True if math co-processor being used */
+ size_t u_tsize; /* text size (pages) */
+ size_t u_dsize; /* data size (pages) */
+ size_t u_ssize; /* stack size (pages) */
+ unsigned long start_code; /* text starting address */
+ unsigned long start_data; /* data starting address */
+ unsigned long start_stack; /* stack starting address */
+ long int signal; /* signal causing core dump */
+ struct regs * u_ar0; /* help gdb find registers */
+ struct user_fpu_struct* u_fpstate; /* Math Co-processor pointer */
+ unsigned long magic; /* identifies a core file */
+ char u_comm[32]; /* user command name */
+};
+
+#define NBPG getpagesize()
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_DATA_START_ADDR (u.start_data)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
#endif /* sys/user.h */
diff --git a/libc/sysdeps/linux/sh/syscall_error.S b/libc/sysdeps/linux/sh/syscall_error.S
index 1764ebfc8..d943dcbb0 100644
--- a/libc/sysdeps/linux/sh/syscall_error.S
+++ b/libc/sysdeps/linux/sh/syscall_error.S
@@ -3,7 +3,7 @@ __syscall_error:
/* Call errno_location, store '-r4' in errno and return -1 */
mov.l r12, @-r15
sts.l pr, @-r15
-#ifdef __HAVE_SHARED__
+#ifdef SHARED
mova .LG, r0
mov.l .LG, r12
add r0, r12
@@ -27,7 +27,7 @@ __syscall_error:
.align 4
-#ifdef __HAVE_SHARED__
+#ifdef SHARED
1: .long __errno_location@GOT
.LG: .long _GLOBAL_OFFSET_TABLE_
#else