diff options
Diffstat (limited to 'libc/sysdeps/linux/sh')
40 files changed, 812 insertions, 960 deletions
diff --git a/libc/sysdeps/linux/sh/Makefile.arch b/libc/sysdeps/linux/sh/Makefile.arch index 77ad570d6..99a77213b 100644 --- a/libc/sysdeps/linux/sh/Makefile.arch +++ b/libc/sysdeps/linux/sh/Makefile.arch @@ -6,9 +6,10 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC := \ - mmap.c pipe.c __init_brk.c brk.c sbrk.c syscall.c pread_write.c +CSRC-y := \ + pipe.c __init_brk.c brk.c sbrk.c pread_write.c -SSRC := setjmp.S __longjmp.S vfork.S clone.S ___fpscr_values.S +SSRC-y := setjmp.S __longjmp.S ___fpscr_values.S -include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch +CSRC-$(UCLIBC_LINUX_SPECIFIC) += cacheflush.c +SSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += clone.S vfork.S diff --git a/libc/sysdeps/linux/sh/___fpscr_values.S b/libc/sysdeps/linux/sh/___fpscr_values.S index de8f0b42d..aac7a8e4f 100644 --- a/libc/sysdeps/linux/sh/___fpscr_values.S +++ b/libc/sysdeps/linux/sh/___fpscr_values.S @@ -14,14 +14,13 @@ details. You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include <features.h> .data -#if defined(__CONFIG_SH4__) +#ifdef __SH4__ .global ___fpscr_values .type ___fpscr_values,@object .size ___fpscr_values,8 diff --git a/libc/sysdeps/linux/sh/__init_brk.c b/libc/sysdeps/linux/sh/__init_brk.c index bb0692448..8a41eb3c4 100644 --- a/libc/sysdeps/linux/sh/__init_brk.c +++ b/libc/sysdeps/linux/sh/__init_brk.c @@ -7,7 +7,7 @@ void * __curbrk attribute_hidden = 0; #define __NR__brk __NR_brk -attribute_hidden _syscall1(void *, _brk, void *, ptr); +attribute_hidden _syscall1(void *, _brk, void *, ptr) extern int __init_brk (void) attribute_hidden; int diff --git a/libc/sysdeps/linux/sh/__longjmp.S b/libc/sysdeps/linux/sh/__longjmp.S index eb569917b..5abf22912 100644 --- a/libc/sysdeps/linux/sh/__longjmp.S +++ b/libc/sysdeps/linux/sh/__longjmp.S @@ -14,12 +14,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ -#define _SETJMP_H -#define _ASM -#include <bits/setjmp.h> #include <features.h> /* __longjmp(jmpbuf, val) */ diff --git a/libc/sysdeps/linux/sh/bits/atomic.h b/libc/sysdeps/linux/sh/bits/atomic.h index 6bb7255c5..18ae9ea77 100644 --- a/libc/sysdeps/linux/sh/bits/atomic.h +++ b/libc/sysdeps/linux/sh/bits/atomic.h @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <stdint.h> @@ -54,6 +53,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 +68,231 @@ typedef uintmax_t uatomic_max_t; r1: saved stack pointer */ -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - ({ __typeof (*(mem)) __result; \ +#if __GNUC_PREREQ (4, 7) +# define rNOSP "u" +#else +# define rNOSP "r" +#endif + +/* 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 __arch_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"); \ - __result; }) + mov." #bwl " %2,@%1\n\ + 1: mov r1,r15\n\ + .ifeqs \"bool\",\"" #version "\"\n\ + movt %0\n\ + .endif\n" \ + : "=&r" (__arch_result) \ + : rNOSP (mem), rNOSP (newval), rNOSP (oldval) \ + : "r0", "r1", "t", "memory"); \ + __arch_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) \ + : rNOSP (mem), rNOSP (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) \ + : rNOSP (mem), rNOSP (__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 93c41d225..84720dcc1 100644 --- a/libc/sysdeps/linux/sh/bits/fcntl.h +++ b/libc/sysdeps/linux/sh/bits/fcntl.h @@ -14,9 +14,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _FCNTL_H # error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." @@ -50,9 +49,8 @@ # define O_DIRECTORY 0200000 /* Must be a directory. */ # define O_NOFOLLOW 0400000 /* Do not follow links. */ # define O_NOATIME 01000000 /* Do not set atime. */ -# if 0 # define O_CLOEXEC 02000000 /* Set close_on_exec. */ -# endif +# define O_PATH 010000000 /* Resolve pathname but do not open file. */ #endif /* For now Linux has synchronisity options for data and read operations. @@ -102,6 +100,8 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with close-on-exit set on new fd. */ +# define F_SETPIPE_SZ 1031 /* Set pipe page size array. */ +# define F_GETPIPE_SZ 1032 /* Get pipe page size array. */ #endif /* For F_[GET|SET]FD. */ @@ -189,7 +189,7 @@ struct flock64 #endif -#ifdef __USE_GNU +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ /* Flags for SYNC_FILE_RANGE. */ # define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages in the range before performing the @@ -212,7 +212,7 @@ struct flock64 __BEGIN_DECLS -#ifdef __USE_GNU +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ /* Provide kernel hint to read ahead. */ extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) diff --git a/libc/sysdeps/linux/sh/bits/fenv.h b/libc/sysdeps/linux/sh/bits/fenv.h index cbbad92e1..38c303ff2 100644 --- a/libc/sysdeps/linux/sh/bits/fenv.h +++ b/libc/sysdeps/linux/sh/bits/fenv.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." diff --git a/libc/sysdeps/linux/sh/bits/huge_val.h b/libc/sysdeps/linux/sh/bits/huge_val.h index 732b06503..984faab91 100644 --- a/libc/sysdeps/linux/sh/bits/huge_val.h +++ b/libc/sysdeps/linux/sh/bits/huge_val.h @@ -16,9 +16,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _MATH_H # error "Never use <bits/huge_val.h> directly; include <math.h> instead." diff --git a/libc/sysdeps/linux/sh/bits/kernel_stat.h b/libc/sysdeps/linux/sh/bits/kernel_stat.h index 2e88dad82..5b51b3cd3 100644 --- a/libc/sysdeps/linux/sh/bits/kernel_stat.h +++ b/libc/sysdeps/linux/sh/bits/kernel_stat.h @@ -1,10 +1,6 @@ #ifndef _BITS_STAT_STRUCT_H #define _BITS_STAT_STRUCT_H -#ifndef _LIBC -#error bits/kernel_stat.h is for internal uClibc use only! -#endif - /* This file provides whatever this particular arch's kernel thinks * struct kernel_stat should look like... It turns out each arch has a * different opinion on the subject... */ @@ -23,12 +19,9 @@ struct kernel_stat { unsigned long st_size; unsigned long st_blksize; unsigned long st_blocks; - unsigned long st_atime; - unsigned long __unused1; - unsigned long st_mtime; - unsigned long __unused2; - unsigned long st_ctime; - unsigned long __unused3; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; unsigned long __unused4; unsigned long __unused5; }; @@ -72,14 +65,9 @@ struct kernel_stat64 { unsigned long __pad4; /* Future possible st_blocks hi bits */ #endif - unsigned long st_atime; - unsigned long __pad5; - - unsigned long st_mtime; - unsigned long __pad6; - - unsigned long st_ctime; - unsigned long __pad7; /* will be high 32 bits of ctime someday */ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; unsigned long __unused1; unsigned long __unused2; diff --git a/libc/sysdeps/linux/sh/bits/kernel_types.h b/libc/sysdeps/linux/sh/bits/kernel_types.h index 7d55cf510..ac97261e6 100644 --- a/libc/sysdeps/linux/sh/bits/kernel_types.h +++ b/libc/sysdeps/linux/sh/bits/kernel_types.h @@ -4,8 +4,9 @@ * our private content, and not the kernel header, will win. * -Erik */ -#ifndef __ASM_SH_POSIX_TYPES_H +#if !defined __ASM_SH_POSIX_TYPES_H && !defined __ASM_SH_POSIX_TYPES_32_H #define __ASM_SH_POSIX_TYPES_H +#define __ASM_SH_POSIX_TYPES_32_H typedef unsigned short __kernel_dev_t; typedef unsigned long __kernel_ino_t; @@ -31,6 +32,8 @@ typedef unsigned int __kernel_gid32_t; typedef unsigned short __kernel_old_uid_t; typedef unsigned short __kernel_old_gid_t; typedef __kernel_dev_t __kernel_old_dev_t; +typedef long __kernel_long_t; +typedef unsigned long __kernel_ulong_t; typedef long long __kernel_loff_t; typedef struct { diff --git a/libc/sysdeps/linux/sh/bits/mathdef.h b/libc/sysdeps/linux/sh/bits/mathdef.h index 2b8caf194..9c7e0566e 100644 --- a/libc/sysdeps/linux/sh/bits/mathdef.h +++ b/libc/sysdeps/linux/sh/bits/mathdef.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #if !defined _MATH_H && !defined _COMPLEX_H # error "Never use <bits/mathdef.h> directly; include <math.h> instead" @@ -30,32 +29,12 @@ #if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF # define _MATH_H_MATHDEF 1 -# ifdef __GNUC__ -# if __STDC__ == 1 - -/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */ +/* SH has both `float' and `double' arithmetic. */ typedef float float_t; /* `float' expressions are evaluated as `float'. */ typedef double double_t; /* `double' expressions are evaluated as `double'. */ -# else - -/* For `gcc -traditional', `float' expressions are evaluated as `double'. */ -typedef double float_t; /* `float' expressions are evaluated as - `double'. */ -typedef double double_t; /* `double' expressions are evaluated as - `double'. */ - -# endif -# else - -/* Wild guess at types for float_t and double_t. */ -typedef double float_t; -typedef double double_t; - -# endif - /* The values returned by `ilogb' for 0 and NaN respectively. */ # define FP_ILOGB0 0x80000001 # define FP_ILOGBNAN 0x7fffffff diff --git a/libc/sysdeps/linux/sh/bits/mman.h b/libc/sysdeps/linux/sh/bits/mman.h deleted file mode 100644 index 7a6b572a4..000000000 --- a/libc/sysdeps/linux/sh/bits/mman.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Definitions for POSIX memory map interface. Linux/SH version. - Copyright (C) 1997,1999,2000,2003,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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _SYS_MMAN_H -# error "Never include this file directly. Use <sys/mman.h> instead" -#endif - -/* The following definitions basically come from the kernel headers. - But the kernel header is not namespace clean. */ - - -/* Protections are chosen from these bits, OR'd together. The - implementation does not necessarily support PROT_EXEC or PROT_WRITE - without PROT_READ. The only guarantees are that no writing will be - allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ - -#define PROT_READ 0x1 /* Page can be read. */ -#define PROT_WRITE 0x2 /* Page can be written. */ -#define PROT_EXEC 0x4 /* Page can be executed. */ -#define PROT_NONE 0x0 /* Page can not be accessed. */ -#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of - growsdown vma (mprotect only). */ -#define PROT_GROWSUP 0x02000000 /* Extend change to start of - growsup vma (mprotect only). */ - -/* Sharing types (must choose one and only one of these). */ -#define MAP_SHARED 0x01 /* Share changes. */ -#define MAP_PRIVATE 0x02 /* Changes are private. */ -#ifdef __USE_MISC -# define MAP_TYPE 0x0f /* Mask for type of mapping. */ -#endif - -/* Other flags. */ -#define MAP_FIXED 0x10 /* Interpret addr exactly. */ -#ifdef __USE_MISC -# define MAP_FILE 0 -# define MAP_ANONYMOUS 0x20 /* Don't use a file. */ -# define MAP_ANON MAP_ANONYMOUS -#endif - -/* These are Linux-specific. */ -#ifdef __USE_MISC -# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */ -# define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */ -# define MAP_LOCKED 0x2000 /* Lock the mapping. */ -# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */ -# define MAP_POPULATE 0x8000 /* Populate (prefault) pagetables. */ -# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */ -#endif - -/* Flags to `msync'. */ -#define MS_ASYNC 1 /* Sync memory asynchronously. */ -#define MS_SYNC 4 /* Synchronous memory sync. */ -#define MS_INVALIDATE 2 /* Invalidate the caches. */ - -/* Flags for `mlockall'. */ -#define MCL_CURRENT 1 /* Lock all currently mapped pages. */ -#define MCL_FUTURE 2 /* Lock all additions to address - space. */ - -/* Flags for `mremap'. */ -#ifdef __USE_GNU -# define MREMAP_MAYMOVE 1 -# define MREMAP_FIXED 2 -#endif - -/* Advice to `madvise'. */ -#ifdef __USE_BSD -# define MADV_NORMAL 0 /* No further special treatment. */ -# define MADV_RANDOM 1 /* Expect random page references. */ -# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ -# define MADV_WILLNEED 3 /* Will need these pages. */ -# define MADV_DONTNEED 4 /* Don't need these pages. */ -# define MADV_REMOVE 9 /* Remove these pages and resources. */ -# define MADV_DONTFORK 10 /* Do not inherit across fork. */ -# define MADV_DOFORK 11 /* Do inherit across fork. */ -#endif - -/* The POSIX people had to invent similar names for the same things. */ -#ifdef __USE_XOPEN2K -# define POSIX_MADV_NORMAL 0 /* No further special treatment. */ -# define POSIX_MADV_RANDOM 1 /* Expect random page references. */ -# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */ -# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */ -# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */ -#endif diff --git a/libc/sysdeps/linux/sh/bits/setjmp.h b/libc/sysdeps/linux/sh/bits/setjmp.h index 6458dfefd..85476a4d8 100644 --- a/libc/sysdeps/linux/sh/bits/setjmp.h +++ b/libc/sysdeps/linux/sh/bits/setjmp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2003,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 @@ -12,19 +12,17 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* Define the machine-dependent type `jmp_buf'. SH version. */ #ifndef _BITS_SETJMP_H -#define _BITS_SETJMP_H 1 +#define _BITS_SETJMP_H 1 #if !defined _SETJMP_H && !defined _PTHREAD_H # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." #endif -#ifndef _ASM typedef struct { /* Callee-saved registers r8 through r15. */ @@ -42,15 +40,5 @@ typedef struct /* Callee-saved floating point registers fr12 through fr15. */ int __fpregs[4]; } __jmp_buf[1]; -#endif - -#if defined __USE_MISC || defined _ASM -# define JB_SIZE (4 * 15) -#endif - -/* Test if longjmp to JMPBUF would unwind the frame - containing a local variable at ADDRESS. */ -#define _JMPBUF_UNWINDS(jmpbuf, address) \ - ((void *) (address) < (void *) (jmpbuf)[0].__regs[7]) -#endif /* bits/setjmp.h */ +#endif /* bits/setjmp.h */ diff --git a/libc/sysdeps/linux/sh/bits/shm.h b/libc/sysdeps/linux/sh/bits/shm.h index ccf4b8943..646e5badc 100644 --- a/libc/sysdeps/linux/sh/bits/shm.h +++ b/libc/sysdeps/linux/sh/bits/shm.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_SHM_H # error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." diff --git a/libc/sysdeps/linux/sh/bits/sigcontextinfo.h b/libc/sysdeps/linux/sh/bits/sigcontextinfo.h index 3e1f3e949..13b36acf7 100644 --- a/libc/sysdeps/linux/sh/bits/sigcontextinfo.h +++ b/libc/sysdeps/linux/sh/bits/sigcontextinfo.h @@ -13,9 +13,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #define SIGCONTEXT int _a2, int _a3, int _a4, struct sigcontext diff --git a/libc/sysdeps/linux/sh/bits/stackinfo.h b/libc/sysdeps/linux/sh/bits/stackinfo.h index e65338f25..c52e7d7b7 100644 --- a/libc/sysdeps/linux/sh/bits/stackinfo.h +++ b/libc/sysdeps/linux/sh/bits/stackinfo.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* This file contains a bit of information about the stack allocation of the processor. */ diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h index e0ab65b82..efd423ed3 100644 --- a/libc/sysdeps/linux/sh/bits/syscalls.h +++ b/libc/sysdeps/linux/sh/bits/syscalls.h @@ -5,7 +5,7 @@ #endif /* The Linux kernel uses different trap numbers on sh-2. */ -#ifdef __CONFIG_SH2__ +#if defined __sh2__ || defined __SH2A__ # define __SH_SYSCALL_TRAP_BASE 0x20 #else # define __SH_SYSCALL_TRAP_BASE 0x10 @@ -15,138 +15,14 @@ #include <errno.h> -#define SYS_ify(syscall_name) (__NR_##syscall_name) - -/* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */ -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-125)) { \ - /* Avoid using "res" which is declared to be in register r0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - __set_errno(__err); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE), "0" (__sc0) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 1), "0" (__sc0), "r" (__sc4) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 2), "0" (__sc0), "r" (__sc4), \ - "r" (__sc5) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 3), "0" (__sc0), "r" (__sc4), \ - "r" (__sc5), "r" (__sc6) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 4), "0" (__sc0), "r" (__sc4), \ - "r" (__sc5), "r" (__sc6), \ - "r" (__sc7) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ -register long __sc3 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -register long __sc0 __asm__ ("r0") = (long) arg5; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 5), "0" (__sc0), "r" (__sc4), \ - "r" (__sc5), "r" (__sc6), "r" (__sc7), "r" (__sc3) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#ifndef __SH_SYSCALL6_TRAPA -#define __SH_SYSCALL6_TRAPA __SH_SYSCALL_TRAP_BASE + 6 -#endif - -/* Add in _syscall6 which is not in the kernel header */ -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ -register long __sc3 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -register long __sc0 __asm__ ("r0") = (long) arg5; \ -register long __sc1 __asm__ ("r1") = (long) arg6; \ -__asm__ __volatile__ ("trapa %1" \ - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL6_TRAPA), "0" (__sc0), "r" (__sc4), \ - "r" (__sc5), "r" (__sc6), "r" (__sc7), "r" (__sc3), "r" (__sc1) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define SYSCALL_INST_STR0 "trapa #0x10\n\t" -#define SYSCALL_INST_STR1 "trapa #0x11\n\t" -#define SYSCALL_INST_STR2 "trapa #0x12\n\t" -#define SYSCALL_INST_STR3 "trapa #0x13\n\t" -#define SYSCALL_INST_STR4 "trapa #0x14\n\t" -#define SYSCALL_INST_STR5 "trapa #0x15\n\t" -#define SYSCALL_INST_STR6 "trapa #0x16\n\t" +#define SYSCALL_INST_STR(x) "trapa #"__stringify(__SH_SYSCALL_TRAP_BASE + x)"\n\t" +#define SYSCALL_INST_STR0 SYSCALL_INST_STR(0) +#define SYSCALL_INST_STR1 SYSCALL_INST_STR(1) +#define SYSCALL_INST_STR2 SYSCALL_INST_STR(2) +#define SYSCALL_INST_STR3 SYSCALL_INST_STR(3) +#define SYSCALL_INST_STR4 SYSCALL_INST_STR(4) +#define SYSCALL_INST_STR5 SYSCALL_INST_STR(5) +#define SYSCALL_INST_STR6 SYSCALL_INST_STR(6) # ifdef NEED_SYSCALL_INST_PAD # define SYSCALL_INST_PAD "\ @@ -236,55 +112,24 @@ __syscall_return(type,__sc0); \ register long int r1 __asm__ ("%r1") = (long int) (_arg6); \ register long int r2 __asm__ ("%r2") = (long int) (_arg7) -#undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ - ({ \ - unsigned int __resultvar = INTERNAL_SYSCALL (name, , nr, args); \ - if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (__resultvar, ), 0)) \ - { \ - __set_errno (INTERNAL_SYSCALL_ERRNO (__resultvar, )); \ - __resultvar = 0xffffffff; \ - } \ - (int) __resultvar; }) - -#undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ - ({ \ - unsigned long int resultvar; \ - register long int r3 __asm__ ("%r3") = SYS_ify (name); \ - SUBSTITUTE_ARGS_##nr(args); \ - \ - __asm__ volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \ - : "=z" (resultvar) \ - : "r" (r3) ASMFMT_##nr \ - : "memory"); \ - \ - (int) resultvar; }) - /* The _NCS variant allows non-constant syscall numbers. */ #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - unsigned long int resultvar; \ - register long int r3 __asm__ ("%r3") = (name); \ - SUBSTITUTE_ARGS_##nr(args); \ - \ - __asm__ volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \ - : "=z" (resultvar) \ - : "r" (r3) ASMFMT_##nr \ - : "memory"); \ - \ - (int) resultvar; }) - -#undef INTERNAL_SYSCALL_DECL -#define INTERNAL_SYSCALL_DECL(err) do { } while (0) - -#undef INTERNAL_SYSCALL_ERROR_P +(__extension__ \ + ({ \ + unsigned long int resultvar; \ + register long int r3 __asm__ ("%r3") = (name); \ + SUBSTITUTE_ARGS_##nr(args); \ + __asm__ __volatile__ (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \ + : "=z" (resultvar) \ + : "r" (r3) ASMFMT_##nr \ + : "memory", "t" \ + ); \ + (int) resultvar; \ + }) \ +) #define INTERNAL_SYSCALL_ERROR_P(val, err) \ ((unsigned int) (val) >= 0xfffff001u) -#undef INTERNAL_SYSCALL_ERRNO -#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) - #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h b/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h index 55e34804f..401bd45d6 100644 --- a/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/sh/bits/uClibc_arch_features.h @@ -6,7 +6,7 @@ #define _BITS_UCLIBC_ARCH_FEATURES_H /* instruction used when calling abort() to kill yourself */ -#if defined(__CONFIG_SH2__) +#ifdef __sh2__ # define __UCLIBC_ABORT_INSTRUCTION__ "trapa #32" #else # define __UCLIBC_ABORT_INSTRUCTION__ "trapa #0xff" @@ -15,8 +15,8 @@ /* can your target use syscall6() for mmap ? */ #define __UCLIBC_MMAP_HAS_6_ARGS__ -/* does your target use syscall4() for truncate64 ? (32bit arches only) */ -#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__ +/* does your target align 64bit values in register pairs ? (32bit arches only) */ +#undef __UCLIBC_SYSCALL_ALIGN_64BIT__ /* does your target have a broken create_module() ? */ #undef __UCLIBC_BROKEN_CREATE_MODULE__ @@ -27,19 +27,19 @@ /* does your target have an asm .set ? */ #define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__ -/* define if target doesn't like .global */ -#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__ - /* define if target supports .weak */ #define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__ /* define if target supports .weakext */ #undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__ -/* needed probably only for ppc64 */ -#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__ +/* define if target supports CFI pseudo ops */ +#define __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__ /* define if target supports IEEE signed zero floats */ #define __UCLIBC_HAVE_SIGNED_ZERO__ +/* only weird assemblers generally need this */ +#undef __UCLIBC_ASM_LINE_SEP__ + #endif /* _BITS_UCLIBC_ARCH_FEATURES_H */ diff --git a/libc/sysdeps/linux/sh/bits/wordsize.h b/libc/sysdeps/linux/sh/bits/wordsize.h index ba643b60a..ca82fd7d4 100644 --- a/libc/sysdeps/linux/sh/bits/wordsize.h +++ b/libc/sysdeps/linux/sh/bits/wordsize.h @@ -12,8 +12,7 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #define __WORDSIZE 32 diff --git a/libc/sysdeps/linux/sh/brk.c b/libc/sysdeps/linux/sh/brk.c index c69c97ad6..a98cd5446 100644 --- a/libc/sysdeps/linux/sh/brk.c +++ b/libc/sysdeps/linux/sh/brk.c @@ -13,7 +13,6 @@ extern void * __curbrk attribute_hidden; extern int __init_brk (void) attribute_hidden; extern void *_brk(void *ptr) attribute_hidden; -libc_hidden_proto(brk) int brk(void * end_data_seg) { if (__init_brk () == 0) diff --git a/libc/sysdeps/linux/sh/cacheflush.c b/libc/sysdeps/linux/sh/cacheflush.c new file mode 100644 index 000000000..619b96b5a --- /dev/null +++ b/libc/sysdeps/linux/sh/cacheflush.c @@ -0,0 +1,14 @@ +/* + * cacheflush syscall for SUPERH + * + * Copyright (C) 2009 STMicroelectronics Ltd + * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ +#include <sys/syscall.h> + +#ifdef __NR_cacheflush +int cacheflush(void *addr, const int nbytes, int op); +_syscall3(int, cacheflush, void *, addr, const int, nbytes, const int, op) +#endif diff --git a/libc/sysdeps/linux/sh/clone.S b/libc/sysdeps/linux/sh/clone.S index 386b4ceb1..3ed6b25de 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, 2007 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 @@ -12,101 +12,117 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* clone() is even more special than fork() as it mucks with stacks and invokes a function in the right context after its all over. */ #include <features.h> -#include <sys/syscall.h> -#define _ERRNO_H +#include <asm/unistd.h> +#include <sysdep.h> +#define _ERRNO_H 1 #include <bits/errno.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 - + bt/s 0f + tst r5, r5 + bf 1f +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 + mov #+SYS_ify(clone), r3 + 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 +#ifdef __sh2__ +/* 12 arithmetic shifts for the 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 @@ -118,8 +134,16 @@ 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/crt1.S b/libc/sysdeps/linux/sh/crt1.S index 1c3c54447..2d3e68ed2 100644 --- a/libc/sysdeps/linux/sh/crt1.S +++ b/libc/sysdeps/linux/sh/crt1.S @@ -14,8 +14,7 @@ details. You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with this program; if not, see <http://www.gnu.org/licenses/>. */ @@ -56,6 +55,35 @@ _start: /* Push the stack_end, rtld_fini and fini func onto the stack */ mov.l r6,@-r15 mov.l r4,@-r15 + +#ifdef __PIC__ + mova L_got, r0 + mov.l L_got, r12 + add r0, r12 + + mov.l L_fini,r0 + add r12, r0 + mov.l r0,@-r15 + + /* Set up the main/init funcs that go in registers */ + mov.l L_main, r4 + add r12, r4 + mov.l L_init, r7 + add r12, r7 + + /* __uClibc_main (main, argc, argv, init, fini, rtld_fini, stack_end) */ + + /* Let the libc call main and exit with its return code. */ + mov.l L_uClibc_main,r0 + mov.l @(r0,r12),r1 + jsr @r1 + nop + /* We should not get here. */ + mov.l L_abort,r0 + mov.l @(r0,r12),r1 + jsr @r1 + nop +#else mov.l L_fini,r0 mov.l r0,@-r15 @@ -73,10 +101,25 @@ _start: mov.l L_abort,r1 jmp @r1 nop +#endif .size _start,.-_start .align 2 +#ifdef __PIC__ +L_got: + .long _GLOBAL_OFFSET_TABLE_ +L_main: + .long main@GOTOFF +L_init: + .long _init@GOTOFF +L_fini: + .long _fini@GOTOFF +L_uClibc_main: + .long __uClibc_main@GOT +L_abort: + .long abort@GOT +#else L_main: .long main L_init: @@ -87,6 +130,7 @@ L_uClibc_main: .long __uClibc_main L_abort: .long abort +#endif /* Define a symbol for the first piece of initialized data. */ .data diff --git a/libc/sysdeps/linux/sh/crtn.S b/libc/sysdeps/linux/sh/crtn.S index 437f8ebc3..e8be7e51f 100644 --- a/libc/sysdeps/linux/sh/crtn.S +++ b/libc/sysdeps/linux/sh/crtn.S @@ -15,7 +15,6 @@ .align 2 .L6: .L7: - .size _init, .-_init .section .fini .hidden _fini @@ -31,6 +30,5 @@ .align 2 .L11: .L12: - .size _fini, .-_fini .ident "GCC: (GNU) 3.3.2" diff --git a/libc/sysdeps/linux/sh/fpu_control.h b/libc/sysdeps/linux/sh/fpu_control.h index db3cc4557..8143041fe 100644 --- a/libc/sysdeps/linux/sh/fpu_control.h +++ b/libc/sysdeps/linux/sh/fpu_control.h @@ -1,5 +1,5 @@ /* FPU control word definitions. SH version. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2009 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 @@ -13,14 +13,15 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H -#warning This file is only correct for sh4 +#ifndef __SH4__ +#error This file is only correct for sh4 +#endif /* masking of interrupts */ #define _FPU_MASK_VM 0x0800 /* Invalid operation */ @@ -47,6 +48,8 @@ typedef unsigned int fpu_control_t; #define _FPU_GETCW(cw) __asm__ ("sts fpscr,%0" : "=r" (cw)) #if defined __GNUC__ +/* GCC provides this function */ +extern void __set_fpscr (unsigned long); #define _FPU_SETCW(cw) __set_fpscr ((cw)) #else #define _FPU_SETCW(cw) __asm__ ("lds %0,fpscr" : : "r" (cw)) diff --git a/libc/sysdeps/linux/sh/jmpbuf-offsets.h b/libc/sysdeps/linux/sh/jmpbuf-offsets.h new file mode 100644 index 000000000..0b824b205 --- /dev/null +++ b/libc/sysdeps/linux/sh/jmpbuf-offsets.h @@ -0,0 +1,19 @@ +/* Private macros for accessing __jmp_buf contents. SH version. + Copyright (C) 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/>. */ + +#define JB_SIZE (4 * 15) diff --git a/libc/sysdeps/linux/sh/jmpbuf-unwind.h b/libc/sysdeps/linux/sh/jmpbuf-unwind.h new file mode 100644 index 000000000..8875cc1c8 --- /dev/null +++ b/libc/sysdeps/linux/sh/jmpbuf-unwind.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ +#include <setjmp.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)[0].__regs[7]) + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <stdint.h> +#include <unwind.h> + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +#define _JMPBUF_UNWINDS_ADJ(jmpbuf, address, adj) \ + ((uintptr_t) (address) - (adj) < (uintptr_t) (jmpbuf)[0].__regs[7] - (adj)) +#endif diff --git a/libc/sysdeps/linux/sh/mmap.c b/libc/sysdeps/linux/sh/mmap.c deleted file mode 100644 index e711b0ff8..000000000 --- a/libc/sysdeps/linux/sh/mmap.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2001 Hewlett-Packard - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU Library General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) any - later version. - - This program 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 Library General Public License for more - details. - - You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Derived in part from the Linux-8086 C library, the GNU C Library, and several - other sundry sources. Files within this library are copyright by their - respective copyright holders. -*/ - -#include <unistd.h> -#include <errno.h> -#include <sys/mman.h> - -libc_hidden_proto(mmap) - -#ifdef HIOS -# define __SH_SYSCALL6_TRAPA 0x2E -#endif - -#include <sys/syscall.h> - -_syscall6(__ptr_t, mmap, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, offset); -libc_hidden_def(mmap) diff --git a/libc/sysdeps/linux/sh/pipe.c b/libc/sysdeps/linux/sh/pipe.c index 432a5bc03..799f51839 100644 --- a/libc/sysdeps/linux/sh/pipe.c +++ b/libc/sysdeps/linux/sh/pipe.c @@ -12,7 +12,6 @@ #include <unistd.h> #include <syscall.h> -libc_hidden_proto(pipe) int pipe(int *fd) { diff --git a/libc/sysdeps/linux/sh/pread_write.c b/libc/sysdeps/linux/sh/pread_write.c index 1fef23ae8..5877f686f 100644 --- a/libc/sysdeps/linux/sh/pread_write.c +++ b/libc/sysdeps/linux/sh/pread_write.c @@ -4,80 +4,8 @@ * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -/* - * Based in part on the files - * ./sysdeps/unix/sysv/linux/pwrite.c, - * ./sysdeps/unix/sysv/linux/pread.c, - * sysdeps/posix/pread.c - * sysdeps/posix/pwrite.c - * from GNU libc 2.2.5, but reworked considerably... - */ - -#include <sys/syscall.h> -#include <unistd.h> -#include <stdint.h> -#include <endian.h> - -#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ -# ifdef __NR_pread -# error "__NR_pread and __NR_pread64 both defined???" -# endif -# define __NR_pread __NR_pread64 -#endif - -#ifdef __NR_pread -extern __typeof(pread) __libc_pread; -# define __NR___syscall_pread __NR_pread -static __inline__ _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); - -ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) -{ - return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset))); -} -weak_alias(__libc_pread,pread) - -# ifdef __UCLIBC_HAS_LFS__ -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))); -} -weak_alias(__libc_pread64,pread64) -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* __NR_pread */ - -/**********************************************************************/ - -#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */ -# ifdef __NR_pwrite -# error "__NR_pwrite and __NR_pwrite64 both defined???" -# endif -# define __NR_pwrite __NR_pwrite64 -#endif - -#ifdef __NR_pwrite -extern __typeof(pwrite) __libc_pwrite; -# define __NR___syscall_pwrite __NR_pwrite -static __inline__ _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); - -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(offset >> 31,offset))); -} -weak_alias(__libc_pwrite,pwrite) -# ifdef __UCLIBC_HAS_LFS__ -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))); -} -weak_alias(__libc_pwrite64,pwrite64) -# endif /* __UCLIBC_HAS_LFS__ */ -#endif /* __NR_pwrite */ +/* SuperH doesn't have this alignment issue. It just decided to copy + * the syscall interface from another arch for no good reason. */ +#define __UCLIBC_SYSCALL_ALIGN_64BIT__ +#include "../common/pread_write.c" diff --git a/libc/sysdeps/linux/sh/sbrk.c b/libc/sysdeps/linux/sh/sbrk.c index a1ff2a148..2dc719a16 100644 --- a/libc/sysdeps/linux/sh/sbrk.c +++ b/libc/sysdeps/linux/sh/sbrk.c @@ -8,7 +8,6 @@ extern void * __curbrk attribute_hidden; extern int __init_brk (void) attribute_hidden; extern void *_brk(void *ptr) attribute_hidden; -libc_hidden_proto(sbrk) void * sbrk(intptr_t increment) { diff --git a/libc/sysdeps/linux/sh/setjmp.S b/libc/sysdeps/linux/sh/setjmp.S index 3296c2ba9..d27cf394c 100644 --- a/libc/sysdeps/linux/sh/setjmp.S +++ b/libc/sysdeps/linux/sh/setjmp.S @@ -14,13 +14,10 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #include <features.h> -#define _SETJMP_H -#define _ASM -#include <bits/setjmp.h> +#include <jmpbuf-offsets.h> .text @@ -77,7 +74,7 @@ __sigsetjmp_intern: mov.l r9, @-r4 mov.l r8, @-r4 -#ifdef __HAVE_SHARED__ +#ifdef __HAVE_SHARED__ mov.l .LG, r2 mova .LG, r0 add r0, r2 diff --git a/libc/sysdeps/linux/sh/sys/io.h b/libc/sysdeps/linux/sh/sys/io.h index 6fdc44ff8..6f8ef2f19 100644 --- a/libc/sysdeps/linux/sh/sys/io.h +++ b/libc/sysdeps/linux/sh/sys/io.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_IO_H @@ -23,6 +22,7 @@ __BEGIN_DECLS +#if defined __UCLIBC_LINUX_SPECIFIC__ /* If TURN_ON is TRUE, request for permission to do direct i/o on the port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O permission off for that range. This call requires root privileges. */ @@ -33,6 +33,7 @@ extern int ioperm (unsigned long int __from, unsigned long int __num, permission to access any I/O port is granted. This call requires root privileges. */ extern int iopl (int __level) __THROW; +#endif /* __UCLIBC_LINUX_SPECIFIC__ */ /* The functions that actually perform reads and writes. */ extern unsigned char inb (unsigned long int port) __THROW; diff --git a/libc/sysdeps/linux/sh/sys/procfs.h b/libc/sysdeps/linux/sh/sys/procfs.h index aad21e5f8..5fc4c579c 100644 --- a/libc/sysdeps/linux/sh/sys/procfs.h +++ b/libc/sysdeps/linux/sh/sys/procfs.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_PROCFS_H #define _SYS_PROCFS_H 1 diff --git a/libc/sysdeps/linux/sh/sys/ucontext.h b/libc/sysdeps/linux/sh/sys/ucontext.h index 0996bf2d5..230b52444 100644 --- a/libc/sysdeps/linux/sh/sys/ucontext.h +++ b/libc/sysdeps/linux/sh/sys/ucontext.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* Where is System V/SH ABI? */ @@ -32,10 +31,10 @@ typedef int greg_t; /* Number of general registers. */ -#define NFPREG 16 +#define NGREG 16 /* Container for all general registers. */ -typedef greg_t gregset_t[NFPREG]; +typedef greg_t gregset_t[NGREG]; #ifdef __USE_GNU /* Number of each register is the `gregset_t' array. */ @@ -98,7 +97,7 @@ typedef struct unsigned int mach; unsigned int macl; -#ifdef __CONFIG_SH4__ +#ifdef __SH4__ /* FPU registers */ fpregset_t fpregs; fpregset_t xfpregs; diff --git a/libc/sysdeps/linux/sh/sys/user.h b/libc/sysdeps/linux/sh/sys/user.h index b1adc13b7..0c6355a51 100644 --- a/libc/sysdeps/linux/sh/sys/user.h +++ b/libc/sysdeps/linux/sh/sys/user.h @@ -12,9 +12,8 @@ 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _SYS_USER_H #define _SYS_USER_H 1 @@ -22,6 +21,17 @@ #include <unistd.h> #include <asm/ptrace.h> +/* asm/ptrace.h polutes the namespace. */ +#undef PTRACE_GETREGS +#undef PTRACE_SETREGS +#undef PTRACE_GETFPREGS +#undef PTRACE_SETFPREGS +#undef PTRACE_GETFDPIC +#undef PTRACE_GETFDPIC_EXEC +#undef PTRACE_GETFDPIC_INTERP +#undef PTRACE_GETDSPREGS +#undef PTRACE_SETDSPREGS + /* * 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 diff --git a/libc/sysdeps/linux/sh/syscall.c b/libc/sysdeps/linux/sh/syscall.c deleted file mode 100644 index ba187c9b7..000000000 --- a/libc/sysdeps/linux/sh/syscall.c +++ /dev/null @@ -1,27 +0,0 @@ - - -#include <features.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/syscall.h> - -long syscall(long sysnum, - long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6) -{ -register long __sc3 __asm__ ("r3") = sysnum; -register long __sc4 __asm__ ("r4") = (long) arg1; -register long __sc5 __asm__ ("r5") = (long) arg2; -register long __sc6 __asm__ ("r6") = (long) arg3; -register long __sc7 __asm__ ("r7") = (long) arg4; -register long __sc0 __asm__ ("r0") = (long) arg5; -register long __sc1 __asm__ ("r1") = (long) arg6; -__asm__ __volatile__ ( - "trapa %1" - : "=z" (__sc0) \ - : "i" (__SH_SYSCALL_TRAP_BASE + 6), - "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ - "r" (__sc3), "r" (__sc1) \ - : "memory" ); -__syscall_return(long,__sc0); -} diff --git a/libc/sysdeps/linux/sh/syscall_error.S b/libc/sysdeps/linux/sh/syscall_error.S index 1764ebfc8..737950308 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 diff --git a/libc/sysdeps/linux/sh/sysdep.h b/libc/sysdeps/linux/sh/sysdep.h new file mode 100644 index 000000000..b9b0009a5 --- /dev/null +++ b/libc/sysdeps/linux/sh/sysdep.h @@ -0,0 +1,293 @@ +/* Assembler macros for SH. + Copyright (C) 1999, 2000, 2005 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 <common/sysdep.h> + +#include <features.h> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#define LOCAL(X) .L_##X +#define ALIGNARG(log2) log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,@##typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +#ifdef SHARED +#define PLTJMP(_x) _x##@PLT +#else +#define PLTJMP(_x) _x +#endif + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + .globl C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \ + .align ALIGNARG(5); \ + C_LABEL(name) \ + cfi_startproc; \ + CALL_MCOUNT + +#undef END +#define END(name) \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(name)) + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +#define CALL_MCOUNT \ + mov.l 1f,r1; \ + sts.l pr,@-r15; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (pr, 0); \ + mova 2f,r0; \ + jmp @r1; \ + lds r0,pr; \ + .align 2; \ +1: .long mcount; \ +2: lds.l @r15+,pr; \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (pr) + +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#ifdef __UCLIBC_UNDERSCORES__ +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount +#endif + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#define SYS_ify(syscall_name) (__NR_##syscall_name) + +#define ret rts ; nop +/* The sh move insn is s, d. */ +#define MOVE(x,y) mov x , y + +/* Linux uses a negative return value to indicate syscall errors, + unlike most Unices, which use the condition codes' carry flag. + + Since version 2.1 the return value of a system call might be + negative even if the call succeeded. E.g., the `lseek' system call + might return a large offset. Therefore we must not anymore test + for < 0, but test for a real error by making sure the value in R0 + is a real error number. Linus said he will make sure the no syscall + returns a value in -1 .. -4095 as a valid result so we can savely + test with -4095. */ + +#define _IMM1 #-1 +#define _IMM12 #-12 +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name); \ + DO_CALL (syscall_name, args); \ + mov r0,r1; \ + mov _IMM12,r2; \ + shad r2,r1; \ + not r1,r1; \ + tst r1,r1; \ + bf .Lpseudo_end; \ + SYSCALL_ERROR_HANDLER; \ + .Lpseudo_end: + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) + +#undef PSEUDO_NOERRNO +#define PSEUDO_NOERRNO(name, syscall_name, args) \ + .text; \ + ENTRY (name); \ + DO_CALL (syscall_name, args) + +#undef PSEUDO_END_NOERRNO +#define PSEUDO_END_NOERRNO(name) \ + END (name) + +#define ret_NOERRNO ret + +#define PSEUDO_ERRVAL(name, syscall_name, args) \ + .text; \ + ENTRY (name); \ + DO_CALL (syscall_name, args); + +#undef PSEUDO_END_ERRVAL +#define PSEUDO_END_ERRVAL(name) \ + END (name) + +#ifndef __PIC__ +# define SYSCALL_ERROR_HANDLER \ + mov.l 0f,r1; \ + jmp @r1; \ + mov r0,r4; \ + .align 2; \ + 0: .long __syscall_error + +#include <libc/sysdeps/linux/sh/syscall_error.S> +#else +# ifdef RTLD_PRIVATE_ERRNO + +# define SYSCALL_ERROR_HANDLER \ + neg r0,r1; \ + mov.l 0f,r12; \ + mova 0f,r0; \ + add r0,r12; \ + mov.l 1f,r0; \ + mov.l r1,@(r0,r12) + bra .Lpseudo_end; \ + mov _IMM1,r0; \ + .align 2; \ + 0: .long _GLOBAL_OFFSET_TABLE_; \ + 1: .long rtld_errno@GOTOFF + +# elif defined _LIBC_REENTRANT + +# if defined USE___THREAD + +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif +# define SYSCALL_ERROR_HANDLER \ + neg r0,r1; \ + mov r12,r2; \ + mov.l 0f,r12; \ + mova 0f,r0; \ + add r0,r12; \ + mov.l 1f,r0; \ + stc gbr, r4; \ + mov.l @(r0,r12),r0; \ + bra .Lskip; \ + add r4,r0; \ + .align 2; \ + 1: .long SYSCALL_ERROR_ERRNO@GOTTPOFF; \ + .Lskip: \ + mov r2,r12; \ + mov.l r1,@r0; \ + bra .Lpseudo_end; \ + mov _IMM1,r0; \ + .align 2; \ + 0: .long _GLOBAL_OFFSET_TABLE_ +# else + +# define SYSCALL_ERROR_HANDLER \ + neg r0,r1; \ + mov.l r14,@-r15; \ + mov.l r12,@-r15; \ + mov.l r1,@-r15; \ + mov.l 0f,r12; \ + mova 0f,r0; \ + add r0,r12; \ + sts.l pr,@-r15; \ + mov r15,r14; \ + mov.l 1f,r1; \ + bsrf r1; \ + nop; \ + 2: mov r14,r15; \ + lds.l @r15+,pr; \ + mov.l @r15+,r1; \ + mov.l r1,@r0; \ + mov.l @r15+,r12; \ + mov.l @r15+,r14; \ + bra .Lpseudo_end; \ + mov _IMM1,r0; \ + .align 2; \ + 0: .long _GLOBAL_OFFSET_TABLE_; \ + 1: .long PLTJMP(C_SYMBOL_NAME(__errno_location))-(2b-.) +/* A quick note: it is assumed that the call to `__errno_location' does + not modify the stack! */ +# endif +# else + +/* Store (-r0) into errno through the GOT. */ +# define SYSCALL_ERROR_HANDLER \ + neg r0,r1; \ + mov r12,r2; \ + mov.l 0f,r12; \ + mova 0f,r0; \ + add r0,r12; \ + mov.l 1f,r0; \ + mov.l @(r0,r12),r0; \ + mov r2,r12; \ + mov.l r1,@r0; \ + bra .Lpseudo_end; \ + mov _IMM1,r0; \ + .align 2; \ + 0: .long _GLOBAL_OFFSET_TABLE_; \ + 1: .long errno@GOT +# endif /* _LIBC_REENTRANT */ +#endif /* __PIC__ */ + +# ifdef __SH4__ +# define SYSCALL_INST_PAD \ + or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0 +# else +# define SYSCALL_INST_PAD +# endif + +#define SYSCALL_INST0 trapa #0x10 +#define SYSCALL_INST1 trapa #0x11 +#define SYSCALL_INST2 trapa #0x12 +#define SYSCALL_INST3 trapa #0x13 +#define SYSCALL_INST4 trapa #0x14 +#define SYSCALL_INST5 mov.l @(0,r15),r0; trapa #0x15 +#define SYSCALL_INST6 mov.l @(0,r15),r0; mov.l @(4,r15),r1; trapa #0x16 + +#undef DO_CALL +#define DO_CALL(syscall_name, args) \ + mov.l 1f,r3; \ + SYSCALL_INST##args; \ + SYSCALL_INST_PAD; \ + bra 2f; \ + nop; \ + .align 2; \ + 1: .long SYS_ify (syscall_name); \ + 2: +#endif /* __ASSEMBLER__ */ + +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(reg, tmp) \ + stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg +# define PTR_MANGLE2(reg, tmp) xor tmp,reg +# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +# else +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + diff --git a/libc/sysdeps/linux/sh/vfork.S b/libc/sysdeps/linux/sh/vfork.S index a9b440d8f..0a0a0da8d 100644 --- a/libc/sysdeps/linux/sh/vfork.S +++ b/libc/sysdeps/linux/sh/vfork.S @@ -12,19 +12,16 @@ details. You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software Foundation, Inc., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with this program; if not, see <http://www.gnu.org/licenses/>. Derived in part from the Linux-8086 C library, the GNU C Library, and several other sundry sources. Files within this library are copyright by their respective copyright holders. */ -#include <features.h> #include <sys/syscall.h> #define _ERRNO_H #include <bits/errno.h> -#include <bits/sysnum.h> /* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is @@ -41,8 +38,8 @@ __vfork: mov.w .L2, r3 trapa #__SH_SYSCALL_TRAP_BASE mov r0, r1 -#ifdef __CONFIG_SH2__ -// 12 arithmetic shifts for the crappy sh2, because shad doesn't exist! +#ifdef __sh2__ +/* 12 arithmetic shifts for the crappy sh2, because shad doesn't exist! */ shar r1 shar r1 shar r1 @@ -55,13 +52,13 @@ __vfork: shar r1 shar r1 shar r1 -#else +#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 + not r1, r1 /* r1=0 means r0 = -1 to -4095 */ + tst r1, r1 /* i.e. error in linux */ bf 2f mov.w .L1, r1 cmp/eq r1, r0 @@ -72,8 +69,8 @@ __vfork: mov.w .L3, r3 trapa #__SH_SYSCALL_TRAP_BASE mov r0, r1 -#ifdef __CONFIG_SH2__ -// 12 arithmetic shifts for the crappy sh2, because shad doesn't exist! +#ifdef __sh2__ +/* 12 arithmetic shifts for the crappy sh2, because shad doesn't exist! */ shar r1 shar r1 shar r1 @@ -86,13 +83,13 @@ __vfork: shar r1 shar r1 shar r1 -#else +#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 + not r1, r1 /* r1=0 means r0 = -1 to -4095 */ + tst r1, r1 /* i.e. error in linux */ bt/s __syscall_error mov r0, r4 2: @@ -109,6 +106,6 @@ __vfork: .size __vfork, .-__vfork weak_alias(__vfork,vfork) -libc_hidden_weak(vfork) +libc_hidden_def(vfork) #include "syscall_error.S" |
