summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-08-08 14:51:40 +0000
committerEric Andersen <andersen@codepoet.org>2002-08-08 14:51:40 +0000
commit9f2d19bf1ef216e536c5e89b82a5ce422002fd01 (patch)
tree1103cecba0916b5c2b42f3ff7f1d6fa12b115b49
parent42650258c1d93e49e102dcbb02ca75de53a0b7b8 (diff)
I reworked syscalls.h to match how I'm doing other arches. Stefan Allius and
Edie C. Dost has some concerns about the perl script used to general crti.o and crtn.o and added their own versions. These versions will win since they are built last,
-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