summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/i386
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/i386')
-rw-r--r--libc/sysdeps/linux/i386/Makefile.arch19
-rw-r--r--libc/sysdeps/linux/i386/__longjmp.S8
-rw-r--r--libc/sysdeps/linux/i386/__syscall_error.c7
-rw-r--r--libc/sysdeps/linux/i386/bits/atomic.h47
-rw-r--r--libc/sysdeps/linux/i386/bits/byteswap.h126
-rw-r--r--libc/sysdeps/linux/i386/bits/fcntl.h14
-rw-r--r--libc/sysdeps/linux/i386/bits/fenv.h9
-rw-r--r--libc/sysdeps/linux/i386/bits/huge_vall.h42
-rw-r--r--libc/sysdeps/linux/i386/bits/kernel_stat.h29
-rw-r--r--libc/sysdeps/linux/i386/bits/kernel_types.h11
-rw-r--r--libc/sysdeps/linux/i386/bits/mathdef.h5
-rw-r--r--libc/sysdeps/linux/i386/bits/mathinline.h34
-rw-r--r--libc/sysdeps/linux/i386/bits/mman.h103
-rw-r--r--libc/sysdeps/linux/i386/bits/select.h5
-rw-r--r--libc/sysdeps/linux/i386/bits/setjmp.h25
-rw-r--r--libc/sysdeps/linux/i386/bits/sigcontextinfo.h5
-rw-r--r--libc/sysdeps/linux/i386/bits/stackinfo.h5
-rw-r--r--libc/sysdeps/linux/i386/bits/syscalls.h344
-rw-r--r--libc/sysdeps/linux/i386/bits/uClibc_arch_features.h14
-rw-r--r--libc/sysdeps/linux/i386/bits/wchar.h5
-rw-r--r--libc/sysdeps/linux/i386/bits/wordsize.h7
-rw-r--r--libc/sysdeps/linux/i386/brk.c53
-rw-r--r--libc/sysdeps/linux/i386/bsd-_setjmp.S9
-rw-r--r--libc/sysdeps/linux/i386/bsd-setjmp.S9
-rw-r--r--libc/sysdeps/linux/i386/clone.S13
-rw-r--r--libc/sysdeps/linux/i386/copysign.S55
-rw-r--r--libc/sysdeps/linux/i386/crt1.S5
-rw-r--r--libc/sysdeps/linux/i386/crtn.S2
-rw-r--r--libc/sysdeps/linux/i386/fpu_control.h5
-rw-r--r--libc/sysdeps/linux/i386/getcontext.S84
-rw-r--r--libc/sysdeps/linux/i386/jmpbuf-offsets.h25
-rw-r--r--libc/sysdeps/linux/i386/jmpbuf-unwind.h23
-rw-r--r--libc/sysdeps/linux/i386/makecontext.S123
-rw-r--r--libc/sysdeps/linux/i386/mmap.S5
-rw-r--r--libc/sysdeps/linux/i386/mmap64.S10
-rw-r--r--libc/sysdeps/linux/i386/posix_fadvise.c34
-rw-r--r--libc/sysdeps/linux/i386/posix_fadvise64.S68
-rw-r--r--libc/sysdeps/linux/i386/setcontext.S96
-rw-r--r--libc/sysdeps/linux/i386/setjmp.S10
-rw-r--r--libc/sysdeps/linux/i386/sigaction.c174
-rw-r--r--libc/sysdeps/linux/i386/swapcontext.S110
-rw-r--r--libc/sysdeps/linux/i386/sync_file_range.S5
-rw-r--r--libc/sysdeps/linux/i386/sys/debugreg.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/elf.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/io.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/perm.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/procfs.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/reg.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/ucontext.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/user.h5
-rw-r--r--libc/sysdeps/linux/i386/sys/vm86.h5
-rw-r--r--libc/sysdeps/linux/i386/sysdep.h429
-rw-r--r--libc/sysdeps/linux/i386/ucontext_i.sym30
-rw-r--r--libc/sysdeps/linux/i386/vfork.S12
54 files changed, 1487 insertions, 811 deletions
diff --git a/libc/sysdeps/linux/i386/Makefile.arch b/libc/sysdeps/linux/i386/Makefile.arch
index bff33a8f2..1c72d23fd 100644
--- a/libc/sysdeps/linux/i386/Makefile.arch
+++ b/libc/sysdeps/linux/i386/Makefile.arch
@@ -5,15 +5,14 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := brk.c sigaction.c __syscall_error.c
+CSRC-y := brk.c __syscall_error.c sigaction.c
-SSRC := \
- __longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \
- sync_file_range.S syscall.S mmap.S mmap64.S
+SSRC-y := \
+ __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \
+ sync_file_range.S syscall.S mmap.S \
+ copysign.S
-ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),y)
-SSRC += posix_fadvise64.S
-CSRC += posix_fadvise.c
-endif
-
-include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
+SSRC-$(UCLIBC_HAS_LFS) += mmap64.S
+SSRC-$(if $(findstring yy,$(UCLIBC_HAS_ADVANCED_REALTIME)$(UCLIBC_HAS_LFS)),y) += posix_fadvise64.S
+SSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += vfork.S clone.S
+SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.S setcontext.S getcontext.S swapcontext.S
diff --git a/libc/sysdeps/linux/i386/__longjmp.S b/libc/sysdeps/linux/i386/__longjmp.S
index e2809c06c..dd71b7c08 100644
--- a/libc/sysdeps/linux/i386/__longjmp.S
+++ b/libc/sysdeps/linux/i386/__longjmp.S
@@ -14,13 +14,9 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
-#include <features.h>
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
+#include <jmpbuf-offsets.h>
.global __longjmp
.type __longjmp,%function
diff --git a/libc/sysdeps/linux/i386/__syscall_error.c b/libc/sysdeps/linux/i386/__syscall_error.c
index 7509d4409..36946bc6d 100644
--- a/libc/sysdeps/linux/i386/__syscall_error.c
+++ b/libc/sysdeps/linux/i386/__syscall_error.c
@@ -28,9 +28,8 @@
int __syscall_error(void) attribute_hidden;
int __syscall_error(void)
{
- register int edx __asm__ ("%edx");
- __asm__ ("mov %eax, %edx\n\t"
- "negl %edx");
- __set_errno (edx);
+ register int eax __asm__ ("%eax");
+ int _errno = -eax;
+ __set_errno (_errno);
return -1;
}
diff --git a/libc/sysdeps/linux/i386/bits/atomic.h b/libc/sysdeps/linux/i386/bits/atomic.h
index a20f424f8..66849acbc 100644
--- a/libc/sysdeps/linux/i386/bits/atomic.h
+++ b/libc/sysdeps/linux/i386/bits/atomic.h
@@ -13,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <stdint.h>
@@ -60,21 +59,21 @@ typedef uintmax_t uatomic_max_t;
#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
- __asm__ __volatile__ (LOCK_PREFIX "cmpxchgb %b2, %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "cmpxchgb %b2, %1" \
: "=a" (ret), "=m" (*mem) \
: "q" (newval), "m" (*mem), "0" (oldval)); \
ret; })
#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
- __asm__ __volatile__ (LOCK_PREFIX "cmpxchgw %w2, %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "cmpxchgw %w2, %1" \
: "=a" (ret), "=m" (*mem) \
: "r" (newval), "m" (*mem), "0" (oldval)); \
ret; })
#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
- __asm__ __volatile__ (LOCK_PREFIX "cmpxchgl %2, %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "cmpxchgl %2, %1" \
: "=a" (ret), "=m" (*mem) \
: "r" (newval), "m" (*mem), "0" (oldval)); \
ret; })
@@ -92,7 +91,7 @@ typedef uintmax_t uatomic_max_t;
# ifdef __PIC__
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
- __asm__ __volatile__ ("xchgl %2, %%ebx\n\t" \
+ __asm__ __volatile__ ("xchgl %2, %%ebx\n\t" \
LOCK_PREFIX "cmpxchg8b %1\n\t" \
"xchgl %2, %%ebx" \
: "=A" (ret), "=m" (*mem) \
@@ -131,7 +130,7 @@ typedef uintmax_t uatomic_max_t;
: "=r" (result), "=m" (*mem) \
: "0" (newvalue), "m" (*mem)); \
else if (sizeof (*mem) == 4) \
- __asm__ __volatile__ ("xchgl %0, %1" \
+ __asm__ __volatile__ ("xchgl %0, %1" \
: "=r" (result), "=m" (*mem) \
: "0" (newvalue), "m" (*mem)); \
else \
@@ -146,11 +145,11 @@ typedef uintmax_t uatomic_max_t;
({ __typeof (*mem) __result; \
__typeof (value) __addval = (value); \
if (sizeof (*mem) == 1) \
- __asm__ __volatile__ (LOCK_PREFIX "xaddb %b0, %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "xaddb %b0, %1" \
: "=r" (__result), "=m" (*mem) \
: "0" (__addval), "m" (*mem)); \
else if (sizeof (*mem) == 2) \
- __asm__ __volatile__ (LOCK_PREFIX "xaddw %w0, %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "xaddw %w0, %1" \
: "=r" (__result), "=m" (*mem) \
: "0" (__addval), "m" (*mem)); \
else if (sizeof (*mem) == 4) \
@@ -204,11 +203,11 @@ typedef uintmax_t uatomic_max_t;
#define atomic_add_negative(mem, value) \
({ unsigned char __result; \
if (sizeof (*mem) == 1) \
- __asm__ __volatile__ (LOCK_PREFIX "addb %b2, %0; sets %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "addb %b2, %0; sets %1" \
: "=m" (*mem), "=qm" (__result) \
: "iq" (value), "m" (*mem)); \
else if (sizeof (*mem) == 2) \
- __asm__ __volatile__ (LOCK_PREFIX "addw %w2, %0; sets %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "addw %w2, %0; sets %1" \
: "=m" (*mem), "=qm" (__result) \
: "ir" (value), "m" (*mem)); \
else if (sizeof (*mem) == 4) \
@@ -223,11 +222,11 @@ typedef uintmax_t uatomic_max_t;
#define atomic_add_zero(mem, value) \
({ unsigned char __result; \
if (sizeof (*mem) == 1) \
- __asm__ __volatile__ (LOCK_PREFIX "addb %b2, %0; setz %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "addb %b2, %0; setz %1" \
: "=m" (*mem), "=qm" (__result) \
: "ir" (value), "m" (*mem)); \
else if (sizeof (*mem) == 2) \
- __asm__ __volatile__ (LOCK_PREFIX "addw %w2, %0; setz %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "addw %w2, %0; setz %1" \
: "=m" (*mem), "=qm" (__result) \
: "ir" (value), "m" (*mem)); \
else if (sizeof (*mem) == 4) \
@@ -241,15 +240,15 @@ typedef uintmax_t uatomic_max_t;
#define atomic_increment(mem) \
(void) ({ if (sizeof (*mem) == 1) \
- __asm__ __volatile__ (LOCK_PREFIX "incb %b0" \
+ __asm__ __volatile__ (LOCK_PREFIX "incb %b0" \
: "=m" (*mem) \
: "m" (*mem)); \
else if (sizeof (*mem) == 2) \
- __asm__ __volatile__ (LOCK_PREFIX "incw %w0" \
+ __asm__ __volatile__ (LOCK_PREFIX "incw %w0" \
: "=m" (*mem) \
: "m" (*mem)); \
else if (sizeof (*mem) == 4) \
- __asm__ __volatile__ (LOCK_PREFIX "incl %0" \
+ __asm__ __volatile__ (LOCK_PREFIX "incl %0" \
: "=m" (*mem) \
: "m" (*mem)); \
else \
@@ -276,7 +275,7 @@ typedef uintmax_t uatomic_max_t;
: "=m" (*mem), "=qm" (__result) \
: "m" (*mem)); \
else if (sizeof (*mem) == 4) \
- __asm__ __volatile__ (LOCK_PREFIX "incl %0; sete %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "incl %0; sete %1" \
: "=m" (*mem), "=qm" (__result) \
: "m" (*mem)); \
else \
@@ -286,15 +285,15 @@ typedef uintmax_t uatomic_max_t;
#define atomic_decrement(mem) \
(void) ({ if (sizeof (*mem) == 1) \
- __asm__ __volatile__ (LOCK_PREFIX "decb %b0" \
+ __asm__ __volatile__ (LOCK_PREFIX "decb %b0" \
: "=m" (*mem) \
: "m" (*mem)); \
else if (sizeof (*mem) == 2) \
- __asm__ __volatile__ (LOCK_PREFIX "decw %w0" \
+ __asm__ __volatile__ (LOCK_PREFIX "decw %w0" \
: "=m" (*mem) \
: "m" (*mem)); \
else if (sizeof (*mem) == 4) \
- __asm__ __volatile__ (LOCK_PREFIX "decl %0" \
+ __asm__ __volatile__ (LOCK_PREFIX "decl %0" \
: "=m" (*mem) \
: "m" (*mem)); \
else \
@@ -305,7 +304,7 @@ typedef uintmax_t uatomic_max_t;
do \
__tmpval = __oldval; \
while ((__oldval = __arch_compare_and_exchange_val_64_acq \
- (__memp, __oldval - 1, __oldval)) == __tmpval); \
+ (__memp, __oldval - 1, __oldval)) == __tmpval); \
} \
})
@@ -321,7 +320,7 @@ typedef uintmax_t uatomic_max_t;
: "=m" (*mem), "=qm" (__result) \
: "m" (*mem)); \
else if (sizeof (*mem) == 4) \
- __asm__ __volatile__ (LOCK_PREFIX "decl %0; sete %1" \
+ __asm__ __volatile__ (LOCK_PREFIX "decl %0; sete %1" \
: "=m" (*mem), "=qm" (__result) \
: "m" (*mem)); \
else \
@@ -361,7 +360,7 @@ typedef uintmax_t uatomic_max_t;
__asm__ __volatile__ (LOCK_PREFIX "btsl %3, %1; setc %0" \
: "=q" (__result), "=m" (*mem) \
: "m" (*mem), "ir" (bit)); \
- else \
+ else \
abort (); \
__result; })
diff --git a/libc/sysdeps/linux/i386/bits/byteswap.h b/libc/sysdeps/linux/i386/bits/byteswap.h
index 33af20888..651852e57 100644
--- a/libc/sysdeps/linux/i386/bits/byteswap.h
+++ b/libc/sysdeps/linux/i386/bits/byteswap.h
@@ -13,121 +13,43 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
-# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
-#endif
-
-#ifndef _BITS_BYTESWAP_H
-#define _BITS_BYTESWAP_H 1
+#ifndef _ASM_BITS_BYTESWAP_H
+#define _ASM_BITS_BYTESWAP_H 1
-/* Swap bytes in 16 bit value. */
-#define __bswap_constant_16(x) \
- ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
-
-#ifdef __GNUC__
-# if __GNUC__ >= 2
-# define __bswap_16(x) \
+#define __bswap_non_constant_16(x) \
(__extension__ \
- ({ register unsigned short int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_16 (__x); \
- else \
- __asm__ ("rorw $8, %w0" \
- : "=r" (__v) \
- : "0" (__x) \
- : "cc"); \
+ ({ register unsigned short int __v; \
+ __asm__ ("rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (x) \
+ : "cc"); \
__v; }))
-# else
-/* This is better than nothing. */
-# define __bswap_16(x) \
- (__extension__ \
- ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
-# endif
-#else
-static __inline unsigned short int
-__bswap_16 (unsigned short int __bsx)
-{
- return __bswap_constant_16 (__bsx);
-}
-#endif
-
-/* Swap bytes in 32 bit value. */
-#define __bswap_constant_32(x) \
- ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
-#ifdef __GNUC__
-# if __GNUC__ >= 2
/* To swap the bytes in a word the i486 processors and up provide the
`bswap' opcode. On i386 we have to use three instructions. */
-# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
+#if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
&& !defined __pentium4__
-# define __bswap_32(x) \
+# define __bswap_non_constant_32(x) \
(__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("rorw $8, %w0;" \
- "rorl $16, %0;" \
- "rorw $8, %w0" \
- : "=r" (__v) \
- : "0" (__x) \
- : "cc"); \
+ ({ register unsigned int __v; \
+ __asm__ ("rorw $8, %w0;" \
+ "rorl $16, %0;" \
+ "rorw $8, %w0" \
+ : "=r" (__v) \
+ : "0" (x) \
+ : "cc"); \
__v; }))
-# else
-# define __bswap_32(x) \
+#else
+# define __bswap_non_constant_32(x) \
(__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
+ ({ register unsigned int __v; \
+ __asm__ ("bswap %0" : "=r" (__v) : "0" (x)); \
__v; }))
-# endif
-# else
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
-# endif
-#else
-static __inline unsigned int
-__bswap_32 (unsigned int __bsx)
-{
- return __bswap_constant_32 (__bsx);
-}
#endif
-
-#if defined __GNUC__ && __GNUC__ >= 2
-/* Swap bytes in 64 bit value. */
-#define __bswap_constant_64(x) \
- ((((x) & 0xff00000000000000ull) >> 56) \
- | (((x) & 0x00ff000000000000ull) >> 40) \
- | (((x) & 0x0000ff0000000000ull) >> 24) \
- | (((x) & 0x000000ff00000000ull) >> 8) \
- | (((x) & 0x00000000ff000000ull) << 8) \
- | (((x) & 0x0000000000ff0000ull) << 24) \
- | (((x) & 0x000000000000ff00ull) << 40) \
- | (((x) & 0x00000000000000ffull) << 56))
-
-# define __bswap_64(x) \
- (__extension__ \
- ({ union { __extension__ unsigned long long int __ll; \
- unsigned long int __l[2]; } __w, __r; \
- if (__builtin_constant_p (x)) \
- __r.__ll = __bswap_constant_64 (x); \
- else \
- { \
- __w.__ll = (x); \
- __r.__l[0] = __bswap_32 (__w.__l[1]); \
- __r.__l[1] = __bswap_32 (__w.__l[0]); \
- } \
- __r.__ll; }))
#endif
-#endif /* _BITS_BYTESWAP_H */
+#include <bits/byteswap-common.h>
diff --git a/libc/sysdeps/linux/i386/bits/fcntl.h b/libc/sysdeps/linux/i386/bits/fcntl.h
index 0b53b459b..4dfeae831 100644
--- a/libc/sysdeps/linux/i386/bits/fcntl.h
+++ b/libc/sysdeps/linux/i386/bits/fcntl.h
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _FCNTL_H
# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
@@ -50,9 +49,8 @@
# define O_DIRECTORY 0200000 /* Must be a directory. */
# define O_NOFOLLOW 0400000 /* Do not follow links. */
# define O_NOATIME 01000000 /* Do not set atime. */
-# if 0
# define O_CLOEXEC 02000000 /* Set close_on_exec. */
-# endif
+# define O_PATH 010000000 /* Resolve pathname but do not open file. */
#endif
/* For now Linux has synchronisity options for data and read operations.
@@ -102,6 +100,8 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */
# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with
close-on-exit set on new fd. */
+# define F_SETPIPE_SZ 1031 /* Set pipe page size array. */
+# define F_GETPIPE_SZ 1032 /* Get pipe page size array. */
#endif
/* For F_[GET|SET]FD. */
@@ -189,7 +189,7 @@ struct flock64
#endif
-#ifdef __USE_GNU
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
/* Flags for SYNC_FILE_RANGE. */
# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
in the range before performing the
@@ -212,7 +212,7 @@ struct flock64
__BEGIN_DECLS
-#ifdef __USE_GNU
+#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
diff --git a/libc/sysdeps/linux/i386/bits/fenv.h b/libc/sysdeps/linux/i386/bits/fenv.h
index ef3fcb384..9bd976fc1 100644
--- a/libc/sysdeps/linux/i386/bits/fenv.h
+++ b/libc/sysdeps/linux/i386/bits/fenv.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _FENV_H
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
@@ -82,9 +81,9 @@ typedef struct
fenv_t;
/* If the default argument is used we use this value. */
-#define FE_DFL_ENV ((__const fenv_t *) -1)
+#define FE_DFL_ENV ((const fenv_t *) -1)
#ifdef __USE_GNU
/* Floating-point environment where none of the exception is masked. */
-# define FE_NOMASK_ENV ((__const fenv_t *) -2)
+# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
diff --git a/libc/sysdeps/linux/i386/bits/huge_vall.h b/libc/sysdeps/linux/i386/bits/huge_vall.h
new file mode 100644
index 000000000..7e9c24d8a
--- /dev/null
+++ b/libc/sysdeps/linux/i386/bits/huge_vall.h
@@ -0,0 +1,42 @@
+/* `HUGE_VALL' constant for ix86 (where it is infinity).
+ Used by <stdlib.h> and <math.h> functions for overflow.
+ Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MATH_H
+# error "Never use <bits/huge_vall.h> directly; include <math.h> instead."
+#endif
+
+#if __GNUC_PREREQ(3,3)
+# define HUGE_VALL (__builtin_huge_vall())
+#elif __GNUC_PREREQ(2,96)
+# define HUGE_VALL (__extension__ 0x1.0p32767L)
+#else
+
+# define __HUGE_VALL_bytes { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f, 0, 0 }
+
+# define __huge_vall_t union { unsigned char __c[12]; long double __ld; }
+# ifdef __GNUC__
+# define HUGE_VALL (__extension__ \
+ ((__huge_vall_t) { __c: __HUGE_VALL_bytes }).__ld)
+# else /* Not GCC. */
+static __huge_vall_t __huge_vall = { __HUGE_VALL_bytes };
+# define HUGE_VALL (__huge_vall.__ld)
+# endif /* GCC. */
+
+#endif /* GCC 2.95 */
diff --git a/libc/sysdeps/linux/i386/bits/kernel_stat.h b/libc/sysdeps/linux/i386/bits/kernel_stat.h
index 20eb6d2ef..231a984b4 100644
--- a/libc/sysdeps/linux/i386/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/i386/bits/kernel_stat.h
@@ -1,17 +1,12 @@
#ifndef _BITS_STAT_STRUCT_H
#define _BITS_STAT_STRUCT_H
-#ifndef _LIBC
-#error bits/kernel_stat.h is for internal uClibc use only!
-#endif
-
/* This file provides whatever this particular arch's kernel thinks
* struct stat should look like... It turns out each arch has a
* different opinion on the subject... */
struct kernel_stat {
- unsigned short st_dev;
- unsigned short __pad1;
+ unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
@@ -22,19 +17,16 @@ struct kernel_stat {
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
- unsigned long st_atime;
- unsigned long __unused1;
- unsigned long st_mtime;
- unsigned long __unused2;
- unsigned long st_ctime;
- unsigned long __unused3;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
unsigned long __unused4;
unsigned long __unused5;
};
struct kernel_stat64 {
- unsigned short st_dev;
- unsigned char __pad0[10];
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
#define _HAVE_STAT64___ST_INO
unsigned long __st_ino;
unsigned int st_mode;
@@ -47,12 +39,9 @@ struct kernel_stat64 {
unsigned long st_blksize;
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
unsigned long __pad4; /* future possible st_blocks high bits */
- unsigned long st_atime;
- unsigned long __pad5;
- unsigned long st_mtime;
- unsigned long __pad6;
- unsigned long st_ctime;
- unsigned long __pad7; /* will be high 32 bits of ctime someday */
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
unsigned long long st_ino;
};
diff --git a/libc/sysdeps/linux/i386/bits/kernel_types.h b/libc/sysdeps/linux/i386/bits/kernel_types.h
index 6609dd312..59044b8e6 100644
--- a/libc/sysdeps/linux/i386/bits/kernel_types.h
+++ b/libc/sysdeps/linux/i386/bits/kernel_types.h
@@ -7,9 +7,14 @@
/* a hack for compiling a 32 bit user space with 64 bit
* kernel on x86_64 */
-#if !defined(__ARCH_I386_POSIX_TYPES_H) && !defined(_ASM_X86_64_POSIX_TYPES_H)
+#if !defined(__ARCH_I386_POSIX_TYPES_H) && \
+ !defined(_ASM_X86_64_POSIX_TYPES_H) && \
+ !defined(_ASM_X86_POSIX_TYPES_32_H) && \
+ !defined(_ASM_X86_POSIX_TYPES_64_H)
#define _ASM_X86_64_POSIX_TYPES_H
#define __ARCH_I386_POSIX_TYPES_H
+#define _ASM_X86_POSIX_TYPES_32_H
+#define _ASM_X86_POSIX_TYPES_64_H
typedef unsigned short __kernel_dev_t;
typedef unsigned long __kernel_ino_t;
@@ -35,6 +40,8 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
typedef __kernel_dev_t __kernel_old_dev_t;
+typedef long __kernel_long_t;
+typedef unsigned long __kernel_ulong_t;
typedef long long __kernel_loff_t;
typedef struct {
@@ -45,4 +52,4 @@ typedef struct {
#endif
} __kernel_fsid_t;
-#endif /* __ARCH_I386_POSIX_TYPES_H */
+#endif
diff --git a/libc/sysdeps/linux/i386/bits/mathdef.h b/libc/sysdeps/linux/i386/bits/mathdef.h
index a3786fc81..ca4d5e5eb 100644
--- a/libc/sysdeps/linux/i386/bits/mathdef.h
+++ b/libc/sysdeps/linux/i386/bits/mathdef.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#if !defined _MATH_H && !defined _COMPLEX_H
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
diff --git a/libc/sysdeps/linux/i386/bits/mathinline.h b/libc/sysdeps/linux/i386/bits/mathinline.h
index ca7277d76..b3a50a538 100644
--- a/libc/sysdeps/linux/i386/bits/mathinline.h
+++ b/libc/sysdeps/linux/i386/bits/mathinline.h
@@ -15,9 +15,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _MATH_H
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
@@ -26,7 +25,7 @@
#ifdef __cplusplus
# define __MATH_INLINE __inline
#else
-# define __MATH_INLINE extern __inline
+# define __MATH_INLINE __extern_inline
#endif
@@ -206,7 +205,7 @@ __NTH (__signbitl (long double __x))
__MATH_INLINE float_type __NTH (func (float_type __x)) \
{ \
register float_type __result; \
- __asm__ __volatile__ (op : "=t" (__result) : params); \
+ __asm__ __volatile__ (op : "=t" (__result) : params); \
return __result; \
}
@@ -529,8 +528,8 @@ __inline_mathcodeNP (tanh, __x, \
__inline_mathcodeNP (floor, __x, \
register long double __value; \
- __volatile unsigned short int __cw; \
- __volatile unsigned short int __cwtmp; \
+ __volatile__ unsigned short int __cw; \
+ __volatile__ unsigned short int __cwtmp; \
__asm__ __volatile__ ("fnstcw %0" : "=m" (__cw)); \
__cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ \
__asm__ __volatile__ ("fldcw %0" : : "m" (__cwtmp)); \
@@ -540,8 +539,8 @@ __inline_mathcodeNP (floor, __x, \
__inline_mathcodeNP (ceil, __x, \
register long double __value; \
- __volatile unsigned short int __cw; \
- __volatile unsigned short int __cwtmp; \
+ __volatile__ unsigned short int __cw; \
+ __volatile__ unsigned short int __cwtmp; \
__asm__ __volatile__ ("fnstcw %0" : "=m" (__cw)); \
__cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ \
__asm__ __volatile__ ("fldcw %0" : : "m" (__cwtmp)); \
@@ -713,11 +712,22 @@ __inline_mathcodeNP2 (drem, __x, __y, \
__MATH_INLINE int
__NTH (__finite (double __x))
{
- return (__extension__
- (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
- | 0x800fffffu) + 1) >> 31));
+ union { double __d; int __i[2]; } u;
+ u.__d = __x;
+ /* Finite numbers have at least one zero bit in exponent. */
+ /* All other numbers will result in 0xffffffff after OR: */
+ return (u.__i[1] | 0x800fffff) != 0xffffffff;
}
+__MATH_INLINE int
+__NTH (__finitef (float __x))
+{
+ union { float __d; int __i; } u;
+ u.__d = __x;
+ return (u.__i | 0x807fffff) != 0xffffffff;
+}
+
+
/* Miscellaneous functions */
# ifdef __FAST_MATH__
__inline_mathcode (__coshm1, __x, \
diff --git a/libc/sysdeps/linux/i386/bits/mman.h b/libc/sysdeps/linux/i386/bits/mman.h
deleted file mode 100644
index 00cb98239..000000000
--- a/libc/sysdeps/linux/i386/bits/mman.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Definitions for POSIX memory map interface. Linux/i386 version.
- Copyright (C) 1997, 2000, 2003, 2005, 2006 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. */
-
-#ifndef _SYS_MMAN_H
-# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
-#endif
-
-/* The following definitions basically come from the kernel headers.
- But the kernel header is not namespace clean. */
-
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
-/* These are Linux-specific. */
-#ifdef __USE_MISC
-# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
-# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
-# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
-# define MAP_LOCKED 0x02000 /* Lock the mapping. */
-# define MAP_NORESERVE 0x04000 /* Don't check for reservations. */
-# define MAP_POPULATE 0x08000 /* Populate (prefault) pagetables. */
-# define MAP_NONBLOCK 0x10000 /* Do not block on IO. */
-#endif
-
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
diff --git a/libc/sysdeps/linux/i386/bits/select.h b/libc/sysdeps/linux/i386/bits/select.h
index 972bfb685..541294f62 100644
--- a/libc/sysdeps/linux/i386/bits/select.h
+++ b/libc/sysdeps/linux/i386/bits/select.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_SELECT_H
# error "Never use <bits/select.h> directly; include <sys/select.h> instead."
diff --git a/libc/sysdeps/linux/i386/bits/setjmp.h b/libc/sysdeps/linux/i386/bits/setjmp.h
index 107fe58b3..6eb29f1c0 100644
--- a/libc/sysdeps/linux/i386/bits/setjmp.h
+++ b/libc/sysdeps/linux/i386/bits/setjmp.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000,2001,2003,2005,2006
+ 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
@@ -12,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* Define the machine-dependent type `jmp_buf'. Intel 386 version. */
#ifndef _BITS_SETJMP_H
@@ -24,23 +24,6 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
-#if defined __USE_MISC || defined _ASM
-# define JB_BX 0
-# define JB_SI 1
-# define JB_DI 2
-# define JB_BP 3
-# define JB_SP 4
-# define JB_PC 5
-# define JB_SIZE 24
-#endif
-
-#ifndef _ASM
typedef int __jmp_buf[6];
-#endif
-
-/* Test if longjmp to JMPBUF would unwind the frame
- containing a local variable at ADDRESS. */
-#define _JMPBUF_UNWINDS(jmpbuf, address) \
- ((void *) (address) < (void *) (jmpbuf)[JB_SP])
#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/i386/bits/sigcontextinfo.h b/libc/sysdeps/linux/i386/bits/sigcontextinfo.h
index b7367bac6..4cafabdcb 100644
--- a/libc/sysdeps/linux/i386/bits/sigcontextinfo.h
+++ b/libc/sysdeps/linux/i386/bits/sigcontextinfo.h
@@ -13,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#define SIGCONTEXT struct sigcontext
#define SIGCONTEXT_EXTRA_ARGS
diff --git a/libc/sysdeps/linux/i386/bits/stackinfo.h b/libc/sysdeps/linux/i386/bits/stackinfo.h
index a9a6745aa..e1b61fae0 100644
--- a/libc/sysdeps/linux/i386/bits/stackinfo.h
+++ b/libc/sysdeps/linux/i386/bits/stackinfo.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* This file contains a bit of information about the stack allocation
of the processor. */
diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h
index 014539c2a..566b5acf5 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -1,211 +1,193 @@
#ifndef _BITS_SYSCALLS_H
#define _BITS_SYSCALLS_H
+
#ifndef _SYSCALL_H
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
/*
- Some of the sneaky macros in the code were taken from
- glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
-*/
+ * Some of the sneaky macros in the code were taken from
+ * glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
+ */
#ifndef __ASSEMBLER__
#include <errno.h>
-#define SYS_ify(syscall_name) (__NR_##syscall_name)
-
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
-
-#define INTERNAL_SYSCALL_ERROR_P(val, err) \
- ((unsigned int) (val) >= 0xfffff001u)
-
-#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
-
-/* We need some help from the assembler to generate optimal code. We
- define some macros here which later will be used. */
-
-#if defined __SUPPORT_LD_DEBUG__ && defined __DOMULTI__
-#error LD debugging and DOMULTI are incompatible
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+(__extension__ \
+ ({ \
+ register unsigned int resultvar; \
+ __asm__ __volatile__ ( \
+ LOADARGS_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "g" (name) ASMFMT_##nr(args) : "memory", "cc" \
+ ); \
+ (int) resultvar; \
+ }) \
+)
+
+#if 1 /* defined __PIC__ || defined __pic__ */
+
+/* This code avoids pushing/popping ebx as much as possible.
+ * I think the main reason was that older GCCs had problems
+ * with proper saving/restoring of ebx if "b" constraint was used,
+ * which was breaking -fPIC code really badly.
+ * At least gcc 4.2.x seems to not need these tricks anymore,
+ * but this code is still useful because it often avoids
+ * using stack for saving ebx.
+ * Keeping it unconditionally enabled for now.
+ */
+
+/* We need some help from the assembler to generate optimal code.
+ * We define some macros here which later will be used. */
+/* gcc>=4.6 with LTO need the same guards as IMA (a.k.a --combine) did.
+ * See gcc.gnu.org/PR47577 */
+/* FIXME: drop these b* macros! */
+
+__asm__ (
+#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
+ /* Protect against asm macro redefinition (happens in __DOMULTI__ mode).
+ * Unfortunately, it ends up visible in .o files. */
+ ".ifndef _BITS_SYSCALLS_ASM\n\t"
+ ".set _BITS_SYSCALLS_ASM,1\n\t"
#endif
-
-#ifdef __DOMULTI__
-__asm__ (".L__X'%ebx = 1\n\t"
- ".L__X'%ecx = 2\n\t"
- ".L__X'%edx = 2\n\t"
- ".L__X'%eax = 3\n\t"
- ".L__X'%esi = 3\n\t"
- ".L__X'%edi = 3\n\t"
- ".L__X'%ebp = 3\n\t"
- ".L__X'%esp = 3\n\t"
- ".ifndef _BITS_SYSCALLS_ASM\n\t"
- ".set _BITS_SYSCALLS_ASM,1\n\t"
- ".macro bpushl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "pushl %ebx\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".macro bpopl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "popl %ebx\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".macro bmovl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "movl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".endif\n\t");
-#else
-__asm__ (".L__X'%ebx = 1\n\t"
- ".L__X'%ecx = 2\n\t"
- ".L__X'%edx = 2\n\t"
- ".L__X'%eax = 3\n\t"
- ".L__X'%esi = 3\n\t"
- ".L__X'%edi = 3\n\t"
- ".L__X'%ebp = 3\n\t"
- ".L__X'%esp = 3\n\t"
- ".macro bpushl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "pushl %ebx\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".macro bpopl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "popl %ebx\n\t"
- ".else\n\t"
- "xchgl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t"
- ".macro bmovl name reg\n\t"
- ".if 1 - \\name\n\t"
- ".if 2 - \\name\n\t"
- "movl \\reg, %ebx\n\t"
- ".endif\n\t"
- ".endif\n\t"
- ".endm\n\t");
+ ".L__X'%ebx = 1\n\t"
+ ".L__X'%ecx = 2\n\t"
+ ".L__X'%edx = 2\n\t"
+ ".L__X'%eax = 3\n\t"
+ ".L__X'%esi = 3\n\t"
+ ".L__X'%edi = 3\n\t"
+ ".L__X'%ebp = 3\n\t"
+ ".L__X'%esp = 3\n\t"
+
+ /* Loading param #1 (ebx) is done by loading it into
+ * another register, and then performing bpushl+bmovl,
+ * since we must preserve ebx */
+
+ ".macro bpushl name reg\n\t"
+ ".if 1 - \\name\n\t" /* if reg!=ebx... */
+ ".if 2 - \\name\n\t" /* if reg can't be clobbered... */
+ "pushl %ebx\n\t" /* save ebx on stack */
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+
+ ".macro bmovl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t" /* if reg can't be clobbered... */
+ "movl \\reg, %ebx\n\t" /* load reg to ebx */
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+
+ ".macro bpopl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t" /* if reg can't be clobbered... */
+ "popl %ebx\n\t" /* restore ebx from stack */
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+
+#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
+ ".endif\n\t" /* _BITS_SYSCALLS_ASM */
#endif
-
-#undef _syscall0
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-return (type) (INLINE_SYSCALL(name, 0)); \
-}
-
-#undef _syscall1
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-return (type) (INLINE_SYSCALL(name, 1, arg1)); \
-}
-
-#undef _syscall2
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
-}
-
-#undef _syscall3
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
-}
-
-#undef _syscall4
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
-}
-
-#undef _syscall5
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5) \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-{ \
-return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
-}
-
-#undef _syscall6
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5,type6,arg6) \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
-{ \
-return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
-}
- #define INLINE_SYSCALL(name, nr, args...) \
- ({ \
- unsigned int _resultvar = INTERNAL_SYSCALL (name, , nr, args); \
- if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_resultvar, ), 0)) \
- { \
- __set_errno (INTERNAL_SYSCALL_ERRNO (_resultvar, )); \
- _resultvar = 0xffffffff; \
- } \
- (int) _resultvar; })
-
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
- ({ \
- register unsigned int resultvar; \
- __asm__ __volatile__ ( \
- LOADARGS_##nr \
- "movl %1, %%eax\n\t" \
- "int $0x80\n\t" \
- RESTOREARGS_##nr \
- : "=a" (resultvar) \
- : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
- (int) resultvar; })
+);
#define LOADARGS_0
-#define LOADARGS_1 \
- "bpushl .L__X'%k2, %k2\n\t" \
- "bmovl .L__X'%k2, %k2\n\t"
-#define LOADARGS_2 LOADARGS_1
-#define LOADARGS_3 LOADARGS_1
-#define LOADARGS_4 LOADARGS_1
-#define LOADARGS_5 LOADARGS_1
-#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t"
+#define LOADARGS_1 "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t"
+#define LOADARGS_2 LOADARGS_1
+#define LOADARGS_3 LOADARGS_1
+#define LOADARGS_4 LOADARGS_1
+#define LOADARGS_5 LOADARGS_1
+#define LOADARGS_6 LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t"
#define RESTOREARGS_0
-#define RESTOREARGS_1 \
- "bpopl .L__X'%k2, %k2\n\t"
-#define RESTOREARGS_2 RESTOREARGS_1
-#define RESTOREARGS_3 RESTOREARGS_1
-#define RESTOREARGS_4 RESTOREARGS_1
-#define RESTOREARGS_5 RESTOREARGS_1
-#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
+#define RESTOREARGS_1 "bpopl .L__X'%k2, %k2\n\t"
+#define RESTOREARGS_2 RESTOREARGS_1
+#define RESTOREARGS_3 RESTOREARGS_1
+#define RESTOREARGS_4 RESTOREARGS_1
+#define RESTOREARGS_5 RESTOREARGS_1
+#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
#define ASMFMT_0()
+/* "acdSD" constraint would work too, but "SD" would use esi/edi and cause
+ * them to be pushed/popped by compiler, "a" would use eax and cause ebx
+ * to be saved/restored on stack, not in register. Narrowing choice down
+ * to "ecx or edx" results in smaller and faster code: */
#define ASMFMT_1(arg1) \
- , "acdSD" (arg1)
+ , "cd" (arg1)
+/* Can use "adSD" constraint here: */
#define ASMFMT_2(arg1, arg2) \
- , "adSD" (arg1), "c" (arg2)
+ , "d" (arg1), "c" (arg2)
+/* Can use "aSD" constraint here: */
#define ASMFMT_3(arg1, arg2, arg3) \
- , "aSD" (arg1), "c" (arg2), "d" (arg3)
+ , "a" (arg1), "c" (arg2), "d" (arg3)
+/* Can use "aD" constraint here: */
#define ASMFMT_4(arg1, arg2, arg3, arg4) \
- , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
, "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
- , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
+ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "g" (arg6)
+
+#else /* !PIC */
+
+/* Simpler code which just uses "b" constraint to load ebx.
+ * Seems to work with gc 4.2.x, and generates slightly smaller,
+ * but slightly slower code. Example (time syscall):
+ *
+ * - 8b 4c 24 04 mov 0x4(%esp),%ecx
+ * - 87 cb xchg %ecx,%ebx
+ * + 53 push %ebx
+ * + 8b 5c 24 08 mov 0x8(%esp),%ebx
+ * b8 0d 00 00 00 mov $0xd,%eax
+ * cd 80 int $0x80
+ * - 87 cb xchg %ecx,%ebx
+ * + 5b pop %ebx
+ * c3 ret
+ *
+ * 2 bytes smaller, but uses stack via "push/pop ebx"
+ */
+
+#define LOADARGS_0
+#define LOADARGS_1
+#define LOADARGS_2
+#define LOADARGS_3
+#define LOADARGS_4
+#define LOADARGS_5
+#define LOADARGS_6 "push %%ebp\n\t" "movl %7, %%ebp\n\t"
+
+#define RESTOREARGS_0
+#define RESTOREARGS_1
+#define RESTOREARGS_2
+#define RESTOREARGS_3
+#define RESTOREARGS_4
+#define RESTOREARGS_5
+#define RESTOREARGS_6 "pop %%ebp\n\t"
+
+#define ASMFMT_0()
+#define ASMFMT_1(arg1) \
+ , "b" (arg1)
+#define ASMFMT_2(arg1, arg2) \
+ , "b" (arg1), "c" (arg2)
+#define ASMFMT_3(arg1, arg2, arg3) \
+ , "b" (arg1), "c" (arg2), "d" (arg3)
+#define ASMFMT_4(arg1, arg2, arg3, arg4) \
+ , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
+ , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+ , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
+
+#endif /* !PIC */
#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/i386/bits/uClibc_arch_features.h b/libc/sysdeps/linux/i386/bits/uClibc_arch_features.h
index f4730d987..5b6c2fc78 100644
--- a/libc/sysdeps/linux/i386/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/i386/bits/uClibc_arch_features.h
@@ -11,8 +11,8 @@
/* can your target use syscall6() for mmap ? */
#undef __UCLIBC_MMAP_HAS_6_ARGS__
-/* does your target use syscall4() for truncate64 ? (32bit arches only) */
-#undef __UCLIBC_TRUNCATE64_HAS_4_ARGS__
+/* does your target align 64bit values in register pairs ? (32bit arches only) */
+#undef __UCLIBC_SYSCALL_ALIGN_64BIT__
/* does your target have a broken create_module() ? */
#define __UCLIBC_BROKEN_CREATE_MODULE__
@@ -24,21 +24,21 @@
/* does your target have an asm .set ? */
#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
-/* define if target doesn't like .global */
-#undef __UCLIBC_ASM_GLOBAL_DIRECTIVE__
-
/* define if target supports .weak */
#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
/* define if target supports .weakext */
#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
-/* needed probably only for ppc64 */
-#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
+/* define if target supports CFI pseudo ops */
+#define __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
/* define if target supports IEEE signed zero floats */
#define __UCLIBC_HAVE_SIGNED_ZERO__
+/* only weird assemblers generally need this */
+#undef __UCLIBC_ASM_LINE_SEP__
+
#if defined _LIBC
#define internal_function __attribute__ ((regparm (3), stdcall))
#endif
diff --git a/libc/sysdeps/linux/i386/bits/wchar.h b/libc/sysdeps/linux/i386/bits/wchar.h
index 442a4621e..b94fc7a3f 100644
--- a/libc/sysdeps/linux/i386/bits/wchar.h
+++ b/libc/sysdeps/linux/i386/bits/wchar.h
@@ -13,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _BITS_WCHAR_H
#define _BITS_WCHAR_H 1
diff --git a/libc/sysdeps/linux/i386/bits/wordsize.h b/libc/sysdeps/linux/i386/bits/wordsize.h
index 7c3cd9c7d..d8f66ddc5 100644
--- a/libc/sysdeps/linux/i386/bits/wordsize.h
+++ b/libc/sysdeps/linux/i386/bits/wordsize.h
@@ -12,13 +12,12 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#define __WORDSIZE 32
-#ifdef UCLIBC_INTERNAL
+#ifdef _LIBC
#ifndef smallint_type
#define smallint_type char
#endif
diff --git a/libc/sysdeps/linux/i386/brk.c b/libc/sysdeps/linux/i386/brk.c
index eda8ad9ce..a513886e3 100644
--- a/libc/sysdeps/linux/i386/brk.c
+++ b/libc/sysdeps/linux/i386/brk.c
@@ -1,6 +1,7 @@
/* brk system call for Linux/i386.
Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+ Copyright (c) 2015 mirabilos <tg@mirbsd.org>
+ This file is part of uclibc-ng, derived from 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
@@ -13,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
@@ -24,26 +24,31 @@
/* This must be initialized data because commons can't have aliases. */
void *__curbrk attribute_hidden = 0;
-libc_hidden_proto(brk)
-int brk (void *addr)
+int brk(void *addr)
{
- 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)));
-
- __curbrk = newbrk;
-
- if (newbrk < addr)
- {
- __set_errno (ENOMEM);
- return -1;
- }
-
- return 0;
+ void *newbrk;
+
+ /*
+ * EBC is used in PIC code, we need to save/restore it manually.
+ * Unfortunately, GCC won't do that for us even if we use con-
+ * straints, and we cannot push it either as ESP clobbers are
+ * silently ignored, but EDX is preserved, so it's scratch space.
+ */
+ __asm__("xchgl %%edx,%%ebx"
+ "\n int $0x80"
+ "\n xchgl %%edx,%%ebx"
+ : "=a" (newbrk)
+ : "0" (__NR_brk), "d" (addr)
+ : "cc"
+ );
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr) {
+ __set_errno(ENOMEM);
+ return -1;
+ }
+
+ return 0;
}
libc_hidden_def(brk)
diff --git a/libc/sysdeps/linux/i386/bsd-_setjmp.S b/libc/sysdeps/linux/i386/bsd-_setjmp.S
index f3cd6cbf6..fac94e351 100644
--- a/libc/sysdeps/linux/i386/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/i386/bsd-_setjmp.S
@@ -13,17 +13,14 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
We cannot do it in C because it must be a tail-call, so frame-unwinding
in setjmp doesn't clobber the state restored by longjmp. */
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
+#include <jmpbuf-offsets.h>
.global _setjmp
.type _setjmp,%function
diff --git a/libc/sysdeps/linux/i386/bsd-setjmp.S b/libc/sysdeps/linux/i386/bsd-setjmp.S
index df46997d9..c634cf16a 100644
--- a/libc/sysdeps/linux/i386/bsd-setjmp.S
+++ b/libc/sysdeps/linux/i386/bsd-setjmp.S
@@ -13,13 +13,8 @@
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. */
-
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
.global setjmp
.type setjmp,%function
diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S
index 14fc25ca1..632cf59df 100644
--- a/libc/sysdeps/linux/i386/clone.S
+++ b/libc/sysdeps/linux/i386/clone.S
@@ -13,9 +13,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* clone() is even more special than fork() as it mucks with stacks
and invokes a function in the right context after its all over.
@@ -79,7 +78,10 @@ clone:
movl %eax,8(%ecx)
/* Don't leak any information. */
movl $0,4(%ecx)
+#ifndef RESET_PID
movl $0,(%ecx)
+#endif
+
/* Do the system call */
pushl %ebx
@@ -90,6 +92,10 @@ clone:
movl FLAGS+12(%esp),%ebx
movl CTID+12(%esp),%edi
movl $__NR_clone,%eax
+#ifdef RESET_PID
+ /* Remember the flag value. */
+ movl %ebx, (%ecx)
+#endif
int $0x80
popl %edi
popl %esi
@@ -121,3 +127,4 @@ __error:
jmp __syscall_error
.size clone,.-clone
+weak_alias(clone, __clone)
diff --git a/libc/sysdeps/linux/i386/copysign.S b/libc/sysdeps/linux/i386/copysign.S
new file mode 100644
index 000000000..6499ce05d
--- /dev/null
+++ b/libc/sysdeps/linux/i386/copysign.S
@@ -0,0 +1,55 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#define _ERRNO_H 1
+#include <features.h>
+#include <bits/errno.h>
+
+.text
+.global copysign
+.type copysign,%function
+copysign:
+ movl 16(%esp),%edx
+ movl 8(%esp),%eax
+ andl $0x80000000,%edx
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,8(%esp)
+ fldl 4(%esp)
+ ret
+.size copysign,.-copysign
+
+libc_hidden_def(copysign)
+
+.global copysignf
+.type copysignf,%function
+copysignf:
+ movl 8(%esp),%edx
+ movl 4(%esp),%eax
+ andl $0x80000000,%edx
+ andl $0x7fffffff,%eax
+ orl %edx,%eax
+ movl %eax,4(%esp)
+ flds 4(%esp)
+ ret
+.size copysignf,.-copysignf
+
+libc_hidden_def(copysignf)
+
+.global copysignl
+.type copysignl,%function
+copysignl:
+ movl 24(%esp),%edx
+ movl 12(%esp),%eax
+ andl $0x8000,%edx
+ andl $0x7fff,%eax
+ orl %edx,%eax
+ movl %eax,12(%esp)
+ fldt 4(%esp)
+ ret
+.size copysignl,.-copysignl
+
+libc_hidden_def(copysignl)
+
diff --git a/libc/sysdeps/linux/i386/crt1.S b/libc/sysdeps/linux/i386/crt1.S
index a133cb9e0..35a6552e8 100644
--- a/libc/sysdeps/linux/i386/crt1.S
+++ b/libc/sysdeps/linux/i386/crt1.S
@@ -31,9 +31,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
diff --git a/libc/sysdeps/linux/i386/crtn.S b/libc/sysdeps/linux/i386/crtn.S
index 191250487..34d5b38e2 100644
--- a/libc/sysdeps/linux/i386/crtn.S
+++ b/libc/sysdeps/linux/i386/crtn.S
@@ -6,7 +6,6 @@
popl %ebx
popl %ebp
ret
-.size _init,.-_init
@@ -16,7 +15,6 @@
popl %ebx
popl %ebp
ret
-.size _fini,.-_fini
diff --git a/libc/sysdeps/linux/i386/fpu_control.h b/libc/sysdeps/linux/i386/fpu_control.h
index c6cb005d7..c2a672d29 100644
--- a/libc/sysdeps/linux/i386/fpu_control.h
+++ b/libc/sysdeps/linux/i386/fpu_control.h
@@ -14,9 +14,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H 1
diff --git a/libc/sysdeps/linux/i386/getcontext.S b/libc/sysdeps/linux/i386/getcontext.S
new file mode 100644
index 000000000..3221b597c
--- /dev/null
+++ b/libc/sysdeps/linux/i386/getcontext.S
@@ -0,0 +1,84 @@
+/* Save current context.
+ Copyright (C) 2001-2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__getcontext)
+ /* Load address of the context data structure. */
+ movl 4(%esp), %eax
+
+ /* Return value of getcontext. EAX is the only register whose
+ value is not preserved. */
+ movl $0, oEAX(%eax)
+
+ /* Save the 32-bit register values and the return address. */
+ movl %ecx, oECX(%eax)
+ movl %edx, oEDX(%eax)
+ movl %edi, oEDI(%eax)
+ movl %esi, oESI(%eax)
+ movl %ebp, oEBP(%eax)
+ movl (%esp), %ecx
+ movl %ecx, oEIP(%eax)
+ leal 4(%esp), %ecx /* Exclude the return address. */
+ movl %ecx, oESP(%eax)
+ movl %ebx, oEBX(%eax)
+
+ /* Save the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ xorl %edx, %edx
+ movw %fs, %dx
+ movl %edx, oFS(%eax)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+ leal oFPREGSMEM(%eax), %ecx
+ movl %ecx, oFPREGS(%eax)
+ /* Save the floating-point context. */
+ fnstenv (%ecx)
+ /* And load it right back since the processor changes the mask.
+ Intel thought this opcode to be used in interrupt handlers which
+ would block all exceptions. */
+ fldenv (%ecx)
+
+ /* Save the current signal mask. */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ leal oSIGMASK(%eax), %edx
+ xorl %ecx, %ecx
+ movl $SIG_BLOCK, %ebx
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* All done, return 0 for success. */
+ xorl %eax, %eax
+L(pseudo_end):
+ ret
+PSEUDO_END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/libc/sysdeps/linux/i386/jmpbuf-offsets.h b/libc/sysdeps/linux/i386/jmpbuf-offsets.h
new file mode 100644
index 000000000..47aa49948
--- /dev/null
+++ b/libc/sysdeps/linux/i386/jmpbuf-offsets.h
@@ -0,0 +1,25 @@
+/* Private macros for accessing __jmp_buf contents. i386 version.
+ Copyright (C) 2006 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define JB_BX 0
+#define JB_SI 1
+#define JB_DI 2
+#define JB_BP 3
+#define JB_SP 4
+#define JB_PC 5
+#define JB_SIZE 24
diff --git a/libc/sysdeps/linux/i386/jmpbuf-unwind.h b/libc/sysdeps/linux/i386/jmpbuf-unwind.h
new file mode 100644
index 000000000..4516d9398
--- /dev/null
+++ b/libc/sysdeps/linux/i386/jmpbuf-unwind.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+ containing a local variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+ ((void *) (address) < (void *) (jmpbuf)[JB_SP])
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+#endif
diff --git a/libc/sysdeps/linux/i386/makecontext.S b/libc/sysdeps/linux/i386/makecontext.S
new file mode 100644
index 000000000..d12799d80
--- /dev/null
+++ b/libc/sysdeps/linux/i386/makecontext.S
@@ -0,0 +1,123 @@
+/* Create new context.
+ Copyright (C) 2001,2002,2005,2007,2008,2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__makecontext)
+ movl 4(%esp), %eax
+
+ /* Load the address of the function we are supposed to run. */
+ movl 8(%esp), %ecx
+
+ /* Compute the address of the stack. The information comes from
+ to us_stack element. */
+ movl oSS_SP(%eax), %edx
+ movl %ecx, oEIP(%eax)
+ addl oSS_SIZE(%eax), %edx
+
+ /* Remember the number of parameters for the exit handler since
+ it has to remove them. We store the number in the EBX register
+ which the function we will call must preserve. */
+ movl 12(%esp), %ecx
+ movl %ecx, oEBX(%eax)
+
+ /* Make room on the new stack for the parameters.
+ Room for the arguments, return address (== L(exitcode)) and
+ oLINK pointer is needed. One of the pointer sizes is subtracted
+ after aligning the stack. */
+ negl %ecx
+ leal -4(%edx,%ecx,4), %edx
+ negl %ecx
+
+ /* Align the stack. */
+ andl $0xfffffff0, %edx
+ subl $4, %edx
+
+ /* Store the future stack pointer. */
+ movl %edx, oESP(%eax)
+
+ /* Put the next context on the new stack (from the uc_link
+ element). */
+ movl oLINK(%eax), %eax
+ movl %eax, 4(%edx,%ecx,4)
+
+ /* Copy all the parameters. */
+ jecxz 2f
+1: movl 12(%esp,%ecx,4), %eax
+ movl %eax, (%edx,%ecx,4)
+ decl %ecx
+ jnz 1b
+2:
+
+ /* If the function we call returns we must continue with the
+ context which is given in the uc_link element. To do this
+ set the return address for the function the user provides
+ to a little bit of helper code which does the magic (see
+ below). */
+#ifdef __PIC__
+ call 1f
+ cfi_adjust_cfa_offset (4)
+1: popl %ecx
+ cfi_adjust_cfa_offset (-4)
+ addl $L(exitcode)-1b, %ecx
+ movl %ecx, (%edx)
+#else
+ movl $L(exitcode), (%edx)
+#endif
+ /* 'makecontext' returns no value. */
+L(pseudo_end):
+ ret
+
+ /* This is the helper code which gets called if a function which
+ is registered with 'makecontext' returns. In this case we
+ have to install the context listed in the uc_link element of
+ the context 'makecontext' manipulated at the time of the
+ 'makecontext' call. If the pointer is NULL the process must
+ terminate. */
+ cfi_endproc
+L(exitcode):
+ /* This removes the parameters passed to the function given to
+ 'makecontext' from the stack. EBX contains the number of
+ parameters (see above). */
+ leal (%esp,%ebx,4), %esp
+
+#ifdef __PIC__
+ call 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#endif
+ cmpl $0, (%esp) /* Check the next context. */
+ je 2f /* If it is zero exit. */
+
+ call JUMPTARGET(__setcontext)
+ /* If this returns (which can happen if the syscall fails) we'll
+ exit the program with the return error value (-1). */
+
+ movl %eax, (%esp)
+2: call HIDDEN_JUMPTARGET(exit)
+ /* The 'exit' call should never return. In case it does cause
+ the process to terminate. */
+ hlt
+ cfi_startproc
+END(__makecontext)
+
+weak_alias (__makecontext, makecontext)
diff --git a/libc/sysdeps/linux/i386/mmap.S b/libc/sysdeps/linux/i386/mmap.S
index fe7a7986c..8f9b03243 100644
--- a/libc/sysdeps/linux/i386/mmap.S
+++ b/libc/sysdeps/linux/i386/mmap.S
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#define _ERRNO_H 1
#include <features.h>
diff --git a/libc/sysdeps/linux/i386/mmap64.S b/libc/sysdeps/linux/i386/mmap64.S
index a6b4aa042..2c80ceb01 100644
--- a/libc/sysdeps/linux/i386/mmap64.S
+++ b/libc/sysdeps/linux/i386/mmap64.S
@@ -12,18 +12,16 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+#include <_lfs_64.h>
#define _ERRNO_H 1
-#include <features.h>
#include <bits/errno.h>
#include <sys/syscall.h>
-#if defined __UCLIBC_HAS_LFS__ && defined __NR_mmap2
-
+#ifdef __NR_mmap2
#define LINKAGE 4
#define PTR_SIZE 4
diff --git a/libc/sysdeps/linux/i386/posix_fadvise.c b/libc/sysdeps/linux/i386/posix_fadvise.c
deleted file mode 100644
index 5406213b8..000000000
--- a/libc/sysdeps/linux/i386/posix_fadvise.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * posix_fadvise() for uClibc
- *
- * Copyright (C) 2008 Bernhard Reutner-Fischer <uclibc@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-#include <sys/syscall.h>
-#if defined __USE_GNU
-#include <fcntl.h>
-
-
-#if defined __NR_fadvise64_64 || defined __NR_fadvise64
-libc_hidden_proto(posix_fadvise64)
-libc_hidden_proto(posix_fadvise)
-int posix_fadvise(int fd, off_t offset, off_t len, int advice)
-{
- if (posix_fadvise64(fd, offset, len, advice) != 0)
- return errno;
- return 0;
-}
-libc_hidden_def(posix_fadvise)
-#elif defined __UCLIBC_HAS_STUBS__
-libc_hidden_proto(posix_fadvise)
-int posix_fadvise(int fd attribute_unused, off_t offset attribute_unused,
- off_t len attribute_unused, int advice attribute_unused)
-{
- return ENOSYS;
-}
-libc_hidden_def(posix_fadvise)
-#endif
-#endif
diff --git a/libc/sysdeps/linux/i386/posix_fadvise64.S b/libc/sysdeps/linux/i386/posix_fadvise64.S
index da3f36394..3047b0d05 100644
--- a/libc/sysdeps/linux/i386/posix_fadvise64.S
+++ b/libc/sysdeps/linux/i386/posix_fadvise64.S
@@ -13,20 +13,18 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
-#define _ERRNO_H 1
-#include <features.h>
-#include <bits/errno.h>
+#include <_lfs_64.h>
#include <sys/syscall.h>
+#ifdef __NR_fadvise64_64
+
.text
.global posix_fadvise64
.type posix_fadvise64,%function
posix_fadvise64:
-#if defined __NR_fadvise64_64 && defined __UCLIBC_HAS_LFS__
/* Save regs */
pushl %ebp
pushl %ebx
@@ -35,12 +33,12 @@ posix_fadvise64:
movl $__NR_fadvise64_64, %eax /* Syscall number in %eax. */
- movl 24(%esp), %ebx
- movl 28(%esp), %ecx
- movl 32(%esp), %edx
- movl 36(%esp), %esi
- movl 40(%esp), %edi
- movl 44(%esp), %ebp
+ movl 20(%esp), %ebx
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ movl 32(%esp), %esi
+ movl 36(%esp), %edi
+ movl 40(%esp), %ebp
/* Do the system call trap. */
int $0x80
@@ -51,48 +49,10 @@ posix_fadvise64:
popl %ebx
popl %ebp
- /* If 0 > %eax > -4096 there was an error. */
- cmpl $-4096, %eax
- ja __syscall_error
-#elif defined __NR_fadvise64
- /* Save regs */
- pushl %ebx
- pushl %esi
- pushl %edi
-
- /* does len overflow long? */
- cmpl $0, 40(%esp)
- movl $-EOVERFLOW, %eax
- ja overflow
+ /* Returns 0 on success, else an error code. */
+ negl %eax
- movl $__NR_fadvise64, %eax /* Syscall number in %eax. */
-
- movl 24(%esp), %ebx
- movl 28(%esp), %ecx
- movl 32(%esp), %edx
- movl 36(%esp), %esi
- movl 44(%esp), %edi
-
- /* Do the system call trap. */
- int $0x80
-overflow:
- /* Restore regs */
- popl %edi
- popl %esi
- popl %ebx
-
- /* If 0 > %eax > -4096 there was an error. */
- cmpl $-4096, %eax
- ja __syscall_error
-
-#elif defined __UCLIBC_HAS_STUBS__
- movl $-ENOSYS, %eax
- jmp __syscall_error
-#endif
/* Successful; return the syscall's value. */
ret
-
.size posix_fadvise64,.-posix_fadvise64
-
-libc_hidden_def(posix_fadvise64)
-
+#endif
diff --git a/libc/sysdeps/linux/i386/setcontext.S b/libc/sysdeps/linux/i386/setcontext.S
new file mode 100644
index 000000000..ae953cc6b
--- /dev/null
+++ b/libc/sysdeps/linux/i386/setcontext.S
@@ -0,0 +1,96 @@
+/* Install given context.
+ Copyright (C) 2001-2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__setcontext)
+ /* Load address of the context data structure. */
+ movl 4(%esp), %eax
+
+ /* Get the current signal mask. Note that we preserve EBX in case
+ the system call fails and we return from the function with an
+ error. */
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ xorl %edx, %edx
+ leal oSIGMASK(%eax), %ecx
+ movl $SIG_SETMASK, %ebx
+ cfi_rel_offset (ebx, 0)
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* EAX was modified, reload it. */
+ movl 4(%esp), %eax
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movl oFPREGS(%eax), %ecx
+ fldenv (%ecx)
+
+ /* Restore the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ movl oFS(%eax), %ecx
+ movw %cx, %fs
+
+ /* Fetch the address to return to. */
+ movl oEIP(%eax), %ecx
+
+ /* Load the new stack pointer. */
+ cfi_def_cfa (eax, 0)
+ cfi_offset (edi, oEDI)
+ cfi_offset (esi, oESI)
+ cfi_offset (ebp, oEBP)
+ cfi_offset (ebx, oEBX)
+ cfi_offset (edx, oEDX)
+ cfi_offset (ecx, oECX)
+ movl oESP(%eax), %esp
+
+ /* Push the return address on the new stack so we can return there. */
+ pushl %ecx
+
+ /* Load the values of all the 32-bit registers (except ESP).
+ Since we are loading from EAX, it must be last. */
+ movl oEDI(%eax), %edi
+ movl oESI(%eax), %esi
+ movl oEBP(%eax), %ebp
+ movl oEBX(%eax), %ebx
+ movl oEDX(%eax), %edx
+ movl oECX(%eax), %ecx
+ movl oEAX(%eax), %eax
+
+ /* End FDE here, we fall into another context. */
+ cfi_endproc
+ cfi_startproc
+
+ /* The following 'ret' will pop the address of the code and jump
+ to it. */
+
+L(pseudo_end):
+ ret
+PSEUDO_END(__setcontext)
+
+weak_alias (__setcontext, setcontext)
diff --git a/libc/sysdeps/linux/i386/setjmp.S b/libc/sysdeps/linux/i386/setjmp.S
index 20a6a0bcf..505b85cf5 100644
--- a/libc/sysdeps/linux/i386/setjmp.S
+++ b/libc/sysdeps/linux/i386/setjmp.S
@@ -13,14 +13,8 @@
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. */
-
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
-
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
.global __sigsetjmp
.type __sigsetjmp,%function
diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c
index e8729647f..77da69d5e 100644
--- a/libc/sysdeps/linux/i386/sigaction.c
+++ b/libc/sysdeps/linux/i386/sigaction.c
@@ -13,8 +13,7 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ see <http://www.gnu.org/licenses/>.
Totally hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
*/
@@ -27,111 +26,81 @@
#define SA_RESTORER 0x04000000
-extern __typeof(sigaction) __libc_sigaction;
-
#if defined __NR_rt_sigaction
-/* Experimentally off - libc_hidden_proto(memcpy) */
-extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden;
-extern void restore (void) __asm__ ("__restore") attribute_hidden;
+extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden;
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
-int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- int result;
- struct kernel_sigaction kact, koact;
-
-#ifdef SIGCANCEL
- if (sig == SIGCANCEL) {
- __set_errno (EINVAL);
- return -1;
- }
-#endif
-
- if (act) {
- kact.k_sa_handler = act->sa_handler;
- memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
- kact.sa_flags = act->sa_flags;
-
- kact.sa_flags = act->sa_flags | SA_RESTORER;
- kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
- ? &restore_rt : &restore);
- }
-
- /* XXX The size argument hopefully will have to be changed to the
- real size of the user-level sigset_t. */
- result = __syscall_rt_sigaction(sig, act ? __ptrvalue (&kact) : NULL,
- oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
-
- if (oact && result >= 0) {
- oact->sa_handler = koact.k_sa_handler;
- memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask));
- oact->sa_flags = koact.sa_flags;
- oact->sa_restorer = koact.sa_restorer;
- }
- return result;
+ struct sigaction kact;
+
+ if (act) {
+ memcpy(&kact, act, sizeof(kact));
+ kact.sa_flags |= SA_RESTORER;
+ kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore;
+ act = &kact;
+ }
+ /* NB: kernel (as of 2.6.25) will return EINVAL
+ * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
+ return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
}
-
#else
-extern void restore (void) __asm__ ("__restore") attribute_hidden;
+
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
-int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- int result;
- struct old_kernel_sigaction kact, koact;
-
-#ifdef SIGCANCEL
- if (sig == SIGCANCEL) {
- __set_errno (EINVAL);
- return -1;
- }
-#endif
-
- if (act) {
- kact.k_sa_handler = act->sa_handler;
- kact.sa_mask = act->sa_mask.__val[0];
- kact.sa_flags = act->sa_flags | SA_RESTORER;
- kact.sa_restorer = &restore;
- }
-
- __asm__ __volatile__ ("pushl %%ebx\n"
- "movl %2, %%ebx\n"
- "int $0x80\n"
- "popl %%ebx"
- : "=a" (result)
- : "0" (__NR_sigaction), "mr" (sig),
- "c" (act ? __ptrvalue (&kact) : 0),
- "d" (oact ? __ptrvalue (&koact) : 0));
-
- if (result < 0) {
- __set_errno(-result);
- return -1;
- }
-
- if (oact) {
- oact->sa_handler = koact.k_sa_handler;
- oact->sa_mask.__val[0] = koact.sa_mask;
- oact->sa_flags = koact.sa_flags;
- oact->sa_restorer = koact.sa_restorer;
- }
- return result;
+ int result;
+ struct old_kernel_sigaction kact, koact;
+
+ if (act) {
+ kact.k_sa_handler = act->sa_handler;
+ kact.sa_mask = act->sa_mask.__val[0];
+ kact.sa_flags = act->sa_flags | SA_RESTORER;
+ kact.sa_restorer = &restore;
+ }
+ __asm__ __volatile__ (
+ " pushl %%ebx\n"
+ " movl %3, %%ebx\n"
+ " int $0x80\n"
+ " popl %%ebx\n"
+ : "=a" (result), "=m" (koact)
+ : "0" (__NR_sigaction), "r" (sig), "m" (kact),
+ "c" (act ? &kact : NULL),
+ "d" (oact ? &koact : NULL));
+ if (result < 0) {
+ __set_errno(-result);
+ return -1;
+ }
+ if (oact) {
+ oact->sa_handler = koact.k_sa_handler;
+ oact->sa_mask.__val[0] = koact.sa_mask;
+ oact->sa_flags = koact.sa_flags;
+ oact->sa_restorer = koact.sa_restorer;
+ }
+ return result;
}
#endif
+
#ifndef LIBC_SIGACTION
-libc_hidden_proto(sigaction)
+# ifndef __UCLIBC_HAS_THREADS__
+strong_alias(__libc_sigaction,sigaction)
+libc_hidden_def(sigaction)
+# else
weak_alias(__libc_sigaction,sigaction)
libc_hidden_weak(sigaction)
+# endif
#endif
-
-
/* NOTE: Please think twice before making any changes to the bits of
code below. GDB needs some intimate knowledge about it to
recognize them as signal trampolines, and make backtraces through
@@ -140,33 +109,30 @@ libc_hidden_weak(sigaction)
If you ever feel the need to make any changes, please notify the
appropriate GDB maintainer. */
-#define RESTORE(name, syscall) RESTORE2 (name, syscall)
-#define RESTORE2(name, syscall) \
-__asm__ \
- ( \
- ".text\n" \
- "__" #name ":\n" \
- " movl $" #syscall ", %eax\n" \
- " int $0x80" \
- );
+#define RESTORE(name, syscall) RESTORE2(name, syscall)
#ifdef __NR_rt_sigaction
/* The return code for realtime-signals. */
-RESTORE (restore_rt, __NR_rt_sigreturn)
+# define RESTORE2(name, syscall) \
+__asm__ ( \
+ ".text\n" \
+ "__" #name ":\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80\n" \
+);
+RESTORE(restore_rt, __NR_rt_sigreturn)
#endif
#ifdef __NR_sigreturn
/* For the boring old signals. */
# undef RESTORE2
# define RESTORE2(name, syscall) \
-__asm__ \
- ( \
- ".text\n" \
- "__" #name ":\n" \
- " popl %eax\n" \
- " movl $" #syscall ", %eax\n" \
- " int $0x80" \
- );
-
-RESTORE (restore, __NR_sigreturn)
+__asm__ ( \
+ ".text\n" \
+ "__" #name ":\n" \
+ " popl %eax\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80\n" \
+);
+RESTORE(restore, __NR_sigreturn)
#endif
diff --git a/libc/sysdeps/linux/i386/swapcontext.S b/libc/sysdeps/linux/i386/swapcontext.S
new file mode 100644
index 000000000..ee5d0e4d5
--- /dev/null
+++ b/libc/sysdeps/linux/i386/swapcontext.S
@@ -0,0 +1,110 @@
+/* Save current context and install the given one.
+ Copyright (C) 2001-2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__swapcontext)
+ /* Load address of the context data structure we save in. */
+ movl 4(%esp), %eax
+
+ /* Return value of swapcontext. EAX is the only register whose
+ value is not preserved. */
+ movl $0, oEAX(%eax)
+
+ /* Save the 32-bit register values and the return address. */
+ movl %ecx, oECX(%eax)
+ movl %edx, oEDX(%eax)
+ movl %edi, oEDI(%eax)
+ movl %esi, oESI(%eax)
+ movl %ebp, oEBP(%eax)
+ movl (%esp), %ecx
+ movl %ecx, oEIP(%eax)
+ leal 4(%esp), %ecx
+ movl %ecx, oESP(%eax)
+ movl %ebx, oEBX(%eax)
+
+ /* Save the FS segment register. */
+ xorl %edx, %edx
+ movw %fs, %dx
+ movl %edx, oFS(%eax)
+
+ /* We have separate floating-point register content memory on the
+ stack. We use the __fpregs_mem block in the context. Set the
+ links up correctly. */
+ leal oFPREGSMEM(%eax), %ecx
+ movl %ecx, oFPREGS(%eax)
+ /* Save the floating-point context. */
+ fnstenv (%ecx)
+
+ /* Load address of the context data structure we have to load. */
+ movl 8(%esp), %ecx
+
+ /* Save the current signal mask and install the new one. */
+ pushl %ebx
+ leal oSIGMASK(%eax), %edx
+ leal oSIGMASK(%ecx), %ecx
+ movl $SIG_SETMASK, %ebx
+ movl $__NR_sigprocmask, %eax
+ ENTER_KERNEL
+ popl %ebx
+ cmpl $-4095, %eax /* Check %eax for error. */
+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+
+ /* EAX was modified, reload it. */
+ movl 8(%esp), %eax
+
+ /* Restore the floating-point context. Not the registers, only the
+ rest. */
+ movl oFPREGS(%eax), %ecx
+ fldenv (%ecx)
+
+ /* Restore the FS segment register. We don't touch the GS register
+ since it is used for threads. */
+ movl oFS(%eax), %edx
+ movw %dx, %fs
+
+ /* Fetch the address to return to. */
+ movl oEIP(%eax), %ecx
+
+ /* Load the new stack pointer. */
+ movl oESP(%eax), %esp
+
+ /* Push the return address on the new stack so we can return there. */
+ pushl %ecx
+
+ /* Load the values of all the 32-bit registers (except ESP).
+ Since we are loading from EAX, it must be last. */
+ movl oEDI(%eax), %edi
+ movl oESI(%eax), %esi
+ movl oEBP(%eax), %ebp
+ movl oEBX(%eax), %ebx
+ movl oEDX(%eax), %edx
+ movl oECX(%eax), %ecx
+ movl oEAX(%eax), %eax
+
+ /* The following 'ret' will pop the address of the code and jump
+ to it. */
+L(pseudo_end):
+ ret
+PSEUDO_END(__swapcontext)
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/libc/sysdeps/linux/i386/sync_file_range.S b/libc/sysdeps/linux/i386/sync_file_range.S
index 6cdaf452a..d2cbd5170 100644
--- a/libc/sysdeps/linux/i386/sync_file_range.S
+++ b/libc/sysdeps/linux/i386/sync_file_range.S
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#define _ERRNO_H 1
#include <features.h>
diff --git a/libc/sysdeps/linux/i386/sys/debugreg.h b/libc/sysdeps/linux/i386/sys/debugreg.h
index c99c94359..ac1926b5b 100644
--- a/libc/sysdeps/linux/i386/sys/debugreg.h
+++ b/libc/sysdeps/linux/i386/sys/debugreg.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_DEBUGREG_H
#define _SYS_DEBUGREG_H 1
diff --git a/libc/sysdeps/linux/i386/sys/elf.h b/libc/sysdeps/linux/i386/sys/elf.h
index d959cdca1..9d64e9768 100644
--- a/libc/sysdeps/linux/i386/sys/elf.h
+++ b/libc/sysdeps/linux/i386/sys/elf.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_ELF_H
#define _SYS_ELF_H 1
diff --git a/libc/sysdeps/linux/i386/sys/io.h b/libc/sysdeps/linux/i386/sys/io.h
index 87b99a94a..fa750995c 100644
--- a/libc/sysdeps/linux/i386/sys/io.h
+++ b/libc/sysdeps/linux/i386/sys/io.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_IO_H
#define _SYS_IO_H 1
diff --git a/libc/sysdeps/linux/i386/sys/perm.h b/libc/sysdeps/linux/i386/sys/perm.h
index e389e6679..c26868114 100644
--- a/libc/sysdeps/linux/i386/sys/perm.h
+++ b/libc/sysdeps/linux/i386/sys/perm.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_PERM_H
diff --git a/libc/sysdeps/linux/i386/sys/procfs.h b/libc/sysdeps/linux/i386/sys/procfs.h
index f0be43309..673baa1ec 100644
--- a/libc/sysdeps/linux/i386/sys/procfs.h
+++ b/libc/sysdeps/linux/i386/sys/procfs.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_PROCFS_H
#define _SYS_PROCFS_H 1
diff --git a/libc/sysdeps/linux/i386/sys/reg.h b/libc/sysdeps/linux/i386/sys/reg.h
index 39003c45b..b993f999a 100644
--- a/libc/sysdeps/linux/i386/sys/reg.h
+++ b/libc/sysdeps/linux/i386/sys/reg.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_REG_H
#define _SYS_REG_H 1
diff --git a/libc/sysdeps/linux/i386/sys/ucontext.h b/libc/sysdeps/linux/i386/sys/ucontext.h
index d6474c722..6306623ab 100644
--- a/libc/sysdeps/linux/i386/sys/ucontext.h
+++ b/libc/sysdeps/linux/i386/sys/ucontext.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_UCONTEXT_H
#define _SYS_UCONTEXT_H 1
diff --git a/libc/sysdeps/linux/i386/sys/user.h b/libc/sysdeps/linux/i386/sys/user.h
index c5cfff256..80dd8a23c 100644
--- a/libc/sysdeps/linux/i386/sys/user.h
+++ b/libc/sysdeps/linux/i386/sys/user.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_USER_H
#define _SYS_USER_H 1
diff --git a/libc/sysdeps/linux/i386/sys/vm86.h b/libc/sysdeps/linux/i386/sys/vm86.h
index 8faeed7f1..1f7871bfb 100644
--- a/libc/sysdeps/linux/i386/sys/vm86.h
+++ b/libc/sysdeps/linux/i386/sys/vm86.h
@@ -12,9 +12,8 @@
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. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _SYS_VM86_H
diff --git a/libc/sysdeps/linux/i386/sysdep.h b/libc/sysdeps/linux/i386/sysdep.h
new file mode 100644
index 000000000..c92a10663
--- /dev/null
+++ b/libc/sysdeps/linux/i386/sysdep.h
@@ -0,0 +1,429 @@
+/* Copyright (C) 1992,1993,1995-2000,2002-2006,2007
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINUX_I386_SYSDEP_H
+#define _LINUX_I386_SYSDEP_H 1
+
+#include <sys/syscall.h>
+#include <common/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+/* Define an entry point visible from C.
+
+ There is currently a bug in gdb which prevents us from specifying
+ incomplete stabs information. Fake some entries here which specify
+ the current source file. */
+#define ENTRY(name) \
+ .globl C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(4); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name) \
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a normal frame pointer being on the stack
+ to locate our caller, so push one just for its benefit. */
+#define CALL_MCOUNT \
+ pushl %ebp; cfi_adjust_cfa_offset (4); movl %esp, %ebp; \
+ cfi_def_cfa_register (ebp); call JUMPTARGET(mcount); \
+ popl %ebp; cfi_def_cfa (esp, 4);
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#undef JUMPTARGET
+#ifdef __PIC__
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ pushl %ebx; \
+ cfi_adjust_cfa_offset (4); \
+ call 0f; \
+0: popl %ebx; \
+ cfi_adjust_cfa_offset (-4); \
+ addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx;
+
+
+# define SETUP_PIC_REG(reg) \
+ .ifndef __x86.get_pc_thunk.reg; \
+ .section .gnu.linkonce.t.__x86.get_pc_thunk.reg,"ax",@progbits; \
+ .globl __x86.get_pc_thunk.reg; \
+ .hidden __x86.get_pc_thunk.reg; \
+ .type __x86.get_pc_thunk.reg,@function; \
+__x86.get_pc_thunk.reg: \
+ movl (%esp), %e##reg; \
+ ret; \
+ .size __x86.get_pc_thunk.reg, . - __x86.get_pc_thunk.reg; \
+ .previous; \
+ .endif; \
+ call __x86.get_pc_thunk.reg
+
+# define LOAD_PIC_REG(reg) \
+ SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg
+
+#else
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+#ifdef HAVE_ELF
+#define L(name) .L##name
+#else
+#define L(name) name
+#endif
+#endif
+
+/* Avoid conflics with thunk section */
+#undef __i686
+#endif /* __ASSEMBLER__ */
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+#if defined USE_DL_SYSINFO \
+ && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# define I386_USE_SYSENTER 1
+#else
+# undef I386_USE_SYSENTER
+#endif
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can savely
+ test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+#ifdef __PIC__
+# define SYSCALL_ERROR_LABEL 0f
+#else
+# define SYSCALL_ERROR_LABEL syscall_error
+#endif
+
+#undef PSEUDO
+#define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ cmpl $-4095, %eax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER \
+ END (name)
+
+#undef PSEUDO_NOERRNO
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+#define ret_NOERRNO ret
+
+/* The function has to return the error code. */
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ negl %eax
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+#ifndef __PIC__
+# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
+#else
+
+# ifdef RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG(cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ movl %edx, rtld_errno@GOTOFF(%ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+
+# elif defined _LIBC_REENTRANT
+
+# if defined USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG (cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+# ifndef NO_TLS_DIRECT_SEG_REFS
+# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
+ movl src, %gs:(destoff)
+# else
+# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
+ addl %gs:0, destoff; \
+ movl src, (destoff)
+# endif
+# else
+# define SYSCALL_ERROR_HANDLER \
+0:pushl %ebx; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); \
+ SETUP_PIC_REG (bx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ pushl %edx; \
+ cfi_adjust_cfa_offset (4); \
+ call __errno_location@PLT; \
+ popl %ecx; \
+ cfi_adjust_cfa_offset (-4); \
+ popl %ebx; \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); \
+ movl %ecx, (%eax); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+/* A quick note: it is assumed that the call to `__errno_location' does
+ not modify the stack! */
+# endif
+# else
+/* Store (- %eax) into errno through the GOT. */
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG(cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ movl errno@GOT(%ecx), %ecx; \
+ movl %edx, (%ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
+# endif /* _LIBC_REENTRANT */
+#endif /* __PIC__ */
+
+
+/* The original calling convention for system calls on Linux/i386 is
+ to use int $0x80. */
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
+# else
+# define ENTER_KERNEL call *_dl_sysinfo
+# endif
+#else
+# define ENTER_KERNEL int $0x80
+#endif
+
+/* Linux takes system call arguments in registers:
+
+ syscall number %eax call-clobbered
+ arg 1 %ebx call-saved
+ arg 2 %ecx call-clobbered
+ arg 3 %edx call-clobbered
+ arg 4 %esi call-saved
+ arg 5 %edi call-saved
+ arg 6 %ebp call-saved
+
+ The stack layout upon entering the function is:
+
+ 24(%esp) Arg# 6
+ 20(%esp) Arg# 5
+ 16(%esp) Arg# 4
+ 12(%esp) Arg# 3
+ 8(%esp) Arg# 2
+ 4(%esp) Arg# 1
+ (%esp) Return address
+
+ (Of course a function with say 3 arguments does not have entries for
+ arguments 4, 5, and 6.)
+
+ The following code tries hard to be optimal. A general assumption
+ (which is true according to the data books I have) is that
+
+ 2 * xchg is more expensive than pushl + movl + popl
+
+ Beside this a neat trick is used. The calling conventions for Linux
+ tell that among the registers used for parameters %ecx and %edx need
+ not be saved. Beside this we may clobber this registers even when
+ they are not used for parameter passing.
+
+ As a result one can see below that we save the content of the %ebx
+ register in the %edx register when we have less than 3 arguments
+ (2 * movl is less expensive than pushl + popl).
+
+ Second unlike for the other registers we don't save the content of
+ %ecx and %edx when we have more than 1 and 2 registers resp.
+
+ The code below might look a bit long but we have to take care for
+ the pipelined processors (i586). Here the `pushl' and `popl'
+ instructions are marked as NP (not pairable) but the exception is
+ two consecutive of these instruction. This gives no penalty on
+ other processors though. */
+
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ PUSHARGS_##args \
+ DOARGS_##args \
+ movl $SYS_ify (syscall_name), %eax; \
+ ENTER_KERNEL \
+ POPARGS_##args
+
+#define PUSHARGS_0 /* No arguments to push. */
+#define DOARGS_0 /* No arguments to frob. */
+#define POPARGS_0 /* No arguments to pop. */
+#define _PUSHARGS_0 /* No arguments to push. */
+#define _DOARGS_0(n) /* No arguments to frob. */
+#define _POPARGS_0 /* No arguments to pop. */
+
+#define PUSHARGS_1 movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
+#define DOARGS_1 _DOARGS_1 (4)
+#define POPARGS_1 POPARGS_0; movl %edx, %ebx; L(RESTBX1):
+#define _PUSHARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
+#define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4)
+#define _POPARGS_1 _POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); L(POPBX1):
+
+#define PUSHARGS_2 PUSHARGS_1
+#define DOARGS_2 _DOARGS_2 (8)
+#define POPARGS_2 POPARGS_1
+#define _PUSHARGS_2 _PUSHARGS_1
+#define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4)
+#define _POPARGS_2 _POPARGS_1
+
+#define PUSHARGS_3 _PUSHARGS_2
+#define DOARGS_3 _DOARGS_3 (16)
+#define POPARGS_3 _POPARGS_3
+#define _PUSHARGS_3 _PUSHARGS_2
+#define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4)
+#define _POPARGS_3 _POPARGS_2
+
+#define PUSHARGS_4 _PUSHARGS_4
+#define DOARGS_4 _DOARGS_4 (24)
+#define POPARGS_4 _POPARGS_4
+#define _PUSHARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
+#define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4)
+#define _POPARGS_4 _POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (esi); L(POPSI1):
+
+#define PUSHARGS_5 _PUSHARGS_5
+#define DOARGS_5 _DOARGS_5 (32)
+#define POPARGS_5 _POPARGS_5
+#define _PUSHARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
+#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4)
+#define _POPARGS_5 _POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (edi); L(POPDI1):
+
+#define PUSHARGS_6 _PUSHARGS_6
+#define DOARGS_6 _DOARGS_6 (40)
+#define POPARGS_6 _POPARGS_6
+#define _PUSHARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
+#define _DOARGS_6(n) movl n(%esp), %ebp; _DOARGS_5 (n-4)
+#define _POPARGS_6 _POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebp); L(POPBP1):
+
+#endif /* __ASSEMBLER__ */
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. Using a global variable
+ is too complicated here since we have no PC-relative addressing mode. */
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \
+ roll $9, reg
+# define PTR_DEMANGLE(reg) rorl $9, reg; \
+ xorl %gs:POINTER_GUARD, reg
+# else
+# include <stddef.h>
+# define PTR_MANGLE(var) __asm__ ("xorl %%gs:%c2, %0\n" \
+ "roll $9, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# define PTR_DEMANGLE(var) __asm__ ("rorl $9, %0\n" \
+ "xorl %%gs:%c2, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# endif
+#endif
+
+#endif /* linux/i386/sysdep.h */
diff --git a/libc/sysdeps/linux/i386/ucontext_i.sym b/libc/sysdeps/linux/i386/ucontext_i.sym
new file mode 100644
index 000000000..b11a5509c
--- /dev/null
+++ b/libc/sysdeps/linux/i386/ucontext_i.sym
@@ -0,0 +1,30 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+#define mreg(reg) mcontext (gregs[REG_##reg])
+
+oLINK ucontext (uc_link)
+oSS_SP ucontext (uc_stack.ss_sp)
+oSS_SIZE ucontext (uc_stack.ss_size)
+oGS mreg (GS)
+oFS mreg (FS)
+oEDI mreg (EDI)
+oESI mreg (ESI)
+oEBP mreg (EBP)
+oESP mreg (ESP)
+oEBX mreg (EBX)
+oEDX mreg (EDX)
+oECX mreg (ECX)
+oEAX mreg (EAX)
+oEIP mreg (EIP)
+oFPREGS mcontext (fpregs)
+oSIGMASK ucontext (uc_sigmask)
+oFPREGSMEM ucontext (__fpregs_mem)
diff --git a/libc/sysdeps/linux/i386/vfork.S b/libc/sysdeps/linux/i386/vfork.S
index 8005ff1d2..d85726f19 100644
--- a/libc/sysdeps/linux/i386/vfork.S
+++ b/libc/sysdeps/linux/i386/vfork.S
@@ -18,9 +18,19 @@
__vfork:
popl %ecx
+
+#ifdef SAVE_PID
+ SAVE_PID
+#endif
+
movl $__NR_vfork,%eax
int $0x80
pushl %ecx
+
+#ifdef RESTORE_PID
+ RESTORE_PID
+#endif
+
cmpl $-4095,%eax
jae __syscall_error
ret
@@ -28,4 +38,4 @@ __vfork:
.size __vfork,.-__vfork
weak_alias(__vfork,vfork)
-libc_hidden_weak(vfork)
+libc_hidden_def(vfork)