summaryrefslogtreecommitdiff
path: root/ports/sysdeps/unix/sysv/linux/arm
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2010-04-14 15:27:25 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2010-04-14 15:27:25 +0000
commitff5707a42600f393c5303517e68ff79eecabcc6d (patch)
tree995e7557d4a454639c392ced77199f54d84bc25c /ports/sysdeps/unix/sysv/linux/arm
parenta9627899a6ea28893ca8b1a2b475aecc58d6f223 (diff)
downloadeglibc2-ff5707a42600f393c5303517e68ff79eecabcc6d.tar.gz
Merge changes between r10202 and r10245 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@10246 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'ports/sysdeps/unix/sysv/linux/arm')
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/Makefile31
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S43
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/nptl/aio_misc.h52
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h38
4 files changed, 95 insertions, 69 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/Makefile b/ports/sysdeps/unix/sysv/linux/arm/eabi/Makefile
index 9f2b0fe8f..761c96406 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/eabi/Makefile
+++ b/ports/sysdeps/unix/sysv/linux/arm/eabi/Makefile
@@ -7,3 +7,34 @@ ifeq ($(subdir),csu)
# unwind tables for __libc_start_main.
CFLAGS-libc-start.c += -fexceptions
endif
+
+# Add a syscall function to each library that needs one.
+
+ifeq ($(subdir),rt)
+librt-sysdep_routines += libc-do-syscall
+librt-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),nptl)
+libpthread-sysdep_routines += libc-do-syscall
+libpthread-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),resolv)
+libanl-sysdep_routines += libc-do-syscall
+libanl-shared-only-routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),csu)
+sysdep_routines += libc-do-syscall
+endif
+
+ifeq ($(subdir),nscd)
+nscd-modules += libc-do-syscall
+endif
+
+ifeq ($(subdir),posix)
+LDFLAGS-tst-rfc3484 += $(common-objpfx)csu/libc-do-syscall.o
+LDFLAGS-tst-rfc3484-2 += $(common-objpfx)csu/libc-do-syscall.o
+LDFLAGS-tst-rfc3484-3 += $(common-objpfx)csu/libc-do-syscall.o
+endif
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S b/ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S
new file mode 100644
index 000000000..d461712af
--- /dev/null
+++ b/ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S
@@ -0,0 +1,43 @@
+/* Copyright (C) 2010 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 <sysdep.h>
+
+/* Out-of-line syscall stub. We expect the system call number in ip
+ and return the raw result in r0. No registers are clobbered.
+ We could avoid using the stack for this, but the goal is accurate
+ unwind information - and while there is a reserved prefix in the
+ ARM unwind tables for register to register moves, the actual opcodes
+ are not defined. */
+
+ .thumb
+ .syntax unified
+ .hidden __libc_do_syscall
+
+ENTRY (__libc_do_syscall)
+ .fnstart
+ push {r7, lr}
+ .save {r7, lr}
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (r7, 0)
+ cfi_rel_offset (lr, 4)
+ mov r7, ip
+ swi 0x0
+ pop {r7, pc}
+ .fnend
+END (__libc_do_syscall)
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/nptl/aio_misc.h b/ports/sysdeps/unix/sysv/linux/arm/eabi/nptl/aio_misc.h
deleted file mode 100644
index 3fb1ec95f..000000000
--- a/ports/sysdeps/unix/sysv/linux/arm/eabi/nptl/aio_misc.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (C) 2008 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_next <aio_misc.h>
-
-#ifdef __thumb2__
-
-#include <errno.h>
-
-/* The Thumb-2 definition of INTERNAL_SYSCALL_RAW has to hide the use
- of r7 from the compiler because it cannot handle asm clobbering the
- hard frame pointer. In aio_suspend, GCC does not eliminate the
- hard frame pointer because the function uses variable-length
- arrays, so it generates unwind information using r7 as virtual
- stack pointer. During system calls, when r7 has been saved on the
- stack, this means the unwind information is invalid. Without extra
- unwind directives, which would need to cause unwind information for
- the asm to be generated separately from that for the parts of the
- function before and after the asm (with three index table entries),
- it is not possible to represent any temporary change to the virtual
- stack pointer. Instead, we move the problematic system calls out
- of line into a function that does not require a frame pointer. */
-
-static __attribute_noinline__ void
-aio_misc_wait (int *resultp,
- volatile int *futexp,
- const struct timespec *timeout,
- int cancel)
-{
- AIO_MISC_WAIT (*resultp, *futexp, timeout, cancel);
-}
-
-#undef AIO_MISC_WAIT
-#define AIO_MISC_WAIT(result, futex, timeout, cancel) \
- aio_misc_wait (&result, &futex, timeout, cancel)
-
-#endif
diff --git a/ports/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
index 9d90f3e35..b7815babf 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
@@ -44,30 +44,34 @@
argument; otherwise the (optional) compatibility code for APCS binaries
may be invoked. */
-#ifdef __thumb__
-/* Hide the use of r7 from the compiler, this would be a lot
- easier but for the fact that the syscalls can exceed 255.
- For the moment the LOAD_ARGS_7 is sacrificed.
+#if defined(__thumb__)
+/* We can not expose the use of r7 to the compiler. GCC (as
+ of 4.5) uses r7 as the hard frame pointer for Thumb - although
+ for Thumb-2 it isn't obviously a better choice than r11.
+ And GCC does not support asms that conflict with the frame
+ pointer.
+
+ This would be easier if syscall numbers never exceeded 255,
+ but they do. For the moment the LOAD_ARGS_7 is sacrificed.
We can't use push/pop inside the asm because that breaks
- unwinding (ie. thread cancellation). */
-/* FIXME: the str / ldr of r7 are not covered by CFI information. */
+ unwinding (i.e. thread cancellation) for this frame. We can't
+ locally save and restore r7, because we do not know if this
+ function uses r7 or if it is our caller's r7; if it is our caller's,
+ then unwinding will fail higher up the stack. So we move the
+ syscall out of line and provide its own unwind information. */
#undef LOAD_ARGS_7
#undef INTERNAL_SYSCALL_RAW
#define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \
({ \
- int _sys_buf[2]; \
register int _a1 asm ("a1"); \
- register int *_r6 asm ("r6") = _sys_buf; \
- *_r6 = name; \
+ int _nametmp = name; \
LOAD_ARGS_##nr (args) \
- asm volatile ("str r7, [r6, #4]\n\t" \
- "ldr r7, [r6]\n\t" \
- "swi 0 @ syscall " #name "\n\t" \
- "ldr r7, [r6, #4]" \
- : "=r" (_a1) \
- : "r" (_r6) ASM_ARGS_##nr \
- : "memory"); \
- _a1; })
+ register int _name asm ("ip") = _nametmp; \
+ asm volatile ("bl __libc_do_syscall" \
+ : "=r" (_a1) \
+ : "r" (_name) ASM_ARGS_##nr \
+ : "memory", "lr"); \
+ _a1; })
#else /* ARM */
#undef INTERNAL_SYSCALL_RAW
#define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \