summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/linux/arm/Makefile2
-rw-r--r--libc/sysdeps/linux/arm/bits/atomicity.h33
-rw-r--r--libc/sysdeps/linux/arm/bits/syscalls.h16
-rw-r--r--libc/sysdeps/linux/arm/brk.c22
-rw-r--r--libc/sysdeps/linux/arm/ioperm.c13
-rw-r--r--libc/sysdeps/linux/arm/iopl.c35
-rw-r--r--libc/sysdeps/linux/arm/syscall.c17
-rw-r--r--libc/sysdeps/linux/common/getcwd.c11
-rw-r--r--libc/sysdeps/linux/common/iopl.c11
-rw-r--r--libc/sysdeps/linux/i386/clone.S16
-rw-r--r--libc/sysdeps/linux/i386/mmap64.S2
11 files changed, 134 insertions, 44 deletions
diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile
index 77245307a..65df75338 100644
--- a/libc/sysdeps/linux/arm/Makefile
+++ b/libc/sysdeps/linux/arm/Makefile
@@ -28,7 +28,7 @@ SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
bsd-_setjmp.S sigrestorer.S mmap64.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=brk.c syscall.c ioperm.c sigaction.c __syscall_error.c
+CSRC=brk.c syscall.c ioperm.c iopl.c sigaction.c __syscall_error.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(COBJS)
diff --git a/libc/sysdeps/linux/arm/bits/atomicity.h b/libc/sysdeps/linux/arm/bits/atomicity.h
index def974f8a..97d278610 100644
--- a/libc/sysdeps/linux/arm/bits/atomicity.h
+++ b/libc/sysdeps/linux/arm/bits/atomicity.h
@@ -31,12 +31,23 @@ exchange_and_add (volatile uint32_t *mem, int val)
int tmp2;
int result;
__asm__ ("\n"
+#if defined(__thumb__)
+ "\t.align 0\n"
+ "\tbx pc\n"
+ "\tnop\n"
+ "\t.arm\n"
+#endif
"0:\tldr\t%0,[%3]\n\t"
"add\t%1,%0,%4\n\t"
"swp\t%2,%1,[%3]\n\t"
"cmp\t%0,%2\n\t"
"swpne\t%1,%2,[%3]\n\t"
"bne\t0b"
+#if defined(__thumb__)
+ "\torr %1, pc, #1\n"
+ "\tbx %1\n"
+ "\t.force_thumb"
+#endif
: "=&r" (result), "=&r" (tmp1), "=&r" (tmp2)
: "r" (mem), "r"(val)
: "cc", "memory");
@@ -51,12 +62,23 @@ atomic_add (volatile uint32_t *mem, int val)
int tmp2;
int tmp3;
__asm__ ("\n"
+#if defined(__thumb__)
+ "\t.align 0\n"
+ "\tbx pc\n"
+ "\tnop\n"
+ "\t.arm\n"
+#endif
"0:\tldr\t%0,[%3]\n\t"
"add\t%1,%0,%4\n\t"
"swp\t%2,%1,[%3]\n\t"
"cmp\t%0,%2\n\t"
"swpne\t%1,%2,[%3]\n\t"
"bne\t0b"
+#if defined(__thumb__)
+ "\torr %1, pc, #1\n"
+ "\tbx %1\n"
+ "\t.force_thumb"
+#endif
: "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
: "r" (mem), "r"(val)
: "cc", "memory");
@@ -68,6 +90,12 @@ compare_and_swap (volatile long int *p, long int oldval, long int newval)
{
int result, tmp;
__asm__ ("\n"
+#if defined(__thumb__)
+ "\t.align 0\n"
+ "\tbx pc\n"
+ "\tnop\n"
+ "\t.arm\n"
+#endif
"0:\tldr\t%1,[%2]\n\t"
"mov\t%0,#0\n\t"
"cmp\t%1,%4\n\t"
@@ -78,6 +106,11 @@ compare_and_swap (volatile long int *p, long int oldval, long int newval)
"bne\t0b\n\t"
"mov\t%0,#1\n"
"1:"
+#if defined(__thumb__)
+ "\torr %1, pc, #1\n"
+ "\tbx %1\n"
+ "\t.force_thumb"
+#endif
: "=&r" (result), "=&r" (tmp)
: "r" (p), "r" (newval), "r" (oldval)
: "cc", "memory");
diff --git a/libc/sysdeps/linux/arm/bits/syscalls.h b/libc/sysdeps/linux/arm/bits/syscalls.h
index 245266730..21e5b8146 100644
--- a/libc/sysdeps/linux/arm/bits/syscalls.h
+++ b/libc/sysdeps/linux/arm/bits/syscalls.h
@@ -97,6 +97,7 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
#undef INTERNAL_SYSCALL
+#if !defined(__thumb__)
#define INTERNAL_SYSCALL(name, err, nr, args...) \
({ unsigned int _sys_result; \
{ \
@@ -109,6 +110,21 @@ return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
_sys_result = _a1; \
} \
(int) _sys_result; })
+#else
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ ({ unsigned int _sys_result; \
+ { \
+ register int _a1 asm ("a1"); \
+ LOAD_ARGS_##nr (args) \
+ register int _r7 asm ("r7") = (int) (SYS_ify(name)); \
+ asm volatile ("swi 0 @ syscall " #name \
+ : "=r" (_a1) \
+ : "r" (_r7) ASM_ARGS_##nr \
+ : "memory"); \
+ _sys_result = _a1; \
+ } \
+ (int) _sys_result; })
+#endif
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) \
diff --git a/libc/sysdeps/linux/arm/brk.c b/libc/sysdeps/linux/arm/brk.c
index fa0326a0e..82b9835ae 100644
--- a/libc/sysdeps/linux/arm/brk.c
+++ b/libc/sysdeps/linux/arm/brk.c
@@ -26,22 +26,14 @@ void *__curbrk = 0;
int brk (void *addr)
{
- void *newbrk;
+ void *newbrk = (void*)INTERNAL_SYSCALL(brk, , 1, addr);
- asm ("mov a1, %1\n" /* save the argment in r0 */
- "swi %2\n" /* do the system call */
- "mov %0, a1;" /* keep the return value */
- : "=r"(newbrk)
- : "r"(addr), "i" (__NR_brk)
- : "a1");
+ __curbrk = newbrk;
- __curbrk = newbrk;
+ if (newbrk < addr) {
+ __set_errno (ENOMEM);
+ return -1;
+ }
- if (newbrk < addr)
- {
- __set_errno (ENOMEM);
- return -1;
- }
-
- return 0;
+ return 0;
}
diff --git a/libc/sysdeps/linux/arm/ioperm.c b/libc/sysdeps/linux/arm/ioperm.c
index 2fba676b1..357d987f8 100644
--- a/libc/sysdeps/linux/arm/ioperm.c
+++ b/libc/sysdeps/linux/arm/ioperm.c
@@ -202,19 +202,6 @@ int ioperm (unsigned long int from, unsigned long int num, int turn_on)
}
-int iopl (unsigned int level)
-{
- if (level > 3) {
- __set_errno (EINVAL);
- return -1;
- }
- if (level) {
- return ioperm (0, MAX_PORT, 1);
- }
- return 0;
-}
-
-
void
outb(unsigned char b, unsigned long int port)
{
diff --git a/libc/sysdeps/linux/arm/iopl.c b/libc/sysdeps/linux/arm/iopl.c
new file mode 100644
index 000000000..0cd306d42
--- /dev/null
+++ b/libc/sysdeps/linux/arm/iopl.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Phil Blundell, based on the Alpha version by
+ David Mosberger.
+
+ 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 <sys/io.h>
+#include <errno.h>
+
+#define MAX_PORT 0x10000
+
+int iopl(int level)
+{
+ if (level > 3) {
+ __set_errno(EINVAL);
+ return -1;
+ }
+ if (level)
+ return ioperm(0, MAX_PORT, 1);
+ return 0;
+}
diff --git a/libc/sysdeps/linux/arm/syscall.c b/libc/sysdeps/linux/arm/syscall.c
index 9938abe03..195c31c74 100644
--- a/libc/sysdeps/linux/arm/syscall.c
+++ b/libc/sysdeps/linux/arm/syscall.c
@@ -26,6 +26,7 @@
long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
{
+#if !defined(__thumb__)
register long _r0 asm("r0")=(long)(sysnum);
register long _r6 asm("r6")=(long)(f);
register long _r5 asm("r5")=(long)(e);
@@ -40,6 +41,21 @@ long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
"r"(_r2), "r"(_r3), "r"(_r4), "r"(_r5),
"r"(_r6)
: "memory");
+#else
+ register long _r7 asm("r7")=(long)(sysnum);
+ register long _r5 asm("r5")=(long)(f);
+ register long _r4 asm("r4")=(long)(e);
+ register long _r3 asm("r3")=(long)(d);
+ register long _r2 asm("r2")=(long)(c);
+ register long _r1 asm("r1")=(long)(b);
+ register long _r0 asm("r0")=(long)(a);
+ asm volatile(
+ "swi 0"
+ : "=r"(_r0)
+ : "r"(_r0), "r"(_r1), "r"(_r2), "r"(_r3),
+ "r"(_r4), "r"(_r5), "r"(_r7)
+ : "memory");
+#endif
if(_r0 >=(unsigned long) -4095) {
long err = _r0;
(*__errno_location())=(-err);
@@ -47,4 +63,3 @@ long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
}
return (long) _r0;
}
-
diff --git a/libc/sysdeps/linux/common/getcwd.c b/libc/sysdeps/linux/common/getcwd.c
index daf056e98..a1de4510c 100644
--- a/libc/sysdeps/linux/common/getcwd.c
+++ b/libc/sysdeps/linux/common/getcwd.c
@@ -10,7 +10,7 @@
#ifdef __NR_getcwd
#define __NR___syscall_getcwd __NR_getcwd
-static inline
+static inline
_syscall2(int, __syscall_getcwd, char *, buf, unsigned long, size);
#else
@@ -134,6 +134,15 @@ int __syscall_getcwd(char * buf, unsigned long size)
olderrno = errno;
len = -1;
+
+ /* get stat for root to have a valid parameters for the terminating condition */
+ if (stat("/", &st) < 0) {
+ /* root dir not found! */
+ return -1;
+ }
+ /* start with actual dir */
+ if (buf) strncpy(buf, ".", size);
+
cwd = recurser(buf, size, st.st_dev, st.st_ino);
if (cwd) {
len = strlen(buf);
diff --git a/libc/sysdeps/linux/common/iopl.c b/libc/sysdeps/linux/common/iopl.c
index 9e507bebc..dd45563c2 100644
--- a/libc/sysdeps/linux/common/iopl.c
+++ b/libc/sysdeps/linux/common/iopl.c
@@ -2,22 +2,19 @@
/*
* iopl() for uClibc
*
- * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
*
* GNU Library General Public License (LGPL) version 2 or later.
*/
#include "syscalls.h"
-/* For arm there is a totally different implementation */
-#if !defined(__arm__)
/* Tuns out the m68k unistd.h kernel header is broken */
-# if defined __ARCH_HAS_MMU__ && defined __NR_iopl && ( !defined(__mc68000__))
+#if defined __ARCH_HAS_MMU__ && defined __NR_iopl && ( !defined(__mc68000__))
_syscall1(int, iopl, int, level);
-# else
+#else
int iopl(int level)
{
__set_errno(ENOSYS);
return -1;
}
-# endif
-# endif
+#endif
diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S
index 259982230..35a4e5b7f 100644
--- a/libc/sysdeps/linux/i386/clone.S
+++ b/libc/sysdeps/linux/i386/clone.S
@@ -51,19 +51,19 @@ __clone:
/* no NULL function pointers */
movl FUNC(%esp),%ecx
#ifdef __PIC__
- jecxz __syscall_error
+ jecxz __error
#else
testl %ecx,%ecx
- jz __syscall_error
+ jz __error
#endif
/* no NULL stack pointers */
movl STACK(%esp),%ecx
#ifdef __PIC__
- jecxz __syscall_error
+ jecxz __error
#else
testl %ecx,%ecx
- jz __syscall_error
+ jz __error
#endif
/* Insert the argument onto the new stack. Make sure the new
@@ -96,7 +96,7 @@ __clone:
popl %ebx
test %eax,%eax
- jl __syscall_error
+ jl __error
jz .Lthread_start
ret
@@ -114,6 +114,12 @@ __clone:
movl $__NR_exit, %eax
int $0x80
+/* Need to indirect jump to syscall error
+ * or we end up with TEXTREL's
+ */
+__error:
+ jmp __syscall_error
+
.size __clone,.-__clone
.weak clone
diff --git a/libc/sysdeps/linux/i386/mmap64.S b/libc/sysdeps/linux/i386/mmap64.S
index 5c89c983b..5405c8a09 100644
--- a/libc/sysdeps/linux/i386/mmap64.S
+++ b/libc/sysdeps/linux/i386/mmap64.S
@@ -87,7 +87,7 @@ L_einval:
popl %ebx
popl %ebp
movl $-EINVAL, %eax
- jmp __error
+ jmp __syscall_error
.size mmap64,.-mmap64