summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/i386/brk.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/i386/brk.c')
-rw-r--r--libc/sysdeps/linux/i386/brk.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/libc/sysdeps/linux/i386/brk.c b/libc/sysdeps/linux/i386/brk.c
index 9e06d0acc..eca0e8326 100644
--- a/libc/sysdeps/linux/i386/brk.c
+++ b/libc/sysdeps/linux/i386/brk.c
@@ -1,32 +1,48 @@
-/* From libc-5.3.12 */
+/* brk system call for Linux/i386.
+ Copyright (C) 1995, 1996, 2000 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. */
+
+#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
-#include <errno.h>
-extern void * ___brk_addr;
-extern int __init_brk ();
+/* This must be initialized data because commons can't have aliases. */
+void *___brk_addr = 0;
-int brk(void * end_data_seg)
+int brk (void *addr)
{
- if (__init_brk () == 0)
+ void *__unbounded newbrk, *__unbounded scratch;
+
+ asm ("movl %%ebx, %1\n" /* Save %ebx in scratch register. */
+ "movl %3, %%ebx\n" /* Put ADDR in %ebx to be syscall arg. */
+ "int $0x80 # %2\n" /* Perform the system call. */
+ "movl %1, %%ebx\n" /* Restore %ebx from scratch register. */
+ : "=a" (newbrk), "=r" (scratch)
+ : "0" (__NR_brk), "g" (__ptrvalue (addr)));
+
+ ___brk_addr = newbrk;
+
+ if (newbrk < addr)
{
-#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" (__NR_brk),"c" (end_data_seg));
-#else
- __asm__ volatile ("int $0x80"
- :"=a" (___brk_addr)
- :"0" (__NR_brk),"b" (end_data_seg));
-#endif
- if (___brk_addr == end_data_seg)
- return 0;
- __set_errno(ENOMEM);
+ __set_errno (ENOMEM);
+ return -1;
}
- return -1;
+
+ return 0;
}