summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/linux/sh/Makefile16
-rw-r--r--libc/sysdeps/linux/sh/bits/syscalls.h134
-rw-r--r--libc/sysdeps/linux/sh/crt0.S39
-rw-r--r--libc/sysdeps/linux/sh/crti.S22
-rw-r--r--libc/sysdeps/linux/sh/crtn.S17
5 files changed, 197 insertions, 31 deletions
diff --git a/libc/sysdeps/linux/sh/Makefile b/libc/sysdeps/linux/sh/Makefile
index 6ff7f87e3..9b46c965a 100644
--- a/libc/sysdeps/linux/sh/Makefile
+++ b/libc/sysdeps/linux/sh/Makefile
@@ -45,7 +45,7 @@ all: $(OBJS) $(LIBC)
$(LIBC): ar-target
-ar-target: $(OBJS) $(CRT0_OBJ)
+ar-target: $(OBJS) $(CRT0_OBJ) $(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
cp $(CRT0_OBJ) $(TOPDIR)lib/$(CRT0_OBJ)
@@ -53,6 +53,20 @@ $(CRT0_OBJ): %.o : %.S
$(CC) $(SFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
+crti.o: crti.S
+ $(CC) $(SAFECFLAGS) -c crti.S -o crti.o
+
+$(TOPDIR)lib/crti.o: crti.o
+ mkdir -p $(TOPDIR)lib/
+ cp crti.o $(TOPDIR)lib/
+
+crtn.o: crtn.S
+ $(CC) $(SAFECFLAGS) -c crtn.S -o crtn.o
+
+$(TOPDIR)lib/crtn.o: crtn.o
+ mkdir -p $(TOPDIR)lib/
+ cp crtn.o $(TOPDIR)lib/
+
$(SOBJS): %.o : %.S
$(CC) $(SFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h
index da6a6d43e..be50af547 100644
--- a/libc/sysdeps/linux/sh/bits/syscalls.h
+++ b/libc/sysdeps/linux/sh/bits/syscalls.h
@@ -4,12 +4,136 @@
# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
#endif
-#include <features.h>
+/* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
+ * header files. It also defines the traditional `SYS_<name>' macros for older
+ * programs. */
+#include <bits/syscall.h>
-/* Do something very evil for now. Until we create our own syscall
- * macros, short circuit bits/syscall.h and use asm/unistd.h instead */
-#define _BITS_SYSCALL_H
-#include <asm/unistd.h>
+#ifndef __set_errno
+# define __set_errno(val) (*__errno_location ()) = (val)
+#endif
+#ifndef SYS_ify
+# define SYS_ify(syscall_name) (__NR_##syscall_name)
+#endif
+
+#ifndef __ASSEMBLER__
+
+/* 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 #0x10" \
+ : "=z" (__sc0) \
+ : "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 #0x11" \
+ : "=z" (__sc0) \
+ : "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 #0x12" \
+ : "=z" (__sc0) \
+ : "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 #0x13" \
+ : "=z" (__sc0) \
+ : "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 #0x14" \
+ : "=z" (__sc0) \
+ : "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 #0x15" \
+ : "=z" (__sc0) \
+ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \
+ "r" (__sc3) \
+ : "memory" ); \
+__syscall_return(type,__sc0); \
+}
+
+/* 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 #0x15" \
+ : "=z" (__sc0) \
+ : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \
+ "r" (__sc3), "r" (__sc1) \
+ : "memory" ); \
+__syscall_return(type,__sc0); \
+}
+#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/sh/crt0.S b/libc/sysdeps/linux/sh/crt0.S
index 149fd21cd..d7b54299f 100644
--- a/libc/sysdeps/linux/sh/crt0.S
+++ b/libc/sysdeps/linux/sh/crt0.S
@@ -42,49 +42,38 @@
...
NULL
*/
-
.text
.globl _start
-
+ .type _start,@function
+ .size _start,_start_end - _start
_start:
- /* Clear the frame pointer since this is the outermost frame. */
+ /* Clear the frame pointer since this is the outermost frame. (in delay slot) */
mov #0, r14
/* Pop argc off the stack and save a pointer to argv */
mov.l @r15+,r4
mov r15, r5
- /* set up the value for the environment pointer
- r6 = (argc+1)*4+argv
- */
+ /*
+ * Setup the value for the environment pointer:
+ * r6 = (argc + 1) * 4
+ * r6 += argv (in delay slot)
+ */
mov r4,r6
add #1,r6
shll2 r6
- add r5,r6
-
- ! Clear BSS area
- mov.l 3f, r1
- add #4, r1
- mov.l 4f, r2
- mov #0, r0
-9: cmp/hs r2, r1
- bf/s 9b ! while (r1 < r2)
- mov.l r0,@-r2
/* call main */
- mov.l L_main,r1
- jsr @r1
- nop
+ mov.l L_main, r0
+ jsr @r0
- /* should never get here....*/
- mov.l L_abort,r1
- jsr @r1
+ /* We should not get here. */
+ mov.l L_abort, r0
+ jsr @r0
nop
-
+_start_end:
.align 2
-3: .long __bss_start
-4: .long _end
L_main:
.long __uClibc_main
diff --git a/libc/sysdeps/linux/sh/crti.S b/libc/sysdeps/linux/sh/crti.S
new file mode 100644
index 000000000..f79b6d2cf
--- /dev/null
+++ b/libc/sysdeps/linux/sh/crti.S
@@ -0,0 +1,22 @@
+ .file "crti.S"
+
+ .section .init
+ .align 2
+ .global _init
+ .hidden _init
+ .type _init,@function
+_init:
+ mov.l r14,@-r15
+ sts.l pr,@-r15
+ mov r15,r14
+
+ .section .fini
+ .align 2
+ .global _fini
+ .hidden _fini
+ .type _fini,@function
+_fini:
+ mov.l r14,@-r15
+ sts.l pr,@-r15
+ mov r15,r14
+
diff --git a/libc/sysdeps/linux/sh/crtn.S b/libc/sysdeps/linux/sh/crtn.S
new file mode 100644
index 000000000..3a8761c1d
--- /dev/null
+++ b/libc/sysdeps/linux/sh/crtn.S
@@ -0,0 +1,17 @@
+ .file "crtn.S"
+
+ .section .init
+ mov r14,r15
+ lds.l @r15+,pr
+ rts
+ mov.l @r15+,r14
+.Lfe1:
+ .size _init,.Lfe1-_init
+
+ .section .fini
+ mov r14,r15
+ lds.l @r15+,pr
+ rts
+ mov.l @r15+,r14
+.Lfe2:
+ .size _fini,.Lfe2-_fini