[klibc 24/43] i386 support for klibc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The parts of klibc specific to the i386 architecture.

Signed-off-by: H. Peter Anvin <[email protected]>

---
commit bd0599e5290ca1a16bb7a68f7c362d395c612eb3
tree 8f33afdd02a14c22e7a3984da2bad13184e3f729
parent 84f6a72f42cf41e32daa59871a0b5424572093e4
author H. Peter Anvin <[email protected]> Sun, 25 Jun 2006 16:58:21 -0700
committer H. Peter Anvin <[email protected]> Sun, 25 Jun 2006 16:58:21 -0700

 usr/include/arch/i386/klibc/archconfig.h |   19 ++++
 usr/include/arch/i386/klibc/archsetjmp.h |   19 ++++
 usr/include/arch/i386/klibc/archsignal.h |  114 +++++++++++++++++++++++++++
 usr/include/arch/i386/klibc/archstat.h   |   38 +++++++++
 usr/include/arch/i386/klibc/archsys.h    |   12 +++
 usr/include/arch/i386/klibc/diverr.h     |   15 ++++
 usr/include/arch/i386/sys/io.h           |  127 ++++++++++++++++++++++++++++++
 usr/include/arch/i386/sys/vm86.h         |   40 +++++++++
 usr/klibc/arch/i386/MCONFIG              |   33 ++++++++
 usr/klibc/arch/i386/Makefile.inc         |   30 +++++++
 usr/klibc/arch/i386/crt0.S               |   31 +++++++
 usr/klibc/arch/i386/libgcc/__ashldi3.S   |   29 +++++++
 usr/klibc/arch/i386/libgcc/__ashrdi3.S   |   29 +++++++
 usr/klibc/arch/i386/libgcc/__lshrdi3.S   |   29 +++++++
 usr/klibc/arch/i386/libgcc/__muldi3.S    |   34 ++++++++
 usr/klibc/arch/i386/libgcc/__negdi2.S    |   21 +++++
 usr/klibc/arch/i386/open.S               |   29 +++++++
 usr/klibc/arch/i386/openat.S             |   26 ++++++
 usr/klibc/arch/i386/setjmp.S             |   58 ++++++++++++++
 usr/klibc/arch/i386/sigreturn.S          |   15 ++++
 usr/klibc/arch/i386/socketcall.S         |   55 +++++++++++++
 usr/klibc/arch/i386/syscall.S            |   69 ++++++++++++++++
 usr/klibc/arch/i386/sysstub.ph           |   26 ++++++
 usr/klibc/arch/i386/varsyscall.S         |   36 +++++++++
 usr/klibc/arch/i386/vfork.S              |   26 ++++++
 25 files changed, 960 insertions(+), 0 deletions(-)

