summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/i386
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-01-11 11:42:17 +0000
committerEric Andersen <andersen@codepoet.org>2001-01-11 11:42:17 +0000
commitae97a89e1a1a9833080dccc81f6cd26784e1b964 (patch)
tree6ff1ddc7e3980591c7fd0bbd5d9b8ac82da12886 /libc/sysdeps/linux/i386
parentabdc3e4d06db2b9d93c509774fc7c4fde918ec8e (diff)
A large update from Manuel Novoa III <mnovoa3@bellsouth.net>.
Diffstat (limited to 'libc/sysdeps/linux/i386')
-rw-r--r--libc/sysdeps/linux/i386/Makefile13
-rw-r--r--libc/sysdeps/linux/i386/__init_brk.c33
-rw-r--r--libc/sysdeps/linux/i386/__uClibc_syscall.S39
-rw-r--r--libc/sysdeps/linux/i386/brk.c32
-rw-r--r--libc/sysdeps/linux/i386/sbrk.c35
5 files changed, 147 insertions, 5 deletions
diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile
index f4520b4ac..9c487bfd1 100644
--- a/libc/sysdeps/linux/i386/Makefile
+++ b/libc/sysdeps/linux/i386/Makefile
@@ -26,9 +26,12 @@ LIBC=$(TOPDIR)libc.a
ASFLAGS=$(CFLAGS)
SSRC=_start.S longjmp.S setjmp.S #_start.S #clone.S
+ifeq ($(UNIFIED_SYSCALL),true)
+ SSRC += __uClibc_syscall.S
+endif
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=fork.c vfork.c
+CSRC=fork.c vfork.c __init_brk.c brk.c sbrk.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(COBJS)
@@ -41,12 +44,12 @@ $(LIBC): ar-target
ar-target: $(OBJS)
$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
-$(SOBJS):
- $(CC) $(CFLAGS) $< -c $*.S -o $*.o
+$(SOBJS): %.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
-$(COBJS):
- $(CC) $(CFLAGS) $< -c $*.c -o $*.o
+$(COBJS): %.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
clean:
diff --git a/libc/sysdeps/linux/i386/__init_brk.c b/libc/sysdeps/linux/i386/__init_brk.c
new file mode 100644
index 000000000..c2ae482dd
--- /dev/null
+++ b/libc/sysdeps/linux/i386/__init_brk.c
@@ -0,0 +1,33 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+void * ___brk_addr = 0;
+
+int
+__init_brk ()
+{
+ if (___brk_addr == 0)
+ {
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl $0,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (0));
+#endif
+ if (___brk_addr == 0)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/libc/sysdeps/linux/i386/__uClibc_syscall.S b/libc/sysdeps/linux/i386/__uClibc_syscall.S
new file mode 100644
index 000000000..ecf2d6350
--- /dev/null
+++ b/libc/sysdeps/linux/i386/__uClibc_syscall.S
@@ -0,0 +1,39 @@
+.globl __uClibc_syscall
+
+.text
+ .align 4
+__uClibc_syscall:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $8,%esp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ /* movl $21,%eax */
+ and $0xff,%eax
+ movl 8(%ebp),%ebx
+ movl 12(%ebp),%ecx
+ movl 16(%ebp),%edx
+ movl 20(%ebp),%esi
+ movl 24(%ebp),%edi
+#APP
+ int $0x80
+#NO_APP
+ movl %eax,-4(%ebp)
+ .p2align 4,,7
+ cmpl $-126,-4(%ebp)
+ jbe .L5
+ movl -4(%ebp),%eax
+ negl %eax
+ movl %eax,errno
+ movl $-1,-4(%ebp)
+.L5:
+ movl -4(%ebp),%edx
+ movl %edx,-8(%ebp)
+ movl -8(%ebp),%eax
+ leal -20(%ebp),%esp
+ popl %ebx
+ popl %esi
+ popl %edi
+ leave
+ ret
diff --git a/libc/sysdeps/linux/i386/brk.c b/libc/sysdeps/linux/i386/brk.c
new file mode 100644
index 000000000..2a776bac1
--- /dev/null
+++ b/libc/sysdeps/linux/i386/brk.c
@@ -0,0 +1,32 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk ();
+
+int brk(void * end_data_seg)
+{
+ if (__init_brk () == 0)
+ {
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"c" (end_data_seg));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (end_data_seg));
+#endif
+ if (___brk_addr == end_data_seg)
+ return 0;
+ errno = ENOMEM;
+ }
+ return -1;
+}
diff --git a/libc/sysdeps/linux/i386/sbrk.c b/libc/sysdeps/linux/i386/sbrk.c
new file mode 100644
index 000000000..f5099d7e8
--- /dev/null
+++ b/libc/sysdeps/linux/i386/sbrk.c
@@ -0,0 +1,35 @@
+/* From libc-5.3.12 */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+extern void * ___brk_addr;
+
+extern int __init_brk (void);
+
+void *
+sbrk(ptrdiff_t increment)
+{
+ if (__init_brk () == 0)
+ {
+ void * tmp = ___brk_addr+increment;
+#if defined(__PIC__) || defined (__pic__)
+ __asm__ volatile ("pushl %%ebx\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"c" (tmp));
+#else
+ __asm__ volatile ("int $0x80"
+ :"=a" (___brk_addr)
+ :"0" (SYS_brk),"b" (tmp));
+#endif
+ if (___brk_addr == tmp)
+ return tmp-increment;
+ errno = ENOMEM;
+ return ((void *) -1);
+ }
+ return ((void *) -1);
+}