diff --git a/usr/include/arch/i386/klibc/archconfig.h b/usr/include/arch/i386/klibc/archconfig.h
new file mode 100644
index 0000000..4463d08
--- /dev/null
+++ b/usr/include/arch/i386/klibc/archconfig.h
@@ -0,0 +1,19 @@
+/*
+ * include/arch/i386/klibc/archconfig.h
+ *
+ * See include/klibc/sysconfig.h for the options that can be set in
+ * this file.
+ *
+ */
+
+#ifndef _KLIBC_ARCHCONFIG_H
+#define _KLIBC_ARCHCONFIG_H
+
+/* On i386, only half the signals are accessible using the legacy calls. */
+#define _KLIBC_USE_RT_SIG 1
+
+/* The stock i386 kernel is fine, but a whole string of Fedora kernels
+   had a broken default restorer.  It's easier to enable this here. */
+#define _KLIBC_NEEDS_SA_RESTORER 1
+
+#endif				/* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/i386/klibc/archsetjmp.h b/usr/include/arch/i386/klibc/archsetjmp.h
new file mode 100644
index 0000000..ea1ba3d
--- /dev/null
+++ b/usr/include/arch/i386/klibc/archsetjmp.h
@@ -0,0 +1,19 @@
+/*
+ * arch/i386/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+	unsigned int __ebx;
+	unsigned int __esp;
+	unsigned int __ebp;
+	unsigned int __esi;
+	unsigned int __edi;
+	unsigned int __eip;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif				/* _SETJMP_H */
diff --git a/usr/include/arch/i386/klibc/archsignal.h b/usr/include/arch/i386/klibc/archsignal.h
new file mode 100644
index 0000000..6c942db
--- /dev/null
+++ b/usr/include/arch/i386/klibc/archsignal.h
@@ -0,0 +1,114 @@
+/*
+ * arch/i386/include/klibc/archsignal.h
+ *
+ * Architecture-specific signal definitions
+ *
+ */
+
+#ifndef _KLIBC_ARCHSIGNAL_H
+#define _KLIBC_ARCHSIGNAL_H
+
+/* The in-kernel headers for i386 still have libc5
+   crap in them.  Reconsider using <asm/signal.h>
+   when/if it gets cleaned up; for now, duplicate
+   the definitions here. */
+
+#define _NSIG           64
+#define _NSIG_BPW       32
+#define _NSIG_WORDS     (_NSIG / _NSIG_BPW)
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP           1
+#define SIGINT           2
+#define SIGQUIT          3
+#define SIGILL           4
+#define SIGTRAP          5
+#define SIGABRT          6
+#define SIGIOT           6
+#define SIGBUS           7
+#define SIGFPE           8
+#define SIGKILL          9
+#define SIGUSR1         10
+#define SIGSEGV         11
+#define SIGUSR2         12
+#define SIGPIPE         13
+#define SIGALRM         14
+#define SIGTERM         15
+#define SIGSTKFLT       16
+#define SIGCHLD         17
+#define SIGCONT         18
+#define SIGSTOP         19
+#define SIGTSTP         20
+#define SIGTTIN         21
+#define SIGTTOU         22
+#define SIGURG          23
+#define SIGXCPU         24
+#define SIGXFSZ         25
+#define SIGVTALRM       26
+#define SIGPROF         27
+#define SIGWINCH        28
+#define SIGIO           29
+#define SIGPOLL         SIGIO
+#define SIGPWR          30
+#define SIGSYS          31
+#define SIGUNUSED       31
+
+#define SIGRTMIN        32
+#define SIGRTMAX        (_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001u
+#define SA_NOCLDWAIT	0x00000002u
+#define SA_SIGINFO	0x00000004u
+#define SA_ONSTACK	0x08000000u
+#define SA_RESTART	0x10000000u
+#define SA_NODEFER	0x40000000u
+#define SA_RESETHAND	0x80000000u
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000	/* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal.h>
+
+/* This uses gcc anonymous union support... */
+struct siginfo;
+
+struct sigaction {
+	union {
+		__sighandler_t sa_handler;
+		void (*sa_sigaction)(int, struct siginfo *, void *);
+	};
+	unsigned long	sa_flags;
+	__sigrestore_t 	sa_restorer;
+	sigset_t	sa_mask;
+};
+
+#endif
diff --git a/usr/include/arch/i386/klibc/archstat.h b/usr/include/arch/i386/klibc/archstat.h
new file mode 100644
index 0000000..c00f955
--- /dev/null
+++ b/usr/include/arch/i386/klibc/archstat.h
@@ -0,0 +1,38 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <klibc/stathelp.h>
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	__stdev64	(st_dev);
+	unsigned char	__pad0[4];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	__stdev64	(st_rdev);
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/usr/include/arch/i386/klibc/archsys.h b/usr/include/arch/i386/klibc/archsys.h
new file mode 100644
index 0000000..e655680
--- /dev/null
+++ b/usr/include/arch/i386/klibc/archsys.h
@@ -0,0 +1,12 @@
+/*
+ * arch/cris/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif				/* _KLIBC_ARCHSYS_H */
diff --git a/usr/include/arch/i386/klibc/diverr.h b/usr/include/arch/i386/klibc/diverr.h
new file mode 100644
index 0000000..fa238ac
--- /dev/null
+++ b/usr/include/arch/i386/klibc/diverr.h
@@ -0,0 +1,15 @@
+/*
+ * arch/i386/include/klibc/diverr.h
+ */
+
+#ifndef _KLIBC_DIVERR_H
+#define _KLIBC_DIVERR_H
+
+#include <signal.h>
+
+static __inline__ void __divide_error(void)
+{
+	asm volatile ("int $0");
+}
+
+#endif				/* _KLIBC_DIVERR_H */
diff --git a/usr/include/arch/i386/sys/io.h b/usr/include/arch/i386/sys/io.h
new file mode 100644
index 0000000..cf31b97
--- /dev/null
+++ b/usr/include/arch/i386/sys/io.h
@@ -0,0 +1,127 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sys/io.h for the i386 architecture
+ *
+ * Basic I/O macros
+ */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+/* I/O-related system calls */
+
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+/* Basic I/O macros */
+
+static __inline__ void outb(unsigned char __v, unsigned short __p)
+{
+	asm volatile ("outb %0,%1" : : "a" (__v), "dN" (__p));
+}
+
+static __inline__ void outw(unsigned short __v, unsigned short __p)
+{
+	asm volatile ("outw %0,%1" : : "a" (__v), "dN" (__p));
+}
+
+static __inline__ void outl(unsigned int __v, unsigned short __p)
+{
+	asm volatile ("outl %0,%1" : : "a" (__v), "dN" (__p));
+}
+
+static __inline__ unsigned char inb(unsigned short __p)
+{
+	unsigned char __v;
+	asm volatile ("inb %1,%0" : "=a" (__v) : "dN" (__p));
+	return __v;
+}
+
+static __inline__ unsigned short inw(unsigned short __p)
+{
+	unsigned short __v;
+	asm volatile ("inw %1,%0" : "=a" (__v) : "dN" (__p));
+	return __v;
+}
+
+static __inline__ unsigned int inl(unsigned short __p)
+{
+	unsigned int __v;
+	asm volatile ("inl %1,%0" : "=a" (__v) : "dN" (__p));
+	return __v;
+}
+
+/* String I/O macros */
+
+static __inline__ void
+outsb(unsigned short __p, const void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; outsb"
+		      : "+S" (__d), "+c" (__n)
+		      : "d" (__p));
+}
+
+static __inline__ void
+outsw(unsigned short __p, const void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; outsw"
+		      : "+S" (__d), "+c" (__n)
+		      : "d" (__p));
+}
+
+static __inline__ void
+outsl(unsigned short __p, const void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; outsl"
+		      : "+S" (__d), "+c"(__n)
+		      : "d" (__p));
+}
+
+static __inline__ void insb(unsigned short __p, void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; insb"
+		      : "+D" (__d), "+c" (__n)
+		      : "d" (__p));
+}
+
+static __inline__ void insw(unsigned short __p, void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; insw"
+		      : "+D" (__d), "+c" (__n)
+		      : "d" (__p));
+}
+
+static __inline__ void insl(unsigned short __p, void *__d, unsigned long __n)
+{
+	asm volatile ("cld; rep; insl"
+		      : "+D" (__d), "+c" (__n)
+		      : "d" (__p));
+}
+
+#endif				/* _SYS_IO_H */
diff --git a/usr/include/arch/i386/sys/vm86.h b/usr/include/arch/i386/sys/vm86.h
new file mode 100644
index 0000000..c4651cd
--- /dev/null
+++ b/usr/include/arch/i386/sys/vm86.h
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sys/vm86.h for i386
+ */
+
+#ifndef _SYS_VM86_H
+#define _SYS_VM86_H 1
+
+#include <asm/vm86.h>
+
+/* Actual system call */
+int vm86(struct vm86_struct *);
+
+#endif
diff --git a/usr/klibc/arch/i386/MCONFIG b/usr/klibc/arch/i386/MCONFIG
new file mode 100644
index 0000000..e173266
--- /dev/null
+++ b/usr/klibc/arch/i386/MCONFIG
@@ -0,0 +1,33 @@
+# -*- makefile -*-
+#
+# arch/i386/MCONFIG
+#
+# Special rules for this architecture.  Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+# Enable this to compile with register parameters; only safe for
+# gcc >= 3
+
+ifeq ($(CONFIG_REGPARM),y)
+REGPARM_OPT := -mregparm=3 -D_REGPARM=3
+endif
+
+gcc_align_option  := $(call cc-option, \
+		-falign-functions=0 -falign-jumps=0 -falign-loops=0, \
+		-malign-functions=0 -malign-jumps=0 -malign-loops=0)
+gcc_m32_option  := $(call cc-option, -m32, )
+
+KLIBCOPTFLAGS     = -march=i386 -Os -g -fomit-frame-pointer $(gcc_align_option)
+KLIBCLDFLAGS      = -m elf_i386
+KLIBCREQFLAGS	  += $(REGPARM_OPT)
+KLIBCARCHREQFLAGS += $(gcc_m32_option)
+
+KLIBCBITSIZE  = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 96 MB - normal binaries start at 128 MB
+KLIBCSHAREDFLAGS	= -Ttext 0x06000200
diff --git a/usr/klibc/arch/i386/Makefile.inc b/usr/klibc/arch/i386/Makefile.inc
new file mode 100644
index 0000000..d13a28f
--- /dev/null
+++ b/usr/klibc/arch/i386/Makefile.inc
@@ -0,0 +1,30 @@
+# -*- makefile -*-
+#
+# arch/i386/Makefile.inc
+#
+# Special rules for this architecture.  Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+KLIBCARCHOBJS = \
+	arch/$(KLIBCARCH)/socketcall.o \
+	arch/$(KLIBCARCH)/setjmp.o \
+	arch/$(KLIBCARCH)/syscall.o \
+	arch/$(KLIBCARCH)/varsyscall.o \
+	arch/$(KLIBCARCH)/open.o \
+	arch/$(KLIBCARCH)/openat.o \
+	arch/$(KLIBCARCH)/sigreturn.o \
+	arch/$(KLIBCARCH)/vfork.o \
+	arch/$(KLIBCARCH)/libgcc/__ashldi3.o \
+	arch/$(KLIBCARCH)/libgcc/__ashrdi3.o \
+	arch/$(KLIBCARCH)/libgcc/__lshrdi3.o \
+	arch/$(KLIBCARCH)/libgcc/__muldi3.o \
+	arch/$(KLIBCARCH)/libgcc/__negdi2.o \
+	libgcc/__divdi3.o \
+	libgcc/__moddi3.o \
+	libgcc/__udivdi3.o \
+	libgcc/__umoddi3.o \
+	libgcc/__udivmoddi4.o
+
+archclean:
diff --git a/usr/klibc/arch/i386/crt0.S b/usr/klibc/arch/i386/crt0.S
new file mode 100644
index 0000000..8c6635e
--- /dev/null
+++ b/usr/klibc/arch/i386/crt0.S
@@ -0,0 +1,31 @@
+#
+# arch/i386/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+	.text
+	.align 4
+	.type _start,@function
+	.globl _start
+_start:
+	# Save the address of the ELF argument array
+	movl %esp,%eax		# Address of ELF arguments
+	# Set up a faux stack frame for the benefit of gdb
+	xorl %ebp,%ebp
+	push %ebp		# Keep gdb from getting confused
+	push %ebp		# Keep gdb from getting confused
+	# Push the arguments and called __libc_init()
+#ifndef _REGPARM
+	push %edx		# atexit() function
+	push %eax		# ELF array
+#endif
+	call __libc_init
+	# If __libc_init returns, problem...
+	hlt
+
+	.size _start, .-_start
diff --git a/usr/klibc/arch/i386/libgcc/__ashldi3.S b/usr/klibc/arch/i386/libgcc/__ashldi3.S
new file mode 100644
index 0000000..7344142
--- /dev/null
+++ b/usr/klibc/arch/i386/libgcc/__ashldi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashldi3.S
+ *
+ * 64-bit shl
+ */
+	.text
+	.align 4
+	.globl __ashldi3
+	.type __ashldi3,@function
+__ashldi3:
+#ifndef _REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shldl %cl,%eax,%edx
+	shl   %cl,%eax
+	ret
+
+1:
+	xorl  %edx,%edx
+	shl   %cl,%eax
+	xchgl %edx,%eax
+	ret
+
+	.size __ashldi3,.-__ashldi3
diff --git a/usr/klibc/arch/i386/libgcc/__ashrdi3.S b/usr/klibc/arch/i386/libgcc/__ashrdi3.S
new file mode 100644
index 0000000..7666eb2
--- /dev/null
+++ b/usr/klibc/arch/i386/libgcc/__ashrdi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__ashrdi3.S
+ *
+ * 64-bit sar
+ */
+	.text
+	.align 4
+	.globl __ashrdi3
+	.type __ashrdi3,@function
+__ashrdi3:
+#ifndef _REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shrdl %cl,%edx,%eax
+	sarl  %cl,%edx
+	ret
+
+1:
+	sarl  %cl,%edx
+	movl  %edx,%eax
+	cdq
+	ret
+
+	.size __ashrdi3,.-__ashrdi3
diff --git a/usr/klibc/arch/i386/libgcc/__lshrdi3.S b/usr/klibc/arch/i386/libgcc/__lshrdi3.S
new file mode 100644
index 0000000..6a63c52
--- /dev/null
+++ b/usr/klibc/arch/i386/libgcc/__lshrdi3.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/libgcc/__lshrdi3.S
+ *
+ * 64-bit shr
+ */
+	.text
+	.align 4
+	.globl __lshrdi3
+	.type __lshrdi3,@function
+__lshrdi3:
+#ifndef _REGPARM
+	movl  4(%esp),%eax
+	movl  8(%esp),%edx
+	movb  12(%esp),%cl
+#endif
+	cmpb  $32,%cl
+	jae   1f
+
+	shrdl %cl,%edx,%eax
+	shrl  %cl,%edx
+	ret
+
+1:
+	shrl  %cl,%edx
+	xorl  %eax,%eax
+	xchgl %edx,%eax
+	ret
+
+	.size __lshrdi3,.-__lshrdi3
diff --git a/usr/klibc/arch/i386/libgcc/__muldi3.S b/usr/klibc/arch/i386/libgcc/__muldi3.S
new file mode 100644
index 0000000..472c7cc
--- /dev/null
+++ b/usr/klibc/arch/i386/libgcc/__muldi3.S
@@ -0,0 +1,34 @@
+/*
+ * arch/i386/libgcc/__muldi3.S
+ *
+ * 64*64 = 64 bit unsigned multiplication
+ */
+
+	.text
+	.align 4
+	.globl __muldi3
+	.type __muldi3,@function
+__muldi3:
+	push  %esi
+#ifndef _REGPARM
+	movl  8(%esp),%eax
+	movl  %eax,%esi
+	movl  16(%esp),%ecx
+	mull  %ecx
+	imull 12(%esp),%ecx
+	imull 20(%esp),%esi
+	addl  %ecx,%edx
+	addl  %esi,%edx
+#else
+	movl  %eax,%esi
+	push  %edx
+	mull  %ecx
+	imull 8(%esp),%esi
+	addl  %esi,%edx
+	pop   %esi
+	imull %esi,%ecx
+	addl  %ecx,%edx
+#endif
+	pop   %esi
+	ret
+	.size __muldi3,.-__muldi3
diff --git a/usr/klibc/arch/i386/libgcc/__negdi2.S b/usr/klibc/arch/i386/libgcc/__negdi2.S
new file mode 100644
index 0000000..147ad94
--- /dev/null
+++ b/usr/klibc/arch/i386/libgcc/__negdi2.S
@@ -0,0 +1,21 @@
+/*
+ * arch/i386/libgcc/__negdi2.S
+ *
+ * 64-bit negation
+ */
+
+	.text
+	.align 4
+	.globl __negdi2
+	.type __negdi2,@function
+__negdi2:
+#ifndef _REGPARM
+	movl 4(%esp),%eax
+	movl 8(%esp),%edx
+#endif
+	negl %edx
+	negl %eax
+	sbbl $0,%edx
+	ret
+
+	.size __negdi2,.-__negdi2
diff --git a/usr/klibc/arch/i386/open.S b/usr/klibc/arch/i386/open.S
new file mode 100644
index 0000000..7cd136c
--- /dev/null
+++ b/usr/klibc/arch/i386/open.S
@@ -0,0 +1,29 @@
+/*
+ * arch/i386/open.S
+ *
+ * Handle the open() system call - oddball due to the varadic
+ * prototype, which forces the use of the cdecl calling convention,
+ * and the need for O_LARGEFILE.
+ */
+
+#include <asm/unistd.h>
+
+/* <asm/fcntl.h>, despite the name, isn't assembly-safe */
+#define O_LARGEFILE     0100000
+
+	.globl	open
+	.type	open,@function
+
+open:
+#ifdef _REGPARM
+	movl	4(%esp),%eax
+	movl	8(%esp),%edx
+	movl	12(%esp),%ecx
+	orl	$O_LARGEFILE,%edx
+#else
+	orl	$O_LARGEFILE,8(%esp)
+#endif
+	pushl	$__NR_open
+	jmp	__syscall_common
+
+	.size	open,.-open
diff --git a/usr/klibc/arch/i386/openat.S b/usr/klibc/arch/i386/openat.S
new file mode 100644
index 0000000..2dfdfe2
--- /dev/null
+++ b/usr/klibc/arch/i386/openat.S
@@ -0,0 +1,26 @@
+/*
+ * arch/i386/openat.S
+ *
+ * Handle the openat() system call - oddball due to the varadic
+ * prototype, which forces the use of the cdecl calling convention,
+ * and the need for O_LARGEFILE.
+ */
+
+#include <asm/unistd.h>
+
+/* <asm/fcntl.h>, despite the name, isn't assembly-safe */
+#define O_LARGEFILE     0100000
+
+#ifdef __NR_openat		/* Don't build if kernel headers too old */
+
+	.globl	openat
+	.type	openat,@function
+
+openat:
+	orl	$O_LARGEFILE,12(%esp)
+	pushl	$__NR_openat
+	jmp	__syscall_varadic
+
+	.size	openat,.-openat
+
+#endif
diff --git a/usr/klibc/arch/i386/setjmp.S b/usr/klibc/arch/i386/setjmp.S
new file mode 100644
index 0000000..b766792
--- /dev/null
+++ b/usr/klibc/arch/i386/setjmp.S
@@ -0,0 +1,58 @@
+#
+# arch/i386/setjmp.S
+#
+# setjmp/longjmp for the i386 architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+#	%ebx
+#	%esp
+#	%ebp
+#	%esi
+#	%edi
+#	<return address>
+#
+
+	.text
+	.align 4
+	.globl setjmp
+	.type setjmp, @function
+setjmp:
+#ifdef _REGPARM
+	movl %eax,%edx
+#else
+	movl 4(%esp),%edx
+#endif
+	popl %ecx			# Return address, and adjust the stack
+	xorl %eax,%eax			# Return value
+	movl %ebx,(%edx)
+	movl %esp,4(%edx)		# Post-return %esp!
+	pushl %ecx			# Make the call/return stack happy
+	movl %ebp,8(%edx)
+	movl %esi,12(%edx)
+	movl %edi,16(%edx)
+	movl %ecx,20(%edx)		# Return address
+	ret
+
+	.size setjmp,.-setjmp
+
+	.text
+	.align 4
+	.globl longjmp
+	.type longjmp, @function
+longjmp:
+#ifdef _REGPARM
+	xchgl %eax,%edx
+#else
+	movl 4(%esp),%edx		# jmp_ptr address
+	movl 8(%esp),%eax		# Return value
+#endif
+	movl (%edx),%ebx
+	movl 4(%edx),%esp
+	movl 8(%edx),%ebp
+	movl 12(%edx),%esi
+	movl 16(%edx),%edi
+	jmp *20(%edx)
+
+	.size longjmp,.-longjmp
diff --git a/usr/klibc/arch/i386/sigreturn.S b/usr/klibc/arch/i386/sigreturn.S
new file mode 100644
index 0000000..f2a3241
--- /dev/null
+++ b/usr/klibc/arch/i386/sigreturn.S
@@ -0,0 +1,15 @@
+#
+# arch/i386/sigreturn.S
+#
+
+#include <asm/unistd.h>
+
+	.text
+	.align 4
+	.globl __sigreturn
+	.type __sigreturn,@function
+__sigreturn:
+	pop	%eax		# Have no idea why this is needed...
+	movl	$__NR_sigreturn,%eax
+	int	$0x80
+	.size __sigreturn,.-__sigreturn
diff --git a/usr/klibc/arch/i386/socketcall.S b/usr/klibc/arch/i386/socketcall.S
new file mode 100644
index 0000000..816db34
--- /dev/null
+++ b/usr/klibc/arch/i386/socketcall.S
@@ -0,0 +1,55 @@
+#
+# socketcall.S
+#
+# Socketcalls use the following convention:
+# %eax = __NR_socketcall
+# %ebx = socketcall number
+# %ecx = pointer to arguments (up to 6)
+#
+	
+#include <asm/unistd.h>
+
+#ifdef __i386__
+
+	.text
+	.align 4
+	.globl __socketcall_common
+	.type __socketcall_common, @function
+
+__socketcall_common:
+	xchgl	%ebx,(%esp)	# The stub passes the socketcall # on stack
+
+#ifdef	_REGPARM
+	pushl	16(%esp)	# Arg 6
+	pushl	16(%esp)	# Arg 5
+	pushl	16(%esp)	# Arg 4
+	pushl	%ecx
+	pushl	%edx
+	pushl	%eax
+	movl	%esp,%ecx
+#else
+	leal	8(%esp),%ecx	# Arguments already contiguous on-stack
+#endif
+
+	movl	$__NR_socketcall,%eax
+	int	$0x80
+
+#ifdef	_REGPARM
+	addl	$6*4, %esp
+#endif
+	
+	cmpl	$-4095,%eax	# Error return?
+
+	popl	%ebx
+
+	jb	1f
+
+	negl	%eax
+	movl	%eax,errno
+	orl	$-1,%eax	# Return -1
+1:
+	ret
+
+	.size __socketcall_common,.-__socketcall_common
+
+#endif
diff --git a/usr/klibc/arch/i386/syscall.S b/usr/klibc/arch/i386/syscall.S
new file mode 100644
index 0000000..d28717b
--- /dev/null
+++ b/usr/klibc/arch/i386/syscall.S
@@ -0,0 +1,69 @@
+/*
+ * arch/i386/syscall.S
+ *
+ * Common tail-handling code for system calls.
+ *
+ * The arguments are on the stack; the system call number in %eax.
+ */
+
+#define ARG(n)	(4*n+20)(%esp)
+
+	.text
+	.align	4
+	.globl	__syscall_common
+	.type	__syscall_common,@function
+__syscall_common:
+#ifdef _REGPARM
+	xchgl	%ebx,(%esp)
+#else
+	popl	%eax
+	pushl	%ebx
+#endif
+	pushl	%esi
+	pushl	%edi
+	pushl	%ebp
+
+#ifdef _REGPARM
+	xchgl	%eax,%ebx
+	xchgl	%ecx,%edx
+	movl	ARG(0),%esi
+	movl	ARG(1),%edi
+	movl	ARG(2),%ebp
+#else
+	movl	ARG(0),%ebx		# Syscall arguments
+	movl	ARG(1),%ecx
+	movl	ARG(2),%edx
+	movl	ARG(3),%esi
+	movl	ARG(4),%edi
+	movl	ARG(5),%ebp
+#endif
+	.globl __syscall_common_tail
+__syscall_common_tail:
+	int	$0x80
+
+	cmpl	$-4095,%eax
+
+	popl	%ebp
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+
+	jb	1f
+
+	# Error return, must set errno
+	negl	%eax
+	movl	%eax,errno
+	orl	$-1,%eax		# Return -1
+
+1:
+	ret
+
+	.size	__syscall_common,.-__syscall_common
+
+#ifndef _REGPARM
+
+	.globl	__syscall_varadic
+	.type	__syscall_varadic,@function
+__syscall_varadic = __syscall_common
+
+#endif
diff --git a/usr/klibc/arch/i386/sysstub.ph b/usr/klibc/arch/i386/sysstub.ph
new file mode 100644
index 0000000..e73a3ff
--- /dev/null
+++ b/usr/klibc/arch/i386/sysstub.ph
@@ -0,0 +1,26 @@
+# -*- perl -*-
+#
+# arch/i386/sysstub.ph
+#
+# Script to generate system call stubs
+#
+
+sub make_sysstub($$$$$@) {
+    my($outputdir, $fname, $type, $sname, $stype, @args) = @_;
+
+    open(OUT, '>', "${outputdir}/${fname}.S");
+    print OUT "#include <asm/unistd.h>\n";
+    print OUT "\n";
+    print OUT "\t.type ${fname},\@function\n";
+    print OUT "\t.globl ${fname}\n";
+    print OUT "${fname}:\n";
+
+    $stype = 'common' if ( $stype eq '' );
+
+    print OUT "\tpushl \$__NR_${sname}\n";
+    print OUT "\tjmp __syscall_$stype\n";
+    print OUT "\t.size ${fname},.-${fname}\n";
+    close(OUT);
+}
+
+1;
diff --git a/usr/klibc/arch/i386/varsyscall.S b/usr/klibc/arch/i386/varsyscall.S
new file mode 100644
index 0000000..24329ea
--- /dev/null
+++ b/usr/klibc/arch/i386/varsyscall.S
@@ -0,0 +1,36 @@
+/*
+ * arch/i386/varsyscall.S
+ *
+ * Common tail-handling code for varadic system calls (which always
+ * use the cdecl convention.)
+ *
+ * The arguments are on the stack; the system call number in %eax.
+ */
+
+#ifdef	_REGPARM
+
+#define ARG(n)	(4*n+20)(%esp)
+
+	.text
+	.align	4
+	.globl	__syscall_varadic
+	.type	__syscall_varadic,@function
+__syscall_varadic:
+	popl	%eax
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	pushl	%ebp
+
+	movl	ARG(0),%ebx		# Syscall arguments
+	movl	ARG(1),%ecx
+	movl	ARG(2),%edx
+	movl	ARG(3),%esi
+	movl	ARG(4),%edi
+	movl	ARG(5),%ebp
+
+	jmp	__syscall_common_tail
+
+	.size	__syscall_varadic,.-__syscall_varadic
+
+#endif
diff --git a/usr/klibc/arch/i386/vfork.S b/usr/klibc/arch/i386/vfork.S
new file mode 100644
index 0000000..c98ba3a
--- /dev/null
+++ b/usr/klibc/arch/i386/vfork.S
@@ -0,0 +1,26 @@
+#
+# usr/klibc/arch/i386/vfork.S
+#
+# vfork is nasty - there must be nothing at all on the stack above
+# the stack frame of the enclosing function.
+#
+
+#include <asm/unistd.h>
+
+        .text
+        .align  4
+	.globl	vfork
+	.type	vfork, @function
+vfork:
+	popl	%edx			/* Return address */
+	movl	$__NR_vfork, %eax
+	int	$0x80
+	pushl	%edx
+	cmpl	$-4095, %eax
+	jae	1f
+	ret
+1:
+	negl	%eax
+	movl	%eax, errno
+	orl	$-1, %eax
+	ret
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux