On Tue, Dec 29, 2015 at 9:18 PM, Alex Potapenko <opotapenko(a)gmail.com> wrote:
>
> I'm unable to get core dump due to system limitations (it's a router):
> I run `ulimit -c unlimited`, yet core dump is never to be found on the
> system after crash :(
Looks like your kernel config simply disables core dumps, just check
that CONFIG_ELF_CORE parameter is set to yes.
> Using gdb, I got this:
>
> #0 0x4004c05c in _dl_debug_state () from /opt/lib/ld-uClibc.so.1
> No symbol table info available.
> #1 0x40050394 in _dl_get_ready_to_run () from /opt/lib/ld-uClibc.so.1
> No symbol table info available.
> #2 0x40050864 in ?? () from /opt/lib/ld-uClibc.so.1
> No symbol table info available.
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
Just gdb notification, non informative.
> I then installed non-stripped uclibc-ng, libffi and openjdk8
> libraries, and got a more informative output (see gdb.log attached).
>
Yes, it is much better (gdb.log):
...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x40ac24d0 (LWP 15709)]
0x4010c804 in initLocalIfs () from /opt/lib/openjdk8/arm/libnet.so
(gdb) bt full
#0 0x4010c804 in initLocalIfs () from /opt/lib/openjdk8/arm/libnet.so
No symbol table info available.
#1 0x4010b3f4 in JNI_OnLoad () from /opt/lib/openjdk8/arm/libnet.so
No symbol table info available.
#2 0x40135de0 in Java_java_lang_ClassLoader_00024NativeLibrary_load
() from /opt/lib/jvm/openjdk8/jre/lib/arm/libjava.so
No symbol table info available.
#3 0x401a433c in ffi_call_SYSV () from /opt/lib/libffi.so.6
No symbol table info available.
#4 0x401a5a54 in ffi_call () from /opt/lib/libffi.so.6
No symbol table info available.
#5 0x404c1640 in CppInterpreter::native_entry(Method*, int, Thread*)
() from /opt/lib/jvm/openjdk8/jre/lib/arm/server/libjvm.so
...
but points inside the OpenJDK native code. I'm found initLocalIfs()
function at jdk/src/solaris/native/java/net/net_util_md.c - very
strange for me, since you are running on linux. Probably, it is due
I'm not familiar with OpenJDK internals.
Anyway, are you able to:
1) update OpenJDK to latest jdk8u76-b01 & uClibc-ng to 1.0.10 ?
2) disable use of IPv6 at all, to exclude any chance of read of
"/proc/net/if_inet6" in initLocalIfs() ?
3) compile only libnet.so with -g3 switch to get a much more of debug info ?
P.S. You forgot to select "Reply all" to allow anyone see your mail in
mailing list
Leonid
Commit e3c3bf2b58 introduce use of pselect6, but has following disadvantages:
* Use of userspace types in args67 structure - it breaks, for example,
configs when 32-bit uClibc-ng compiled against 64-bit kernel. Syscall
will always return EINVAL. We must use __kernel_* types and
__SYSCALL_SIGSET_T_SIZE.
* It have excess checks for NSEC_PER_SEC. Original code from select()
implementation has struct timeval => struct timespec conversion,
kernel select() syscall implementation do the same.
But none of libc versions (glibc, eglibc, musl) I know, perform similar
checks for pselect() - there is no structure fields conversions,
just struct timespec through all the calls.
To have such checks in uClibc-ng we need one example, at least.
* It is possible to avoid extra userspace reads from kernel code if
sigmask == NULL. I suggest to do it, for a few bytes cost.
* Commit didn't add test case to testsuite.
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
---
libc/sysdeps/linux/common/pselect.c | 67 ++++++++++++-------------------------
test/unistd/tst-pselect.c | 51 ++++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 45 deletions(-)
create mode 100644 test/unistd/tst-pselect.c
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index 3f1dd28..fbe85b7 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -31,55 +31,32 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
const sigset_t *sigmask)
{
#ifdef __NR_pselect6
-#define NSEC_PER_SEC 1000000000L
- struct timespec _ts, *ts = 0;
- if (timeout) {
- /* The Linux kernel can in some situations update the timeout value.
- * We do not want that so use a local variable.
- */
+ /* The Linux kernel can in some situations update the timeout value.
+ * We do not want that so use a local variable.
+ */
+ struct timespec _ts;
+
+ if (timeout != NULL) {
_ts = *timeout;
+ timeout = &_ts;
+ }
+ /* Note: the system call expects 7 values but on most architectures
+ we can only pass in 6 directly. If there is an architecture with
+ support for more parameters a new version of this file needs to
+ be created. */
+ struct {
+ __kernel_ulong_t ss;
+ __kernel_size_t ss_len;
+ } data;
- /* GNU extension: allow for timespec values where the sub-sec
- * field is equal to or more than 1 second. The kernel will
- * reject this on us, so take care of the time shift ourself.
- * Some applications (like readline and linphone) do this.
- * See 'clarification on select() type calls and invalid timeouts'
- * on the POSIX general list for more information.
- */
- if (_ts.tv_nsec >= NSEC_PER_SEC) {
- _ts.tv_sec += _ts.tv_nsec / NSEC_PER_SEC;
- _ts.tv_nsec %= NSEC_PER_SEC;
- }
-
- ts = &_ts;
+ if (sigmask != NULL) {
+ data.ss = (__kernel_ulong_t) sigmask;
+ data.ss_len = __SYSCALL_SIGSET_T_SIZE;
+
+ sigmask = (void *)&data;
}
- /* The pselect6 syscall API is strange. It wants a 7th arg to be
- * the sizeof(*sigmask). However syscalls with > 6 arguments aren't
- * supported on linux. So arguments 6 and 7 are stuffed in a struct
- * and a pointer to that struct is passed as the 6th argument to
- * the syscall.
- * Glibc stuffs arguments 6 and 7 in a ulong[2]. Linux reads
- * them as if there were a struct { sigset_t*; size_t } in
- * userspace. There woudl be trouble if userspace and the kernel are
- * compiled differently enough that size_t isn't the same as ulong,
- * but not enough to trigger the compat layer in linux. I can't
- * think of such a case, so I'm using linux's struct.
- * Furthermore Glibc sets the sigsetsize to _NSIG/8. However linux
- * checks for sizeof(sigset_t), which internally is a ulong array.
- * This means that if _NSIG isn't a multiple of BITS_PER_LONG then
- * linux will refuse glibc's value. So I prefer sizeof(sigset_t) for
- * the value of sigsetsize.
- */
- struct {
- const sigset_t *sigmask;
- size_t sigsetsize;
- } args67 = {
- sigmask,
- sizeof(sigset_t),
- };
-
- return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, ts, &args67);
+ return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
#else
struct timeval tval;
int retval;
diff --git a/test/unistd/tst-pselect.c b/test/unistd/tst-pselect.c
new file mode 100644
index 0000000..cab9451
--- /dev/null
+++ b/test/unistd/tst-pselect.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/select.h>
+
+// our SIGALRM handler
+void handler(int signum) {
+ (void)signum;
+ puts("got signal\n");
+}
+
+static int
+do_test (void)
+{
+ int rc;
+ sigset_t wait_mask, mask_sigchld;
+ struct sigaction act;
+
+ // block SIGALRM. We want to handle it only when we're ready
+ sigemptyset(&mask_sigchld);
+ sigaddset(&mask_sigchld, SIGALRM);
+ sigprocmask(SIG_BLOCK, &mask_sigchld, &wait_mask);
+ sigdelset(&wait_mask, SIGALRM);
+
+ // register a signal handler so we can see when the signal arrives
+ memset(&act, 0, sizeof(act));
+ sigemptyset(&act.sa_mask); // just in case an empty set isn't all 0's (total paranoia)
+ act.sa_handler = handler;
+ sigaction(SIGALRM, &act, NULL);
+
+ // send ourselves a SIGARLM. It will pend until we unblock that signal in pselect()
+ printf("sending ourselves a signal\n");
+ kill(getpid(), SIGALRM);
+
+ printf("signal is pending; calling pselect()\n");
+ rc = pselect(0, NULL, NULL, NULL, NULL, &wait_mask);
+ if (rc != -1 || errno != EINTR) {
+ int e = errno;
+ printf("pselect() returned %d, errno %d (%s)\n", rc, e, strerror(e));
+ exit(1);
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
--
1.8.5.6
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The branch, 1.0 has been updated
via a65637cc30455841909b2676599589b702bd654e (commit)
via 382f51ae1cafb977d7a17b9aee62e098396886f3 (commit)
from 0ad73077c230093ae004829da44418597f330c6a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit a65637cc30455841909b2676599589b702bd654e
Author: Waldemar Brodkorb <wbx(a)openadk.org>
Date: Tue Dec 29 15:24:11 2015 +0100
Xtensa is biendian, allow to choose between the modes.
commit 382f51ae1cafb977d7a17b9aee62e098396886f3
Author: Max Filippov <jcmvbkbc(a)gmail.com>
Date: Tue Dec 29 03:13:13 2015 +0300
xtensa: fix vfork return address calculations
vfork internally unwinds stack up one frame, saving the original return
address in the a3 of the unwound frame. To do this in windowed ABI it
needs to exchange two topmost bits of the original return address and of
the helper entry point. Current code doesn't do it correctly for
addresses above 0x40000000, resulting in illegal instruction exception
for configurations that put code high, e.g. for noMMU.
Signed-off-by: Max Filippov <jcmvbkbc(a)gmail.com>
-----------------------------------------------------------------------
Summary of changes:
extra/Configs/Config.xtensa | 1 +
libc/sysdeps/linux/xtensa/vfork.S | 10 ++++++----
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/extra/Configs/Config.xtensa b/extra/Configs/Config.xtensa
index 5448e51..3ee8817 100644
--- a/extra/Configs/Config.xtensa
+++ b/extra/Configs/Config.xtensa
@@ -11,3 +11,4 @@ config FORCE_OPTIONS_FOR_ARCH
bool
default y
select ARCH_HAS_DEPRECATED_SYSCALLS
+ select ARCH_ANY_ENDIAN
diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S
index b8db5c1..8058fb0 100644
--- a/libc/sysdeps/linux/xtensa/vfork.S
+++ b/libc/sysdeps/linux/xtensa/vfork.S
@@ -59,11 +59,13 @@ HIDDEN_ENTRY (__vfork)
movi a0, .Ljumptable
extui a2, a3, 30, 2 # call-size: call4/8/12 = 1/2/3
addx4 a0, a2, a0 # find return address in jumptable
- slli a2, a2, 30
l32i a0, a0, 0
-
- xor a3, a3, a2 # remove call-size from return address
- or a0, a0, a2 # create temporary return address
+ # exchange top 2 bits of a0 and a3:
+ xor a2, a0, a3
+ extui a2, a2, 30, 2
+ slli a2, a2, 30
+ xor a0, a0, a2
+ xor a3, a3, a2
retw
/* a7: return address */
hooks/post-receive
--
uClibc-ng - small C library for embedded systems
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The branch, master has been updated
via 7db56e580823ca91aff186d46eac693b09b9bb0e (commit)
from 49b3d8569a8c8cb724ba6eadb34dea2df9b5ec4d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7db56e580823ca91aff186d46eac693b09b9bb0e
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Mon Dec 28 12:11:16 2015 +0100
remove deprecated architectures v850/i960
Both architectures are more or less deprecated.
No Linux upstream support, no gcc support for uClinux.
-----------------------------------------------------------------------
Summary of changes:
Rules.mak | 12 -
extra/Configs/Config.i960 | 16 --
extra/Configs/Config.in | 16 --
extra/Configs/Config.v850 | 16 --
extra/Configs/defconfigs/i960/defconfig | 1 -
extra/Configs/defconfigs/v850/defconfig | 1 -
include/elf.h | 47 ----
libc/sysdeps/linux/i960/AUTHORS | 4 -
libc/sysdeps/linux/i960/Makefile | 55 -----
libc/sysdeps/linux/i960/README | 71 ------
libc/sysdeps/linux/i960/bits/endian.h | 15 --
libc/sysdeps/linux/i960/bits/fcntl.h | 234 --------------------
libc/sysdeps/linux/i960/bits/setjmp.h | 38 ----
libc/sysdeps/linux/i960/bits/syscalls.h | 15 --
.../sysdeps/linux/i960/bits/uClibc_arch_features.h | 42 ----
libc/sysdeps/linux/i960/bits/wordsize.h | 18 --
libc/sysdeps/linux/i960/clone.S | 61 -----
libc/sysdeps/linux/i960/crt0.S | 57 -----
libc/sysdeps/linux/i960/mmap.S | 51 -----
libc/sysdeps/linux/i960/setjmp.S | 126 -----------
.../i960/specs.uclinux.gcc-2.95.i960-intel-coff | 64 ------
libc/sysdeps/linux/i960/sys/procfs.h | 125 -----------
libc/sysdeps/linux/i960/sys/ucontext.h | 75 -------
libc/sysdeps/linux/i960/vfork.S | 34 ---
libc/sysdeps/linux/sparc/soft-fp/longlong.h | 19 --
libc/sysdeps/linux/v850/Makefile | 64 ------
libc/sysdeps/linux/v850/__longjmp.S | 36 ---
libc/sysdeps/linux/v850/bits/byteswap.h | 31 ---
libc/sysdeps/linux/v850/bits/endian.h | 18 --
libc/sysdeps/linux/v850/bits/fcntl.h | 234 --------------------
libc/sysdeps/linux/v850/bits/kernel_stat.h | 54 -----
libc/sysdeps/linux/v850/bits/kernel_types.h | 55 -----
libc/sysdeps/linux/v850/bits/poll.h | 42 ----
libc/sysdeps/linux/v850/bits/select.h | 64 ------
libc/sysdeps/linux/v850/bits/setjmp.h | 33 ---
libc/sysdeps/linux/v850/bits/sigcontextinfo.h | 17 --
libc/sysdeps/linux/v850/bits/stackinfo.h | 23 --
libc/sysdeps/linux/v850/bits/syscalls.h | 15 --
.../sysdeps/linux/v850/bits/uClibc_arch_features.h | 42 ----
libc/sysdeps/linux/v850/bits/wordsize.h | 18 --
libc/sysdeps/linux/v850/clinkage.h | 14 --
libc/sysdeps/linux/v850/clone.c | 50 -----
libc/sysdeps/linux/v850/crt0.S | 57 -----
libc/sysdeps/linux/v850/crti.S | 27 ---
libc/sysdeps/linux/v850/crtn.S | 22 --
libc/sysdeps/linux/v850/jmpbuf-offsets.h | 6 -
libc/sysdeps/linux/v850/jmpbuf-unwind.h | 11 -
libc/sysdeps/linux/v850/setjmp.S | 44 ----
libc/sysdeps/linux/v850/sys/procfs.h | 135 -----------
libc/sysdeps/linux/v850/sys/ptrace.h | 97 --------
libc/sysdeps/linux/v850/sys/ucontext.h | 40 ----
libc/sysdeps/linux/v850/syscall.c | 43 ----
libc/sysdeps/linux/v850/vfork.S | 36 ---
.../sysdeps/microblaze/sigcontextinfo.h | 2 +-
libpthread/linuxthreads/sysdeps/v850/pt-machine.h | 52 -----
test/Rules.mak | 1 -
utils/ldd.c | 5 -
57 files changed, 1 insertion(+), 2600 deletions(-)
delete mode 100644 extra/Configs/Config.i960
delete mode 100644 extra/Configs/Config.v850
delete mode 100644 extra/Configs/defconfigs/i960/defconfig
delete mode 100644 extra/Configs/defconfigs/v850/defconfig
delete mode 100644 libc/sysdeps/linux/i960/AUTHORS
delete mode 100644 libc/sysdeps/linux/i960/Makefile
delete mode 100644 libc/sysdeps/linux/i960/README
delete mode 100644 libc/sysdeps/linux/i960/bits/endian.h
delete mode 100644 libc/sysdeps/linux/i960/bits/fcntl.h
delete mode 100644 libc/sysdeps/linux/i960/bits/setjmp.h
delete mode 100644 libc/sysdeps/linux/i960/bits/syscalls.h
delete mode 100644 libc/sysdeps/linux/i960/bits/uClibc_arch_features.h
delete mode 100644 libc/sysdeps/linux/i960/bits/wordsize.h
delete mode 100644 libc/sysdeps/linux/i960/clone.S
delete mode 100644 libc/sysdeps/linux/i960/crt0.S
delete mode 100644 libc/sysdeps/linux/i960/mmap.S
delete mode 100644 libc/sysdeps/linux/i960/setjmp.S
delete mode 100644 libc/sysdeps/linux/i960/specs.uclinux.gcc-2.95.i960-intel-coff
delete mode 100644 libc/sysdeps/linux/i960/sys/procfs.h
delete mode 100644 libc/sysdeps/linux/i960/sys/ucontext.h
delete mode 100644 libc/sysdeps/linux/i960/vfork.S
delete mode 100644 libc/sysdeps/linux/v850/Makefile
delete mode 100644 libc/sysdeps/linux/v850/__longjmp.S
delete mode 100644 libc/sysdeps/linux/v850/bits/byteswap.h
delete mode 100644 libc/sysdeps/linux/v850/bits/endian.h
delete mode 100644 libc/sysdeps/linux/v850/bits/fcntl.h
delete mode 100644 libc/sysdeps/linux/v850/bits/kernel_stat.h
delete mode 100644 libc/sysdeps/linux/v850/bits/kernel_types.h
delete mode 100644 libc/sysdeps/linux/v850/bits/poll.h
delete mode 100644 libc/sysdeps/linux/v850/bits/select.h
delete mode 100644 libc/sysdeps/linux/v850/bits/setjmp.h
delete mode 100644 libc/sysdeps/linux/v850/bits/sigcontextinfo.h
delete mode 100644 libc/sysdeps/linux/v850/bits/stackinfo.h
delete mode 100644 libc/sysdeps/linux/v850/bits/syscalls.h
delete mode 100644 libc/sysdeps/linux/v850/bits/uClibc_arch_features.h
delete mode 100644 libc/sysdeps/linux/v850/bits/wordsize.h
delete mode 100644 libc/sysdeps/linux/v850/clinkage.h
delete mode 100644 libc/sysdeps/linux/v850/clone.c
delete mode 100644 libc/sysdeps/linux/v850/crt0.S
delete mode 100644 libc/sysdeps/linux/v850/crti.S
delete mode 100644 libc/sysdeps/linux/v850/crtn.S
delete mode 100644 libc/sysdeps/linux/v850/jmpbuf-offsets.h
delete mode 100644 libc/sysdeps/linux/v850/jmpbuf-unwind.h
delete mode 100644 libc/sysdeps/linux/v850/setjmp.S
delete mode 100644 libc/sysdeps/linux/v850/sys/procfs.h
delete mode 100644 libc/sysdeps/linux/v850/sys/ptrace.h
delete mode 100644 libc/sysdeps/linux/v850/sys/ucontext.h
delete mode 100644 libc/sysdeps/linux/v850/syscall.c
delete mode 100644 libc/sysdeps/linux/v850/vfork.S
delete mode 100644 libpthread/linuxthreads/sysdeps/v850/pt-machine.h
diff --git a/Rules.mak b/Rules.mak
index c609c1d..a6bec7a 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -433,10 +433,6 @@ ifeq ($(TARGET_ARCH),h8300)
CPU_CFLAGS-$(CONFIG_H8S) += -ms -mint32
endif
-ifeq ($(TARGET_ARCH),i960)
- OPTIMIZATION+=-mh -mint32 #-fsigned-char
-endif
-
ifeq ($(TARGET_ARCH),cris)
CPU_LDFLAGS-$(CONFIG_CRIS)+=-Wl,-mcrislinux
CPU_LDFLAGS-$(CONFIG_CRISV32)+=-Wl,-mcrislinux
@@ -494,14 +490,6 @@ ifeq ($(strip $(TARGET_ARCH)),avr32)
CPU_LDFLAGS-$(CONFIG_LINKRELAX) += --relax
endif
-ifeq ($(TARGET_ARCH),i960)
- SYMBOL_PREFIX=_
-endif
-
-ifeq ($(TARGET_ARCH),v850)
- SYMBOL_PREFIX=_
-endif
-
ifeq ($(TARGET_ARCH),c6x)
PIEFLAG:=
CPU_CFLAGS-$(CONFIG_TMS320C64X) += -march=c64x
diff --git a/extra/Configs/Config.i960 b/extra/Configs/Config.i960
deleted file mode 100644
index bf937ab..0000000
--- a/extra/Configs/Config.i960
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see extra/config/Kconfig-language.txt
-#
-
-config TARGET_ARCH
- string
- default "i960"
-
-config FORCE_OPTIONS_FOR_ARCH
- bool
- default y
- select ARCH_LITTLE_ENDIAN
- select ARCH_HAS_NO_MMU
- select HAS_NO_THREADS
- select ARCH_HAS_DEPRECATED_SYSCALLS
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index e8f9e4c..81c2293 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -25,7 +25,6 @@ choice
default TARGET_h8300 if DESIRED_TARGET_ARCH = "h8300"
default TARGET_hppa if DESIRED_TARGET_ARCH = "hppa"
default TARGET_i386 if DESIRED_TARGET_ARCH = "i386"
- default TARGET_i960 if DESIRED_TARGET_ARCH = "i960"
default TARGET_ia64 if DESIRED_TARGET_ARCH = "ia64"
default TARGET_lm32 if DESIRED_TARGET_ARCH = "lm32"
default TARGET_m68k if DESIRED_TARGET_ARCH = "m68k"
@@ -37,7 +36,6 @@ choice
default TARGET_powerpc if DESIRED_TARGET_ARCH = "powerpc"
default TARGET_sh if DESIRED_TARGET_ARCH = "sh"
default TARGET_sparc if DESIRED_TARGET_ARCH = "sparc"
- default TARGET_v850 if DESIRED_TARGET_ARCH = "v850"
default TARGET_x86_64 if DESIRED_TARGET_ARCH = "x86_64"
default TARGET_xtensa if DESIRED_TARGET_ARCH = "xtensa"
help
@@ -78,9 +76,6 @@ config TARGET_hppa
config TARGET_i386
bool "i386"
-config TARGET_i960
- bool "i960"
-
config TARGET_ia64
bool "ia64"
@@ -114,9 +109,6 @@ config TARGET_sh
config TARGET_sparc
bool "sparc"
-config TARGET_v850
- bool "v850"
-
config TARGET_x86_64
bool "x86_64"
@@ -164,10 +156,6 @@ if TARGET_i386
source "extra/Configs/Config.i386"
endif
-if TARGET_i960
-source "extra/Configs/Config.i960"
-endif
-
if TARGET_ia64
source "extra/Configs/Config.ia64"
endif
@@ -212,10 +200,6 @@ if TARGET_sparc
source "extra/Configs/Config.sparc"
endif
-if TARGET_v850
-source "extra/Configs/Config.v850"
-endif
-
if TARGET_x86_64
source "extra/Configs/Config.x86_64"
endif
diff --git a/extra/Configs/Config.v850 b/extra/Configs/Config.v850
deleted file mode 100644
index 82d8be0..0000000
--- a/extra/Configs/Config.v850
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see extra/config/Kconfig-language.txt
-#
-
-config TARGET_ARCH
- string
- default "v850"
-
-config FORCE_OPTIONS_FOR_ARCH
- bool
- default y
- select ARCH_LITTLE_ENDIAN
- select ARCH_HAS_NO_MMU
- select ARCH_HAS_DEPRECATED_SYSCALLS
- select HAVE_NO_PIC
diff --git a/extra/Configs/defconfigs/i960/defconfig b/extra/Configs/defconfigs/i960/defconfig
deleted file mode 100644
index 5abe6dc..0000000
--- a/extra/Configs/defconfigs/i960/defconfig
+++ /dev/null
@@ -1 +0,0 @@
-TARGET_i960=y
diff --git a/extra/Configs/defconfigs/v850/defconfig b/extra/Configs/defconfigs/v850/defconfig
deleted file mode 100644
index 046d5d4..0000000
--- a/extra/Configs/defconfigs/v850/defconfig
+++ /dev/null
@@ -1 +0,0 @@
-TARGET_v850=y
diff --git a/include/elf.h b/include/elf.h
index ed95266..5f47905 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -2821,53 +2821,6 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
#define R_M32R_NUM 256 /* Keep this the last entry. */
-/* i960 Relocations */
-#define R_960_NONE 0
-#define R_960_12 1
-#define R_960_32 2
-#define R_960_IP24 3
-#define R_960_SUB 4
-#define R_960_OPTCALL 5
-#define R_960_OPTCALLX 6
-#define R_960_OPTCALLXA 7
-/* Keep this the last entry. */
-#define R_960_NUM 8
-
-
-/* v850 relocations. */
-#define R_V850_NONE 0
-#define R_V850_9_PCREL 1
-#define R_V850_22_PCREL 2
-#define R_V850_HI16_S 3
-#define R_V850_HI16 4
-#define R_V850_LO16 5
-#define R_V850_32 6
-#define R_V850_16 7
-#define R_V850_8 8
-#define R_V850_SDA_16_16_OFFSET 9 /* For ld.b, st.b, set1, clr1,
- not1, tst1, movea, movhi */
-#define R_V850_SDA_15_16_OFFSET 10 /* For ld.w, ld.h, ld.hu, st.w, st.h */
-#define R_V850_ZDA_16_16_OFFSET 11 /* For ld.b, st.b, set1, clr1,
- not1, tst1, movea, movhi */
-#define R_V850_ZDA_15_16_OFFSET 12 /* For ld.w, ld.h, ld.hu, st.w, st.h */
-#define R_V850_TDA_6_8_OFFSET 13 /* For sst.w, sld.w */
-#define R_V850_TDA_7_8_OFFSET 14 /* For sst.h, sld.h */
-#define R_V850_TDA_7_7_OFFSET 15 /* For sst.b, sld.b */
-#define R_V850_TDA_16_16_OFFSET 16 /* For set1, clr1, not1, tst1,
- movea, movhi */
-/* CYGNUS LOCAL v850e */
-#define R_V850_TDA_4_5_OFFSET 17 /* For sld.hu */
-#define R_V850_TDA_4_4_OFFSET 18 /* For sld.bu */
-#define R_V850_SDA_16_16_SPLIT_OFFSET 19 /* For ld.bu */
-#define R_V850_ZDA_16_16_SPLIT_OFFSET 20 /* For ld.bu */
-#define R_V850_CALLT_6_7_OFFSET 21 /* For callt */
-#define R_V850_CALLT_16_16_OFFSET 22 /* For callt */
-/* END CYGNUS LOCAL */
-#define R_V850_GNU_VTINHERIT 23
-#define R_V850_GNU_VTENTRY 24
-/* Keep this the last entry. */
-#define R_V850_NUM 25
-
/* Atmel AVR32 relocations. */
#define R_AVR32_NONE 0
#define R_AVR32_32 1
diff --git a/libc/sysdeps/linux/i960/AUTHORS b/libc/sysdeps/linux/i960/AUTHORS
deleted file mode 100644
index 0d65549..0000000
--- a/libc/sysdeps/linux/i960/AUTHORS
+++ /dev/null
@@ -1,4 +0,0 @@
-The initial support (inspired by what was done in an old i960 port of uC-libc):
-
-Martin Proulx <mproulx at okiok.com>
-http://www.okiok.com
diff --git a/libc/sysdeps/linux/i960/Makefile b/libc/sysdeps/linux/i960/Makefile
deleted file mode 100644
index d6ae358..0000000
--- a/libc/sysdeps/linux/i960/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# Makefile for uClibc
-#
-# Copyright (C) 2000-2006 Erik Andersen <andersen(a)uclibc.org>
-#
-# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-
-TOPDIR=../../../../
-include $(TOPDIR)Rules.mak
-
-#FIXME -- this arch should include its own crti.S and crtn.S
-UCLIBC_CTOR_DTOR=n
-
-CRT_SRC := crt0.S
-CRT_OBJ := crt0.o crt1.o
-CTOR_TARGETS := $(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
-
-SSRC := clone.S _mmap.S setjmp.S vfork.S
-SOBJ := $(patsubst %.S,%.o, $(SSRC))
-
-OBJS := $(SOBJ)
-
-OBJ_LIST := ../../../obj.sysdeps.$(TARGET_ARCH)
-
-all: $(OBJ_LIST) $(CTOR_TARGETS)
-
-$(OBJ_LIST): $(OBJS) $(CRT_OBJ)
- $(STRIPTOOL) -x -R .note -R .comment $^
- $(INSTALL) -d $(TOPDIR)lib/
- cp $(CRT_OBJ) $(TOPDIR)lib/
- echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $@
-
-$(CRT_OBJ): $(CRT_SRC)
- $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
-
-$(SOBJ): %.o : %.S
- $(CC) $(ASFLAGS) -c $< -o $@
-
-ifeq ($(UCLIBC_CTOR_DTOR),y)
-$(TOPDIR)lib/crti.o: crti.S
- $(INSTALL) -d $(TOPDIR)lib/
- $(CC) $(ASFLAGS) $(SSP_DISABLE_FLAGS) -c $< -o $@
-
-$(TOPDIR)lib/crtn.o: crtn.S
- $(INSTALL) -d $(TOPDIR)lib/
- $(CC) $(ASFLAGS) $(SSP_DISABLE_FLAGS) -c $< -o $@
-else
-$(CTOR_TARGETS):
- $(INSTALL) -d $(TOPDIR)lib/
- $(AR) $(ARFLAGS) $@
-endif
-
-headers:
-
-clean:
- $(RM) *.o *~ core
diff --git a/libc/sysdeps/linux/i960/README b/libc/sysdeps/linux/i960/README
deleted file mode 100644
index 7516735..0000000
--- a/libc/sysdeps/linux/i960/README
+++ /dev/null
@@ -1,71 +0,0 @@
-Overview
----------------------------------------------------------------------------
-
-This is the README file for the i960 support in uClibc.
-
-This has been tested with gcc 2.95.3 and i960-intel-coff target.
-
-There is no support at all to compile with the intel CTOOLS, as this would
-have required too many changes to uClibc. So you won't see any support
-in the asm files for position independent data or code.
-
-Quirks needed
----------------------------------------------------------------------------
-
-prepended underscore
---------------------
-
-As the i960 compiler prepends an underscore to symbols, it is critical that
-Rules.mak defines SYMBOL_PREFIX as _, such that -D__UCLIBC_UNDERSCORES__
-is added to CFLAGS to make sure that underscores are applied to symbol
-names when needed.
-
-
-__va_copy in va-i960.h
-----------------------
-
-When compiled with gcc-2.95, the __va_copy macro in va-i960.h seems to be broken
-and it has to be modified in order for uClibc to compile correctly.
-
-Change:
-
-#define __va_copy(dest, src) (dest) = (src)
-
-To:
-
-#define __va_copy(dest, src) dest[0] = src[0]; dest[1] = src[1]
-
-
-gcc integration
----------------------------------------------------------------------------
-
-I've preferred modifying the specs file so that the i960-intel-coff compiler
-directly compiles with uClibc.
-
-First, compile and install the standard i960-intel-coff compiler, which is meant
-to be used with newlib.
-
-Then, compile uClibc, installing over the newlib include files and libraries.
-
-Update the specs file with the included specs.uclinux.gcc-2.95.i960-intel-coff
-
-This specs file always build relocatable objects, which has the disadvantage
-of not letting you know if the link is missing any symbols.
-
-coff2flt
----------------------------------------------------------------------------
-
-In order to run the executables under uClinux, fully relocatable binaries
-need to be built using coff2flt.
-
-We have built a working coff2flt that works with the i960 and the current version
-of binfmt_flat with uClinux.
-
-Contact Martin Proulx <mproulx at okiok.com> for further informations.
-
-
-
-
-
-Check:
- _mmap.S: besoin???
diff --git a/libc/sysdeps/linux/i960/bits/endian.h b/libc/sysdeps/linux/i960/bits/endian.h
deleted file mode 100644
index e2b1316..0000000
--- a/libc/sysdeps/linux/i960/bits/endian.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This file should define __BYTE_ORDER as appropriate for the machine
- in question. See string/endian.h for how to define it.
-
- If only the stub bits/endian.h applies to a particular configuration,
- bytesex.h is generated by running a program on the host machine.
- So if cross-compiling to a machine with a different byte order,
- the bits/endian.h file for that machine must exist. */
-
-#ifndef _ENDIAN_H
-# error "Never use <bits/endian.h> directly; include <endian.h> instead."
-#endif
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-
diff --git a/libc/sysdeps/linux/i960/bits/fcntl.h b/libc/sysdeps/linux/i960/bits/fcntl.h
deleted file mode 100644
index f6e145d..0000000
--- a/libc/sysdeps/linux/i960/bits/fcntl.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _FCNTL_H
-# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
-#endif
-
-
-#include <sys/types.h>
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define O_FSYNC O_SYNC
-#define O_ASYNC 020000
-
-#ifdef __USE_GNU
-# define O_DIRECT 040000 /* Direct disk access. */
-# define O_DIRECTORY 0200000 /* Must be a directory. */
-# define O_NOFOLLOW 0400000 /* Do not follow links. */
-#endif
-
-/* For now Linux has synchronisity options for data and read operations.
- We define the symbols here but let them do the same as O_SYNC since
- this is a superset. */
-#if defined __USE_POSIX199309 || defined __USE_UNIX98
-# define O_DSYNC O_SYNC /* Synchronize data. */
-# define O_RSYNC O_SYNC /* Synchronize read operations. */
-#endif
-
-#ifdef __USE_LARGEFILE64
-# define O_LARGEFILE 0100000
-#endif
-
-/* Values for the second argument to `fcntl'. */
-#define F_DUPFD 0 /* Duplicate file descriptor. */
-#define F_GETFD 1 /* Get file descriptor flags. */
-#define F_SETFD 2 /* Set file descriptor flags. */
-#define F_GETFL 3 /* Get file status flags. */
-#define F_SETFL 4 /* Set file status flags. */
-#ifndef __USE_FILE_OFFSET64
-# define F_GETLK 5 /* Get record locking info. */
-# define F_SETLK 6 /* Set record locking info (non-blocking). */
-# define F_SETLKW 7 /* Set record locking info (blocking). */
-#else
-# define F_GETLK F_GETLK64 /* Get record locking info. */
-# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
-# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
-#endif
-#define F_GETLK64 12 /* Get record locking info. */
-#define F_SETLK64 13 /* Set record locking info (non-blocking). */
-#define F_SETLKW64 14 /* Set record locking info (blocking). */
-
-#if defined __USE_BSD || defined __USE_XOPEN2K
-# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
-# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
-#endif
-
-#ifdef __USE_GNU
-# define F_SETSIG 10 /* Set number of signal to be sent. */
-# define F_GETSIG 11 /* Get number of signal to be sent. */
-#endif
-
-#ifdef __USE_GNU
-# define F_SETLEASE 1024 /* Set a lease. */
-# define F_GETLEASE 1025 /* Enquire what lease is active. */
-# 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]FL. */
-#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
-
-/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
-#define F_RDLCK 0 /* Read lock. */
-#define F_WRLCK 1 /* Write lock. */
-#define F_UNLCK 2 /* Remove lock. */
-
-/* For old implementation of bsd flock(). */
-#define F_EXLCK 4 /* or 3 */
-#define F_SHLCK 8 /* or 4 */
-
-#ifdef __USE_BSD
-/* Operations for bsd flock(), also used by the kernel implementation. */
-# define LOCK_SH 1 /* shared lock */
-# define LOCK_EX 2 /* exclusive lock */
-# define LOCK_NB 4 /* or'd with one of the above to prevent
- blocking */
-# define LOCK_UN 8 /* remove lock */
-#endif
-
-#ifdef __USE_GNU
-# define LOCK_MAND 32 /* This is a mandatory flock: */
-# define LOCK_READ 64 /* ... which allows concurrent read operations. */
-# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
-# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
-#endif
-
-#ifdef __USE_GNU
-/* Types of directory notifications that may be requested with F_NOTIFY. */
-# define DN_ACCESS 0x00000001 /* File accessed. */
-# define DN_MODIFY 0x00000002 /* File modified. */
-# define DN_CREATE 0x00000004 /* File created. */
-# define DN_DELETE 0x00000008 /* File removed. */
-# define DN_RENAME 0x00000010 /* File renamed. */
-# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
-# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
-#endif
-
-struct flock
- {
- short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
- short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
-#ifndef __USE_FILE_OFFSET64
- __off_t l_start; /* Offset where the lock begins. */
- __off_t l_len; /* Size of the locked area; zero means until EOF. */
-#else
- __off64_t l_start; /* Offset where the lock begins. */
- __off64_t l_len; /* Size of the locked area; zero means until EOF. */
-#endif
- __pid_t l_pid; /* Process holding the lock. */
- };
-
-#ifdef __USE_LARGEFILE64
-struct flock64
- {
- short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
- short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
- __off64_t l_start; /* Offset where the lock begins. */
- __off64_t l_len; /* Size of the locked area; zero means until EOF. */
- __pid_t l_pid; /* Process holding the lock. */
- };
-#endif
-
-/* Define some more compatibility macros to be backward compatible with
- BSD systems which did not managed to hide these kernel macros. */
-#ifdef __USE_BSD
-# define FAPPEND O_APPEND
-# define FFSYNC O_FSYNC
-# define FASYNC O_ASYNC
-# define FNONBLOCK O_NONBLOCK
-# define FNDELAY O_NDELAY
-#endif /* Use BSD. */
-
-/* Advise to `posix_fadvise'. */
-#ifdef __USE_XOPEN2K
-# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
-# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
-#endif
-
-
-#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
- write. */
-# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
- dirty pages in the range which are
- not presently under writeback. */
-# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
- the range after performing the
- write. */
-
-/* Flags for SPLICE and VMSPLICE. */
-# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
-# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
- (but we may still block on the fd
- we splice from/to). */
-# define SPLICE_F_MORE 4 /* Expect more data. */
-# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
-#endif
-
-__BEGIN_DECLS
-
-#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)
- __THROW;
-
-
-/* Selective file content synch'ing. */
-extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
- unsigned int __flags);
-
-/* Splice address range into a pipe. */
-extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
- size_t __count, unsigned int __flags);
-
-/* Splice two files together. */
-extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
- __off64_t *__offout, size_t __len,
- unsigned int __flags);
-
-/* In-kernel implementation of tee for pipe buffers. */
-extern ssize_t tee (int __fdin, int __fdout, size_t __len,
- unsigned int __flags);
-
-#endif
-__END_DECLS
-
diff --git a/libc/sysdeps/linux/i960/bits/setjmp.h b/libc/sysdeps/linux/i960/bits/setjmp.h
deleted file mode 100644
index f90e4ce..0000000
--- a/libc/sysdeps/linux/i960/bits/setjmp.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Define the machine-dependent type `jmp_buf'. i960 version. */
-
-#ifndef _BITS_SETJMP_H
-#define _BITS_SETJMP_H 1
-
-#if !defined _SETJMP_H && !defined _PTHREAD_H
-# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
-#endif
-
-/*
- * assume that every single local and global register
- * must be saved.
- *
- * ___SAVEREGS is the number of quads to save.
- *
- * Using the structure will guarantee quad-word alignment for the
- * jmp_buf type.
- */
-
-#define ___SAVEREGS 8
-
-typedef struct __jmp_buf__ {
- long _q0;
- long _q1;
- long _q2;
- long _q3;
-} __attribute__ ((aligned (16))) __jmp_buf[___SAVEREGS] ;
-
-/* I have not yet figured out what this should be for the i960... */
-
-#if 0
-/* Test if longjmp to JMPBUF would unwind the frame
- containing a local variable at ADDRESS. */
-#define _JMPBUF_UNWINDS(jmpbuf, address) \
- ((void *) (address) < (void *) (jmpbuf)[0].__sp)
-#endif
-
-#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/i960/bits/syscalls.h b/libc/sysdeps/linux/i960/bits/syscalls.h
deleted file mode 100644
index b218513..0000000
--- a/libc/sysdeps/linux/i960/bits/syscalls.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _BITS_SYSCALLS_H
-#define _BITS_SYSCALLS_H
-#ifndef _SYSCALL_H
-# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
-#endif
-
-#include <features.h>
-
-/* Do something very evil for now. Until we create our own syscall
- * macros, short circuit bits/sysnum.h and use asm/unistd.h instead */
-#warning "fixme -- add arch specific syscall macros.h"
-#include <asm/unistd.h>
-
-#endif /* _BITS_SYSCALLS_H */
-
diff --git a/libc/sysdeps/linux/i960/bits/uClibc_arch_features.h b/libc/sysdeps/linux/i960/bits/uClibc_arch_features.h
deleted file mode 100644
index a13ed37..0000000
--- a/libc/sysdeps/linux/i960/bits/uClibc_arch_features.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Track misc arch-specific features that aren't config options
- */
-
-#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
-#define _BITS_UCLIBC_ARCH_FEATURES_H
-
-/* instruction used when calling abort() to kill yourself */
-/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/
-#undef __UCLIBC_ABORT_INSTRUCTION__
-
-/* can your target use syscall6() for mmap ? */
-#undef __UCLIBC_MMAP_HAS_6_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__
-
-/* does your target have to worry about older [gs]etrlimit() ? */
-#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
-
-/* does your target have an asm .set ? */
-#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
-
-/* define if target supports .weak */
-#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
-
-/* define if target supports .weakext */
-#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
-
-/* define if target supports CFI pseudo ops */
-#undef __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__
-
-#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/i960/bits/wordsize.h b/libc/sysdeps/linux/i960/bits/wordsize.h
deleted file mode 100644
index ca82fd7..0000000
--- a/libc/sysdeps/linux/i960/bits/wordsize.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (C) 1999 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 __WORDSIZE 32
diff --git a/libc/sysdeps/linux/i960/clone.S b/libc/sysdeps/linux/i960/clone.S
deleted file mode 100644
index 9419f28..0000000
--- a/libc/sysdeps/linux/i960/clone.S
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# clone.S, part of the i960 support for the uClibc library.
-#
-# Copyright (C) 2002 by Okiok Data Ltd. http://www.okiok.com/
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Library General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program 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 Library General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# Derived from an old port of uC-libc to the i960 by Keith Adams (kma(a)cse.ogi.edu).
-#
-
-#include <sys/syscall.h>
-#include <bits/errno.h>
-
-/* clone is even more special than fork as it mucks with stacks
- and invokes a function in the right context after its all over. */
-
-/* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
-
- .globl clone
-clone:
- /* set up new stack image in regs r4-r7; argument will be in r3 in child. */
- ldconst 0, r4 /* pfp == 0 */
- addo 16, g1, r5 /* sp == newfp + 16 */
- mov g0, r6 /* rip == fnc */
- mov g2, r7
- stq r4, (g1)
-
- addo sp, 4, sp
- st g10, -4(sp)
- mov sp, g10
- ldconst __NR_clone, g13
- calls 0
-
- /* Do the system call */
- cmpibg 0, g0, __syscall_error /* if < 0, error */
- be thread_start /* if == 0, we're the child */
- ret /* we're the parent */
-
-__syscall_error:
- not g0, r3
- callx ___errno_location
- st r3, (g0)
- ret
-
-thread_start:
- # our new pfp is in g1; here we go
- flushreg
- mov g1, pfp
- flushreg
- ret
diff --git a/libc/sysdeps/linux/i960/crt0.S b/libc/sysdeps/linux/i960/crt0.S
deleted file mode 100644
index 48a08dd..0000000
--- a/libc/sysdeps/linux/i960/crt0.S
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# crt0.S, part of the i960 support for the uClibc library.
-#
-# Copyright (C) 2002 by Okiok Data Ltd. http://www.okiok.com/
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Library General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program 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 Library General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-
-/*
- *
- * The behavior in this file is tightly coupled with how the linux kernel sets things up
- * on the stack before calling us.
- *
- * Currently fs/binfmt_flat.c (for STACK_GROWS_UP) and arch/i960/kernel/process.c
- * build things so that a pointer to argc is left in g13 by start_thread().
- *
- * ^
- * | <- sp somewhere around here, after being aligned.
- * |
- * |envp -> envp[0]
- * |argv -> argv[0]
- * |argc <- g13
- *
- * A complete picture of how things are set up can be seen in the comments of
- * create_flat_tables_stack_grows_up in fs/binfmt_flat.c
- *
- * I believe having to use this register could probably be avoided.
- *
- */
-
- .globl start
-start:
- mov g13, r3
- ldt (r3), g0
- callx ___uClibc_main
-
-/* We might want to add some instruction so that it crashes if main returns */
-
-/* Define a symbol for the first piece of initialized data. */
- .data
- .globl __data_start
-__data_start:
- .long 0
- .weak data_start
- data_start = __data_start
-
diff --git a/libc/sysdeps/linux/i960/mmap.S b/libc/sysdeps/linux/i960/mmap.S
deleted file mode 100644
index 63a2843..0000000
--- a/libc/sysdeps/linux/i960/mmap.S
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# __mmap.S, part of the i960 support for the uClibc library.
-#
-# Copyright (C) 2002 by Okiok Data Ltd. http://www.okiok.com/
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU Library General Public License as published by the Free
-# Software Foundation; either version 2 of the License, or (at your option) any
-# later version.
-#
-# This program 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 Library General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Library General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# Derived from an old port of uC-libc to the i960 by Keith Adams (kma(a)cse.ogi.edu).
-#
-
-#include <sys/syscall.h>
-
-/* This is a plain system call. The 6 arguments are already set up correctly */
-/* void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset) */
-
-
- .globl _mmap
-_mmap:
- mov g13, r3
- ldconst __NR_mmap, g13
- calls 0
- mov r3, g13
-
- /* We now need to check if the return value is a small negative integer. */
- /* This is somewhat tricky as the return code (normally an address) is an */
- /* unsigned type, or an ordinal in i960 assembler. */
- /* We'll use the fact that, integers from -256 to -1 are ordinals 0xFFFFFF00 to 0xFFFFFFFF. */
- /* So by checking that the return address is in the top range of the ordinals, we'll */
- /* in fact be checking if it's not an encoded negated erro code. */
-
- /* The range -256 to -1 should be enough since that in uClinux 2.0.39, there are */
- /* 124 system calls for the i960. */
-
- ldconst 0xFFFFFF00, r3 /* This is the integer's -256 representation */
- cmpobl g0, r3, 1f /* Something smaller than this means it's out of the range, and a valid address */
- subi g0, 0, r3 /* If it's an errno, save its negated (now positive) value in _errno. */
- st r3, _errno
- subi 1, 0, g0 /* And return -1. */
-1:
- ret
diff --git a/libc/sysdeps/linux/i960/setjmp.S b/libc/sysdeps/linux/i960/setjmp.S
deleted file mode 100644
index 2525f55..0000000
--- a/libc/sysdeps/linux/i960/setjmp.S
+++ /dev/null
@@ -1,126 +0,0 @@
-/*******************************************************************************
- *
- * Copyright (c) 1993 Intel Corporation
- *
- * Intel hereby grants you permission to copy, modify, and distribute this
- * software and its documentation. Intel grants this permission provided
- * that the above copyright notice appears in all copies and that both the
- * copyright notice and this permission notice appear in supporting
- * documentation. In addition, Intel grants this permission provided that
- * you prominently mark as "not part of the original" any modifications
- * made to this software or documentation, and that the name of Intel
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software or the documentation without specific,
- * written prior permission.
- *
- * Intel Corporation provides this AS IS, WITHOUT ANY WARRANTY, EXPRESS OR
- * IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY
- * OR FITNESS FOR A PARTICULAR PURPOSE. Intel makes no guarantee or
- * representations regarding the use of, or the results of the use of,
- * the software and documentation in terms of correctness, accuracy,
- * reliability, currentness, or otherwise; and you rely on the software,
- * documentation and results solely at your own risk.
- *
- * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
- * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
- * OF ANY KIND. IN NO EVENT SHALL INTEL'S TOTAL LIABILITY EXCEED THE SUM
- * PAID TO INTEL FOR THE PRODUCT LICENSED HEREUNDER.
- *
- ******************************************************************************/
-
-/***************************************************************************
- *
- * Modified from the original in order to fit with
- * uClibc's setjmp, _setjmp, __sigsetjmp and ___sigjmp_save.
- *
- *
- * int setjmp (jmp_buf __env) is the BSD style setjmp function.
- * It simply calls __sigsetjmp(env, 1)
- *
- * int _setjmp (jmp_buf __env) is the posix style setjmp function.
- * It simply calls __sigsetjmp(env, 0)
- * This is the one normally used.
- *
- ***************************************************************************/
-
- .text
- .align 4
- .globl _setjmp
- .globl __setjmp
-
-_setjmp:
- mov 1, g1 /* __sigsetjmp(env, 1) */
- bx __sigsetjmp
-
-__setjmp:
- mov 0, g1 /* __sigsetjmp(env, 0) */
- bx __sigsetjmp
-
-
-/******************************************************************************/
-/* */
-/* setjmp(), longjmp() */
-/* */
-/******************************************************************************/
- .file "setjmp.S"
- .text
- /* .link_pix */
-
- .align 4
- .globl __sigsetjmp
-__sigsetjmp:
- flushreg
- andnot 0xf,pfp,g2 /* get pfp, mask out return status bits */
- st g2, 0x58(g0) /* save fp of caller*/
- /* save globals not killed by the calling convention */
- stq g8, 0x40(g0) /* save g8-g11*/
- st g12, 0x50(g0) /* save g12*/
- st g14, 0x54(g0) /* save g14*/
- /* save previous frame local registers */
- ldq (g2), g4 /* get previous frame pfp, sp, rip, r3 */
- stq g4, (g0) /* save pfp, sp, rip, r3 */
- ldq 0x10(g2), g4 /* get previous frame r4-r7 */
- stq g4, 0x10(g0) /* save r4-r7 */
- ldq 0x20(g2), g4 /* get previous frame r8-r11 */
- stq g4, 0x20(g0) /* save r8-r11 */
- ldq 0x30(g2), g4 /* get previous frame r12-r15 */
- stq g4, 0x30(g0) /* save r12-r15 */
-
- bx ___sigjmp_save
-
- /*
- * fake a return to the place that called the corresponding __sigsetjmp
- */
- .align 4
- .globl ___longjmp
-___longjmp:
- call 0f /* ensure there is at least one stack frame */
-
-0:
- flushreg /* do this before swapping stack */
- ld 0x58(g0), pfp /* get fp of caller of setjmp */
- /* restore local registers
- * the following code modifies the frame of the function which originally
- * called setjmp.
- */
- ldq (g0), g4 /* get pfp, sp, rip, r3 */
- stq g4, (pfp) /* restore pfp, sp, rip, r3 */
- ldq 0x10(g0), g4 /* get r4-r7 */
- stq g4, 0x10(pfp) /* restore r4-r7 */
- ldq 0x20(g0), g4 /* get r8-r11 */
- stq g4, 0x20(pfp) /* restore r8-r11 */
- ldq 0x30(g0), g4 /* get r12-r15 */
- stq g4, 0x30(pfp) /* restore r12-r15 */
- /* restore global registers */
- ldq 0x40(g0), g8 /* get old g8-g11 values */
- ld 0x50(g0), g12 /* get old g12 value */
- ld 0x54(g0), g14 /* get old g14 value */
-
- mov g1, g0 /* get return value */
- cmpo g0, 0 /* make sure it is not zero */
- bne 0f
- mov 1, g0 /* return 1 by default */
-0:
- ret /* return to caller of __sigsetjmp */
-
-libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/i960/specs.uclinux.gcc-2.95.i960-intel-coff b/libc/sysdeps/linux/i960/specs.uclinux.gcc-2.95.i960-intel-coff
deleted file mode 100644
index cefd853..0000000
--- a/libc/sysdeps/linux/i960/specs.uclinux.gcc-2.95.i960-intel-coff
+++ /dev/null
@@ -1,64 +0,0 @@
-*asm:
-%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB} %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF} %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX} %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-AKB}}}}}}}}}}}} %{mlink-relax:-linkrelax}
-
-*asm_final:
-
-
-*cpp:
-%{mic*:-D__i960 %{mka:-D__i960KA}%{mkb:-D__i960KB} %{mja:-D__i960JA}%{mjd:-D__i960JD}%{mjf:-D__i960JF} %{mrp:-D__i960RP} %{msa:-D__i960SA}%{msb:-D__i960SB} %{mmc:-D__i960MC} %{mca:-D__i960CA}%{mcc:-D__i960CC} %{mcf:-D__i960CF}} %{mka:-D__i960KA__ -D__i960_KA__} %{mkb:-D__i960KB__ -D__i960_KB__} %{msa:-D__i960SA__ -D__i960_SA__} %{msb:-D__i960SB__ -D__i960_SB__} %{mmc:-D__i960MC__ -D__i960_MC__} %{mca:-D__i960CA__ -D__i960_CA__} %{mcc:-D__i960CC__ -D__i960_CC__} %{mcf:-D__i960CF__ -D__i960_CF__} %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca: %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}} %{mlong-double-64:-D__LONG_DOUBLE_64__}
-
-*cc1:
-%{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-mka}}}}}}}}}}}} %{!gs*:%{!gc*:%{mbout:%{g*:-gstabs}} %{mcoff:%{g*:-gcoff}} %{!mbout:%{!mcoff:%{g*:-gstabs}}}}}
-
-*cc1plus:
-
-
-*endfile:
-crtn.o%s
-
-*link:
-%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB} %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF} %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX} %{mbout:-Fbout}%{mcoff:-Fcoff} %{mlink-relax:-relax} -r -d
-
-*lib:
--lc -lgcc
-
-*libgcc:
-
-
-*startfile:
-%{!shared:%{pg:pgcrt0%O%s}%{!pg:%{p:pcrt0%O%s}%{!p:crt0%O%s}}} crti.o%s
-
-*switches_need_spaces:
-
-
-*signed_char:
-%{!fsigned-char:%{!mic*:-D__CHAR_UNSIGNED__}}
-
-*predefines:
--Di960 -Di80960 -DI960 -DI80960 -Acpu(i960) -Amachine(i960) -Dunix -Dlinux -Asystem(posix) -D__linux__ -D__uClinux__ -DEMBED
-
-*cross_compile:
-1
-
-*version:
-2.95.3
-
-*multilib:
-. !mnumerics !msoft-float !mlong-double-64;float mnumerics !msoft-float !mlong-double-64;soft-float !mnumerics msoft-float !mlong-double-64;ld64 !mnumerics !msoft-float mlong-double-64;float/ld64 mnumerics !msoft-float mlong-double-64;soft-float/ld64 !mnumerics msoft-float mlong-double-64;
-
-*multilib_defaults:
-mnumerics
-
-*multilib_extra:
-
-
-*multilib_matches:
-msb mnumerics;msc mnumerics;mkb mnumerics;mkc mnumerics;mmc mnumerics;mcb mnumerics;mcc mnumerics;mjf mnumerics;msa msoft-float;mka msoft-float;mca msoft-float;mcf msoft-float;mnumerics mnumerics;msoft-float msoft-float;mlong-double-64 mlong-double-64;
-
-*linker:
-collect2
-
-*link_command:
-%{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
- }}}}}}
-
diff --git a/libc/sysdeps/linux/i960/sys/procfs.h b/libc/sysdeps/linux/i960/sys/procfs.h
deleted file mode 100644
index 1722bf0..0000000
--- a/libc/sysdeps/linux/i960/sys/procfs.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Copyright (C) 1996, 1997, 1999, 2000, 2001 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 _SYS_PROCFS_H
-#define _SYS_PROCFS_H 1
-
-/* This is somewhat modelled after the file of the same name on SVR4
- systems. It provides a definition of the core file format for ELF
- used on Linux. It doesn't have anything to do with the /proc file
- system, even though Linux has one.
-
- Anyway, the whole purpose of this file is for GDB and GDB only.
- Don't read too much into it. Don't use it for anything other than
- GDB unless you know what you are doing. */
-
-#include <features.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/user.h>
-
-__BEGIN_DECLS
-
-/* Type for a general-purpose register. */
-typedef unsigned long elf_greg_t;
-
-/* And the whole bunch of them. We could have used `struct
- user_regs_struct' directly in the typedef, but tradition says that
- the register set is an array, which does have some peculiar
- semantics, so leave it that way. */
-#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Register set for the floating-point registers. */
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-
-/* Signal info. */
-struct elf_siginfo
- {
- int si_signo; /* Signal number. */
- int si_code; /* Extra code. */
- int si_errno; /* Errno. */
- };
-
-
-/* Definitions to generate Intel SVR4-like core files. These mostly
- have the same names as the SVR4 types with "elf_" tacked on the
- front to prevent clashes with Linux definitions, and the typedef
- forms have been avoided. This is mostly like the SVR4 structure,
- but more Linuxy, with things that Linux does not support and which
- GDB doesn't really use excluded. */
-
-struct elf_prstatus
- {
- struct elf_siginfo pr_info; /* Info associated with signal. */
- short int pr_cursig; /* Current signal. */
- unsigned long int pr_sigpend; /* Set of pending signals. */
- unsigned long int pr_sighold; /* Set of held signals. */
- __pid_t pr_pid;
- __pid_t pr_ppid;
- __pid_t pr_pgrp;
- __pid_t pr_sid;
- struct timeval pr_utime; /* User time. */
- struct timeval pr_stime; /* System time. */
- struct timeval pr_cutime; /* Cumulative user time. */
- struct timeval pr_cstime; /* Cumulative system time. */
- elf_gregset_t pr_reg; /* GP registers. */
- int pr_fpvalid; /* True if math copro being used. */
- };
-
-
-#define ELF_PRARGSZ (80) /* Number of chars for args. */
-
-struct elf_prpsinfo
- {
- char pr_state; /* Numeric process state. */
- char pr_sname; /* Char for pr_state. */
- char pr_zomb; /* Zombie. */
- char pr_nice; /* Nice val. */
- unsigned long int pr_flag; /* Flags. */
- unsigned short int pr_uid;
- unsigned short int pr_gid;
- int pr_pid, pr_ppid, pr_pgrp, pr_sid;
- /* Lots missing */
- char pr_fname[16]; /* Filename of executable. */
- char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
- };
-
-
-/* The rest of this file provides the types for emulation of the
- Solaris <proc_service.h> interfaces that should be implemented by
- users of libthread_db. */
-
-/* Addresses. */
-typedef void *psaddr_t;
-
-/* Register sets. Linux has different names. */
-typedef elf_gregset_t prgregset_t;
-typedef elf_fpregset_t prfpregset_t;
-
-/* We don't have any differences between processes and threads,
- therefore have only one PID type. */
-typedef __pid_t lwpid_t;
-
-/* Process status and info. In the end we do provide typedefs for them. */
-typedef struct elf_prstatus prstatus_t;
-typedef struct elf_prpsinfo prpsinfo_t;
-
-__END_DECLS
-
-#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/linux/i960/sys/ucontext.h b/libc/sysdeps/linux/i960/sys/ucontext.h
deleted file mode 100644
index 7000f98..0000000
--- a/libc/sysdeps/linux/i960/sys/ucontext.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-/* Don't rely on this, the interface is currently messed up and may need to
- be broken to be fixed. */
-#ifndef _SYS_UCONTEXT_H
-#define _SYS_UCONTEXT_H 1
-
-#include <features.h>
-#include <signal.h>
-
-/* We need the signal context definitions even if they are not used
- included in <signal.h>. */
-#include <bits/sigcontext.h>
-
-
-/* Type for general register. */
-typedef unsigned long int greg_t;
-
-/* Number of general registers. */
-#define NGREG 32 /* 16 global and 16 local */
-
-/* Container for all general registers. */
-/* gregset_t must be an array. The below declared array corresponds to:
-typedef struct gregset {
- greg_t g_regs[32];
- greg_t g_hi;
- greg_t g_lo;
- greg_t g_pad[3];
-} gregset_t; */
-typedef greg_t gregset_t[NGREG];
-
-/* Container for all FPU registers. */
-typedef struct fpregset {
- /* No floating point registers on most i960 */
-
- /* Otherwise, signal the missing implementation */
-#if defined(__i960SB) || defined(__i960KB)
-#error Floating point support is not yet implemented for the i960 platform.
-#endif
-} fpregset_t;
-
-
-/* Context to describe whole processor state. */
-typedef struct
- {
- gregset_t gregs;
- fpregset_t fpregs;
- } mcontext_t;
-
-/* Userlevel context. */
-typedef struct ucontext
- {
- unsigned long int uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
- } ucontext_t;
-
-#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/i960/vfork.S b/libc/sysdeps/linux/i960/vfork.S
deleted file mode 100644
index e43146c..0000000
--- a/libc/sysdeps/linux/i960/vfork.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * clone.S, part of the i960 support for the uClibc library.
- *
- * Copyright (C) 2002 by Okiok Data Ltd. http://www.okiok.com/
- * Copyright (C) 2000-2006 Erik Andersen <andersen(a)uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-/*
- * Derived from an old port of uC-libc to the i960 by Keith Adams (kma(a)cse.ogi.edu).
- */
-
-#include <sys/syscall.h>
-
-#ifndef __NR_vfork
-#define __NR_vfork __NR_fork /* uClinux-2.0 only has fork which is vfork */
-#endif
-
- .globl ___vfork
- .hidden ___vfork
- .type ___vfork,@function
-___vfork:
- mov g13, r3
- ldconst __NR_vfork, g13
- calls 0
- mov r3, g13
- cmpible 0, g0, 1f
- subo g0, 0, r3
- st r3, _errno
-1:
- ret
-
-weak_alias(__vfork,vfork)
-libc_hidden_def(vfork)
diff --git a/libc/sysdeps/linux/sparc/soft-fp/longlong.h b/libc/sysdeps/linux/sparc/soft-fp/longlong.h
index 9eebae3..bd0d9be 100644
--- a/libc/sysdeps/linux/sparc/soft-fp/longlong.h
+++ b/libc/sysdeps/linux/sparc/soft-fp/longlong.h
@@ -397,25 +397,6 @@ UDItype __umulsidi3 (USItype, USItype);
#define UDIV_TIME 40
#endif /* x86_64 */
-#if defined (__i960__) && W_TYPE_SIZE == 32
-#define umul_ppmm(w1, w0, u, v) \
- ({union {UDItype __ll; \
- struct {USItype __l, __h;} __i; \
- } __xx; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__xx.__ll) \
- : "%dI" ((USItype) (u)), \
- "dI" ((USItype) (v))); \
- (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
-#define __umulsidi3(u, v) \
- ({UDItype __w; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__w) \
- : "%dI" ((USItype) (u)), \
- "dI" ((USItype) (v))); \
- __w; })
-#endif /* __i960__ */
-
#if defined (__M32R__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
diff --git a/libc/sysdeps/linux/v850/Makefile b/libc/sysdeps/linux/v850/Makefile
deleted file mode 100644
index d6ed3cc..0000000
--- a/libc/sysdeps/linux/v850/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# Makefile for uClibc
-#
-# Copyright (C) 2001,2002 NEC Corporation
-# Copyright (C) 2001,2002 Miles Bader <miles(a)gnu.org>
-#
-# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-
-TOPDIR=../../../../
-include $(TOPDIR)Rules.mak
-
-CFLAGS += -I..
-ASFLAGS += -I.. -D__ASSEMBLER
-
-TARGET_MACHINE_TYPE=$(shell $(CC) -dumpmachine)
-
-CRT_SRC := crt0.S
-CRT_OBJ := crt0.o crt1.o
-CTOR_TARGETS := $(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
-
-SSRC := setjmp.S __longjmp.S vfork.S
-SOBJ := $(patsubst %.S,%.o, $(SSRC))
-
-CSRC := syscall.c clone.c
-COBJ := $(patsubst %.c,%.o, $(CSRC))
-
-OBJS := $(SOBJ) $(COBJ)
-
-OBJ_LIST := ../../../obj.sysdeps.$(TARGET_ARCH)
-
-all: $(OBJ_LIST) $(CTOR_TARGETS)
-
-$(OBJ_LIST): $(OBJS) $(CRT_OBJ)
- $(STRIPTOOL) -x -R .note -R .comment $^
- $(INSTALL) -d $(TOPDIR)lib/
- cp $(CRT_OBJ) $(TOPDIR)lib/
- echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $@
-
-$(CRT_OBJ): $(CRT_SRC)
- $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
-
-$(SOBJ): %.o : %.S
- $(CC) $(ASFLAGS) -c $< -o $@
-
-$(COBJ): %.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-ifeq ($(UCLIBC_CTOR_DTOR),y)
-$(TOPDIR)lib/crti.o: crti.S
- $(INSTALL) -d $(TOPDIR)lib/
- $(CC) $(ASFLAGS) $(SSP_DISABLE_FLAGS) -c $< -o $@
-
-$(TOPDIR)lib/crtn.o: crtn.S
- $(INSTALL) -d $(TOPDIR)lib/
- $(CC) $(ASFLAGS) $(SSP_DISABLE_FLAGS) -c $< -o $@
-else
-$(CTOR_TARGETS):
- $(INSTALL) -d $(TOPDIR)lib/
- $(AR) $(ARFLAGS) $@
-endif
-
-headers:
-
-clean:
- $(RM) *.o *~ core
diff --git a/libc/sysdeps/linux/v850/__longjmp.S b/libc/sysdeps/linux/v850/__longjmp.S
deleted file mode 100644
index 0996099..0000000
--- a/libc/sysdeps/linux/v850/__longjmp.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/longjmp.S -- `longjmp' for v850
- *
- * Copyright (C) 2001,02 NEC Corporation
- * Copyright (C) 2001,02 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <clinkage.h>
-
- .text
-C_ENTRY(__longjmp):
- /* Save registers */
- mov r6, ep
- sld.w 0[ep], sp
- sld.w 4[ep], lp
- sld.w 8[ep], r2
- sld.w 12[ep], r20
- sld.w 16[ep], r21
- sld.w 20[ep], r22
- sld.w 24[ep], r23
- sld.w 28[ep], r24
- sld.w 32[ep], r25
- sld.w 36[ep], r26
- sld.w 40[ep], r27
- sld.w 44[ep], r28
- sld.w 48[ep], r29
- mov 1, r10 /* return val */
- jmp [lp]
-C_END(__longjmp)
-libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/v850/bits/byteswap.h b/libc/sysdeps/linux/v850/bits/byteswap.h
deleted file mode 100644
index b2e1ddb..0000000
--- a/libc/sysdeps/linux/v850/bits/byteswap.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/bits/byteswap.h -- Macros to swap the order
- * of bytes in integer values
- *
- * Copyright (C) 2001 NEC Corporation
- * Copyright (C) 2001 Miles Bader <miles(a)gnu.org>
- * Copyright (C) 1997,1998,2001 Free Software Foundation, Inc.
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- */
-
-#ifndef _ASM_BITS_BYTESWAP_H
-#define _ASM_BITS_BYTESWAP_H 1
-
-#define __bswap_non_constant_16(x) \
- (__extension__ \
- ({ unsigned long int __bswap_16_v; \
- __asm__ ("bsh %1, %0" : "=r" (__bswap_16_v) : "r" (x)); \
- __bswap_16_v; }))
-
-# define __bswap_non_constant_32(x) \
- (__extension__ \
- ({ unsigned long int __bswap_32_v; \
- __asm__ ("bsw %1, %0" : "=r" (__bswap_32_v) : "r" (x)); \
- __bswap_32_v; }))
-
-#endif
-
-#include <bits/byteswap-common.h>
diff --git a/libc/sysdeps/linux/v850/bits/endian.h b/libc/sysdeps/linux/v850/bits/endian.h
deleted file mode 100644
index ae78da3..0000000
--- a/libc/sysdeps/linux/v850/bits/endian.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/bits/endian.h -- Define processor endianess
- *
- * Copyright (C) 2001 NEC Corporation
- * Copyright (C) 2001 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#ifndef _ENDIAN_H
-# error "Never use <bits/endian.h> directly; include <endian.h> instead."
-#endif
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/libc/sysdeps/linux/v850/bits/fcntl.h b/libc/sysdeps/linux/v850/bits/fcntl.h
deleted file mode 100644
index 45deec4..0000000
--- a/libc/sysdeps/linux/v850/bits/fcntl.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _FCNTL_H
-# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
-#endif
-
-
-#include <sys/types.h>
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define O_FSYNC O_SYNC
-#define O_ASYNC 020000
-
-#ifdef __USE_GNU
-# define O_DIRECTORY 040000 /* Must be a directory. */
-# define O_NOFOLLOW 0100000 /* Do not follow links. */
-# define O_DIRECT 0200000 /* Direct disk access. */
-#endif
-
-/* For now Linux has synchronisity options for data and read operations.
- We define the symbols here but let them do the same as O_SYNC since
- this is a superset. */
-#if defined __USE_POSIX199309 || defined __USE_UNIX98
-# define O_DSYNC O_SYNC /* Synchronize data. */
-# define O_RSYNC O_SYNC /* Synchronize read operations. */
-#endif
-
-#ifdef __USE_LARGEFILE64
-# define O_LARGEFILE 0400000
-#endif
-
-/* Values for the second argument to `fcntl'. */
-#define F_DUPFD 0 /* Duplicate file descriptor. */
-#define F_GETFD 1 /* Get file descriptor flags. */
-#define F_SETFD 2 /* Set file descriptor flags. */
-#define F_GETFL 3 /* Get file status flags. */
-#define F_SETFL 4 /* Set file status flags. */
-#ifndef __USE_FILE_OFFSET64
-# define F_GETLK 5 /* Get record locking info. */
-# define F_SETLK 6 /* Set record locking info (non-blocking). */
-# define F_SETLKW 7 /* Set record locking info (blocking). */
-#else
-# define F_GETLK F_GETLK64 /* Get record locking info. */
-# define F_SETLK F_SETLK64 /* Set record locking info (non-blocking).*/
-# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
-#endif
-#define F_GETLK64 12 /* Get record locking info. */
-#define F_SETLK64 13 /* Set record locking info (non-blocking). */
-#define F_SETLKW64 14 /* Set record locking info (blocking). */
-
-#if defined __USE_BSD || defined __USE_XOPEN2K
-# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */
-# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
-#endif
-
-#ifdef __USE_GNU
-# define F_SETSIG 10 /* Set number of signal to be sent. */
-# define F_GETSIG 11 /* Get number of signal to be sent. */
-#endif
-
-#ifdef __USE_GNU
-# define F_SETLEASE 1024 /* Set a lease. */
-# define F_GETLEASE 1025 /* Enquire what lease is active. */
-# 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]FL. */
-#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
-
-/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
-#define F_RDLCK 0 /* Read lock. */
-#define F_WRLCK 1 /* Write lock. */
-#define F_UNLCK 2 /* Remove lock. */
-
-/* For old implementation of bsd flock(). */
-#define F_EXLCK 4 /* or 3 */
-#define F_SHLCK 8 /* or 4 */
-
-#ifdef __USE_BSD
-/* Operations for bsd flock(), also used by the kernel implementation. */
-# define LOCK_SH 1 /* shared lock */
-# define LOCK_EX 2 /* exclusive lock */
-# define LOCK_NB 4 /* or'd with one of the above to prevent
- blocking */
-# define LOCK_UN 8 /* remove lock */
-#endif
-
-#ifdef __USE_GNU
-# define LOCK_MAND 32 /* This is a mandatory flock: */
-# define LOCK_READ 64 /* ... which allows concurrent read operations. */
-# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */
-# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */
-#endif
-
-#ifdef __USE_GNU
-/* Types of directory notifications that may be requested with F_NOTIFY. */
-# define DN_ACCESS 0x00000001 /* File accessed. */
-# define DN_MODIFY 0x00000002 /* File modified. */
-# define DN_CREATE 0x00000004 /* File created. */
-# define DN_DELETE 0x00000008 /* File removed. */
-# define DN_RENAME 0x00000010 /* File renamed. */
-# define DN_ATTRIB 0x00000020 /* File changed attibutes. */
-# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
-#endif
-
-struct flock
- {
- short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
- short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
-#ifndef __USE_FILE_OFFSET64
- __off_t l_start; /* Offset where the lock begins. */
- __off_t l_len; /* Size of the locked area; zero means until EOF. */
-#else
- __off64_t l_start; /* Offset where the lock begins. */
- __off64_t l_len; /* Size of the locked area; zero means until EOF. */
-#endif
- __pid_t l_pid; /* Process holding the lock. */
- };
-
-#ifdef __USE_LARGEFILE64
-struct flock64
- {
- short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
- short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
- __off64_t l_start; /* Offset where the lock begins. */
- __off64_t l_len; /* Size of the locked area; zero means until EOF. */
- __pid_t l_pid; /* Process holding the lock. */
- };
-#endif
-
-/* Define some more compatibility macros to be backward compatible with
- BSD systems which did not managed to hide these kernel macros. */
-#ifdef __USE_BSD
-# define FAPPEND O_APPEND
-# define FFSYNC O_FSYNC
-# define FASYNC O_ASYNC
-# define FNONBLOCK O_NONBLOCK
-# define FNDELAY O_NDELAY
-#endif /* Use BSD. */
-
-/* Advise to `posix_fadvise'. */
-#ifdef __USE_XOPEN2K
-# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
-# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
-#endif
-
-
-#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
- write. */
-# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
- dirty pages in the range which are
- not presently under writeback. */
-# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
- the range after performing the
- write. */
-
-/* Flags for SPLICE and VMSPLICE. */
-# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
-# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
- (but we may still block on the fd
- we splice from/to). */
-# define SPLICE_F_MORE 4 /* Expect more data. */
-# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
-#endif
-
-__BEGIN_DECLS
-
-#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)
- __THROW;
-
-
-/* Selective file content synch'ing. */
-extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
- unsigned int __flags);
-
-/* Splice address range into a pipe. */
-extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
- size_t __count, unsigned int __flags);
-
-/* Splice two files together. */
-extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
- __off64_t *__offout, size_t __len,
- unsigned int __flags);
-
-/* In-kernel implementation of tee for pipe buffers. */
-extern ssize_t tee (int __fdin, int __fdout, size_t __len,
- unsigned int __flags);
-
-#endif
-__END_DECLS
-
diff --git a/libc/sysdeps/linux/v850/bits/kernel_stat.h b/libc/sysdeps/linux/v850/bits/kernel_stat.h
deleted file mode 100644
index 1b925ca..0000000
--- a/libc/sysdeps/linux/v850/bits/kernel_stat.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Stat structure for linux/v850 */
-
-#ifndef _BITS_STAT_STRUCT_H
-#define _BITS_STAT_STRUCT_H
-
-struct kernel_stat
-{
- __kernel_dev_t st_dev;
- __kernel_ino_t st_ino;
- __kernel_mode_t st_mode;
- __kernel_nlink_t st_nlink;
- __kernel_uid_t st_uid;
- __kernel_gid_t st_gid;
- __kernel_dev_t st_rdev;
- __kernel_off_t st_size;
- unsigned long st_blksize;
- unsigned long st_blocks;
- struct timespec st_atim;
- struct timespec st_mtim;
- struct timespec st_ctim;
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-struct kernel_stat64
-{
- __kernel_dev_t st_dev;
- unsigned long __unused0;
- unsigned long __unused1;
-
- __kernel_ino64_t st_ino;
-
- __kernel_mode_t st_mode;
- __kernel_nlink_t st_nlink;
-
- __kernel_uid_t st_uid;
- __kernel_gid_t st_gid;
-
- __kernel_dev_t st_rdev;
- unsigned long __unused2;
- unsigned long __unused3;
-
- __kernel_loff_t st_size;
- unsigned long st_blksize;
-
- unsigned long __unused4; /* future possible st_blocks high bits */
- unsigned long st_blocks; /* Number 512-byte blocks allocated. */
-
- struct timespec st_atim;
- struct timespec st_mtim;
- struct timespec st_ctim;
-};
-
-#endif /* _BITS_STAT_STRUCT_H */
diff --git a/libc/sysdeps/linux/v850/bits/kernel_types.h b/libc/sysdeps/linux/v850/bits/kernel_types.h
deleted file mode 100644
index 780aa8a..0000000
--- a/libc/sysdeps/linux/v850/bits/kernel_types.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * sysdeps/linux/v850/bits/kernel_types.h -- Kernel versions of standard types
- *
- * Copyright (C) 2001,2002 NEC Corporation
- * Copyright (C) 2001,2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#ifndef __V850_POSIX_TYPES_H__
-#define __V850_POSIX_TYPES_H__
-
-typedef unsigned int __kernel_dev_t;
-typedef unsigned long __kernel_ino_t;
-typedef unsigned long long __kernel_ino64_t;
-typedef unsigned int __kernel_mode_t;
-typedef unsigned int __kernel_nlink_t;
-typedef long __kernel_off_t;
-typedef long long __kernel_loff_t;
-typedef int __kernel_pid_t;
-typedef unsigned short __kernel_ipc_pid_t;
-typedef unsigned int __kernel_uid_t;
-typedef unsigned int __kernel_gid_t;
-typedef unsigned int __kernel_size_t;
-typedef int __kernel_ssize_t;
-typedef int __kernel_ptrdiff_t;
-typedef long __kernel_time_t;
-typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
-typedef int __kernel_daddr_t;
-typedef char * __kernel_caddr_t;
-typedef unsigned short __kernel_uid16_t;
-typedef unsigned short __kernel_gid16_t;
-typedef unsigned int __kernel_uid32_t;
-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 struct {
-#ifdef __USE_ALL
- int val[2];
-#else
- int __val[2];
-#endif
-} __kernel_fsid_t;
-
-#endif /* __V850_POSIX_TYPES_H__ */
diff --git a/libc/sysdeps/linux/v850/bits/poll.h b/libc/sysdeps/linux/v850/bits/poll.h
deleted file mode 100644
index 1d845eb..0000000
--- a/libc/sysdeps/linux/v850/bits/poll.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (C) 1997, 2001 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 _SYS_POLL_H
-# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
-#endif
-
-/* Event types that can be polled for. These bits may be set in `events'
- to indicate the interesting event types; they will appear in `revents'
- to indicate the status of the file descriptor. */
-#define POLLIN 0x001 /* There is data to read. */
-#define POLLPRI 0x002 /* There is urgent data to read. */
-#define POLLOUT 0x004 /* Writing now will not block. */
-
-#ifdef __USE_XOPEN
-/* These values are defined in XPG4.2. */
-# define POLLRDNORM 0x040 /* Normal data may be read. */
-# define POLLRDBAND 0x080 /* Priority data may be read. */
-# define POLLWRNORM POLLOUT /* Writing now will not block. */
-# define POLLWRBAND 0x100 /* Priority data may be written. */
-#endif
-
-/* Event types always implicitly polled for. These bits need not be set in
- `events', but they will appear in `revents' to indicate the status of
- the file descriptor. */
-#define POLLERR 0x008 /* Error condition. */
-#define POLLHUP 0x010 /* Hung up. */
-#define POLLNVAL 0x020 /* Invalid polling request. */
diff --git a/libc/sysdeps/linux/v850/bits/select.h b/libc/sysdeps/linux/v850/bits/select.h
deleted file mode 100644
index b6bb054..0000000
--- a/libc/sysdeps/linux/v850/bits/select.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * include/bits/select.h -- fd_set operations
- *
- * Copyright (C) 2001 NEC Corporation
- * Copyright (C) 2001 Miles Bader <miles(a)gnu.org>
- * Copyright (C) 1997, 1998 Free Software Foundation, Inc.
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- */
-
-#ifndef _SYS_SELECT_H
-# error "Never use <bits/select.h> directly; include <sys/select.h> instead."
-#endif
-
-#ifdef __GNUC__
-
-/* We don't use `memset' because this would require a prototype and
- the array isn't too big. */
-#define __FD_ZERO(s) \
- do { \
- unsigned int __i; \
- fd_set *__arr = (s); \
- for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
- __FDS_BITS (__arr)[__i] = 0; \
- } while (0)
-
-#define __FD_SET(fd, s) \
- do { \
- int __fd = (fd); \
- void *__addr = (void *)&__FDS_BITS (s); \
- __asm__ __volatile__ ("set1 %0, [%1]" \
- : /*nothing*/ \
- : "r" (__fd & 0x7), "r" (__addr + (__fd >> 3)));\
- } while (0)
-
-#define __FD_CLR(fd, s) \
- do { \
- int __fd = (fd); \
- void *__addr = (void *)&__FDS_BITS (s); \
- __asm__ __volatile__ ("clr1 %0, [%1]" \
- : /*nothing*/ \
- : "r" (__fd & 0x7), "r" (__addr + (__fd >> 3)));\
- } while (0)
-
-#define __FD_ISSET(fd, s) \
- ({ \
- int __fd = (fd); \
- void *__addr = (void *)&__FDS_BITS (s); \
- int res; \
- __asm__ ("tst1 %1, [%2]; setf nz, %0" \
- : "=r" (res) \
- : "r" (__fd & 0x7), "r" (__addr + (__fd >> 3))); \
- res; \
- })
-
-#else /* !__GNUC__ */
-
-#define __FD_SET(d, s) (__FDS_BITS (s)[__FDELT(d)] |= __FDMASK(d))
-#define __FD_CLR(d, s) (__FDS_BITS (s)[__FDELT(d)] &= ~__FDMASK(d))
-#define __FD_ISSET(d, s) ((__FDS_BITS (s)[__FDELT(d)] & __FDMASK(d)) != 0)
-
-#endif /* __GNUC__ */
diff --git a/libc/sysdeps/linux/v850/bits/setjmp.h b/libc/sysdeps/linux/v850/bits/setjmp.h
deleted file mode 100644
index b76df85..0000000
--- a/libc/sysdeps/linux/v850/bits/setjmp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/bits/setjmp.h -- v850 version of `jmp_buf' type
- *
- * Copyright (C) 2001 NEC Corporation
- * Copyright (C) 2001 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#ifndef _BITS_SETJMP_H
-#define _BITS_SETJMP_H 1
-
-#if !defined _SETJMP_H && !defined _PTHREAD_H
-# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
-#endif
-
-typedef struct
- {
- /* Stack pointer. */
- void *__sp;
-
- /* Link pointer. */
- void *__lp;
-
- /* Callee-saved registers r2 and r20-r29. */
- int __regs[11];
- } __jmp_buf[1];
-
-#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/v850/bits/sigcontextinfo.h b/libc/sysdeps/linux/v850/bits/sigcontextinfo.h
deleted file mode 100644
index de450ff..0000000
--- a/libc/sysdeps/linux/v850/bits/sigcontextinfo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * sysdeps/v850/sigcontextinfo.h -- v850-specific pthread signal definitions
- *
- * Copyright (C) 2002 NEC Electronics Corporation
- * Copyright (C) 2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <signal.h>
-
-#define SIGCONTEXT struct sigcontext *
-#define SIGCONTEXT_EXTRA_ARGS
diff --git a/libc/sysdeps/linux/v850/bits/stackinfo.h b/libc/sysdeps/linux/v850/bits/stackinfo.h
deleted file mode 100644
index 3ed732a..0000000
--- a/libc/sysdeps/linux/v850/bits/stackinfo.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * bits/stackinfo.h -- v850-specific pthread definitions
- *
- * Copyright (C) 2003 NEC Electronics Corporation
- * Copyright (C) 2003 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-/* This file contains a bit of information about the stack allocation
- of the processor. */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H 1
-
-/* On v80 the stack grows down. */
-#define _STACK_GROWS_DOWN 1
-
-#endif /* stackinfo.h */
diff --git a/libc/sysdeps/linux/v850/bits/syscalls.h b/libc/sysdeps/linux/v850/bits/syscalls.h
deleted file mode 100644
index b218513..0000000
--- a/libc/sysdeps/linux/v850/bits/syscalls.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _BITS_SYSCALLS_H
-#define _BITS_SYSCALLS_H
-#ifndef _SYSCALL_H
-# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
-#endif
-
-#include <features.h>
-
-/* Do something very evil for now. Until we create our own syscall
- * macros, short circuit bits/sysnum.h and use asm/unistd.h instead */
-#warning "fixme -- add arch specific syscall macros.h"
-#include <asm/unistd.h>
-
-#endif /* _BITS_SYSCALLS_H */
-
diff --git a/libc/sysdeps/linux/v850/bits/uClibc_arch_features.h b/libc/sysdeps/linux/v850/bits/uClibc_arch_features.h
deleted file mode 100644
index 32293e6..0000000
--- a/libc/sysdeps/linux/v850/bits/uClibc_arch_features.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Track misc arch-specific features that aren't config options
- */
-
-#ifndef _BITS_UCLIBC_ARCH_FEATURES_H
-#define _BITS_UCLIBC_ARCH_FEATURES_H
-
-/* instruction used when calling abort() to kill yourself */
-/*#define __UCLIBC_ABORT_INSTRUCTION__ "asm instruction"*/
-#undef __UCLIBC_ABORT_INSTRUCTION__
-
-/* can your target use syscall6() for mmap ? */
-#define __UCLIBC_MMAP_HAS_6_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() ? */
-#undef __UCLIBC_BROKEN_CREATE_MODULE__
-
-/* does your target have to worry about older [gs]etrlimit() ? */
-#undef __UCLIBC_HANDLE_OLDER_RLIMIT__
-
-/* does your target have an asm .set ? */
-#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
-
-/* define if target supports .weak */
-#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__
-
-/* define if target supports .weakext */
-#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__
-
-/* define if target supports CFI pseudo ops */
-#undef __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__
-
-#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/v850/bits/wordsize.h b/libc/sysdeps/linux/v850/bits/wordsize.h
deleted file mode 100644
index ca82fd7..0000000
--- a/libc/sysdeps/linux/v850/bits/wordsize.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (C) 1999 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 __WORDSIZE 32
diff --git a/libc/sysdeps/linux/v850/clinkage.h b/libc/sysdeps/linux/v850/clinkage.h
deleted file mode 100644
index e85d39f..0000000
--- a/libc/sysdeps/linux/v850/clinkage.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/clinkage.h -- Macros for C symbols in assembler
- *
- * Copyright (C) 2001 NEC Corporation
- * Copyright (C) 2001 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <asm/clinkage.h>
diff --git a/libc/sysdeps/linux/v850/clone.c b/libc/sysdeps/linux/v850/clone.c
deleted file mode 100644
index d2e2208..0000000
--- a/libc/sysdeps/linux/v850/clone.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/clone.c -- `clone' syscall for linux/v850
- *
- * Copyright (C) 2002,03 NEC Electronics Corporation
- * Copyright (C) 2002,03 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <errno.h>
-#include <sys/syscall.h>
-
-int
-clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)
-{
- register unsigned long rval __asm__ (SYSCALL_RET) = -EINVAL;
-
- if (fn && child_stack)
- {
- register unsigned long syscall __asm__ (SYSCALL_NUM);
- register unsigned long arg0 __asm__ (SYSCALL_ARG0);
- register unsigned long arg1 __asm__ (SYSCALL_ARG1);
-
- /* Clone this thread. */
- arg0 = flags;
- arg1 = (unsigned long)child_stack;
- syscall = __NR_clone;
- __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP
- : "=r" (rval), "=r" (syscall)
- : "1" (syscall), "r" (arg0), "r" (arg1)
- : SYSCALL_SHORT_CLOBBERS);
-
- if (rval == 0)
- /* In child thread, call FN and exit. */
- {
- arg0 = (*fn) (arg);
- syscall = __NR_exit;
- __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP
- : "=r" (rval), "=r" (syscall)
- : "1" (syscall), "r" (arg0)
- : SYSCALL_SHORT_CLOBBERS);
- }
- }
-
- __syscall_return (int, rval);
-}
diff --git a/libc/sysdeps/linux/v850/crt0.S b/libc/sysdeps/linux/v850/crt0.S
deleted file mode 100644
index 01e9f83..0000000
--- a/libc/sysdeps/linux/v850/crt0.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/crt0.S -- Initial program entry point for linux/v850
- *
- * Copyright (C) 2001,02,03 NEC Electronics Corporation
- * Copyright (C) 2001,02,03 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <clinkage.h>
-
-/* Upon entry, the stack contains the following data:
- argc, argv[0], ..., argv[argc-1], 0, envp[0], ..., 0
-*/
-
- .text
-C_ENTRY(start):
- ld.w 0[sp], r6 /* Arg 0: argc */
-
- addi 4, sp, r7 /* Arg 1: argv */
-
- mov r7, r8 /* Arg 2: envp */
- mov r6, r10 /* skip argc elements to get envp start */
- add 1, r10 /* ...plus the NULL at the end of argv */
- shl 2, r10 /* Convert to byte-count to skip */
- add r10, r8
-
- /* Load CTBP register */
- mov hilo(C_SYMBOL_NAME(_ctbp)), r19
- ldsr r19, ctbp
-
- /* Load GP */
- mov hilo(C_SYMBOL_NAME(_gp)), gp
-
- /* tail-call uclibc's startup routine */
- addi -24, sp, sp /* Stack space reserved for args */
- jr C_SYMBOL_NAME(__uClibc_main)
-
-
-/* Stick in a dummy reference to `main', so that if an application
- is linking when the `main' function is in a static library (.a)
- we can be sure that `main' actually gets linked in. */
-L_dummy_main_reference:
- .long C_SYMBOL_NAME(main)
-
-/* Define a symbol for the first piece of initialized data. */
- .data
- .globl __data_start
-__data_start:
- .long 0
- .weak data_start
- data_start = __data_start
-
diff --git a/libc/sysdeps/linux/v850/crti.S b/libc/sysdeps/linux/v850/crti.S
deleted file mode 100644
index c1e5293..0000000
--- a/libc/sysdeps/linux/v850/crti.S
+++ /dev/null
@@ -1,27 +0,0 @@
- .file "initfini.c"
-#APP
-
- .section .init
-#NO_APP
- .align 1
- .global __init
- .type __init, @function
-__init:
- jarl __save_r31, r10
-#APP
-
- .align 1
-
-
- .section .fini
-#NO_APP
- .align 1
- .global __fini
- .type __fini, @function
-__fini:
- jarl __save_r31, r10
-#APP
- .align 1
-
-
- .ident "GCC: (GNU) 3.3.2"
diff --git a/libc/sysdeps/linux/v850/crtn.S b/libc/sysdeps/linux/v850/crtn.S
deleted file mode 100644
index 6bb0b39..0000000
--- a/libc/sysdeps/linux/v850/crtn.S
+++ /dev/null
@@ -1,22 +0,0 @@
- .file "initfini.c"
-#APP
-
- .section .init
-#NO_APP
- .align 1
- .global __init
- .type __init, @function
-#NO_APP
- jr __return_r31
-#APP
-
- .section .fini
-#NO_APP
- .align 1
- .global __fini
- .type __fini, @function
-#NO_APP
- jr __return_r31
-#APP
-
- .ident "GCC: (GNU) 3.3.2"
diff --git a/libc/sysdeps/linux/v850/jmpbuf-offsets.h b/libc/sysdeps/linux/v850/jmpbuf-offsets.h
deleted file mode 100644
index cea9963..0000000
--- a/libc/sysdeps/linux/v850/jmpbuf-offsets.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen(a)uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-#define JB_SIZE (4 * 13)
diff --git a/libc/sysdeps/linux/v850/jmpbuf-unwind.h b/libc/sysdeps/linux/v850/jmpbuf-unwind.h
deleted file mode 100644
index a24cd12..0000000
--- a/libc/sysdeps/linux/v850/jmpbuf-unwind.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen(a)uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-#include <setjmp.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)[0].__sp)
diff --git a/libc/sysdeps/linux/v850/setjmp.S b/libc/sysdeps/linux/v850/setjmp.S
deleted file mode 100644
index 8bb3649..0000000
--- a/libc/sysdeps/linux/v850/setjmp.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/setjmp.S -- `setjmp' for v850
- *
- * Copyright (C) 2001,2002 NEC Corporation
- * Copyright (C) 2001,2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <clinkage.h>
-
- .text
-C_ENTRY(setjmp):
- mov 1, r7 /* Save the signal mask. */
- br C_SYMBOL_NAME(__sigsetjmp)
-
- .globl C_SYMBOL_NAME(_setjmp)
-C_SYMBOL_NAME(_setjmp):
- mov 0, r7 /* Don't save the signal mask. */
-
- .globl C_SYMBOL_NAME(__sigsetjmp)
-C_SYMBOL_NAME(__sigsetjmp):
- /* Save registers */
- mov r6, ep
- sst.w sp, 0[ep]
- sst.w lp, 4[ep]
- sst.w r2, 8[ep]
- sst.w r20, 12[ep]
- sst.w r21, 16[ep]
- sst.w r22, 20[ep]
- sst.w r23, 24[ep]
- sst.w r24, 28[ep]
- sst.w r25, 32[ep]
- sst.w r26, 36[ep]
- sst.w r27, 40[ep]
- sst.w r28, 44[ep]
- sst.w r29, 48[ep]
- /* Make a tail call to __sigjmp_save; it takes the same args. */
- jr C_SYMBOL_NAME(__sigjmp_save)
-C_END(setjmp)
diff --git a/libc/sysdeps/linux/v850/sys/procfs.h b/libc/sysdeps/linux/v850/sys/procfs.h
deleted file mode 100644
index 32f000c..0000000
--- a/libc/sysdeps/linux/v850/sys/procfs.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002 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 _SYS_PROCFS_H
-#define _SYS_PROCFS_H 1
-
-/* This is somewhat modelled after the file of the same name on SVR4
- systems. It provides a definition of the core file format for ELF
- used on Linux. It doesn't have anything to do with the /proc file
- system, even though Linux has one.
-
- Anyway, the whole purpose of this file is for GDB and GDB only.
- Don't read too much into it. Don't use it for anything other than
- GDB unless you know what you are doing. */
-
-#include <features.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-
-/* Type for a general-purpose register. */
-typedef unsigned long elf_greg_t;
-
-/* This is exactly the same as `struct pt_regs' in the kernel. */
-struct elf_gregset
-{
- /* General purpose registers. */
- elf_greg_t gpr[32];
-
- elf_greg_t pc; /* program counter */
- elf_greg_t psw; /* program status word */
-
- /* Registers used by `callt' instruction: */
- elf_greg_t ctpc; /* saved program counter */
- elf_greg_t ctpsw; /* saved psw */
- elf_greg_t ctbp; /* base pointer for callt table */
-
- char kernel_mode; /* 1 if in `kernel mode', 0 if user mode */
-};
-
-#define ELF_NGREG (sizeof (struct elf_gregset) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* Register set for the floating-point registers. */
-typedef void elf_fpregset_t;
-
-
-struct elf_siginfo
-{
- int si_signo; /* signal number */
- int si_code; /* extra code */
- int si_errno; /* errno */
-};
-
-
-/*
- * Definitions to generate Intel SVR4-like core files.
- * These mostly have the same names as the SVR4 types with "elf_"
- * tacked on the front to prevent clashes with linux definitions,
- * and the typedef forms have been avoided. This is mostly like
- * the SVR4 structure, but more Linuxy, with things that Linux does
- * not support and which gdb doesn't really use excluded.
- * Fields present but not used are marked with "XXX".
- */
-struct elf_prstatus
-{
- struct elf_siginfo pr_info; /* Info associated with signal */
- short pr_cursig; /* Current signal */
- unsigned long pr_sigpend; /* Set of pending signals */
- unsigned long pr_sighold; /* Set of held signals */
- __kernel_pid_t pr_pid;
- __kernel_pid_t pr_ppid;
- __kernel_pid_t pr_pgrp;
- __kernel_pid_t pr_sid;
- struct timeval pr_utime; /* User time */
- struct timeval pr_stime; /* System time */
- struct timeval pr_cutime; /* Cumulative user time */
- struct timeval pr_cstime; /* Cumulative system time */
- elf_gregset_t pr_reg; /* GP registers */
- int pr_fpvalid; /* True if math co-processor being used. */
-};
-
-#define ELF_PRARGSZ (80) /* Number of chars for args */
-
-struct elf_prpsinfo
-{
- char pr_state; /* numeric process state */
- char pr_sname; /* char for pr_state */
- char pr_zomb; /* zombie */
- char pr_nice; /* nice val */
- unsigned long pr_flag; /* flags */
- __kernel_uid_t pr_uid;
- __kernel_gid_t pr_gid;
- __kernel_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
- /* Lots missing */
- char pr_fname[16]; /* filename of executable */
- char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
-};
-
-
-/* The rest of this file provides the types for emulation of the
- Solaris <proc_service.h> interfaces that should be implemented by
- users of libthread_db. */
-
-/* Addresses. */
-typedef void *psaddr_t;
-
-/* Register sets. Linux has different names. */
-typedef elf_gregset_t prgregset_t;
-typedef elf_fpregset_t prfpregset_t;
-
-/* We don't have any differences between processes and threads,
- therefore have only one PID type. */
-typedef __kernel_pid_t lwpid_t;
-
-/* Process status and info. In the end we do provide typedefs for them. */
-typedef struct elf_prstatus prstatus_t;
-typedef struct elf_prpsinfo prpsinfo_t;
-
-
-#endif /* sys/procfs.h */
diff --git a/libc/sysdeps/linux/v850/sys/ptrace.h b/libc/sysdeps/linux/v850/sys/ptrace.h
deleted file mode 100644
index 2490b10..0000000
--- a/libc/sysdeps/linux/v850/sys/ptrace.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* `ptrace' debugger support interface. Linux/v850 version.
- Copyright (C) 2001, 2002, 2003 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 _SYS_PTRACE_H
-#define _SYS_PTRACE_H 1
-
-#include <features.h>
-
-__BEGIN_DECLS
-
-/* Type of the REQUEST argument to `ptrace.' */
-enum __ptrace_request
-{
- /* Indicate that the process making this request should be traced.
- All signals received by this process can be intercepted by its
- parent, and its parent can use the other `ptrace' requests. */
- PTRACE_TRACEME = 0,
-#define PT_TRACE_ME PTRACE_TRACEME
-
- /* Return the word in the process's text space at address ADDR. */
- PTRACE_PEEKTEXT = 1,
-#define PT_READ_I PTRACE_PEEKTEXT
-
- /* Return the word in the process's data space at address ADDR. */
- PTRACE_PEEKDATA = 2,
-#define PT_READ_D PTRACE_PEEKDATA
-
- /* Return the word in the process's user area at offset ADDR. */
- PTRACE_PEEKUSER = 3,
-#define PT_READ_U PTRACE_PEEKUSER
-
- /* Write the word DATA into the process's text space at address ADDR. */
- PTRACE_POKETEXT = 4,
-#define PT_WRITE_I PTRACE_POKETEXT
-
- /* Write the word DATA into the process's data space at address ADDR. */
- PTRACE_POKEDATA = 5,
-#define PT_WRITE_D PTRACE_POKEDATA
-
- /* Write the word DATA into the process's user area at offset ADDR. */
- PTRACE_POKEUSER = 6,
-#define PT_WRITE_U PTRACE_POKEUSER
-
- /* Continue the process. */
- PTRACE_CONT = 7,
-#define PT_CONTINUE PTRACE_CONT
-
- /* Kill the process. */
- PTRACE_KILL = 8,
-#define PT_KILL PTRACE_KILL
-
- /* Single step the process. */
- PTRACE_SINGLESTEP = 9,
-#define PT_STEP PTRACE_SINGLESTEP
-
- /* Attach to a process that is already running. */
- PTRACE_ATTACH = 16,
-#define PT_ATTACH PTRACE_ATTACH
-
- /* Detach from a process attached to with PTRACE_ATTACH. */
- PTRACE_DETACH = 17,
-#define PT_DETACH PTRACE_DETACH
-
- /* Continue and stop at the next (return from) syscall. */
- PTRACE_SYSCALL = 24
-#define PT_SYSCALL PTRACE_SYSCALL
-};
-
-/* Perform process tracing functions. REQUEST is one of the values
- above, and determines the action to be taken.
- For all requests except PTRACE_TRACEME, PID specifies the process to be
- traced.
-
- PID and the other arguments described above for the various requests should
- appear (those that are used for the particular request) as:
- pid_t PID, void *ADDR, int DATA, void *ADDR2
- after REQUEST. */
-extern long int ptrace (enum __ptrace_request __request, ...) __THROW;
-
-__END_DECLS
-
-#endif /* _SYS_PTRACE_H */
diff --git a/libc/sysdeps/linux/v850/sys/ucontext.h b/libc/sysdeps/linux/v850/sys/ucontext.h
deleted file mode 100644
index 7c5e303..0000000
--- a/libc/sysdeps/linux/v850/sys/ucontext.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 1997, 1998, 1999 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 _SYS_UCONTEXT_H
-#define _SYS_UCONTEXT_H 1
-
-#include <features.h>
-#include <signal.h>
-
-/* We need the signal context definitions even if they are not used
- included in <signal.h>. */
-#include <bits/sigcontext.h>
-
-typedef struct sigcontext mcontext_t;
-
-/* Userlevel context. */
-typedef struct ucontext
- {
- unsigned long int uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
- } ucontext_t;
-
-#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/v850/syscall.c b/libc/sysdeps/linux/v850/syscall.c
deleted file mode 100644
index dbcc87c..0000000
--- a/libc/sysdeps/linux/v850/syscall.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/syscall.c -- generic syscall function for linux/v850
- *
- * Copyright (C) 2002 NEC Corporation
- * Copyright (C) 2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <errno.h>
-#include <sys/syscall.h>
-
-typedef unsigned long arg_t;
-
-/* Invoke `system call' NUM, passing it the remaining arguments.
- This is completely system-dependent, and not often useful. */
-long
-syscall (long num, arg_t a1, arg_t a2, arg_t a3, arg_t a4, arg_t a5, arg_t a6)
-{
- /* We don't know how many arguments are valid, so A5 and A6 are fetched
- off the stack even for (the majority of) system calls with fewer
- arguments; hopefully this won't cause any problems. A1-A4 are in
- registers, so they're OK. */
- register arg_t a __asm__ (SYSCALL_ARG0) = a1;
- register arg_t b __asm__ (SYSCALL_ARG1) = a2;
- register arg_t c __asm__ (SYSCALL_ARG2) = a3;
- register arg_t d __asm__ (SYSCALL_ARG3) = a4;
- register arg_t e __asm__ (SYSCALL_ARG4) = a5;
- register arg_t f __asm__ (SYSCALL_ARG5) = a6;
- register unsigned long syscall __asm__ (SYSCALL_NUM) = num;
- register unsigned long ret __asm__ (SYSCALL_RET);
-
- __asm__ ("trap " SYSCALL_LONG_TRAP
- : "=r" (ret)
- : "r" (syscall), "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f)
- : SYSCALL_CLOBBERS);
-
- __syscall_return (long, ret);
-}
diff --git a/libc/sysdeps/linux/v850/vfork.S b/libc/sysdeps/linux/v850/vfork.S
deleted file mode 100644
index b67ebf8..0000000
--- a/libc/sysdeps/linux/v850/vfork.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * libc/sysdeps/linux/v850/vfork.S -- `vfork' syscall for linux/v850
- *
- * Copyright (C) 2001,2002 NEC Corporation
- * Copyright (C) 2001,2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#include <sys/syscall.h>
-#include <clinkage.h>
-
-/* Clone the calling process, but without copying the whole address space.
- The calling process is suspended until the new process exits or is
- replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
- and the process ID of the new process to the old process. */
-
-/* this should be made hidden */
-C_ENTRY (__vfork):
- addi SYS_vfork, r0, r12
- trap 0
- addi -125, r0, r11 /* minimum err value */
- cmp r11, r10
- bh 1f
- jmp [lp] /* normal return */
-1: mov hilo(C_SYMBOL_NAME(errno)), r11
- subr r0, r10
- st.w r10, 0[r11]
- jmp [lp] /* error return */
-C_END(__vfork)
-weak_alias(__vfork,vfork)
-libc_hidden_def(vfork)
diff --git a/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h b/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h
index de450ff..f5408ad 100644
--- a/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h
+++ b/libpthread/linuxthreads/sysdeps/microblaze/sigcontextinfo.h
@@ -1,5 +1,5 @@
/*
- * sysdeps/v850/sigcontextinfo.h -- v850-specific pthread signal definitions
+ * sysdeps/microblaze/sigcontextinfo.h -- microblaze-specific pthread signal definitions
*
* Copyright (C) 2002 NEC Electronics Corporation
* Copyright (C) 2002 Miles Bader <miles(a)gnu.org>
diff --git a/libpthread/linuxthreads/sysdeps/v850/pt-machine.h b/libpthread/linuxthreads/sysdeps/v850/pt-machine.h
deleted file mode 100644
index 34de63b..0000000
--- a/libpthread/linuxthreads/sysdeps/v850/pt-machine.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * sysdeps/v850/pt-machine.h -- v850-specific pthread definitions
- *
- * Copyright (C) 2002 NEC Electronics Corporation
- * Copyright (C) 2002 Miles Bader <miles(a)gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Miles Bader <miles(a)gnu.org>
- */
-
-#ifndef _PT_MACHINE_H
-#define _PT_MACHINE_H 1
-
-#include <features.h>
-
-#ifndef PT_EI
-# define PT_EI __extern_always_inline
-#endif
-
-/* Get some notion of the current stack. Need not be exactly the top
- of the stack, just something somewhere in the current frame. */
-#define CURRENT_STACK_FRAME __stack_pointer
-register char *__stack_pointer __asm__ ("sp");
-
-#define HAS_COMPARE_AND_SWAP
-
-/* Atomically: If *PTR == OLD, set *PTR to NEW and return true,
- otherwise do nothing and return false. */
-PT_EI int
-__compare_and_swap (long *ptr, long old, long new)
-{
- unsigned long psw;
-
- /* disable interrupts */
- __asm__ __volatile__ ("stsr psw, %0; di" : "=&r" (psw));
-
- if (likely (*ptr == old))
- {
- *ptr = new;
- __asm__ __volatile__ ("ldsr %0, psw" :: "r" (psw)); /* re-enable */
- return 1;
- }
- else
- {
- __asm__ __volatile__ ("ldsr %0, psw" :: "r" (psw)); /* re-enable */
- return 0;
- }
-}
-#endif /* pt-machine.h */
diff --git a/test/Rules.mak b/test/Rules.mak
index 86ea855..9416a0c 100644
--- a/test/Rules.mak
+++ b/test/Rules.mak
@@ -50,7 +50,6 @@ TARGET_ARCH:=$(shell $(CC) -dumpmachine | sed -e s'/-.*//' \
-e 's/m68k.*/m68k/' \
-e 's/parisc.*/hppa/' \
-e 's/ppc/powerpc/g' \
- -e 's/v850.*/v850/g' \
-e 's/sh[234]/sh/' \
-e 's/mips.*/mips/' \
-e 's/cris.*/cris/' \
diff --git a/utils/ldd.c b/utils/ldd.c
index 7e1c314..7fd4f7b 100644
--- a/utils/ldd.c
+++ b/utils/ldd.c
@@ -91,11 +91,6 @@
#define ELFCLASSM ELFCLASS32
#endif
-#if defined(__v850e__)
-#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
-#define ELFCLASSM ELFCLASS32
-#endif
-
#if defined(__sparc__)
#define MATCH_MACHINE(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
#define ELFCLASSM ELFCLASS32
hooks/post-receive
--
uClibc-ng - small C library for embedded systems
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The branch, master has been updated
via 49b3d8569a8c8cb724ba6eadb34dea2df9b5ec4d (commit)
via b778f37b8395a3258925e13a706dbc7d43c7c0ed (commit)
via e6555c6f15da4545496c02ba569f3bc61e2a0210 (commit)
via a312047276043f460d796ed7b38ca52791eef386 (commit)
via de234fb71b8847e00007dd951e22091d8e954c7b (commit)
via 2ffb76519c1369c239364bd5bc11e6a92937b7e9 (commit)
via 382c1c583cd55486c654cd9e1d429e2b1256acda (commit)
via 990f2ce7da5ee67599d6d8a12b681713776275e0 (commit)
via 5659e2a1c763a51957c3e9bd13737534a1d894c6 (commit)
via 7807bd3ada8b488167f1e5ab486ef0feb560eab8 (commit)
from 6c718953a5d42a1a815af39f276aa0fa47e75e4b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 49b3d8569a8c8cb724ba6eadb34dea2df9b5ec4d
Author: Steve Ellcey <sellcey(a)imgtec.com>
Date: Wed Dec 23 08:38:41 2015 -0800
Replace bltzal with lapc for MIPS R6 builds.
The R6 version of MIPS does not support the bltzal instruction. This
patch changes dl-startup.h and dl-sysdep.h to use lapc on R6 instead.
lapc is a new R6 insruction so older systems need to continue to use
bltzal in order to load register $31.
Signed-off-by: Steve Ellcey <sellcey(a)imgtec.com>
commit b778f37b8395a3258925e13a706dbc7d43c7c0ed
Author: Steve Ellcey <sellcey(a)imgtec.com>
Date: Mon Dec 21 13:22:07 2015 -0800
Replace MIPS specific memcpy.S/memset.S with version from glibc/newlib.
These MIPS specific versions of memcpy.S and memset.S are faster than
the current ones and match what is in newlib and glibc. They also have
support for the mips32r6 and mips64r6 architectures.
Signed-off-by: Steve Ellcey <sellcey(a)imgtec.com>
commit e6555c6f15da4545496c02ba569f3bc61e2a0210
Author: Nicolas S. Dade <nic.dade(a)gmail.com>
Date: Fri Dec 18 19:39:19 2015 -0800
pselect: Use linux pselect syscall when available
Linux has a pselect syscall since 2.6.something. Using it
rather than emulating it with sigprocmask+select+sigprocmask
is smaller code, and works properly. (The emulation has
race conditions when unblocked signals arrive before or
after the select)
The tv.nsec >= 1E9 handling comes from uclibc's linux select()
implementation, which itself uses pselect() internally if the
pselect syscall exists. I though it would be good to do the
same here.
Note that although the libc pselect() API has 6 arguments,
the linux kernel syscall as 7 arguments. There is an extra,
somewhat vestigial, sizeof the signal mask argument.
Signed-off-by: Nicolas S. Dade <nic.dade(a)gmail.com>
commit a312047276043f460d796ed7b38ca52791eef386
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:58:08 2015 +0100
libc/pwd_grp: Create template for non-reentrant functions
Avoid a lot of copy'n'paste code, no functionality change
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit de234fb71b8847e00007dd951e22091d8e954c7b
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:56:08 2015 +0100
Use gcc's __builtin_mempcpy() as __mempcpy(), if possible
Patch from OpenWrt.
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 2ffb76519c1369c239364bd5bc11e6a92937b7e9
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:51:13 2015 +0100
use arch specific thread stack size for nptl
Use the arch specific thread stack size for nptl if the size
returned by getrlimits exceeds it - fixes threads on systems
with only 16 MB RAM.
Patch from OpenWRT
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 382c1c583cd55486c654cd9e1d429e2b1256acda
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:52:55 2015 +0100
Do define some IPv6 related symbols even with IPv6 disabled
Fixes compilation of some faulty applictions.
Patch from Freetz.org
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 990f2ce7da5ee67599d6d8a12b681713776275e0
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:47:56 2015 +0100
resolv: fix gethostbyname2_r to match gethostbyname_r, fixing bugs with AAAA lookups
The latter half of gethostbyname2_r (doing AAAA queries) is rather dramatically different
from the corresponding portion of gethostbyname_r (doing A queries). This leads to problems
like calls to getaddrinfo only returning one IPv6 address, even when multiple exist.
Seems to be entirely a case of divergent evolution -- a half-decade of fixes for the IPv4
code but no love for IPv6. Until now. ;)
DNS behaviour for IPv6 is really no different than for IPv4 -- beyond the difference in
address sizes, there's no need for the functions to be so different.
Consequently, this patch really is almost just a cut-and-paste of gethostbyname_r, with
the appropriate substitutions of in6_addr, AF_INET6, etc; while holding on to the few
extra bits that actually belong in there (eg #ifdef __UCLIBC_HAS_IPV6__).
Signed-off-by: Wes Campaigne <westacular(a)gmail.com>
commit 5659e2a1c763a51957c3e9bd13737534a1d894c6
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:45:51 2015 +0100
inet/resolv: Fix broken h_aliases list terminator after 2dab3f5
Commit 2dab3f5a "resolv: tiny shrinkage in /etc/hosts handling" leads to
that read_etc_hosts_r() provide garbage pointer at the end of h_aliases
list if more than four hostnames follow a dotted quad in /etc/hosts
Test-case:
Add following line to /etc/hosts
63.63.0.2 host1 alias2 alias3 alias4 alias5
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main (void)
{
int i;
char *a;
struct hostent *he;
struct in_addr ipv4addr;
inet_pton(AF_INET, "63.63.0.2", &ipv4addr);
he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
if (he == NULL)
exit(1);
printf("Host name: '%s'\n", he->h_name);
i = 0;
while ((a = he->h_aliases[i]) != NULL) {
printf("Host alias: '%s'\n", a);
++i;
}
return 0;
}
Wrong output:
Host name: 'host1'
Host alias: 'alias2'
Host alias: 'alias3'
Host alias: 'alias4'
Host alias: 'alias5'
Host alias: '??'
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
commit 7807bd3ada8b488167f1e5ab486ef0feb560eab8
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Thu Dec 17 21:07:07 2015 +0100
Revert "glibc compat: bump glibc minor version"
This reverts commit 4a05ed87ceb946608100642121c32e642b58cd0d.
This breaks SSP detection for gcc, which might be problematic
for some projects. Revert it after some discussion with
buildroot and openembedded people.
-----------------------------------------------------------------------
Summary of changes:
include/features.h | 2 +-
include/string.h | 4 +-
ldso/ldso/mips/dl-startup.h | 5 +
ldso/ldso/mips/dl-sysdep.h | 5 +
libc/inet/resolv.c | 165 ++++--
libc/pwd_grp/fgetgrent.c | 12 +-
libc/pwd_grp/fgetpwent.c | 12 +-
libc/pwd_grp/fgetspent.c | 6 +-
libc/pwd_grp/getgrent.c | 5 +-
libc/pwd_grp/getgrgid.c | 6 +-
libc/pwd_grp/getgrgid_r.c | 7 +-
libc/pwd_grp/getgrnam.c | 6 +-
libc/pwd_grp/getgrnam_r.c | 7 +-
libc/pwd_grp/getpwent.c | 5 +-
libc/pwd_grp/getpwnam.c | 7 +-
libc/pwd_grp/getpwnam_r.c | 7 +-
libc/pwd_grp/getpwuid.c | 6 +-
libc/pwd_grp/getpwuid_r.c | 7 +-
libc/pwd_grp/getspent.c | 5 +-
libc/pwd_grp/getspnam.c | 6 +-
libc/pwd_grp/getspnam_r.c | 7 +-
libc/pwd_grp/pwd_grp.c | 263 +--------
libc/pwd_grp/pwd_grp_internal.c | 49 +-
libc/pwd_grp/sgetspent.c | 6 +-
libc/string/generic/mempcpy.c | 1 +
libc/string/mips/memcpy.S | 1051 +++++++++++++++++++++++++++--------
libc/string/mips/memset.S | 516 +++++++++++++----
libc/sysdeps/linux/common/bits/in.h | 2 +-
libc/sysdeps/linux/common/pselect.c | 52 ++
libpthread/nptl/init.c | 4 +
30 files changed, 1549 insertions(+), 687 deletions(-)
diff --git a/include/features.h b/include/features.h
index f6fbbf4..dcf1348 100644
--- a/include/features.h
+++ b/include/features.h
@@ -393,7 +393,7 @@ uClibc was built without large file support enabled.
these macros to test for features in specific releases. */
/* Don't do it, if you want to keep uClibc happy. */
#define __GLIBC__ 2
-#define __GLIBC_MINOR__ 10
+#define __GLIBC_MINOR__ 2
#endif
#define __GLIBC_PREREQ(maj, min) \
diff --git a/include/string.h b/include/string.h
index 1d75f44..80585ef 100644
--- a/include/string.h
+++ b/include/string.h
@@ -258,7 +258,9 @@ extern void *memmem (const void *__haystack, size_t __haystacklen,
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
last written byte. */
-#if 0 /* uClibc: disabled */
+#if __GNUC_PREREQ (3, 4)
+# define __mempcpy(dest, src, n) __builtin_mempcpy(dest, src, n)
+#else /* uClibc: disabled */
extern void *__mempcpy (void *__restrict __dest,
const void *__restrict __src, size_t __n)
__THROW __nonnull ((1, 2));
diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h
index 4d9918d..0cab7be 100644
--- a/ldso/ldso/mips/dl-startup.h
+++ b/ldso/ldso/mips/dl-startup.h
@@ -37,6 +37,7 @@ __asm__(""
#if _MIPS_SIM == _MIPS_SIM_ABI32
" subu $29, 16\n"
#endif
+# if !defined __mips_isa_rev || __mips_isa_rev < 6
#if _MIPS_SIM == _MIPS_SIM_ABI64
" dla $8, .coff\n"
#else /* O32 || N32 */
@@ -44,6 +45,10 @@ __asm__(""
#endif /* O32 || N32 */
" bltzal $8, .coff\n"
".coff:\n"
+# else
+ ".coff:\n"
+ " lapc $31, .coff\n"
+# endif
#if _MIPS_SIM == _MIPS_SIM_ABI64
" dsubu $8, $31, $8\n"
" dla $25, _dl_start\n"
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 6041245..b2caa7f 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/ldso/ldso/mips/dl-sysdep.h
@@ -225,10 +225,15 @@ elf_machine_load_address (void)
{
ElfW(Addr) addr;
__asm__ (" .set noreorder\n"
+# if !defined __mips_isa_rev || __mips_isa_rev < 6
" " STRINGXP (PTR_LA) " %0, 0f\n"
" bltzal $0, 0f\n"
" nop\n"
"0: " STRINGXP (PTR_SUBU) " %0, $31, %0\n"
+#else
+ "0: lapc $31, 0\n"
+ " " STRINGXP (PTR_SUBU) " %0, $31, %0\n"
+#endif
" .set reorder\n"
: "=r" (addr)
: /* No inputs */
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index bd2c6fc..c7487a6 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1596,7 +1596,7 @@ parser_t * __open_etc_hosts(void)
#define MINTOKENS 2 /* ip address + canonical name */
#define MAXTOKENS (MINTOKENS + MAXALIASES)
-#define HALISTOFF (sizeof(char*) * MAXTOKENS)
+#define HALISTOFF (sizeof(char*) * (MAXTOKENS + 1)) /* reserve space for list terminator */
#define INADDROFF (HALISTOFF + 2 * sizeof(char*))
int __read_etc_hosts_r(
@@ -2197,12 +2197,13 @@ int gethostbyname2_r(const char *name,
? gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop)
: HOST_NOT_FOUND;
#else
- struct in6_addr *in;
struct in6_addr **addr_list;
+ char **alias;
+ char *alias0;
unsigned char *packet;
struct resolv_answer a;
int i;
- int nest = 0;
+ int packet_len;
int wrong_af = 0;
if (family == AF_INET)
@@ -2217,9 +2218,8 @@ int gethostbyname2_r(const char *name,
/* do /etc/hosts first */
{
- int old_errno = errno; /* Save the old errno and reset errno */
- __set_errno(0); /* to check for missing /etc/hosts. */
-
+ int old_errno = errno; /* save the old errno and reset errno */
+ __set_errno(0); /* to check for missing /etc/hosts. */
i = __get_hosts_byname_r(name, AF_INET6 /*family*/, result_buf,
buf, buflen, result, h_errnop);
if (i == NETDB_SUCCESS) {
@@ -2241,42 +2241,58 @@ int gethostbyname2_r(const char *name,
}
__set_errno(old_errno);
}
+
DPRINTF("Nothing found in /etc/hosts\n");
*h_errnop = NETDB_INTERNAL;
+ /* prepare future h_aliases[0] */
+ i = strlen(name) + 1;
+ if ((ssize_t)buflen <= i)
+ return ERANGE;
+ memcpy(buf, name, i); /* paranoia: name might change */
+ alias0 = buf;
+ buf += i;
+ buflen -= i;
/* make sure pointer is aligned */
i = ALIGN_BUFFER_OFFSET(buf);
buf += i;
buflen -= i;
/* Layout in buf:
- * struct in6_addr* in;
- * struct in6_addr* addr_list[2];
- * char scratch_buf[256];
+ * char *alias[2];
+ * struct in6_addr* addr_list[NN+1];
+ * struct in6_addr* in[NN];
*/
- in = (struct in6_addr*)buf;
- buf += sizeof(*in);
- buflen -= sizeof(*in);
- addr_list = (struct in6_addr**)buf;
- buf += sizeof(*addr_list) * 2;
- buflen -= sizeof(*addr_list) * 2;
+ alias = (char **)buf;
+ buf += sizeof(alias[0]) * 2;
+ buflen -= sizeof(alias[0]) * 2;
+ addr_list = (struct in6_addr **)buf;
+ /* buflen may be < 0, must do signed compare */
if ((ssize_t)buflen < 256)
return ERANGE;
- addr_list[0] = in;
- addr_list[1] = NULL;
- strncpy(buf, name, buflen);
- buf[buflen] = '\0';
+
+ /* we store only one "alias" - the name itself */
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO -- generate the full list
+#endif
+ alias[0] = alias0;
+ alias[1] = NULL;
/* maybe it is already an address? */
- if (inet_pton(AF_INET6, name, in)) {
- result_buf->h_name = buf;
- result_buf->h_addrtype = AF_INET6;
- result_buf->h_length = sizeof(*in);
- result_buf->h_addr_list = (char **) addr_list;
- /* result_buf->h_aliases = ??? */
- *result = result_buf;
- *h_errnop = NETDB_SUCCESS;
- return NETDB_SUCCESS;
+ {
+ struct in6_addr *in = (struct in6_addr *)(buf + sizeof(addr_list[0]) * 2);
+ if (inet_pton(AF_INET6, name, in)) {
+ addr_list[0] = in;
+ addr_list[1] = NULL;
+ result_buf->h_name = alias0;
+ result_buf->h_aliases = alias;
+ result_buf->h_addrtype = AF_INET6;
+ result_buf->h_length = sizeof(struct in6_addr);
+ result_buf->h_addr_list = (char **) addr_list;
+ *result = result_buf;
+ *h_errnop = NETDB_SUCCESS;
+ return NETDB_SUCCESS;
+ }
}
/* what if /etc/hosts has it but it's not IPv6?
@@ -2288,51 +2304,80 @@ int gethostbyname2_r(const char *name,
}
/* talk to DNS servers */
-/* TODO: why it's so different from gethostbyname_r (IPv4 case)? */
- memset(&a, '\0', sizeof(a));
- for (;;) {
- int packet_len;
+ a.buf = buf;
+ /* take into account that at least one address will be there,
+ * we'll need space of one in6_addr + two addr_list[] elems */
+ a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in6_addr)));
+ a.add_count = 0;
+ packet_len = __dns_lookup(name, T_AAAA, &packet, &a);
+ if (packet_len < 0) {
+ *h_errnop = HOST_NOT_FOUND;
+ DPRINTF("__dns_lookup returned < 0\n");
+ return TRY_AGAIN;
+ }
-/* Hmm why we memset(a) to zeros only once? */
- packet_len = __dns_lookup(buf, T_AAAA, &packet, &a);
- if (packet_len < 0) {
- *h_errnop = HOST_NOT_FOUND;
- return TRY_AGAIN;
+ if (a.atype == T_AAAA) { /* ADDRESS */
+ /* we need space for addr_list[] and one IPv6 address */
+ /* + 1 accounting for 1st addr (it's in a.rdata),
+ * another + 1 for NULL in last addr_list[]: */
+ int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1)
+ /* for 1st addr (it's in a.rdata): */
+ + sizeof(struct in6_addr);
+ /* how many bytes will 2nd and following addresses take? */
+ int ips_len = a.add_count * a.rdlength;
+
+ buflen -= (need_bytes + ips_len);
+ if ((ssize_t)buflen < 0) {
+ DPRINTF("buffer too small for all addresses\n");
+ /* *h_errnop = NETDB_INTERNAL; - already is */
+ i = ERANGE;
+ goto free_and_ret;
}
- strncpy(buf, a.dotted, buflen);
- free(a.dotted);
- if (a.atype != T_CNAME)
- break;
+ /* if there are additional addresses in buf,
+ * move them forward so that they are not destroyed */
+ DPRINTF("a.add_count:%d a.rdlength:%d a.rdata:%p\n", a.add_count, a.rdlength, a.rdata);
+ memmove(buf + need_bytes, buf, ips_len);
- DPRINTF("Got a CNAME in gethostbyname()\n");
- if (++nest > MAX_RECURSE) {
- *h_errnop = NO_RECOVERY;
- return -1;
+ /* 1st address is in a.rdata, insert it */
+ buf += need_bytes - sizeof(struct in6_addr);
+ memcpy(buf, a.rdata, sizeof(struct in6_addr));
+
+ /* fill addr_list[] */
+ for (i = 0; i <= a.add_count; i++) {
+ addr_list[i] = (struct in6_addr*)buf;
+ buf += sizeof(struct in6_addr);
}
- i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
- free(packet);
- if (i < 0) {
- *h_errnop = NO_RECOVERY;
- return -1;
+ addr_list[i] = NULL;
+
+ /* if we have enough space, we can report "better" name
+ * (it may contain search domains attached by __dns_lookup,
+ * or CNAME of the host if it is different from the name
+ * we used to find it) */
+ if (a.dotted && buflen > strlen(a.dotted)) {
+ strcpy(buf, a.dotted);
+ alias0 = buf;
}
- }
- if (a.atype == T_AAAA) { /* ADDRESS */
- memcpy(in, a.rdata, sizeof(*in));
- result_buf->h_name = buf;
+
+ result_buf->h_name = alias0;
+ result_buf->h_aliases = alias;
result_buf->h_addrtype = AF_INET6;
- result_buf->h_length = sizeof(*in);
+ result_buf->h_length = sizeof(struct in6_addr);
result_buf->h_addr_list = (char **) addr_list;
- /* result_buf->h_aliases = ??? */
- free(packet);
*result = result_buf;
*h_errnop = NETDB_SUCCESS;
- return NETDB_SUCCESS;
+ i = NETDB_SUCCESS;
+ goto free_and_ret;
}
- free(packet);
+
*h_errnop = HOST_NOT_FOUND;
- return TRY_AGAIN;
+ __set_h_errno(HOST_NOT_FOUND);
+ i = TRY_AGAIN;
+ free_and_ret:
+ free(a.dotted);
+ free(packet);
+ return i;
#endif /* __UCLIBC_HAS_IPV6__ */
}
libc_hidden_def(gethostbyname2_r)
diff --git a/libc/pwd_grp/fgetgrent.c b/libc/pwd_grp/fgetgrent.c
index 695aee1..6a45799 100644
--- a/libc/pwd_grp/fgetgrent.c
+++ b/libc/pwd_grp/fgetgrent.c
@@ -4,5 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetgrent
+#include <features.h>
+
+#ifdef __USE_SVID
+
+#define GETXXKEY_FUNC fgetgrent
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
+
+#endif
diff --git a/libc/pwd_grp/fgetpwent.c b/libc/pwd_grp/fgetpwent.c
index ddcc7ff..6f65cf6 100644
--- a/libc/pwd_grp/fgetpwent.c
+++ b/libc/pwd_grp/fgetpwent.c
@@ -4,5 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetpwent
+#include <features.h>
+
+#ifdef __USE_SVID
+
+#define GETXXKEY_FUNC fgetpwent
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
+
+#endif
diff --git a/libc/pwd_grp/fgetspent.c b/libc/pwd_grp/fgetspent.c
index b7c1ef2..77ca0b8 100644
--- a/libc/pwd_grp/fgetspent.c
+++ b/libc/pwd_grp/fgetspent.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetspent
+#define GETXXKEY_FUNC fgetspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrent.c b/libc/pwd_grp/getgrent.c
index 808e4e8..5b03b31 100644
--- a/libc/pwd_grp/getgrent.c
+++ b/libc/pwd_grp/getgrent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrent
+#define GETXXKEY_FUNC getgrent
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c
index 96ce903..2988452 100644
--- a/libc/pwd_grp/getgrgid.c
+++ b/libc/pwd_grp/getgrgid.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrgid
+#define GETXXKEY_FUNC getgrgid
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS gid_t git
+#define GETXXKEY_ADD_VARIABLES git
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrgid_r.c b/libc/pwd_grp/getgrgid_r.c
index a962f4c..b0f0c9a 100644
--- a/libc/pwd_grp/getgrgid_r.c
+++ b/libc/pwd_grp/getgrgid_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrgid_r
+#define GETXXKEY_R_FUNC getgrgid_r
+#define GETXXKEY_R_PARSER __parsegrent
+#define GETXXKEY_R_ENTTYPE struct group
+#define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key)
+#define DO_GETXXKEY_R_KEYTYPE gid_t
+#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c
index 3b47d9a..f6ce459 100644
--- a/libc/pwd_grp/getgrnam.c
+++ b/libc/pwd_grp/getgrnam.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrnam
+#define GETXXKEY_FUNC getgrnam
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrnam_r.c b/libc/pwd_grp/getgrnam_r.c
index 592a66c..35121e7 100644
--- a/libc/pwd_grp/getgrnam_r.c
+++ b/libc/pwd_grp/getgrnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrnam_r
+#define GETXXKEY_R_FUNC getgrnam_r
+#define GETXXKEY_R_PARSER __parsegrent
+#define GETXXKEY_R_ENTTYPE struct group
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwent.c b/libc/pwd_grp/getpwent.c
index a617bc8..7ddc8ee 100644
--- a/libc/pwd_grp/getpwent.c
+++ b/libc/pwd_grp/getpwent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwent
+#define GETXXKEY_FUNC getpwent
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c
index d00640b..e3e8c02 100644
--- a/libc/pwd_grp/getpwnam.c
+++ b/libc/pwd_grp/getpwnam.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwnam
+#define GETXXKEY_FUNC getpwnam
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
+#define GETXXKEY_FUNC_HIDDEN
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwnam_r.c b/libc/pwd_grp/getpwnam_r.c
index a4440e7..bc5e3d5 100644
--- a/libc/pwd_grp/getpwnam_r.c
+++ b/libc/pwd_grp/getpwnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwnam_r
+#define GETXXKEY_R_FUNC getpwnam_r
+#define GETXXKEY_R_PARSER __parsepwent
+#define GETXXKEY_R_ENTTYPE struct passwd
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c
index 16ac50f..1ad2688 100644
--- a/libc/pwd_grp/getpwuid.c
+++ b/libc/pwd_grp/getpwuid.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwuid
+#define GETXXKEY_FUNC getpwuid
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS uid_t uid
+#define GETXXKEY_ADD_VARIABLES uid
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwuid_r.c b/libc/pwd_grp/getpwuid_r.c
index 21d39ed..0a5aa96 100644
--- a/libc/pwd_grp/getpwuid_r.c
+++ b/libc/pwd_grp/getpwuid_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwuid_r
+#define GETXXKEY_R_FUNC getpwuid_r
+#define GETXXKEY_R_PARSER __parsepwent
+#define GETXXKEY_R_ENTTYPE struct passwd
+#define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key)
+#define DO_GETXXKEY_R_KEYTYPE uid_t
+#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspent.c b/libc/pwd_grp/getspent.c
index 5699b67..4feb9f9 100644
--- a/libc/pwd_grp/getspent.c
+++ b/libc/pwd_grp/getspent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspent
+#define GETXXKEY_FUNC getspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspnam.c b/libc/pwd_grp/getspnam.c
index 19e40c7..a0a01ec 100644
--- a/libc/pwd_grp/getspnam.c
+++ b/libc/pwd_grp/getspnam.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspnam
+#define GETXXKEY_FUNC getspnam
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspnam_r.c b/libc/pwd_grp/getspnam_r.c
index 053b697..ea23848 100644
--- a/libc/pwd_grp/getspnam_r.c
+++ b/libc/pwd_grp/getspnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspnam_r
+#define GETXXKEY_R_FUNC getspnam_r
+#define GETXXKEY_R_PARSER __parsespent
+#define GETXXKEY_R_ENTTYPE struct spwd
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c
index 0e7c7f7..acdb08d 100644
--- a/libc/pwd_grp/pwd_grp.c
+++ b/libc/pwd_grp/pwd_grp.c
@@ -127,59 +127,6 @@ libc_hidden_def(fgetspent_r)
#endif
/**********************************************************************/
-/* For the various fget??ent funcs, return NULL on failure and a
- * pointer to the appropriate struct (statically allocated) on success.
- */
-/**********************************************************************/
-#ifdef L_fgetpwent
-
-#ifdef __USE_SVID
-
-struct passwd *fgetpwent(FILE *stream)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- fgetpwent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_fgetgrent
-
-#ifdef __USE_SVID
-
-struct group *fgetgrent(FILE *stream)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- fgetgrent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_fgetspent
-
-
-struct spwd *fgetspent(FILE *stream)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- fgetspent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_sgetspent_r
int sgetspent_r(const char *string, struct spwd *result_buf,
@@ -213,92 +160,6 @@ libc_hidden_def(sgetspent_r)
#endif
/**********************************************************************/
-
-#ifdef GETXXKEY_R_FUNC
-#error GETXXKEY_R_FUNC is already defined!
-#endif
-
-#ifdef L_getpwnam_r
-#define GETXXKEY_R_FUNC getpwnam_r
-#define GETXXKEY_R_PARSER __parsepwent
-#define GETXXKEY_R_ENTTYPE struct passwd
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getgrnam_r
-#define GETXXKEY_R_FUNC getgrnam_r
-#define GETXXKEY_R_PARSER __parsegrent
-#define GETXXKEY_R_ENTTYPE struct group
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getspnam_r
-#define GETXXKEY_R_FUNC getspnam_r
-#define GETXXKEY_R_PARSER __parsespent
-#define GETXXKEY_R_ENTTYPE struct spwd
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getpwuid_r
-#define GETXXKEY_R_FUNC getpwuid_r
-#define GETXXKEY_R_PARSER __parsepwent
-#define GETXXKEY_R_ENTTYPE struct passwd
-#define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key)
-#define DO_GETXXKEY_R_KEYTYPE uid_t
-#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getgrgid_r
-#define GETXXKEY_R_FUNC getgrgid_r
-#define GETXXKEY_R_PARSER __parsegrent
-#define GETXXKEY_R_ENTTYPE struct group
-#define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key)
-#define DO_GETXXKEY_R_KEYTYPE gid_t
-#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
-#include "pwd_grp_internal.c"
-#endif
-
-/**********************************************************************/
-#ifdef L_getpwuid
-
-
-struct passwd *getpwuid(uid_t uid)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrgid
-
-
-struct group *getgrgid(gid_t gid)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- getgrgid_r(gid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_getspuid_r
/* This function is non-standard and is currently not built. It seems
@@ -325,69 +186,6 @@ int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf,
#endif
/**********************************************************************/
-#ifdef L_getspuid
-
-/* This function is non-standard and is currently not built.
- * Why it was added, I do not know. */
-
-struct spwd *getspuid(uid_t uid)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- getspuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getpwnam
-
-
-struct passwd *getpwnam(const char *name)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- getpwnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-libc_hidden_def(getpwnam)
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrnam
-
-
-struct group *getgrnam(const char *name)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- getgrnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getspnam
-
-
-struct spwd *getspnam(const char *name)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- getspnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_getpw
@@ -585,65 +383,14 @@ libc_hidden_def(getspent_r)
#endif
/**********************************************************************/
-#ifdef L_getpwent
-
-
-struct passwd *getpwent(void)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd pwd;
- struct passwd *result;
-
- getpwent_r(&pwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrent
-
-
-struct group *getgrent(void)
-{
- static char line_buff[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group gr;
- struct group *result;
-
- getgrent_r(&gr, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
-#endif
+/* For the various fget??ent funcs, return NULL on failure and a
+ * pointer to the appropriate struct (statically allocated) on success.
+ */
/**********************************************************************/
-#ifdef L_getspent
-
-
-struct spwd *getspent(void)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd spwd;
- struct spwd *result;
-
- getspent_r(&spwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
+#if defined(GETXXKEY_FUNC) || defined(GETXXKEY_R_FUNC)
+#include "pwd_grp_internal.c"
#endif
-/**********************************************************************/
-#ifdef L_sgetspent
-
-
-struct spwd *sgetspent(const char *string)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd spwd;
- struct spwd *result;
-
- sgetspent_r(string, &spwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-#endif
/**********************************************************************/
#ifdef L___getgrouplist_internal
diff --git a/libc/pwd_grp/pwd_grp_internal.c b/libc/pwd_grp/pwd_grp_internal.c
index d2fde11..104f532 100644
--- a/libc/pwd_grp/pwd_grp_internal.c
+++ b/libc/pwd_grp/pwd_grp_internal.c
@@ -36,18 +36,10 @@
#endif
/**********************************************************************/
-/* Sizes for statically allocated buffers. */
-
-/* If you change these values, also change _SC_GETPW_R_SIZE_MAX and
- * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
-
-/**********************************************************************/
/* Prototypes for internal functions. */
-#ifndef GETXXKEY_R_FUNC
-#error GETXXKEY_R_FUNC is not defined!
+#if !defined(GETXXKEY_R_FUNC) && !defined(GETXXKEY_FUNC)
+#error GETXXKEY_R_FUNC/GETXXKEY_FUNC are not defined!
#endif
/**********************************************************************/
#ifdef GETXXKEY_R_FUNC
@@ -89,9 +81,44 @@ int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
}
libc_hidden_def(GETXXKEY_R_FUNC)
+#endif /* GETXXKEY_R_FUNC */
+
+/**********************************************************************/
+#ifdef GETXXKEY_FUNC
+
+#define REENTRANT_NAME APPEND_R(GETXXKEY_FUNC)
+#define APPEND_R(name) APPEND_R1(name)
+#define APPEND_R1(name) name##_r
+
+GETXXKEY_ENTTYPE *GETXXKEY_FUNC(GETXXKEY_ADD_PARAMS)
+{
+ static char buffer[GETXXKEY_BUFLEN];
+ static GETXXKEY_ENTTYPE resultbuf;
+ GETXXKEY_ENTTYPE *result;
+
+# ifdef GETXXKEY_ADD_VARIABLES
+ REENTRANT_NAME(GETXXKEY_ADD_VARIABLES, &resultbuf, buffer, sizeof(buffer), &result);
+# else
+ REENTRANT_NAME(&resultbuf, buffer, sizeof(buffer), &result);
+# endif
+ return result;
+}
+#ifdef GETXXKEY_FUNC_HIDDEN
+libc_hidden_def(GETXXKEY_FUNC)
#endif
+
+#undef REENTRANT_NAME
+#undef APPEND_R
+#undef APPEND_R1
+#endif /* GETXXKEY_FUNC */
+
/**********************************************************************/
-#undef GETXXKEY_R_FUNC_HIDDEN
+#undef GETXXKEY_FUNC
+#undef GETXXKEY_ENTTYPE
+#undef GETXXKEY_BUFLEN
+#undef GETXXKEY_FUNC_HIDDEN
+#undef GETXXKEY_ADD_PARAMS
+#undef GETXXKEY_ADD_VARIABLES
#undef GETXXKEY_R_FUNC
#undef GETXXKEY_R_PARSER
#undef GETXXKEY_R_ENTTYPE
diff --git a/libc/pwd_grp/sgetspent.c b/libc/pwd_grp/sgetspent.c
index 877a247..990c0b6 100644
--- a/libc/pwd_grp/sgetspent.c
+++ b/libc/pwd_grp/sgetspent.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_sgetspent
+#define GETXXKEY_FUNC sgetspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS const char *string
+#define GETXXKEY_ADD_VARIABLES string
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/string/generic/mempcpy.c b/libc/string/generic/mempcpy.c
index d7fa79e..bb5563a 100644
--- a/libc/string/generic/mempcpy.c
+++ b/libc/string/generic/mempcpy.c
@@ -16,4 +16,5 @@ void *mempcpy (void *dstpp, const void *srcpp, size_t len)
return (void *)(((char *)dstpp) + len);
}
libc_hidden_weak(mempcpy)
+strong_alias(mempcpy,__mempcpy)
#endif
diff --git a/libc/string/mips/memcpy.S b/libc/string/mips/memcpy.S
index 48c4f2a..2a187ef 100644
--- a/libc/string/mips/memcpy.S
+++ b/libc/string/mips/memcpy.S
@@ -1,6 +1,5 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2012-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Hartvig Ekner <hartvige(a)mips.com>, 2002.
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,243 +12,861 @@
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
+ License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <features.h>
-#include <sysdep.h>
-#include <endian.h>
+#ifdef ANDROID_CHANGES
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define USE_MEMMOVE_FOR_OVERLAP
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif _LIBC
+# include <sysdep.h>
+# include <regdef.h>
+# include <sys/asm.h>
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif defined _COMPILING_NEWLIB
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#else
+# include <regdef.h>
+# include <sys/asm.h>
+#endif
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+# ifndef DISABLE_PREFETCH
+# define USE_PREFETCH
+# endif
+#endif
+
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
+# ifndef DISABLE_DOUBLE
+# define USE_DOUBLE
+# endif
+#endif
+
+/* Some asm.h files do not have the L macro definition. */
+#ifndef L
+# if _MIPS_SIM == _ABIO32
+# define L(label) $L ## label
+# else
+# define L(label) .L ## label
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_ADDIU macro definition. */
+#ifndef PTR_ADDIU
+# ifdef USE_DOUBLE
+# define PTR_ADDIU daddiu
+# else
+# define PTR_ADDIU addiu
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_SRA macro definition. */
+#ifndef PTR_SRA
+# ifdef USE_DOUBLE
+# define PTR_SRA dsra
+# else
+# define PTR_SRA sra
+# endif
+#endif
+
+/* New R6 instructions that may not be in asm.h. */
+#ifndef PTR_LSA
+# if _MIPS_SIM == _ABI64
+# define PTR_LSA dlsa
+# else
+# define PTR_LSA lsa
+# endif
+#endif
+
+/*
+ * Using PREFETCH_HINT_LOAD_STREAMED instead of PREFETCH_LOAD on load
+ * prefetches appears to offer a slight preformance advantage.
+ *
+ * Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
+ * or PREFETCH_STORE_STREAMED offers a large performance advantage
+ * but PREPAREFORSTORE has some special restrictions to consider.
+ *
+ * Prefetch with the 'prepare for store' hint does not copy a memory
+ * location into the cache, it just allocates a cache line and zeros
+ * it out. This means that if you do not write to the entire cache
+ * line before writing it out to memory some data will get zero'ed out
+ * when the cache line is written back to memory and data will be lost.
+ *
+ * Also if you are using this memcpy to copy overlapping buffers it may
+ * not behave correctly when using the 'prepare for store' hint. If you
+ * use the 'prepare for store' prefetch on a memory area that is in the
+ * memcpy source (as well as the memcpy destination), then you will get
+ * some data zero'ed out before you have a chance to read it and data will
+ * be lost.
+ *
+ * If you are going to use this memcpy routine with the 'prepare for store'
+ * prefetch you may want to set USE_MEMMOVE_FOR_OVERLAP in order to avoid
+ * the problem of running memcpy on overlapping buffers.
+ *
+ * There are ifdef'ed sections of this memcpy to make sure that it does not
+ * do prefetches on cache lines that are not going to be completely written.
+ * This code is only needed and only used when PREFETCH_STORE_HINT is set to
+ * PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are
+ * 32 bytes and if the cache line is larger it will not work correctly.
+ */
+
+#ifdef USE_PREFETCH
+# define PREFETCH_HINT_LOAD 0
+# define PREFETCH_HINT_STORE 1
+# define PREFETCH_HINT_LOAD_STREAMED 4
+# define PREFETCH_HINT_STORE_STREAMED 5
+# define PREFETCH_HINT_LOAD_RETAINED 6
+# define PREFETCH_HINT_STORE_RETAINED 7
+# define PREFETCH_HINT_WRITEBACK_INVAL 25
+# define PREFETCH_HINT_PREPAREFORSTORE 30
+
+/*
+ * If we have not picked out what hints to use at this point use the
+ * standard load and store prefetch hints.
+ */
+# ifndef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
+# endif
+# ifndef PREFETCH_LOAD_HINT
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD
+# endif
+
+/*
+ * We double everything when USE_DOUBLE is true so we do 2 prefetches to
+ * get 64 bytes in that case. The assumption is that each individual
+ * prefetch brings in 32 bytes.
+ */
+
+# ifdef USE_DOUBLE
+# define PREFETCH_CHUNK 64
+# define PREFETCH_FOR_LOAD(chunk, reg) \
+ pref PREFETCH_LOAD_HINT, (chunk)*64(reg); \
+ pref PREFETCH_LOAD_HINT, ((chunk)*64)+32(reg)
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
+ pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
+# else
+# define PREFETCH_CHUNK 32
+# define PREFETCH_FOR_LOAD(chunk, reg) \
+ pref PREFETCH_LOAD_HINT, (chunk)*32(reg)
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*32(reg)
+# endif
+/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
+ * than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size
+ * of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
+ * hint is used, the code will not work correctly. If PREPAREFORSTORE is not
+ * used then MAX_PREFETCH_SIZE does not matter. */
+# define MAX_PREFETCH_SIZE 128
+/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
+ * than 5 on a STORE prefetch and that a single prefetch can never be larger
+ * than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because
+ * we actually do two prefetches in that case, one 32 bytes after the other. */
+# ifdef USE_DOUBLE
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
+# else
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
+# endif
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
+ && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
+/* We cannot handle this because the initial prefetches may fetch bytes that
+ * are before the buffer being copied. We start copies with an offset
+ * of 4 so avoid this situation when using PREPAREFORSTORE. */
+#error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
+# endif
+#else /* USE_PREFETCH not defined */
+# define PREFETCH_FOR_LOAD(offset, reg)
+# define PREFETCH_FOR_STORE(offset, reg)
+#endif
+
+#if __mips_isa_rev > 5
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+# undef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
+# endif
+# define R6_CODE
+#endif
-/* void *memcpy(void *s1, const void *s2, size_t n); */
+/* Allow the routine to be named something else if desired. */
+#ifndef MEMCPY_NAME
+# define MEMCPY_NAME memcpy
+#endif
+
+/* We use these 32/64 bit registers as temporaries to do the copying. */
+#define REG0 t0
+#define REG1 t1
+#define REG2 t2
+#define REG3 t3
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABIO64))
+# define REG4 t4
+# define REG5 t5
+# define REG6 t6
+# define REG7 t7
+#else
+# define REG4 ta0
+# define REG5 ta1
+# define REG6 ta2
+# define REG7 ta3
+#endif
-#ifdef __mips64
+/* We load/store 64 bits at a time when USE_DOUBLE is true.
+ * The C_ prefix stands for CHUNK and is used to avoid macro name
+ * conflicts with system header files. */
-#include <sys/asm.h>
+#ifdef USE_DOUBLE
+# define C_ST sd
+# define C_LD ld
+# ifdef __MIPSEB
+# define C_LDHI ldl /* high part is left in big-endian */
+# define C_STHI sdl /* high part is left in big-endian */
+# define C_LDLO ldr /* low part is right in big-endian */
+# define C_STLO sdr /* low part is right in big-endian */
+# else
+# define C_LDHI ldr /* high part is right in little-endian */
+# define C_STHI sdr /* high part is right in little-endian */
+# define C_LDLO ldl /* low part is left in little-endian */
+# define C_STLO sdl /* low part is left in little-endian */
+# endif
+# define C_ALIGN dalign /* r6 align instruction */
+#else
+# define C_ST sw
+# define C_LD lw
+# ifdef __MIPSEB
+# define C_LDHI lwl /* high part is left in big-endian */
+# define C_STHI swl /* high part is left in big-endian */
+# define C_LDLO lwr /* low part is right in big-endian */
+# define C_STLO swr /* low part is right in big-endian */
+# else
+# define C_LDHI lwr /* high part is right in little-endian */
+# define C_STHI swr /* high part is right in little-endian */
+# define C_LDLO lwl /* low part is left in little-endian */
+# define C_STLO swl /* low part is left in little-endian */
+# endif
+# define C_ALIGN align /* r6 align instruction */
+#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define LDHI ldl /* high part is left in big-endian */
-# define SDHI sdl /* high part is left in big-endian */
-# define LDLO ldr /* low part is right in big-endian */
-# define SDLO sdr /* low part is right in big-endian */
+/* Bookkeeping values for 32 vs. 64 bit mode. */
+#ifdef USE_DOUBLE
+# define NSIZE 8
+# define NSIZEMASK 0x3f
+# define NSIZEDMASK 0x7f
#else
-# define LDHI ldr /* high part is right in little-endian */
-# define SDHI sdr /* high part is right in little-endian */
-# define LDLO ldl /* low part is left in little-endian */
-# define SDLO sdl /* low part is left in little-endian */
+# define NSIZE 4
+# define NSIZEMASK 0x1f
+# define NSIZEDMASK 0x3f
#endif
+#define UNIT(unit) ((unit)*NSIZE)
+#define UNITM1(unit) (((unit)*NSIZE)-1)
-ENTRY (memcpy)
+#ifdef ANDROID_CHANGES
+LEAF(MEMCPY_NAME, 0)
+#else
+LEAF(MEMCPY_NAME)
+#endif
+ .set nomips16
.set noreorder
+/*
+ * Below we handle the case where memcpy is called with overlapping src and dst.
+ * Although memcpy is not required to handle this case, some parts of Android
+ * like Skia rely on such usage. We call memmove to handle such cases.
+ */
+#ifdef USE_MEMMOVE_FOR_OVERLAP
+ PTR_SUBU t0,a0,a1
+ PTR_SRA t2,t0,31
+ xor t1,t0,t2
+ PTR_SUBU t0,t1,t2
+ sltu t2,t0,a2
+ beq t2,zero,L(memcpy)
+ la t9,memmove
+ jr t9
+ nop
+L(memcpy):
+#endif
+/*
+ * If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
+ * size, copy dst pointer to v0 for the return value.
+ */
+ slti t2,a2,(2 * NSIZE)
+ bne t2,zero,L(lasts)
+#if defined(RETURN_FIRST_PREFETCH) || defined(RETURN_LAST_PREFETCH)
+ move v0,zero
+#else
+ move v0,a0
+#endif
- slti t0, a2, 16 # Less than 16?
- bne t0, zero, L(last16)
- move v0, a0 # Setup exit value before too late
-
- xor t0, a1, a0 # Find a0/a1 displacement
- andi t0, 0x7
- bne t0, zero, L(shift) # Go handle the unaligned case
- PTR_SUBU t1, zero, a1
- andi t1, 0x7 # a0/a1 are aligned, but are we
- beq t1, zero, L(chk8w) # starting in the middle of a word?
- PTR_SUBU a2, t1
- LDHI t0, 0(a1) # Yes we are... take care of that
- PTR_ADDU a1, t1
- SDHI t0, 0(a0)
- PTR_ADDU a0, t1
-
-L(chk8w):
- andi t0, a2, 0x3f # 64 or more bytes left?
- beq t0, a2, L(chk1w)
- PTR_SUBU a3, a2, t0 # Yes
- PTR_ADDU a3, a1 # a3 = end address of loop
- move a2, t0 # a2 = what will be left after loop
-L(lop8w):
- ld t0, 0(a1) # Loop taking 8 words at a time
- ld t1, 8(a1)
- ld t2, 16(a1)
- ld t3, 24(a1)
- ld ta0, 32(a1)
- ld ta1, 40(a1)
- ld ta2, 48(a1)
- ld ta3, 56(a1)
- PTR_ADDIU a0, 64
- PTR_ADDIU a1, 64
- sd t0, -64(a0)
- sd t1, -56(a0)
- sd t2, -48(a0)
- sd t3, -40(a0)
- sd ta0, -32(a0)
- sd ta1, -24(a0)
- sd ta2, -16(a0)
- bne a1, a3, L(lop8w)
- sd ta3, -8(a0)
+#ifndef R6_CODE
-L(chk1w):
- andi t0, a2, 0x7 # 8 or more bytes left?
- beq t0, a2, L(last16)
- PTR_SUBU a3, a2, t0 # Yes, handle them one dword at a time
- PTR_ADDU a3, a1 # a3 again end address
- move a2, t0
-L(lop1w):
- ld t0, 0(a1)
- PTR_ADDIU a0, 8
- PTR_ADDIU a1, 8
- bne a1, a3, L(lop1w)
- sd t0, -8(a0)
-
-L(last16):
- blez a2, L(lst16e) # Handle last 16 bytes, one at a time
- PTR_ADDU a3, a2, a1
-L(lst16l):
- lb t0, 0(a1)
- PTR_ADDIU a0, 1
- PTR_ADDIU a1, 1
- bne a1, a3, L(lst16l)
- sb t0, -1(a0)
-L(lst16e):
- jr ra # Bye, bye
- nop
+/*
+ * If src and dst have different alignments, go to L(unaligned), if they
+ * have the same alignment (but are not actually aligned) do a partial
+ * load/store to make them aligned. If they are both already aligned
+ * we can start copying at L(aligned).
+ */
+ xor t8,a1,a0
+ andi t8,t8,(NSIZE-1) /* t8 is a0/a1 word-displacement */
+ bne t8,zero,L(unaligned)
+ PTR_SUBU a3, zero, a0
-L(shift):
- PTR_SUBU a3, zero, a0 # Src and Dest unaligned
- andi a3, 0x7 # (unoptimized case...)
- beq a3, zero, L(shft1)
- PTR_SUBU a2, a3 # a2 = bytes left
- LDHI t0, 0(a1) # Take care of first odd part
- LDLO t0, 7(a1)
- PTR_ADDU a1, a3
- SDHI t0, 0(a0)
- PTR_ADDU a0, a3
-L(shft1):
- andi t0, a2, 0x7
- PTR_SUBU a3, a2, t0
- PTR_ADDU a3, a1
-L(shfth):
- LDHI t1, 0(a1) # Limp through, dword by dword
- LDLO t1, 7(a1)
- PTR_ADDIU a0, 8
- PTR_ADDIU a1, 8
- bne a1, a3, L(shfth)
- sd t1, -8(a0)
- b L(last16) # Handle anything which may be left
- move a2, t0
+ andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */
+ beq a3,zero,L(aligned) /* if a3=0, it is already aligned */
+ PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */
- .set reorder
-END (memcpy)
+ C_LDHI t8,0(a1)
+ PTR_ADDU a1,a1,a3
+ C_STHI t8,0(a0)
+ PTR_ADDU a0,a0,a3
+
+#else /* R6_CODE */
+
+/*
+ * Align the destination and hope that the source gets aligned too. If it
+ * doesn't we jump to L(r6_unaligned*) to do unaligned copies using the r6
+ * align instruction.
+ */
+ andi t8,a0,7
+ lapc t9,L(atable)
+ PTR_LSA t9,t8,t9,2
+ jrc t9
+L(atable):
+ bc L(lb0)
+ bc L(lb7)
+ bc L(lb6)
+ bc L(lb5)
+ bc L(lb4)
+ bc L(lb3)
+ bc L(lb2)
+ bc L(lb1)
+L(lb7):
+ lb a3, 6(a1)
+ sb a3, 6(a0)
+L(lb6):
+ lb a3, 5(a1)
+ sb a3, 5(a0)
+L(lb5):
+ lb a3, 4(a1)
+ sb a3, 4(a0)
+L(lb4):
+ lb a3, 3(a1)
+ sb a3, 3(a0)
+L(lb3):
+ lb a3, 2(a1)
+ sb a3, 2(a0)
+L(lb2):
+ lb a3, 1(a1)
+ sb a3, 1(a0)
+L(lb1):
+ lb a3, 0(a1)
+ sb a3, 0(a0)
+
+ li t9,8
+ subu t8,t9,t8
+ PTR_SUBU a2,a2,t8
+ PTR_ADDU a0,a0,t8
+ PTR_ADDU a1,a1,t8
+L(lb0):
-#else /* !__mips64 */
+ andi t8,a1,(NSIZE-1)
+ lapc t9,L(jtable)
+ PTR_LSA t9,t8,t9,2
+ jrc t9
+L(jtable):
+ bc L(aligned)
+ bc L(r6_unaligned1)
+ bc L(r6_unaligned2)
+ bc L(r6_unaligned3)
+# ifdef USE_DOUBLE
+ bc L(r6_unaligned4)
+ bc L(r6_unaligned5)
+ bc L(r6_unaligned6)
+ bc L(r6_unaligned7)
+# endif
+#endif /* R6_CODE */
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define LWHI lwl /* high part is left in big-endian */
-# define SWHI swl /* high part is left in big-endian */
-# define LWLO lwr /* low part is right in big-endian */
-# define SWLO swr /* low part is right in big-endian */
+L(aligned):
+
+/*
+ * Now dst/src are both aligned to (word or double word) aligned addresses
+ * Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ * chunks are copied and a3 to the dst pointer after all the 64/128 byte
+ * chunks have been copied. We will loop, incrementing a0 and a1 until a0
+ * equals a3.
+ */
+
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
+
+/* When in the loop we may prefetch with the 'prepare to store' hint,
+ * in this case the a0+x should not be past the "t0-32" address. This
+ * means: for x=128 the last "safe" a0 address is "t0-160". Alternatively,
+ * for x=64 the last "safe" a0 address is "t0-96" In the current version we
+ * will use "prefetch hint,128(a0)", so "t0-160" is the limit.
+ */
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+#endif
+ PREFETCH_FOR_LOAD (0, a1)
+ PREFETCH_FOR_LOAD (1, a1)
+ PREFETCH_FOR_LOAD (2, a1)
+ PREFETCH_FOR_LOAD (3, a1)
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+#endif
+#if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH)
+# if PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE
+ sltu v1,t9,a0
+ bgtz v1,L(skip_set)
+ nop
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4)
+L(skip_set):
+# else
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1)
+# endif
+#endif
+#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*3)
+# ifdef USE_DOUBLE
+ PTR_ADDIU v0,v0,32
+# endif
+#endif
+L(loop16w):
+ C_LD t0,UNIT(0)(a1)
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */
+ bgtz v1,L(skip_pref)
+#endif
+ C_LD t1,UNIT(1)(a1)
+#ifdef R6_CODE
+ PREFETCH_FOR_STORE (2, a0)
#else
-# define LWHI lwr /* high part is right in little-endian */
-# define SWHI swr /* high part is right in little-endian */
-# define LWLO lwl /* low part is left in little-endian */
-# define SWLO swl /* low part is left in little-endian */
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
+#endif
+#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH)
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*5)
+# ifdef USE_DOUBLE
+ PTR_ADDIU v0,v0,32
+# endif
#endif
+L(skip_pref):
+ C_LD REG2,UNIT(2)(a1)
+ C_LD REG3,UNIT(3)(a1)
+ C_LD REG4,UNIT(4)(a1)
+ C_LD REG5,UNIT(5)(a1)
+ C_LD REG6,UNIT(6)(a1)
+ C_LD REG7,UNIT(7)(a1)
+#ifdef R6_CODE
+ PREFETCH_FOR_LOAD (3, a1)
+#else
+ PREFETCH_FOR_LOAD (4, a1)
+#endif
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
-ENTRY (memcpy)
- .set noreorder
+ C_LD t0,UNIT(8)(a1)
+ C_LD t1,UNIT(9)(a1)
+ C_LD REG2,UNIT(10)(a1)
+ C_LD REG3,UNIT(11)(a1)
+ C_LD REG4,UNIT(12)(a1)
+ C_LD REG5,UNIT(13)(a1)
+ C_LD REG6,UNIT(14)(a1)
+ C_LD REG7,UNIT(15)(a1)
+#ifndef R6_CODE
+ PREFETCH_FOR_LOAD (5, a1)
+#endif
+ C_ST t0,UNIT(8)(a0)
+ C_ST t1,UNIT(9)(a0)
+ C_ST REG2,UNIT(10)(a0)
+ C_ST REG3,UNIT(11)(a0)
+ C_ST REG4,UNIT(12)(a0)
+ C_ST REG5,UNIT(13)(a0)
+ C_ST REG6,UNIT(14)(a0)
+ C_ST REG7,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(loop16w)
+ PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */
+ move a2,t8
+
+/* Here we have src and dest word-aligned but less than 64-bytes or
+ * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there
+ * is one. Otherwise jump down to L(chk1w) to handle the tail end of
+ * the copy.
+ */
+
+L(chkw):
+ PREFETCH_FOR_LOAD (0, a1)
+ andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */
+ /* The t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(chk1w) /* When a2=t8, no 32-byte chunk */
+ nop
+ C_LD t0,UNIT(0)(a1)
+ C_LD t1,UNIT(1)(a1)
+ C_LD REG2,UNIT(2)(a1)
+ C_LD REG3,UNIT(3)(a1)
+ C_LD REG4,UNIT(4)(a1)
+ C_LD REG5,UNIT(5)(a1)
+ C_LD REG6,UNIT(6)(a1)
+ C_LD REG7,UNIT(7)(a1)
+ PTR_ADDIU a1,a1,UNIT(8)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+
+/*
+ * Here we have less than 32(64) bytes to copy. Set up for a loop to
+ * copy one word (or double word) at a time. Set a2 to count how many
+ * bytes we have to copy after all the word (or double word) chunks are
+ * copied and a3 to the dst pointer after all the (d)word chunks have
+ * been copied. We will loop, incrementing a0 and a1 until a0 equals a3.
+ */
+L(chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(lastw)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
- slti t0, a2, 8 # Less than 8?
- bne t0, zero, L(last8)
- move v0, a0 # Setup exit value before too late
-
- xor t0, a1, a0 # Find a0/a1 displacement
- andi t0, 0x3
- bne t0, zero, L(shift) # Go handle the unaligned case
- subu t1, zero, a1
- andi t1, 0x3 # a0/a1 are aligned, but are we
- beq t1, zero, L(chk8w) # starting in the middle of a word?
- subu a2, t1
- LWHI t0, 0(a1) # Yes we are... take care of that
- addu a1, t1
- SWHI t0, 0(a0)
- addu a0, t1
-
-L(chk8w):
- andi t0, a2, 0x1f # 32 or more bytes left?
- beq t0, a2, L(chk1w)
- subu a3, a2, t0 # Yes
- addu a3, a1 # a3 = end address of loop
- move a2, t0 # a2 = what will be left after loop
-L(lop8w):
- lw t0, 0(a1) # Loop taking 8 words at a time
- lw t1, 4(a1)
- lw t2, 8(a1)
- lw t3, 12(a1)
- lw t4, 16(a1)
- lw t5, 20(a1)
- lw t6, 24(a1)
- lw t7, 28(a1)
- addiu a0, 32
- addiu a1, 32
- sw t0, -32(a0)
- sw t1, -28(a0)
- sw t2, -24(a0)
- sw t3, -20(a0)
- sw t4, -16(a0)
- sw t5, -12(a0)
- sw t6, -8(a0)
- bne a1, a3, L(lop8w)
- sw t7, -4(a0)
-
-L(chk1w):
- andi t0, a2, 0x3 # 4 or more bytes left?
- beq t0, a2, L(last8)
- subu a3, a2, t0 # Yes, handle them one word at a time
- addu a3, a1 # a3 again end address
- move a2, t0
-L(lop1w):
- lw t0, 0(a1)
- addiu a0, 4
- addiu a1, 4
- bne a1, a3, L(lop1w)
- sw t0, -4(a0)
-
-L(last8):
- blez a2, L(lst8e) # Handle last 8 bytes, one at a time
- addu a3, a2, a1
-L(lst8l):
- lb t0, 0(a1)
- addiu a0, 1
- addiu a1, 1
- bne a1, a3, L(lst8l)
- sb t0, -1(a0)
-L(lst8e):
- jr ra # Bye, bye
+/* copying in words (4-byte or 8-byte chunks) */
+L(wordCopy_loop):
+ C_LD REG3,UNIT(0)(a1)
+ PTR_ADDIU a0,a0,UNIT(1)
+ PTR_ADDIU a1,a1,UNIT(1)
+ bne a0,a3,L(wordCopy_loop)
+ C_ST REG3,UNIT(-1)(a0)
+
+/* If we have been copying double words, see if we can copy a single word
+ before doing byte copies. We can have, at most, one word to copy. */
+
+L(lastw):
+#ifdef USE_DOUBLE
+ andi t8,a2,3 /* a2 is the remainder past 4 byte chunks. */
+ beq t8,a2,L(lastb)
+ lw REG3,0(a1)
+ sw REG3,0(a0)
+ PTR_ADDIU a0,a0,4
+ PTR_ADDIU a1,a1,4
+ move a2,t8
+#endif
+
+/* Copy the last 8 (or 16) bytes */
+L(lastb):
+ blez a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(lastbloop):
+ lb v1,0(a1)
+ PTR_ADDIU a0,a0,1
+ PTR_ADDIU a1,a1,1
+ bne a0,a3,L(lastbloop)
+ sb v1,-1(a0)
+L(leave):
+ j ra
nop
-L(shift):
- subu a3, zero, a0 # Src and Dest unaligned
- andi a3, 0x3 # (unoptimized case...)
- beq a3, zero, L(shft1)
- subu a2, a3 # a2 = bytes left
- LWHI t0, 0(a1) # Take care of first odd part
- LWLO t0, 3(a1)
- addu a1, a3
- SWHI t0, 0(a0)
- addu a0, a3
-L(shft1):
- andi t0, a2, 0x3
- subu a3, a2, t0
- addu a3, a1
-L(shfth):
- LWHI t1, 0(a1) # Limp through, word by word
- LWLO t1, 3(a1)
- addiu a0, 4
- addiu a1, 4
- bne a1, a3, L(shfth)
- sw t1, -4(a0)
- b L(last8) # Handle anything which may be left
- move a2, t0
+/* We jump here with a memcpy of less than 8 or 16 bytes, depending on
+ whether or not USE_DOUBLE is defined. Instead of just doing byte
+ copies, check the alignment and size and use lw/sw if possible.
+ Otherwise, do byte copies. */
- .set reorder
-END (memcpy)
+L(lasts):
+ andi t8,a2,3
+ beq t8,a2,L(lastb)
+
+ andi t9,a0,3
+ bne t9,zero,L(lastb)
+ andi t9,a1,3
+ bne t9,zero,L(lastb)
+
+ PTR_SUBU a3,a2,t8
+ PTR_ADDU a3,a0,a3
+
+L(wcopy_loop):
+ lw REG3,0(a1)
+ PTR_ADDIU a0,a0,4
+ PTR_ADDIU a1,a1,4
+ bne a0,a3,L(wcopy_loop)
+ sw REG3,-4(a0)
-#endif /* !__mips64 */
+ b L(lastb)
+ move a2,t8
-libc_hidden_def(memcpy)
+#ifndef R6_CODE
+/*
+ * UNALIGNED case, got here with a3 = "negu a0"
+ * This code is nearly identical to the aligned code above
+ * but only the destination (not the source) gets aligned
+ * so we need to do partial loads of the source followed
+ * by normal stores to the destination (once we have aligned
+ * the destination).
+ */
+
+L(unaligned):
+ andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */
+ beqz a3,L(ua_chk16w) /* if a3=0, it is already aligned */
+ PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */
+
+ C_LDHI v1,UNIT(0)(a1)
+ C_LDLO v1,UNITM1(1)(a1)
+ PTR_ADDU a1,a1,a3
+ C_STHI v1,UNIT(0)(a0)
+ PTR_ADDU a0,a0,a3
+
+/*
+ * Now the destination (but not the source) is aligned
+ * Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ * chunks are copied and a3 to the dst pointer after all the 64/128 byte
+ * chunks have been copied. We will loop, incrementing a0 and a1 until a0
+ * equals a3.
+ */
+
+L(ua_chk16w):
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(ua_chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
+
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+# endif
+ PREFETCH_FOR_LOAD (0, a1)
+ PREFETCH_FOR_LOAD (1, a1)
+ PREFETCH_FOR_LOAD (2, a1)
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+# endif
+# if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH)
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0
+ bgtz v1,L(ua_skip_set)
+ nop
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4)
+L(ua_skip_set):
+# else
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1)
+# endif
+# endif
+L(ua_loop16w):
+ PREFETCH_FOR_LOAD (3, a1)
+ C_LDHI t0,UNIT(0)(a1)
+ C_LDHI t1,UNIT(1)(a1)
+ C_LDHI REG2,UNIT(2)(a1)
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0
+ bgtz v1,L(ua_skip_pref)
+# endif
+ C_LDHI REG3,UNIT(3)(a1)
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
+L(ua_skip_pref):
+ C_LDHI REG4,UNIT(4)(a1)
+ C_LDHI REG5,UNIT(5)(a1)
+ C_LDHI REG6,UNIT(6)(a1)
+ C_LDHI REG7,UNIT(7)(a1)
+ C_LDLO t0,UNITM1(1)(a1)
+ C_LDLO t1,UNITM1(2)(a1)
+ C_LDLO REG2,UNITM1(3)(a1)
+ C_LDLO REG3,UNITM1(4)(a1)
+ C_LDLO REG4,UNITM1(5)(a1)
+ C_LDLO REG5,UNITM1(6)(a1)
+ C_LDLO REG6,UNITM1(7)(a1)
+ C_LDLO REG7,UNITM1(8)(a1)
+ PREFETCH_FOR_LOAD (4, a1)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ C_LDHI t0,UNIT(8)(a1)
+ C_LDHI t1,UNIT(9)(a1)
+ C_LDHI REG2,UNIT(10)(a1)
+ C_LDHI REG3,UNIT(11)(a1)
+ C_LDHI REG4,UNIT(12)(a1)
+ C_LDHI REG5,UNIT(13)(a1)
+ C_LDHI REG6,UNIT(14)(a1)
+ C_LDHI REG7,UNIT(15)(a1)
+ C_LDLO t0,UNITM1(9)(a1)
+ C_LDLO t1,UNITM1(10)(a1)
+ C_LDLO REG2,UNITM1(11)(a1)
+ C_LDLO REG3,UNITM1(12)(a1)
+ C_LDLO REG4,UNITM1(13)(a1)
+ C_LDLO REG5,UNITM1(14)(a1)
+ C_LDLO REG6,UNITM1(15)(a1)
+ C_LDLO REG7,UNITM1(16)(a1)
+ PREFETCH_FOR_LOAD (5, a1)
+ C_ST t0,UNIT(8)(a0)
+ C_ST t1,UNIT(9)(a0)
+ C_ST REG2,UNIT(10)(a0)
+ C_ST REG3,UNIT(11)(a0)
+ C_ST REG4,UNIT(12)(a0)
+ C_ST REG5,UNIT(13)(a0)
+ C_ST REG6,UNIT(14)(a0)
+ C_ST REG7,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(ua_loop16w)
+ PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */
+ move a2,t8
+
+/* Here we have src and dest word-aligned but less than 64-bytes or
+ * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there
+ * is one. Otherwise jump down to L(ua_chk1w) to handle the tail end of
+ * the copy. */
+
+L(ua_chkw):
+ PREFETCH_FOR_LOAD (0, a1)
+ andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */
+ /* t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(ua_chk1w) /* When a2=t8, no 32-byte chunk */
+ nop
+ C_LDHI t0,UNIT(0)(a1)
+ C_LDHI t1,UNIT(1)(a1)
+ C_LDHI REG2,UNIT(2)(a1)
+ C_LDHI REG3,UNIT(3)(a1)
+ C_LDHI REG4,UNIT(4)(a1)
+ C_LDHI REG5,UNIT(5)(a1)
+ C_LDHI REG6,UNIT(6)(a1)
+ C_LDHI REG7,UNIT(7)(a1)
+ C_LDLO t0,UNITM1(1)(a1)
+ C_LDLO t1,UNITM1(2)(a1)
+ C_LDLO REG2,UNITM1(3)(a1)
+ C_LDLO REG3,UNITM1(4)(a1)
+ C_LDLO REG4,UNITM1(5)(a1)
+ C_LDLO REG5,UNITM1(6)(a1)
+ C_LDLO REG6,UNITM1(7)(a1)
+ C_LDLO REG7,UNITM1(8)(a1)
+ PTR_ADDIU a1,a1,UNIT(8)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+/*
+ * Here we have less than 32(64) bytes to copy. Set up for a loop to
+ * copy one word (or double word) at a time.
+ */
+L(ua_chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(ua_smallCopy)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
+
+/* copying in words (4-byte or 8-byte chunks) */
+L(ua_wordCopy_loop):
+ C_LDHI v1,UNIT(0)(a1)
+ C_LDLO v1,UNITM1(1)(a1)
+ PTR_ADDIU a0,a0,UNIT(1)
+ PTR_ADDIU a1,a1,UNIT(1)
+ bne a0,a3,L(ua_wordCopy_loop)
+ C_ST v1,UNIT(-1)(a0)
+
+/* Copy the last 8 (or 16) bytes */
+L(ua_smallCopy):
+ beqz a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(ua_smallCopy_loop):
+ lb v1,0(a1)
+ PTR_ADDIU a0,a0,1
+ PTR_ADDIU a1,a1,1
+ bne a0,a3,L(ua_smallCopy_loop)
+ sb v1,-1(a0)
+
+ j ra
+ nop
+
+#else /* R6_CODE */
+
+# ifdef __MIPSEB
+# define SWAP_REGS(X,Y) X, Y
+# define ALIGN_OFFSET(N) (N)
+# else
+# define SWAP_REGS(X,Y) Y, X
+# define ALIGN_OFFSET(N) (NSIZE-N)
+# endif
+# define R6_UNALIGNED_WORD_COPY(BYTEOFFSET) \
+ andi REG7, a2, (NSIZE-1);/* REG7 is # of bytes to by bytes. */ \
+ beq REG7, a2, L(lastb); /* Check for bytes to copy by word */ \
+ PTR_SUBU a3, a2, REG7; /* a3 is number of bytes to be copied in */ \
+ /* (d)word chunks. */ \
+ move a2, REG7; /* a2 is # of bytes to copy byte by byte */ \
+ /* after word loop is finished. */ \
+ PTR_ADDU REG6, a0, a3; /* REG6 is the dst address after loop. */ \
+ PTR_SUBU REG2, a1, t8; /* REG2 is the aligned src address. */ \
+ PTR_ADDU a1, a1, a3; /* a1 is addr of source after word loop. */ \
+ C_LD t0, UNIT(0)(REG2); /* Load first part of source. */ \
+L(r6_ua_wordcopy##BYTEOFFSET): \
+ C_LD t1, UNIT(1)(REG2); /* Load second part of source. */ \
+ C_ALIGN REG3, SWAP_REGS(t1,t0), ALIGN_OFFSET(BYTEOFFSET); \
+ PTR_ADDIU a0, a0, UNIT(1); /* Increment destination pointer. */ \
+ PTR_ADDIU REG2, REG2, UNIT(1); /* Increment aligned source pointer.*/ \
+ move t0, t1; /* Move second part of source to first. */ \
+ bne a0, REG6,L(r6_ua_wordcopy##BYTEOFFSET); \
+ C_ST REG3, UNIT(-1)(a0); \
+ j L(lastb); \
+ nop
+
+ /* We are generating R6 code, the destination is 4 byte aligned and
+ the source is not 4 byte aligned. t8 is 1, 2, or 3 depending on the
+ alignment of the source. */
+
+L(r6_unaligned1):
+ R6_UNALIGNED_WORD_COPY(1)
+L(r6_unaligned2):
+ R6_UNALIGNED_WORD_COPY(2)
+L(r6_unaligned3):
+ R6_UNALIGNED_WORD_COPY(3)
+# ifdef USE_DOUBLE
+L(r6_unaligned4):
+ R6_UNALIGNED_WORD_COPY(4)
+L(r6_unaligned5):
+ R6_UNALIGNED_WORD_COPY(5)
+L(r6_unaligned6):
+ R6_UNALIGNED_WORD_COPY(6)
+L(r6_unaligned7):
+ R6_UNALIGNED_WORD_COPY(7)
+# endif
+#endif /* R6_CODE */
+
+ .set at
+ .set reorder
+END(MEMCPY_NAME)
+#ifndef ANDROID_CHANGES
+# ifdef _LIBC
+# ifdef __UCLIBC__
+libc_hidden_def(MEMCPY_NAME)
+# else
+libc_hidden_builtin_def (MEMCPY_NAME)
+# endif
+# endif
+#endif
diff --git a/libc/string/mips/memset.S b/libc/string/mips/memset.S
index 26b2598..ef8ab0b 100644
--- a/libc/string/mips/memset.S
+++ b/libc/string/mips/memset.S
@@ -1,6 +1,5 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Hartvig Ekner <hartvige(a)mips.com>, 2002.
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,145 +12,420 @@
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
+ License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <features.h>
-#include <sysdep.h>
-#include <endian.h>
+#ifdef ANDROID_CHANGES
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif _LIBC
+# include <sysdep.h>
+# include <regdef.h>
+# include <sys/asm.h>
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif defined _COMPILING_NEWLIB
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#else
+# include <regdef.h>
+# include <sys/asm.h>
+#endif
+
+/* Check to see if the MIPS architecture we are compiling for supports
+ prefetching. */
+
+#if (__mips == 4) || (__mips == 5) || (__mips == 32) || (__mips == 64)
+# ifndef DISABLE_PREFETCH
+# define USE_PREFETCH
+# endif
+#endif
+
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
+# ifndef DISABLE_DOUBLE
+# define USE_DOUBLE
+# endif
+#endif
+
+#ifndef USE_DOUBLE
+# ifndef DISABLE_DOUBLE_ALIGN
+# define DOUBLE_ALIGN
+# endif
+#endif
+
+
+/* Some asm.h files do not have the L macro definition. */
+#ifndef L
+# if _MIPS_SIM == _ABIO32
+# define L(label) $L ## label
+# else
+# define L(label) .L ## label
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_ADDIU macro definition. */
+#ifndef PTR_ADDIU
+# ifdef USE_DOUBLE
+# define PTR_ADDIU daddiu
+# else
+# define PTR_ADDIU addiu
+# endif
+#endif
-/* void *memset(void *s, int c, size_t n). */
+/* New R6 instructions that may not be in asm.h. */
+#ifndef PTR_LSA
+# if _MIPS_SIM == _ABI64
+# define PTR_LSA dlsa
+# else
+# define PTR_LSA lsa
+# endif
+#endif
+
+/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
+ or PREFETCH_STORE_STREAMED offers a large performance advantage
+ but PREPAREFORSTORE has some special restrictions to consider.
+
+ Prefetch with the 'prepare for store' hint does not copy a memory
+ location into the cache, it just allocates a cache line and zeros
+ it out. This means that if you do not write to the entire cache
+ line before writing it out to memory some data will get zero'ed out
+ when the cache line is written back to memory and data will be lost.
+
+ There are ifdef'ed sections of this memcpy to make sure that it does not
+ do prefetches on cache lines that are not going to be completely written.
+ This code is only needed and only used when PREFETCH_STORE_HINT is set to
+ PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are
+ less than MAX_PREFETCH_SIZE bytes and if the cache line is larger it will
+ not work correctly. */
+
+#ifdef USE_PREFETCH
+# define PREFETCH_HINT_STORE 1
+# define PREFETCH_HINT_STORE_STREAMED 5
+# define PREFETCH_HINT_STORE_RETAINED 7
+# define PREFETCH_HINT_PREPAREFORSTORE 30
+
+/* If we have not picked out what hints to use at this point use the
+ standard load and store prefetch hints. */
+# ifndef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
+# endif
+
+/* We double everything when USE_DOUBLE is true so we do 2 prefetches to
+ get 64 bytes in that case. The assumption is that each individual
+ prefetch brings in 32 bytes. */
+# ifdef USE_DOUBLE
+# define PREFETCH_CHUNK 64
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
+ pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
+# else
+# define PREFETCH_CHUNK 32
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*32(reg)
+# endif
-#ifdef __mips64
+/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
+ than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size
+ of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
+ hint is used, the code will not work correctly. If PREPAREFORSTORE is not
+ used than MAX_PREFETCH_SIZE does not matter. */
+# define MAX_PREFETCH_SIZE 128
+/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
+ than 5 on a STORE prefetch and that a single prefetch can never be larger
+ than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because
+ we actually do two prefetches in that case, one 32 bytes after the other. */
+# ifdef USE_DOUBLE
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
+# else
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
+# endif
-#include <sys/asm.h>
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
+ && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
+/* We cannot handle this because the initial prefetches may fetch bytes that
+ are before the buffer being copied. We start copies with an offset
+ of 4 so avoid this situation when using PREPAREFORSTORE. */
+# error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
+# endif
+#else /* USE_PREFETCH not defined */
+# define PREFETCH_FOR_STORE(offset, reg)
+#endif
+
+#if __mips_isa_rev > 5
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+# undef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
+# endif
+# define R6_CODE
+#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define SDHI sdl /* high part is left in big-endian */
+/* Allow the routine to be named something else if desired. */
+#ifndef MEMSET_NAME
+# define MEMSET_NAME memset
+#endif
+
+/* We load/store 64 bits at a time when USE_DOUBLE is true.
+ The C_ prefix stands for CHUNK and is used to avoid macro name
+ conflicts with system header files. */
+
+#ifdef USE_DOUBLE
+# define C_ST sd
+# ifdef __MIPSEB
+# define C_STHI sdl /* high part is left in big-endian */
+# else
+# define C_STHI sdr /* high part is right in little-endian */
+# endif
#else
-# define SDHI sdr /* high part is right in little-endian */
+# define C_ST sw
+# ifdef __MIPSEB
+# define C_STHI swl /* high part is left in big-endian */
+# else
+# define C_STHI swr /* high part is right in little-endian */
+# endif
#endif
-ENTRY (memset)
- .set noreorder
+/* Bookkeeping values for 32 vs. 64 bit mode. */
+#ifdef USE_DOUBLE
+# define NSIZE 8
+# define NSIZEMASK 0x3f
+# define NSIZEDMASK 0x7f
+#else
+# define NSIZE 4
+# define NSIZEMASK 0x1f
+# define NSIZEDMASK 0x3f
+#endif
+#define UNIT(unit) ((unit)*NSIZE)
+#define UNITM1(unit) (((unit)*NSIZE)-1)
- slti ta1, a2, 16 # Less than 16?
- bne ta1, zero, L(last16)
- move v0, a0 # Setup exit value before too late
-
- beq a1, zero, L(ueven) # If zero pattern, no need to extend
- andi a1, 0xff # Avoid problems with bogus arguments
- dsll ta0, a1, 8
- or a1, ta0
- dsll ta0, a1, 16
- or a1, ta0 # a1 is now pattern in full word
- dsll ta0, a1, 32
- or a1, ta0 # a1 is now pattern in double word
-
-L(ueven):
- PTR_SUBU ta0, zero, a0 # Unaligned address?
- andi ta0, 0x7
- beq ta0, zero, L(chkw)
- PTR_SUBU a2, ta0
- SDHI a1, 0(a0) # Yes, handle first unaligned part
- PTR_ADDU a0, ta0 # Now both a0 and a2 are updated
+#ifdef ANDROID_CHANGES
+LEAF(MEMSET_NAME,0)
+#else
+LEAF(MEMSET_NAME)
+#endif
-L(chkw):
- andi ta0, a2, 0xf # Enough left for one loop iteration?
- beq ta0, a2, L(chkl)
- PTR_SUBU a3, a2, ta0
- PTR_ADDU a3, a0 # a3 is last loop address +1
- move a2, ta0 # a2 is now # of bytes left after loop
-L(loopw):
- PTR_ADDIU a0, 16 # Handle 2 dwords pr. iteration
- sd a1, -16(a0)
- bne a0, a3, L(loopw)
- sd a1, -8(a0)
-
-L(chkl):
- andi ta0, a2, 0x8 # Check if there is at least a double
- beq ta0, zero, L(last16) # word remaining after the loop
- PTR_SUBU a2, ta0
- sd a1, 0(a0) # Yes...
- PTR_ADDIU a0, 8
-
-L(last16):
- blez a2, L(exit) # Handle last 16 bytes (if cnt>0)
- PTR_ADDU a3, a2, a0 # a3 is last address +1
-L(lst16l):
- PTR_ADDIU a0, 1
- bne a0, a3, L(lst16l)
- sb a1, -1(a0)
-L(exit):
- j ra # Bye, bye
+ .set nomips16
+ .set noreorder
+/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
+ size, copy dst pointer to v0 for the return value. */
+ slti t2,a2,(2 * NSIZE)
+ bne t2,zero,L(lastb)
+ move v0,a0
+
+/* If memset value is not zero, we copy it to all the bytes in a 32 or 64
+ bit word. */
+ beq a1,zero,L(set0) /* If memset value is zero no smear */
+ PTR_SUBU a3,zero,a0
nop
- .set reorder
-END (memset)
+ /* smear byte into 32 or 64 bit word */
+#if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)
+# ifdef USE_DOUBLE
+ dins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
+ dins a1, a1, 16, 16 /* Replicate fill byte into word. */
+ dins a1, a1, 32, 32 /* Replicate fill byte into dbl word. */
+# else
+ ins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
+ ins a1, a1, 16, 16 /* Replicate fill byte into word. */
+# endif
+#else
+# ifdef USE_DOUBLE
+ and a1,0xff
+ dsll t2,a1,8
+ or a1,t2
+ dsll t2,a1,16
+ or a1,t2
+ dsll t2,a1,32
+ or a1,t2
+# else
+ and a1,0xff
+ sll t2,a1,8
+ or a1,t2
+ sll t2,a1,16
+ or a1,t2
+# endif
+#endif
+
+/* If the destination address is not aligned do a partial store to get it
+ aligned. If it is already aligned just jump to L(aligned). */
+L(set0):
+#ifndef R6_CODE
+ andi t2,a3,(NSIZE-1) /* word-unaligned address? */
+ beq t2,zero,L(aligned) /* t2 is the unalignment count */
+ PTR_SUBU a2,a2,t2
+ C_STHI a1,0(a0)
+ PTR_ADDU a0,a0,t2
+#else /* R6_CODE */
+ andi t2,a0,(NSIZE-1)
+ lapc t9,L(atable)
+ PTR_LSA t9,t2,t9,2
+ jrc t9
+L(atable):
+ bc L(aligned)
+# ifdef USE_DOUBLE
+ bc L(lb7)
+ bc L(lb6)
+ bc L(lb5)
+ bc L(lb4)
+# endif
+ bc L(lb3)
+ bc L(lb2)
+ bc L(lb1)
+L(lb7):
+ sb a1,6(a0)
+L(lb6):
+ sb a1,5(a0)
+L(lb5):
+ sb a1,4(a0)
+L(lb4):
+ sb a1,3(a0)
+L(lb3):
+ sb a1,2(a0)
+L(lb2):
+ sb a1,1(a0)
+L(lb1):
+ sb a1,0(a0)
+
+ li t9,NSIZE
+ subu t2,t9,t2
+ PTR_SUBU a2,a2,t2
+ PTR_ADDU a0,a0,t2
+#endif /* R6_CODE */
+
+L(aligned):
+/* If USE_DOUBLE is not set we may still want to align the data on a 16
+ byte boundry instead of an 8 byte boundry to maximize the opportunity
+ of proAptiv chips to do memory bonding (combining two sequential 4
+ byte stores into one 8 byte store). We know there are at least 4 bytes
+ left to store or we would have jumped to L(lastb) earlier in the code. */
+#ifdef DOUBLE_ALIGN
+ andi t2,a3,4
+ beq t2,zero,L(double_aligned)
+ PTR_SUBU a2,a2,t2
+ sw a1,0(a0)
+ PTR_ADDU a0,a0,t2
+L(double_aligned):
+#endif
-#else /* !__mips64 */
+/* Now the destination is aligned to (word or double word) aligned address
+ Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ chunks are copied and a3 to the dest pointer after all the 64/128 byte
+ chunks have been copied. We will loop, incrementing a0 until it equals
+ a3. */
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define SWHI swl /* high part is left in big-endian */
+/* When in the loop we may prefetch with the 'prepare to store' hint,
+ in this case the a0+x should not be past the "t0-32" address. This
+ means: for x=128 the last "safe" a0 address is "t0-160". Alternatively,
+ for x=64 the last "safe" a0 address is "t0-96" In the current version we
+ will use "prefetch hint,128(a0)", so "t0-160" is the limit. */
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+#endif
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+#endif
+
+L(loop16w):
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */
+ bgtz v1,L(skip_pref)
+ nop
+#endif
+#ifdef R6_CODE
+ PREFETCH_FOR_STORE (2, a0)
#else
-# define SWHI swr /* high part is right in little-endian */
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
#endif
+L(skip_pref):
+ C_ST a1,UNIT(0)(a0)
+ C_ST a1,UNIT(1)(a0)
+ C_ST a1,UNIT(2)(a0)
+ C_ST a1,UNIT(3)(a0)
+ C_ST a1,UNIT(4)(a0)
+ C_ST a1,UNIT(5)(a0)
+ C_ST a1,UNIT(6)(a0)
+ C_ST a1,UNIT(7)(a0)
+ C_ST a1,UNIT(8)(a0)
+ C_ST a1,UNIT(9)(a0)
+ C_ST a1,UNIT(10)(a0)
+ C_ST a1,UNIT(11)(a0)
+ C_ST a1,UNIT(12)(a0)
+ C_ST a1,UNIT(13)(a0)
+ C_ST a1,UNIT(14)(a0)
+ C_ST a1,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(loop16w)
+ nop
+ move a2,t8
-ENTRY (memset)
- .set noreorder
+/* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go.
+ Check for a 32(64) byte chunk and copy if if there is one. Otherwise
+ jump down to L(chk1w) to handle the tail end of the copy. */
+L(chkw):
+ andi t8,a2,NSIZEMASK /* is there a 32-byte/64-byte chunk. */
+ /* the t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
+ nop
+ C_ST a1,UNIT(0)(a0)
+ C_ST a1,UNIT(1)(a0)
+ C_ST a1,UNIT(2)(a0)
+ C_ST a1,UNIT(3)(a0)
+ C_ST a1,UNIT(4)(a0)
+ C_ST a1,UNIT(5)(a0)
+ C_ST a1,UNIT(6)(a0)
+ C_ST a1,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+
+/* Here we have less than 32(64) bytes to set. Set up for a loop to
+ copy one word (or double word) at a time. Set a2 to count how many
+ bytes we have to copy after all the word (or double word) chunks are
+ copied and a3 to the dest pointer after all the (d)word chunks have
+ been copied. We will loop, incrementing a0 until a0 equals a3. */
+L(chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(lastb)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
- slti t1, a2, 8 # Less than 8?
- bne t1, zero, L(last8)
- move v0, a0 # Setup exit value before too late
-
- beq a1, zero, L(ueven) # If zero pattern, no need to extend
- andi a1, 0xff # Avoid problems with bogus arguments
- sll t0, a1, 8
- or a1, t0
- sll t0, a1, 16
- or a1, t0 # a1 is now pattern in full word
-
-L(ueven):
- subu t0, zero, a0 # Unaligned address?
- andi t0, 0x3
- beq t0, zero, L(chkw)
- subu a2, t0
- SWHI a1, 0(a0) # Yes, handle first unaligned part
- addu a0, t0 # Now both a0 and a2 are updated
-
-L(chkw):
- andi t0, a2, 0x7 # Enough left for one loop iteration?
- beq t0, a2, L(chkl)
- subu a3, a2, t0
- addu a3, a0 # a3 is last loop address +1
- move a2, t0 # a2 is now # of bytes left after loop
-L(loopw):
- addiu a0, 8 # Handle 2 words pr. iteration
- sw a1, -8(a0)
- bne a0, a3, L(loopw)
- sw a1, -4(a0)
-
-L(chkl):
- andi t0, a2, 0x4 # Check if there is at least a full
- beq t0, zero, L(last8) # word remaining after the loop
- subu a2, t0
- sw a1, 0(a0) # Yes...
- addiu a0, 4
-
-L(last8):
- blez a2, L(exit) # Handle last 8 bytes (if cnt>0)
- addu a3, a2, a0 # a3 is last address +1
-L(lst8l):
- addiu a0, 1
- bne a0, a3, L(lst8l)
- sb a1, -1(a0)
-L(exit):
- j ra # Bye, bye
+/* copying in words (4-byte or 8 byte chunks) */
+L(wordCopy_loop):
+ PTR_ADDIU a0,a0,UNIT(1)
+ bne a0,a3,L(wordCopy_loop)
+ C_ST a1,UNIT(-1)(a0)
+
+/* Copy the last 8 (or 16) bytes */
+L(lastb):
+ blez a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(lastbloop):
+ PTR_ADDIU a0,a0,1
+ bne a0,a3,L(lastbloop)
+ sb a1,-1(a0)
+L(leave):
+ j ra
nop
+ .set at
.set reorder
-END (memset)
-
-#endif /* !__mips64 */
+END(MEMSET_NAME)
+#ifndef ANDROID_CHANGES
+# ifdef _LIBC
+# ifdef __UCLIBC__
+libc_hidden_def(MEMSET_NAME)
+# else
+libc_hidden_builtin_def (MEMSET_NAME)
+# endif
+# endif
+#endif
-libc_hidden_def(memset)
diff --git a/libc/sysdeps/linux/common/bits/in.h b/libc/sysdeps/linux/common/bits/in.h
index f4a340b..c67fbf8 100644
--- a/libc/sysdeps/linux/common/bits/in.h
+++ b/libc/sysdeps/linux/common/bits/in.h
@@ -120,7 +120,7 @@ struct in_pktinfo
};
#endif
-#ifdef __UCLIBC_HAS_IPV6__
+#if defined __UCLIBC_HAS_IPV6__ || !defined __UCLIBC_STRICT_HEADERS__
/* Options for use with `getsockopt' and `setsockopt' at the IPv6 level.
The first word in the comment at the right is the data type used;
"bool" means a boolean value stored in an `int'. */
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index bf19ce3..3f1dd28 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -30,6 +30,57 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask)
{
+#ifdef __NR_pselect6
+#define NSEC_PER_SEC 1000000000L
+ struct timespec _ts, *ts = 0;
+ if (timeout) {
+ /* The Linux kernel can in some situations update the timeout value.
+ * We do not want that so use a local variable.
+ */
+ _ts = *timeout;
+
+ /* GNU extension: allow for timespec values where the sub-sec
+ * field is equal to or more than 1 second. The kernel will
+ * reject this on us, so take care of the time shift ourself.
+ * Some applications (like readline and linphone) do this.
+ * See 'clarification on select() type calls and invalid timeouts'
+ * on the POSIX general list for more information.
+ */
+ if (_ts.tv_nsec >= NSEC_PER_SEC) {
+ _ts.tv_sec += _ts.tv_nsec / NSEC_PER_SEC;
+ _ts.tv_nsec %= NSEC_PER_SEC;
+ }
+
+ ts = &_ts;
+ }
+
+ /* The pselect6 syscall API is strange. It wants a 7th arg to be
+ * the sizeof(*sigmask). However syscalls with > 6 arguments aren't
+ * supported on linux. So arguments 6 and 7 are stuffed in a struct
+ * and a pointer to that struct is passed as the 6th argument to
+ * the syscall.
+ * Glibc stuffs arguments 6 and 7 in a ulong[2]. Linux reads
+ * them as if there were a struct { sigset_t*; size_t } in
+ * userspace. There woudl be trouble if userspace and the kernel are
+ * compiled differently enough that size_t isn't the same as ulong,
+ * but not enough to trigger the compat layer in linux. I can't
+ * think of such a case, so I'm using linux's struct.
+ * Furthermore Glibc sets the sigsetsize to _NSIG/8. However linux
+ * checks for sizeof(sigset_t), which internally is a ulong array.
+ * This means that if _NSIG isn't a multiple of BITS_PER_LONG then
+ * linux will refuse glibc's value. So I prefer sizeof(sigset_t) for
+ * the value of sigsetsize.
+ */
+ struct {
+ const sigset_t *sigmask;
+ size_t sigsetsize;
+ } args67 = {
+ sigmask,
+ sizeof(sigset_t),
+ };
+
+ return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, ts, &args67);
+#else
struct timeval tval;
int retval;
sigset_t savemask;
@@ -57,6 +108,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
sigprocmask (SIG_SETMASK, &savemask, NULL);
return retval;
+#endif
}
CANCELLABLE_SYSCALL(int, pselect, (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask),
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index bcd49ed..776bec7 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -382,6 +382,10 @@ __pthread_initialize_minimal_internal (void)
Use the minimal size acceptable. */
limit.rlim_cur = PTHREAD_STACK_MIN;
+ /* Do not exceed architecture specific default */
+ if (limit.rlim_cur > ARCH_STACK_DEFAULT_SIZE)
+ limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
+
/* Make sure it meets the minimum size that allocate_stack
(allocatestack.c) will demand, which depends on the page size. */
const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
hooks/post-receive
--
uClibc-ng - small C library for embedded systems
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The annotated tag, v1.0.10 has been created
at b59543b5b75c405c7f30410bcc098dec5a666fd9 (tag)
tagging 0ad73077c230093ae004829da44418597f330c6a (commit)
replaces v1.0.9
tagged by Waldemar Brodkorb
on Thu Dec 24 00:49:56 2015 +0100
- Log -----------------------------------------------------------------
release 1.0.10 - Tongerlo Brune
Khem Raj (2):
Do not support localised optimizations this helps to have a global -O level
Add implementation for copysignl for ppc
Markus Mayer (1):
config: allow config to handle longer path names
Nicolas S. Dade (1):
pselect: Use linux pselect syscall when available
Steve Ellcey (3):
mips: fix definition.
Replace MIPS specific memcpy.S/memset.S with version from glibc/newlib.
Replace bltzal with lapc for MIPS R6 builds.
Vladislav Grishenko (2):
Fix syslog messages lost after syslogd restarts
Fix syslog messages lost if syslogd is temporary busy
Waldemar Brodkorb (47):
mips: remove ISA choice
xtensa: remove ldso workaround by real pointer check
xtensa: avoid some compiler warnings
bfin: use vfork.S again
bfin: fix clashing with newer gcc
remove __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
remove __UCLIBC_ASM_GLOBAL_DIRECTIVE__
remove sh64 support
good bye vax
good by e1
good by nios
add definitions for O_PATH
sync with glibc, add some missing defines
Avoid unnecessary rebuilds due to compiler flag changes
Define __attribute_const__
Make malloc_stats() GNU libc compatible
Reduce the initial buffer size for open_memstream
bsd supports the same floating point classification functions as c99
new test is only for MALLOC_STANDARD
allow linuxthreads for superh (sh2 noMMU)
sh: add back sh2 specific assembly for clone()
do not hardcode path to perl
arc: add ulps file for math tests
disable always failing tst-tls16, until someone unbreak it
fix tst-signal7 failure
Revert "fix tst-signal7 failure"
fix readdir_r returns success code while it in fact failed
libc/stdio: Rework custom streams interface similar to glibc.
test needs -fPIC for m68k
only strip test binaries when DOSTRIP is enabled
svc.c: svc_getreqset() buffer overflow
dynamically allocate ahostbuf buffer
resolv: __dns_lookup - immediately switch to next server in case of poll() set error events
resolv: NI_IDN unimplemented
dlclose fix
test/tls: tls-macros*.h fixes from glibc
utlis/ldd: Fix host ldd in case of target wordsize differs from host one
testsuite subdir fix
reduce stack cache size to save memory space
Revert "glibc compat: bump glibc minor version"
inet/resolv: Fix broken h_aliases list terminator after 2dab3f5
resolv: fix gethostbyname2_r to match gethostbyname_r, fixing bugs with AAAA lookups
Do define some IPv6 related symbols even with IPv6 disabled
use arch specific thread stack size for nptl
Use gcc's __builtin_mempcpy() as __mempcpy(), if possible
libc/pwd_grp: Create template for non-reentrant functions
prepare for release of 1.0.10
Wojciech Nizinski (1):
libc/stdlib: canonicalize_file_name() memory leak
-----------------------------------------------------------------------
hooks/post-receive
--
uClibc-ng - small C library for embedded systems
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "uClibc-ng - small C library for embedded systems".
The branch, 1.0 has been updated
via 0ad73077c230093ae004829da44418597f330c6a (commit)
via cc82a850a0ebfbacb7fb62ea2c5b7dd6aebb005d (commit)
via 2636b17616a19d628c3dbc373ebae67ef6e2b1f6 (commit)
via e3c3bf2b5801d0cc544e732fcee1ba51121051b3 (commit)
via f5bdd8ff82607e55a1c511e13e37a984408c8094 (commit)
via 2a3ffa836a3a9f94f19ee2671f41c1851221a105 (commit)
via 74b17c7956b8f0bd109b0fd26a8a9869441d09bf (commit)
via 73491f469c244ec077e8448d41c4e193b6a3599b (commit)
via 6b4bcce3cbb89442f96e2e47a507b5983f27a191 (commit)
via 6994bbf289dc098d38b27521da3a7431e17736db (commit)
from 836c1a7baa9421c1222e022cdc263d8c1a5a2b14 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 0ad73077c230093ae004829da44418597f330c6a
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Thu Dec 24 00:46:18 2015 +0100
prepare for release of 1.0.10
commit cc82a850a0ebfbacb7fb62ea2c5b7dd6aebb005d
Author: Steve Ellcey <sellcey(a)imgtec.com>
Date: Wed Dec 23 08:38:41 2015 -0800
Replace bltzal with lapc for MIPS R6 builds.
The R6 version of MIPS does not support the bltzal instruction. This
patch changes dl-startup.h and dl-sysdep.h to use lapc on R6 instead.
lapc is a new R6 insruction so older systems need to continue to use
bltzal in order to load register $31.
Signed-off-by: Steve Ellcey <sellcey(a)imgtec.com>
commit 2636b17616a19d628c3dbc373ebae67ef6e2b1f6
Author: Steve Ellcey <sellcey(a)imgtec.com>
Date: Mon Dec 21 13:22:07 2015 -0800
Replace MIPS specific memcpy.S/memset.S with version from glibc/newlib.
These MIPS specific versions of memcpy.S and memset.S are faster than
the current ones and match what is in newlib and glibc. They also have
support for the mips32r6 and mips64r6 architectures.
Signed-off-by: Steve Ellcey <sellcey(a)imgtec.com>
commit e3c3bf2b5801d0cc544e732fcee1ba51121051b3
Author: Nicolas S. Dade <nic.dade(a)gmail.com>
Date: Fri Dec 18 19:39:19 2015 -0800
pselect: Use linux pselect syscall when available
Linux has a pselect syscall since 2.6.something. Using it
rather than emulating it with sigprocmask+select+sigprocmask
is smaller code, and works properly. (The emulation has
race conditions when unblocked signals arrive before or
after the select)
The tv.nsec >= 1E9 handling comes from uclibc's linux select()
implementation, which itself uses pselect() internally if the
pselect syscall exists. I though it would be good to do the
same here.
Note that although the libc pselect() API has 6 arguments,
the linux kernel syscall as 7 arguments. There is an extra,
somewhat vestigial, sizeof the signal mask argument.
Signed-off-by: Nicolas S. Dade <nic.dade(a)gmail.com>
commit f5bdd8ff82607e55a1c511e13e37a984408c8094
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:58:08 2015 +0100
libc/pwd_grp: Create template for non-reentrant functions
Avoid a lot of copy'n'paste code, no functionality change
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 2a3ffa836a3a9f94f19ee2671f41c1851221a105
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:56:08 2015 +0100
Use gcc's __builtin_mempcpy() as __mempcpy(), if possible
Patch from OpenWrt.
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 74b17c7956b8f0bd109b0fd26a8a9869441d09bf
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:51:13 2015 +0100
use arch specific thread stack size for nptl
Use the arch specific thread stack size for nptl if the size
returned by getrlimits exceeds it - fixes threads on systems
with only 16 MB RAM.
Patch from OpenWRT
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 73491f469c244ec077e8448d41c4e193b6a3599b
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:52:55 2015 +0100
Do define some IPv6 related symbols even with IPv6 disabled
Fixes compilation of some faulty applictions.
Patch from Freetz.org
Reported-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
commit 6b4bcce3cbb89442f96e2e47a507b5983f27a191
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:47:56 2015 +0100
resolv: fix gethostbyname2_r to match gethostbyname_r, fixing bugs with AAAA lookups
The latter half of gethostbyname2_r (doing AAAA queries) is rather dramatically different
from the corresponding portion of gethostbyname_r (doing A queries). This leads to problems
like calls to getaddrinfo only returning one IPv6 address, even when multiple exist.
Seems to be entirely a case of divergent evolution -- a half-decade of fixes for the IPv4
code but no love for IPv6. Until now. ;)
DNS behaviour for IPv6 is really no different than for IPv4 -- beyond the difference in
address sizes, there's no need for the functions to be so different.
Consequently, this patch really is almost just a cut-and-paste of gethostbyname_r, with
the appropriate substitutions of in6_addr, AF_INET6, etc; while holding on to the few
extra bits that actually belong in there (eg #ifdef __UCLIBC_HAS_IPV6__).
Signed-off-by: Wes Campaigne <westacular(a)gmail.com>
commit 6994bbf289dc098d38b27521da3a7431e17736db
Author: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
Date: Tue Dec 22 10:45:51 2015 +0100
inet/resolv: Fix broken h_aliases list terminator after 2dab3f5
Commit 2dab3f5a "resolv: tiny shrinkage in /etc/hosts handling" leads to
that read_etc_hosts_r() provide garbage pointer at the end of h_aliases
list if more than four hostnames follow a dotted quad in /etc/hosts
Test-case:
Add following line to /etc/hosts
63.63.0.2 host1 alias2 alias3 alias4 alias5
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main (void)
{
int i;
char *a;
struct hostent *he;
struct in_addr ipv4addr;
inet_pton(AF_INET, "63.63.0.2", &ipv4addr);
he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
if (he == NULL)
exit(1);
printf("Host name: '%s'\n", he->h_name);
i = 0;
while ((a = he->h_aliases[i]) != NULL) {
printf("Host alias: '%s'\n", a);
++i;
}
return 0;
}
Wrong output:
Host name: 'host1'
Host alias: 'alias2'
Host alias: 'alias3'
Host alias: 'alias4'
Host alias: 'alias5'
Host alias: '??'
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx(a)uclibc-ng.org>
-----------------------------------------------------------------------
Summary of changes:
Rules.mak | 2 +-
include/string.h | 4 +-
ldso/ldso/mips/dl-startup.h | 5 +
ldso/ldso/mips/dl-sysdep.h | 5 +
libc/inet/resolv.c | 165 ++++--
libc/pwd_grp/fgetgrent.c | 12 +-
libc/pwd_grp/fgetpwent.c | 12 +-
libc/pwd_grp/fgetspent.c | 6 +-
libc/pwd_grp/getgrent.c | 5 +-
libc/pwd_grp/getgrgid.c | 6 +-
libc/pwd_grp/getgrgid_r.c | 7 +-
libc/pwd_grp/getgrnam.c | 6 +-
libc/pwd_grp/getgrnam_r.c | 7 +-
libc/pwd_grp/getpwent.c | 5 +-
libc/pwd_grp/getpwnam.c | 7 +-
libc/pwd_grp/getpwnam_r.c | 7 +-
libc/pwd_grp/getpwuid.c | 6 +-
libc/pwd_grp/getpwuid_r.c | 7 +-
libc/pwd_grp/getspent.c | 5 +-
libc/pwd_grp/getspnam.c | 6 +-
libc/pwd_grp/getspnam_r.c | 7 +-
libc/pwd_grp/pwd_grp.c | 263 +--------
libc/pwd_grp/pwd_grp_internal.c | 49 +-
libc/pwd_grp/sgetspent.c | 6 +-
libc/string/generic/mempcpy.c | 1 +
libc/string/mips/memcpy.S | 1051 +++++++++++++++++++++++++++--------
libc/string/mips/memset.S | 516 +++++++++++++----
libc/sysdeps/linux/common/bits/in.h | 2 +-
libc/sysdeps/linux/common/pselect.c | 52 ++
libpthread/nptl/init.c | 4 +
30 files changed, 1549 insertions(+), 687 deletions(-)
diff --git a/Rules.mak b/Rules.mak
index 7652aab..7f244b4 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -126,7 +126,7 @@ export RUNTIME_PREFIX DEVEL_PREFIX KERNEL_HEADERS MULTILIB_DIR
# Now config hard core
MAJOR_VERSION := 1
MINOR_VERSION := 0
-SUBLEVEL := 9
+SUBLEVEL := 10
EXTRAVERSION :=
VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL)
ABI_VERSION := $(MAJOR_VERSION)
diff --git a/include/string.h b/include/string.h
index 1d75f44..80585ef 100644
--- a/include/string.h
+++ b/include/string.h
@@ -258,7 +258,9 @@ extern void *memmem (const void *__haystack, size_t __haystacklen,
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
last written byte. */
-#if 0 /* uClibc: disabled */
+#if __GNUC_PREREQ (3, 4)
+# define __mempcpy(dest, src, n) __builtin_mempcpy(dest, src, n)
+#else /* uClibc: disabled */
extern void *__mempcpy (void *__restrict __dest,
const void *__restrict __src, size_t __n)
__THROW __nonnull ((1, 2));
diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h
index 4d9918d..0cab7be 100644
--- a/ldso/ldso/mips/dl-startup.h
+++ b/ldso/ldso/mips/dl-startup.h
@@ -37,6 +37,7 @@ __asm__(""
#if _MIPS_SIM == _MIPS_SIM_ABI32
" subu $29, 16\n"
#endif
+# if !defined __mips_isa_rev || __mips_isa_rev < 6
#if _MIPS_SIM == _MIPS_SIM_ABI64
" dla $8, .coff\n"
#else /* O32 || N32 */
@@ -44,6 +45,10 @@ __asm__(""
#endif /* O32 || N32 */
" bltzal $8, .coff\n"
".coff:\n"
+# else
+ ".coff:\n"
+ " lapc $31, .coff\n"
+# endif
#if _MIPS_SIM == _MIPS_SIM_ABI64
" dsubu $8, $31, $8\n"
" dla $25, _dl_start\n"
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 6041245..b2caa7f 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/ldso/ldso/mips/dl-sysdep.h
@@ -225,10 +225,15 @@ elf_machine_load_address (void)
{
ElfW(Addr) addr;
__asm__ (" .set noreorder\n"
+# if !defined __mips_isa_rev || __mips_isa_rev < 6
" " STRINGXP (PTR_LA) " %0, 0f\n"
" bltzal $0, 0f\n"
" nop\n"
"0: " STRINGXP (PTR_SUBU) " %0, $31, %0\n"
+#else
+ "0: lapc $31, 0\n"
+ " " STRINGXP (PTR_SUBU) " %0, $31, %0\n"
+#endif
" .set reorder\n"
: "=r" (addr)
: /* No inputs */
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 8e5a97d..3851b2a 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1596,7 +1596,7 @@ parser_t * __open_etc_hosts(void)
#define MINTOKENS 2 /* ip address + canonical name */
#define MAXTOKENS (MINTOKENS + MAXALIASES)
-#define HALISTOFF (sizeof(char*) * MAXTOKENS)
+#define HALISTOFF (sizeof(char*) * (MAXTOKENS + 1)) /* reserve space for list terminator */
#define INADDROFF (HALISTOFF + 2 * sizeof(char*))
int __read_etc_hosts_r(
@@ -2200,12 +2200,13 @@ int gethostbyname2_r(const char *name,
? gethostbyname_r(name, result_buf, buf, buflen, result, h_errnop)
: HOST_NOT_FOUND;
#else
- struct in6_addr *in;
struct in6_addr **addr_list;
+ char **alias;
+ char *alias0;
unsigned char *packet;
struct resolv_answer a;
int i;
- int nest = 0;
+ int packet_len;
int wrong_af = 0;
if (family == AF_INET)
@@ -2220,9 +2221,8 @@ int gethostbyname2_r(const char *name,
/* do /etc/hosts first */
{
- int old_errno = errno; /* Save the old errno and reset errno */
- __set_errno(0); /* to check for missing /etc/hosts. */
-
+ int old_errno = errno; /* save the old errno and reset errno */
+ __set_errno(0); /* to check for missing /etc/hosts. */
i = __get_hosts_byname_r(name, AF_INET6 /*family*/, result_buf,
buf, buflen, result, h_errnop);
if (i == NETDB_SUCCESS) {
@@ -2244,42 +2244,58 @@ int gethostbyname2_r(const char *name,
}
__set_errno(old_errno);
}
+
DPRINTF("Nothing found in /etc/hosts\n");
*h_errnop = NETDB_INTERNAL;
+ /* prepare future h_aliases[0] */
+ i = strlen(name) + 1;
+ if ((ssize_t)buflen <= i)
+ return ERANGE;
+ memcpy(buf, name, i); /* paranoia: name might change */
+ alias0 = buf;
+ buf += i;
+ buflen -= i;
/* make sure pointer is aligned */
i = ALIGN_BUFFER_OFFSET(buf);
buf += i;
buflen -= i;
/* Layout in buf:
- * struct in6_addr* in;
- * struct in6_addr* addr_list[2];
- * char scratch_buf[256];
+ * char *alias[2];
+ * struct in6_addr* addr_list[NN+1];
+ * struct in6_addr* in[NN];
*/
- in = (struct in6_addr*)buf;
- buf += sizeof(*in);
- buflen -= sizeof(*in);
- addr_list = (struct in6_addr**)buf;
- buf += sizeof(*addr_list) * 2;
- buflen -= sizeof(*addr_list) * 2;
+ alias = (char **)buf;
+ buf += sizeof(alias[0]) * 2;
+ buflen -= sizeof(alias[0]) * 2;
+ addr_list = (struct in6_addr **)buf;
+ /* buflen may be < 0, must do signed compare */
if ((ssize_t)buflen < 256)
return ERANGE;
- addr_list[0] = in;
- addr_list[1] = NULL;
- strncpy(buf, name, buflen);
- buf[buflen] = '\0';
+
+ /* we store only one "alias" - the name itself */
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning TODO -- generate the full list
+#endif
+ alias[0] = alias0;
+ alias[1] = NULL;
/* maybe it is already an address? */
- if (inet_pton(AF_INET6, name, in)) {
- result_buf->h_name = buf;
- result_buf->h_addrtype = AF_INET6;
- result_buf->h_length = sizeof(*in);
- result_buf->h_addr_list = (char **) addr_list;
- /* result_buf->h_aliases = ??? */
- *result = result_buf;
- *h_errnop = NETDB_SUCCESS;
- return NETDB_SUCCESS;
+ {
+ struct in6_addr *in = (struct in6_addr *)(buf + sizeof(addr_list[0]) * 2);
+ if (inet_pton(AF_INET6, name, in)) {
+ addr_list[0] = in;
+ addr_list[1] = NULL;
+ result_buf->h_name = alias0;
+ result_buf->h_aliases = alias;
+ result_buf->h_addrtype = AF_INET6;
+ result_buf->h_length = sizeof(struct in6_addr);
+ result_buf->h_addr_list = (char **) addr_list;
+ *result = result_buf;
+ *h_errnop = NETDB_SUCCESS;
+ return NETDB_SUCCESS;
+ }
}
/* what if /etc/hosts has it but it's not IPv6?
@@ -2291,51 +2307,80 @@ int gethostbyname2_r(const char *name,
}
/* talk to DNS servers */
-/* TODO: why it's so different from gethostbyname_r (IPv4 case)? */
- memset(&a, '\0', sizeof(a));
- for (;;) {
- int packet_len;
+ a.buf = buf;
+ /* take into account that at least one address will be there,
+ * we'll need space of one in6_addr + two addr_list[] elems */
+ a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in6_addr)));
+ a.add_count = 0;
+ packet_len = __dns_lookup(name, T_AAAA, &packet, &a);
+ if (packet_len < 0) {
+ *h_errnop = HOST_NOT_FOUND;
+ DPRINTF("__dns_lookup returned < 0\n");
+ return TRY_AGAIN;
+ }
-/* Hmm why we memset(a) to zeros only once? */
- packet_len = __dns_lookup(buf, T_AAAA, &packet, &a);
- if (packet_len < 0) {
- *h_errnop = HOST_NOT_FOUND;
- return TRY_AGAIN;
+ if (a.atype == T_AAAA) { /* ADDRESS */
+ /* we need space for addr_list[] and one IPv6 address */
+ /* + 1 accounting for 1st addr (it's in a.rdata),
+ * another + 1 for NULL in last addr_list[]: */
+ int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1)
+ /* for 1st addr (it's in a.rdata): */
+ + sizeof(struct in6_addr);
+ /* how many bytes will 2nd and following addresses take? */
+ int ips_len = a.add_count * a.rdlength;
+
+ buflen -= (need_bytes + ips_len);
+ if ((ssize_t)buflen < 0) {
+ DPRINTF("buffer too small for all addresses\n");
+ /* *h_errnop = NETDB_INTERNAL; - already is */
+ i = ERANGE;
+ goto free_and_ret;
}
- strncpy(buf, a.dotted, buflen);
- free(a.dotted);
- if (a.atype != T_CNAME)
- break;
+ /* if there are additional addresses in buf,
+ * move them forward so that they are not destroyed */
+ DPRINTF("a.add_count:%d a.rdlength:%d a.rdata:%p\n", a.add_count, a.rdlength, a.rdata);
+ memmove(buf + need_bytes, buf, ips_len);
- DPRINTF("Got a CNAME in gethostbyname()\n");
- if (++nest > MAX_RECURSE) {
- *h_errnop = NO_RECOVERY;
- return -1;
+ /* 1st address is in a.rdata, insert it */
+ buf += need_bytes - sizeof(struct in6_addr);
+ memcpy(buf, a.rdata, sizeof(struct in6_addr));
+
+ /* fill addr_list[] */
+ for (i = 0; i <= a.add_count; i++) {
+ addr_list[i] = (struct in6_addr*)buf;
+ buf += sizeof(struct in6_addr);
}
- i = __decode_dotted(packet, a.rdoffset, packet_len, buf, buflen);
- free(packet);
- if (i < 0) {
- *h_errnop = NO_RECOVERY;
- return -1;
+ addr_list[i] = NULL;
+
+ /* if we have enough space, we can report "better" name
+ * (it may contain search domains attached by __dns_lookup,
+ * or CNAME of the host if it is different from the name
+ * we used to find it) */
+ if (a.dotted && buflen > strlen(a.dotted)) {
+ strcpy(buf, a.dotted);
+ alias0 = buf;
}
- }
- if (a.atype == T_AAAA) { /* ADDRESS */
- memcpy(in, a.rdata, sizeof(*in));
- result_buf->h_name = buf;
+
+ result_buf->h_name = alias0;
+ result_buf->h_aliases = alias;
result_buf->h_addrtype = AF_INET6;
- result_buf->h_length = sizeof(*in);
+ result_buf->h_length = sizeof(struct in6_addr);
result_buf->h_addr_list = (char **) addr_list;
- /* result_buf->h_aliases = ??? */
- free(packet);
*result = result_buf;
*h_errnop = NETDB_SUCCESS;
- return NETDB_SUCCESS;
+ i = NETDB_SUCCESS;
+ goto free_and_ret;
}
- free(packet);
+
*h_errnop = HOST_NOT_FOUND;
- return TRY_AGAIN;
+ __set_h_errno(HOST_NOT_FOUND);
+ i = TRY_AGAIN;
+ free_and_ret:
+ free(a.dotted);
+ free(packet);
+ return i;
#endif /* __UCLIBC_HAS_IPV6__ */
}
libc_hidden_def(gethostbyname2_r)
diff --git a/libc/pwd_grp/fgetgrent.c b/libc/pwd_grp/fgetgrent.c
index 695aee1..6a45799 100644
--- a/libc/pwd_grp/fgetgrent.c
+++ b/libc/pwd_grp/fgetgrent.c
@@ -4,5 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetgrent
+#include <features.h>
+
+#ifdef __USE_SVID
+
+#define GETXXKEY_FUNC fgetgrent
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
+
+#endif
diff --git a/libc/pwd_grp/fgetpwent.c b/libc/pwd_grp/fgetpwent.c
index ddcc7ff..6f65cf6 100644
--- a/libc/pwd_grp/fgetpwent.c
+++ b/libc/pwd_grp/fgetpwent.c
@@ -4,5 +4,15 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetpwent
+#include <features.h>
+
+#ifdef __USE_SVID
+
+#define GETXXKEY_FUNC fgetpwent
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
+
+#endif
diff --git a/libc/pwd_grp/fgetspent.c b/libc/pwd_grp/fgetspent.c
index b7c1ef2..77ca0b8 100644
--- a/libc/pwd_grp/fgetspent.c
+++ b/libc/pwd_grp/fgetspent.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_fgetspent
+#define GETXXKEY_FUNC fgetspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS FILE *stream
+#define GETXXKEY_ADD_VARIABLES stream
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrent.c b/libc/pwd_grp/getgrent.c
index 808e4e8..5b03b31 100644
--- a/libc/pwd_grp/getgrent.c
+++ b/libc/pwd_grp/getgrent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrent
+#define GETXXKEY_FUNC getgrent
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c
index 96ce903..2988452 100644
--- a/libc/pwd_grp/getgrgid.c
+++ b/libc/pwd_grp/getgrgid.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrgid
+#define GETXXKEY_FUNC getgrgid
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS gid_t git
+#define GETXXKEY_ADD_VARIABLES git
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrgid_r.c b/libc/pwd_grp/getgrgid_r.c
index a962f4c..b0f0c9a 100644
--- a/libc/pwd_grp/getgrgid_r.c
+++ b/libc/pwd_grp/getgrgid_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrgid_r
+#define GETXXKEY_R_FUNC getgrgid_r
+#define GETXXKEY_R_PARSER __parsegrent
+#define GETXXKEY_R_ENTTYPE struct group
+#define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key)
+#define DO_GETXXKEY_R_KEYTYPE gid_t
+#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c
index 3b47d9a..f6ce459 100644
--- a/libc/pwd_grp/getgrnam.c
+++ b/libc/pwd_grp/getgrnam.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrnam
+#define GETXXKEY_FUNC getgrnam
+#define GETXXKEY_ENTTYPE struct group
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_GRP_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getgrnam_r.c b/libc/pwd_grp/getgrnam_r.c
index 592a66c..35121e7 100644
--- a/libc/pwd_grp/getgrnam_r.c
+++ b/libc/pwd_grp/getgrnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getgrnam_r
+#define GETXXKEY_R_FUNC getgrnam_r
+#define GETXXKEY_R_PARSER __parsegrent
+#define GETXXKEY_R_ENTTYPE struct group
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwent.c b/libc/pwd_grp/getpwent.c
index a617bc8..7ddc8ee 100644
--- a/libc/pwd_grp/getpwent.c
+++ b/libc/pwd_grp/getpwent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwent
+#define GETXXKEY_FUNC getpwent
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c
index d00640b..e3e8c02 100644
--- a/libc/pwd_grp/getpwnam.c
+++ b/libc/pwd_grp/getpwnam.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwnam
+#define GETXXKEY_FUNC getpwnam
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
+#define GETXXKEY_FUNC_HIDDEN
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwnam_r.c b/libc/pwd_grp/getpwnam_r.c
index a4440e7..bc5e3d5 100644
--- a/libc/pwd_grp/getpwnam_r.c
+++ b/libc/pwd_grp/getpwnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwnam_r
+#define GETXXKEY_R_FUNC getpwnam_r
+#define GETXXKEY_R_PARSER __parsepwent
+#define GETXXKEY_R_ENTTYPE struct passwd
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c
index 16ac50f..1ad2688 100644
--- a/libc/pwd_grp/getpwuid.c
+++ b/libc/pwd_grp/getpwuid.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwuid
+#define GETXXKEY_FUNC getpwuid
+#define GETXXKEY_ENTTYPE struct passwd
+#define GETXXKEY_ADD_PARAMS uid_t uid
+#define GETXXKEY_ADD_VARIABLES uid
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getpwuid_r.c b/libc/pwd_grp/getpwuid_r.c
index 21d39ed..0a5aa96 100644
--- a/libc/pwd_grp/getpwuid_r.c
+++ b/libc/pwd_grp/getpwuid_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getpwuid_r
+#define GETXXKEY_R_FUNC getpwuid_r
+#define GETXXKEY_R_PARSER __parsepwent
+#define GETXXKEY_R_ENTTYPE struct passwd
+#define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key)
+#define DO_GETXXKEY_R_KEYTYPE uid_t
+#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspent.c b/libc/pwd_grp/getspent.c
index 5699b67..4feb9f9 100644
--- a/libc/pwd_grp/getspent.c
+++ b/libc/pwd_grp/getspent.c
@@ -4,5 +4,8 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspent
+#define GETXXKEY_FUNC getspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS void
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspnam.c b/libc/pwd_grp/getspnam.c
index 19e40c7..a0a01ec 100644
--- a/libc/pwd_grp/getspnam.c
+++ b/libc/pwd_grp/getspnam.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspnam
+#define GETXXKEY_FUNC getspnam
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS const char *name
+#define GETXXKEY_ADD_VARIABLES name
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/getspnam_r.c b/libc/pwd_grp/getspnam_r.c
index 053b697..ea23848 100644
--- a/libc/pwd_grp/getspnam_r.c
+++ b/libc/pwd_grp/getspnam_r.c
@@ -4,5 +4,10 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_getspnam_r
+#define GETXXKEY_R_FUNC getspnam_r
+#define GETXXKEY_R_PARSER __parsespent
+#define GETXXKEY_R_ENTTYPE struct spwd
+#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key))
+#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
+#define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW
#include "pwd_grp.c"
diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c
index 0e7c7f7..acdb08d 100644
--- a/libc/pwd_grp/pwd_grp.c
+++ b/libc/pwd_grp/pwd_grp.c
@@ -127,59 +127,6 @@ libc_hidden_def(fgetspent_r)
#endif
/**********************************************************************/
-/* For the various fget??ent funcs, return NULL on failure and a
- * pointer to the appropriate struct (statically allocated) on success.
- */
-/**********************************************************************/
-#ifdef L_fgetpwent
-
-#ifdef __USE_SVID
-
-struct passwd *fgetpwent(FILE *stream)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- fgetpwent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_fgetgrent
-
-#ifdef __USE_SVID
-
-struct group *fgetgrent(FILE *stream)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- fgetgrent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_fgetspent
-
-
-struct spwd *fgetspent(FILE *stream)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- fgetspent_r(stream, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_sgetspent_r
int sgetspent_r(const char *string, struct spwd *result_buf,
@@ -213,92 +160,6 @@ libc_hidden_def(sgetspent_r)
#endif
/**********************************************************************/
-
-#ifdef GETXXKEY_R_FUNC
-#error GETXXKEY_R_FUNC is already defined!
-#endif
-
-#ifdef L_getpwnam_r
-#define GETXXKEY_R_FUNC getpwnam_r
-#define GETXXKEY_R_PARSER __parsepwent
-#define GETXXKEY_R_ENTTYPE struct passwd
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getgrnam_r
-#define GETXXKEY_R_FUNC getgrnam_r
-#define GETXXKEY_R_PARSER __parsegrent
-#define GETXXKEY_R_ENTTYPE struct group
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getspnam_r
-#define GETXXKEY_R_FUNC getspnam_r
-#define GETXXKEY_R_PARSER __parsespent
-#define GETXXKEY_R_ENTTYPE struct spwd
-#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key))
-#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
-#define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getpwuid_r
-#define GETXXKEY_R_FUNC getpwuid_r
-#define GETXXKEY_R_PARSER __parsepwent
-#define GETXXKEY_R_ENTTYPE struct passwd
-#define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key)
-#define DO_GETXXKEY_R_KEYTYPE uid_t
-#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
-#include "pwd_grp_internal.c"
-#endif
-
-#ifdef L_getgrgid_r
-#define GETXXKEY_R_FUNC getgrgid_r
-#define GETXXKEY_R_PARSER __parsegrent
-#define GETXXKEY_R_ENTTYPE struct group
-#define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key)
-#define DO_GETXXKEY_R_KEYTYPE gid_t
-#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
-#include "pwd_grp_internal.c"
-#endif
-
-/**********************************************************************/
-#ifdef L_getpwuid
-
-
-struct passwd *getpwuid(uid_t uid)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrgid
-
-
-struct group *getgrgid(gid_t gid)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- getgrgid_r(gid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_getspuid_r
/* This function is non-standard and is currently not built. It seems
@@ -325,69 +186,6 @@ int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf,
#endif
/**********************************************************************/
-#ifdef L_getspuid
-
-/* This function is non-standard and is currently not built.
- * Why it was added, I do not know. */
-
-struct spwd *getspuid(uid_t uid)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- getspuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getpwnam
-
-
-struct passwd *getpwnam(const char *name)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd resultbuf;
- struct passwd *result;
-
- getpwnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-libc_hidden_def(getpwnam)
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrnam
-
-
-struct group *getgrnam(const char *name)
-{
- static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group resultbuf;
- struct group *result;
-
- getgrnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getspnam
-
-
-struct spwd *getspnam(const char *name)
-{
- static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd resultbuf;
- struct spwd *result;
-
- getspnam_r(name, &resultbuf, buffer, sizeof(buffer), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
#ifdef L_getpw
@@ -585,65 +383,14 @@ libc_hidden_def(getspent_r)
#endif
/**********************************************************************/
-#ifdef L_getpwent
-
-
-struct passwd *getpwent(void)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct passwd pwd;
- struct passwd *result;
-
- getpwent_r(&pwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_getgrent
-
-
-struct group *getgrent(void)
-{
- static char line_buff[__UCLIBC_GRP_BUFFER_SIZE__];
- static struct group gr;
- struct group *result;
-
- getgrent_r(&gr, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
-#endif
+/* For the various fget??ent funcs, return NULL on failure and a
+ * pointer to the appropriate struct (statically allocated) on success.
+ */
/**********************************************************************/
-#ifdef L_getspent
-
-
-struct spwd *getspent(void)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd spwd;
- struct spwd *result;
-
- getspent_r(&spwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-
+#if defined(GETXXKEY_FUNC) || defined(GETXXKEY_R_FUNC)
+#include "pwd_grp_internal.c"
#endif
-/**********************************************************************/
-#ifdef L_sgetspent
-
-
-struct spwd *sgetspent(const char *string)
-{
- static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
- static struct spwd spwd;
- struct spwd *result;
-
- sgetspent_r(string, &spwd, line_buff, sizeof(line_buff), &result);
- return result;
-}
-#endif
/**********************************************************************/
#ifdef L___getgrouplist_internal
diff --git a/libc/pwd_grp/pwd_grp_internal.c b/libc/pwd_grp/pwd_grp_internal.c
index d2fde11..104f532 100644
--- a/libc/pwd_grp/pwd_grp_internal.c
+++ b/libc/pwd_grp/pwd_grp_internal.c
@@ -36,18 +36,10 @@
#endif
/**********************************************************************/
-/* Sizes for statically allocated buffers. */
-
-/* If you change these values, also change _SC_GETPW_R_SIZE_MAX and
- * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
-
-/**********************************************************************/
/* Prototypes for internal functions. */
-#ifndef GETXXKEY_R_FUNC
-#error GETXXKEY_R_FUNC is not defined!
+#if !defined(GETXXKEY_R_FUNC) && !defined(GETXXKEY_FUNC)
+#error GETXXKEY_R_FUNC/GETXXKEY_FUNC are not defined!
#endif
/**********************************************************************/
#ifdef GETXXKEY_R_FUNC
@@ -89,9 +81,44 @@ int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
}
libc_hidden_def(GETXXKEY_R_FUNC)
+#endif /* GETXXKEY_R_FUNC */
+
+/**********************************************************************/
+#ifdef GETXXKEY_FUNC
+
+#define REENTRANT_NAME APPEND_R(GETXXKEY_FUNC)
+#define APPEND_R(name) APPEND_R1(name)
+#define APPEND_R1(name) name##_r
+
+GETXXKEY_ENTTYPE *GETXXKEY_FUNC(GETXXKEY_ADD_PARAMS)
+{
+ static char buffer[GETXXKEY_BUFLEN];
+ static GETXXKEY_ENTTYPE resultbuf;
+ GETXXKEY_ENTTYPE *result;
+
+# ifdef GETXXKEY_ADD_VARIABLES
+ REENTRANT_NAME(GETXXKEY_ADD_VARIABLES, &resultbuf, buffer, sizeof(buffer), &result);
+# else
+ REENTRANT_NAME(&resultbuf, buffer, sizeof(buffer), &result);
+# endif
+ return result;
+}
+#ifdef GETXXKEY_FUNC_HIDDEN
+libc_hidden_def(GETXXKEY_FUNC)
#endif
+
+#undef REENTRANT_NAME
+#undef APPEND_R
+#undef APPEND_R1
+#endif /* GETXXKEY_FUNC */
+
/**********************************************************************/
-#undef GETXXKEY_R_FUNC_HIDDEN
+#undef GETXXKEY_FUNC
+#undef GETXXKEY_ENTTYPE
+#undef GETXXKEY_BUFLEN
+#undef GETXXKEY_FUNC_HIDDEN
+#undef GETXXKEY_ADD_PARAMS
+#undef GETXXKEY_ADD_VARIABLES
#undef GETXXKEY_R_FUNC
#undef GETXXKEY_R_PARSER
#undef GETXXKEY_R_ENTTYPE
diff --git a/libc/pwd_grp/sgetspent.c b/libc/pwd_grp/sgetspent.c
index 877a247..990c0b6 100644
--- a/libc/pwd_grp/sgetspent.c
+++ b/libc/pwd_grp/sgetspent.c
@@ -4,5 +4,9 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
-#define L_sgetspent
+#define GETXXKEY_FUNC sgetspent
+#define GETXXKEY_ENTTYPE struct spwd
+#define GETXXKEY_ADD_PARAMS const char *string
+#define GETXXKEY_ADD_VARIABLES string
+#define GETXXKEY_BUFLEN __UCLIBC_PWD_BUFFER_SIZE__
#include "pwd_grp.c"
diff --git a/libc/string/generic/mempcpy.c b/libc/string/generic/mempcpy.c
index d7fa79e..bb5563a 100644
--- a/libc/string/generic/mempcpy.c
+++ b/libc/string/generic/mempcpy.c
@@ -16,4 +16,5 @@ void *mempcpy (void *dstpp, const void *srcpp, size_t len)
return (void *)(((char *)dstpp) + len);
}
libc_hidden_weak(mempcpy)
+strong_alias(mempcpy,__mempcpy)
#endif
diff --git a/libc/string/mips/memcpy.S b/libc/string/mips/memcpy.S
index 48c4f2a..2a187ef 100644
--- a/libc/string/mips/memcpy.S
+++ b/libc/string/mips/memcpy.S
@@ -1,6 +1,5 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2012-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Hartvig Ekner <hartvige(a)mips.com>, 2002.
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,243 +12,861 @@
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
+ License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <features.h>
-#include <sysdep.h>
-#include <endian.h>
+#ifdef ANDROID_CHANGES
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define USE_MEMMOVE_FOR_OVERLAP
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif _LIBC
+# include <sysdep.h>
+# include <regdef.h>
+# include <sys/asm.h>
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif defined _COMPILING_NEWLIB
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD_STREAMED
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#else
+# include <regdef.h>
+# include <sys/asm.h>
+#endif
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+# ifndef DISABLE_PREFETCH
+# define USE_PREFETCH
+# endif
+#endif
+
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
+# ifndef DISABLE_DOUBLE
+# define USE_DOUBLE
+# endif
+#endif
+
+/* Some asm.h files do not have the L macro definition. */
+#ifndef L
+# if _MIPS_SIM == _ABIO32
+# define L(label) $L ## label
+# else
+# define L(label) .L ## label
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_ADDIU macro definition. */
+#ifndef PTR_ADDIU
+# ifdef USE_DOUBLE
+# define PTR_ADDIU daddiu
+# else
+# define PTR_ADDIU addiu
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_SRA macro definition. */
+#ifndef PTR_SRA
+# ifdef USE_DOUBLE
+# define PTR_SRA dsra
+# else
+# define PTR_SRA sra
+# endif
+#endif
+
+/* New R6 instructions that may not be in asm.h. */
+#ifndef PTR_LSA
+# if _MIPS_SIM == _ABI64
+# define PTR_LSA dlsa
+# else
+# define PTR_LSA lsa
+# endif
+#endif
+
+/*
+ * Using PREFETCH_HINT_LOAD_STREAMED instead of PREFETCH_LOAD on load
+ * prefetches appears to offer a slight preformance advantage.
+ *
+ * Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
+ * or PREFETCH_STORE_STREAMED offers a large performance advantage
+ * but PREPAREFORSTORE has some special restrictions to consider.
+ *
+ * Prefetch with the 'prepare for store' hint does not copy a memory
+ * location into the cache, it just allocates a cache line and zeros
+ * it out. This means that if you do not write to the entire cache
+ * line before writing it out to memory some data will get zero'ed out
+ * when the cache line is written back to memory and data will be lost.
+ *
+ * Also if you are using this memcpy to copy overlapping buffers it may
+ * not behave correctly when using the 'prepare for store' hint. If you
+ * use the 'prepare for store' prefetch on a memory area that is in the
+ * memcpy source (as well as the memcpy destination), then you will get
+ * some data zero'ed out before you have a chance to read it and data will
+ * be lost.
+ *
+ * If you are going to use this memcpy routine with the 'prepare for store'
+ * prefetch you may want to set USE_MEMMOVE_FOR_OVERLAP in order to avoid
+ * the problem of running memcpy on overlapping buffers.
+ *
+ * There are ifdef'ed sections of this memcpy to make sure that it does not
+ * do prefetches on cache lines that are not going to be completely written.
+ * This code is only needed and only used when PREFETCH_STORE_HINT is set to
+ * PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are
+ * 32 bytes and if the cache line is larger it will not work correctly.
+ */
+
+#ifdef USE_PREFETCH
+# define PREFETCH_HINT_LOAD 0
+# define PREFETCH_HINT_STORE 1
+# define PREFETCH_HINT_LOAD_STREAMED 4
+# define PREFETCH_HINT_STORE_STREAMED 5
+# define PREFETCH_HINT_LOAD_RETAINED 6
+# define PREFETCH_HINT_STORE_RETAINED 7
+# define PREFETCH_HINT_WRITEBACK_INVAL 25
+# define PREFETCH_HINT_PREPAREFORSTORE 30
+
+/*
+ * If we have not picked out what hints to use at this point use the
+ * standard load and store prefetch hints.
+ */
+# ifndef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
+# endif
+# ifndef PREFETCH_LOAD_HINT
+# define PREFETCH_LOAD_HINT PREFETCH_HINT_LOAD
+# endif
+
+/*
+ * We double everything when USE_DOUBLE is true so we do 2 prefetches to
+ * get 64 bytes in that case. The assumption is that each individual
+ * prefetch brings in 32 bytes.
+ */
+
+# ifdef USE_DOUBLE
+# define PREFETCH_CHUNK 64
+# define PREFETCH_FOR_LOAD(chunk, reg) \
+ pref PREFETCH_LOAD_HINT, (chunk)*64(reg); \
+ pref PREFETCH_LOAD_HINT, ((chunk)*64)+32(reg)
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
+ pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
+# else
+# define PREFETCH_CHUNK 32
+# define PREFETCH_FOR_LOAD(chunk, reg) \
+ pref PREFETCH_LOAD_HINT, (chunk)*32(reg)
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*32(reg)
+# endif
+/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
+ * than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size
+ * of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
+ * hint is used, the code will not work correctly. If PREPAREFORSTORE is not
+ * used then MAX_PREFETCH_SIZE does not matter. */
+# define MAX_PREFETCH_SIZE 128
+/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
+ * than 5 on a STORE prefetch and that a single prefetch can never be larger
+ * than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because
+ * we actually do two prefetches in that case, one 32 bytes after the other. */
+# ifdef USE_DOUBLE
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
+# else
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
+# endif
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
+ && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
+/* We cannot handle this because the initial prefetches may fetch bytes that
+ * are before the buffer being copied. We start copies with an offset
+ * of 4 so avoid this situation when using PREPAREFORSTORE. */
+#error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
+# endif
+#else /* USE_PREFETCH not defined */
+# define PREFETCH_FOR_LOAD(offset, reg)
+# define PREFETCH_FOR_STORE(offset, reg)
+#endif
+
+#if __mips_isa_rev > 5
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+# undef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
+# endif
+# define R6_CODE
+#endif
-/* void *memcpy(void *s1, const void *s2, size_t n); */
+/* Allow the routine to be named something else if desired. */
+#ifndef MEMCPY_NAME
+# define MEMCPY_NAME memcpy
+#endif
+
+/* We use these 32/64 bit registers as temporaries to do the copying. */
+#define REG0 t0
+#define REG1 t1
+#define REG2 t2
+#define REG3 t3
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABIO64))
+# define REG4 t4
+# define REG5 t5
+# define REG6 t6
+# define REG7 t7
+#else
+# define REG4 ta0
+# define REG5 ta1
+# define REG6 ta2
+# define REG7 ta3
+#endif
-#ifdef __mips64
+/* We load/store 64 bits at a time when USE_DOUBLE is true.
+ * The C_ prefix stands for CHUNK and is used to avoid macro name
+ * conflicts with system header files. */
-#include <sys/asm.h>
+#ifdef USE_DOUBLE
+# define C_ST sd
+# define C_LD ld
+# ifdef __MIPSEB
+# define C_LDHI ldl /* high part is left in big-endian */
+# define C_STHI sdl /* high part is left in big-endian */
+# define C_LDLO ldr /* low part is right in big-endian */
+# define C_STLO sdr /* low part is right in big-endian */
+# else
+# define C_LDHI ldr /* high part is right in little-endian */
+# define C_STHI sdr /* high part is right in little-endian */
+# define C_LDLO ldl /* low part is left in little-endian */
+# define C_STLO sdl /* low part is left in little-endian */
+# endif
+# define C_ALIGN dalign /* r6 align instruction */
+#else
+# define C_ST sw
+# define C_LD lw
+# ifdef __MIPSEB
+# define C_LDHI lwl /* high part is left in big-endian */
+# define C_STHI swl /* high part is left in big-endian */
+# define C_LDLO lwr /* low part is right in big-endian */
+# define C_STLO swr /* low part is right in big-endian */
+# else
+# define C_LDHI lwr /* high part is right in little-endian */
+# define C_STHI swr /* high part is right in little-endian */
+# define C_LDLO lwl /* low part is left in little-endian */
+# define C_STLO swl /* low part is left in little-endian */
+# endif
+# define C_ALIGN align /* r6 align instruction */
+#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define LDHI ldl /* high part is left in big-endian */
-# define SDHI sdl /* high part is left in big-endian */
-# define LDLO ldr /* low part is right in big-endian */
-# define SDLO sdr /* low part is right in big-endian */
+/* Bookkeeping values for 32 vs. 64 bit mode. */
+#ifdef USE_DOUBLE
+# define NSIZE 8
+# define NSIZEMASK 0x3f
+# define NSIZEDMASK 0x7f
#else
-# define LDHI ldr /* high part is right in little-endian */
-# define SDHI sdr /* high part is right in little-endian */
-# define LDLO ldl /* low part is left in little-endian */
-# define SDLO sdl /* low part is left in little-endian */
+# define NSIZE 4
+# define NSIZEMASK 0x1f
+# define NSIZEDMASK 0x3f
#endif
+#define UNIT(unit) ((unit)*NSIZE)
+#define UNITM1(unit) (((unit)*NSIZE)-1)
-ENTRY (memcpy)
+#ifdef ANDROID_CHANGES
+LEAF(MEMCPY_NAME, 0)
+#else
+LEAF(MEMCPY_NAME)
+#endif
+ .set nomips16
.set noreorder
+/*
+ * Below we handle the case where memcpy is called with overlapping src and dst.
+ * Although memcpy is not required to handle this case, some parts of Android
+ * like Skia rely on such usage. We call memmove to handle such cases.
+ */
+#ifdef USE_MEMMOVE_FOR_OVERLAP
+ PTR_SUBU t0,a0,a1
+ PTR_SRA t2,t0,31
+ xor t1,t0,t2
+ PTR_SUBU t0,t1,t2
+ sltu t2,t0,a2
+ beq t2,zero,L(memcpy)
+ la t9,memmove
+ jr t9
+ nop
+L(memcpy):
+#endif
+/*
+ * If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
+ * size, copy dst pointer to v0 for the return value.
+ */
+ slti t2,a2,(2 * NSIZE)
+ bne t2,zero,L(lasts)
+#if defined(RETURN_FIRST_PREFETCH) || defined(RETURN_LAST_PREFETCH)
+ move v0,zero
+#else
+ move v0,a0
+#endif
- slti t0, a2, 16 # Less than 16?
- bne t0, zero, L(last16)
- move v0, a0 # Setup exit value before too late
-
- xor t0, a1, a0 # Find a0/a1 displacement
- andi t0, 0x7
- bne t0, zero, L(shift) # Go handle the unaligned case
- PTR_SUBU t1, zero, a1
- andi t1, 0x7 # a0/a1 are aligned, but are we
- beq t1, zero, L(chk8w) # starting in the middle of a word?
- PTR_SUBU a2, t1
- LDHI t0, 0(a1) # Yes we are... take care of that
- PTR_ADDU a1, t1
- SDHI t0, 0(a0)
- PTR_ADDU a0, t1
-
-L(chk8w):
- andi t0, a2, 0x3f # 64 or more bytes left?
- beq t0, a2, L(chk1w)
- PTR_SUBU a3, a2, t0 # Yes
- PTR_ADDU a3, a1 # a3 = end address of loop
- move a2, t0 # a2 = what will be left after loop
-L(lop8w):
- ld t0, 0(a1) # Loop taking 8 words at a time
- ld t1, 8(a1)
- ld t2, 16(a1)
- ld t3, 24(a1)
- ld ta0, 32(a1)
- ld ta1, 40(a1)
- ld ta2, 48(a1)
- ld ta3, 56(a1)
- PTR_ADDIU a0, 64
- PTR_ADDIU a1, 64
- sd t0, -64(a0)
- sd t1, -56(a0)
- sd t2, -48(a0)
- sd t3, -40(a0)
- sd ta0, -32(a0)
- sd ta1, -24(a0)
- sd ta2, -16(a0)
- bne a1, a3, L(lop8w)
- sd ta3, -8(a0)
+#ifndef R6_CODE
-L(chk1w):
- andi t0, a2, 0x7 # 8 or more bytes left?
- beq t0, a2, L(last16)
- PTR_SUBU a3, a2, t0 # Yes, handle them one dword at a time
- PTR_ADDU a3, a1 # a3 again end address
- move a2, t0
-L(lop1w):
- ld t0, 0(a1)
- PTR_ADDIU a0, 8
- PTR_ADDIU a1, 8
- bne a1, a3, L(lop1w)
- sd t0, -8(a0)
-
-L(last16):
- blez a2, L(lst16e) # Handle last 16 bytes, one at a time
- PTR_ADDU a3, a2, a1
-L(lst16l):
- lb t0, 0(a1)
- PTR_ADDIU a0, 1
- PTR_ADDIU a1, 1
- bne a1, a3, L(lst16l)
- sb t0, -1(a0)
-L(lst16e):
- jr ra # Bye, bye
- nop
+/*
+ * If src and dst have different alignments, go to L(unaligned), if they
+ * have the same alignment (but are not actually aligned) do a partial
+ * load/store to make them aligned. If they are both already aligned
+ * we can start copying at L(aligned).
+ */
+ xor t8,a1,a0
+ andi t8,t8,(NSIZE-1) /* t8 is a0/a1 word-displacement */
+ bne t8,zero,L(unaligned)
+ PTR_SUBU a3, zero, a0
-L(shift):
- PTR_SUBU a3, zero, a0 # Src and Dest unaligned
- andi a3, 0x7 # (unoptimized case...)
- beq a3, zero, L(shft1)
- PTR_SUBU a2, a3 # a2 = bytes left
- LDHI t0, 0(a1) # Take care of first odd part
- LDLO t0, 7(a1)
- PTR_ADDU a1, a3
- SDHI t0, 0(a0)
- PTR_ADDU a0, a3
-L(shft1):
- andi t0, a2, 0x7
- PTR_SUBU a3, a2, t0
- PTR_ADDU a3, a1
-L(shfth):
- LDHI t1, 0(a1) # Limp through, dword by dword
- LDLO t1, 7(a1)
- PTR_ADDIU a0, 8
- PTR_ADDIU a1, 8
- bne a1, a3, L(shfth)
- sd t1, -8(a0)
- b L(last16) # Handle anything which may be left
- move a2, t0
+ andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */
+ beq a3,zero,L(aligned) /* if a3=0, it is already aligned */
+ PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */
- .set reorder
-END (memcpy)
+ C_LDHI t8,0(a1)
+ PTR_ADDU a1,a1,a3
+ C_STHI t8,0(a0)
+ PTR_ADDU a0,a0,a3
+
+#else /* R6_CODE */
+
+/*
+ * Align the destination and hope that the source gets aligned too. If it
+ * doesn't we jump to L(r6_unaligned*) to do unaligned copies using the r6
+ * align instruction.
+ */
+ andi t8,a0,7
+ lapc t9,L(atable)
+ PTR_LSA t9,t8,t9,2
+ jrc t9
+L(atable):
+ bc L(lb0)
+ bc L(lb7)
+ bc L(lb6)
+ bc L(lb5)
+ bc L(lb4)
+ bc L(lb3)
+ bc L(lb2)
+ bc L(lb1)
+L(lb7):
+ lb a3, 6(a1)
+ sb a3, 6(a0)
+L(lb6):
+ lb a3, 5(a1)
+ sb a3, 5(a0)
+L(lb5):
+ lb a3, 4(a1)
+ sb a3, 4(a0)
+L(lb4):
+ lb a3, 3(a1)
+ sb a3, 3(a0)
+L(lb3):
+ lb a3, 2(a1)
+ sb a3, 2(a0)
+L(lb2):
+ lb a3, 1(a1)
+ sb a3, 1(a0)
+L(lb1):
+ lb a3, 0(a1)
+ sb a3, 0(a0)
+
+ li t9,8
+ subu t8,t9,t8
+ PTR_SUBU a2,a2,t8
+ PTR_ADDU a0,a0,t8
+ PTR_ADDU a1,a1,t8
+L(lb0):
-#else /* !__mips64 */
+ andi t8,a1,(NSIZE-1)
+ lapc t9,L(jtable)
+ PTR_LSA t9,t8,t9,2
+ jrc t9
+L(jtable):
+ bc L(aligned)
+ bc L(r6_unaligned1)
+ bc L(r6_unaligned2)
+ bc L(r6_unaligned3)
+# ifdef USE_DOUBLE
+ bc L(r6_unaligned4)
+ bc L(r6_unaligned5)
+ bc L(r6_unaligned6)
+ bc L(r6_unaligned7)
+# endif
+#endif /* R6_CODE */
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define LWHI lwl /* high part is left in big-endian */
-# define SWHI swl /* high part is left in big-endian */
-# define LWLO lwr /* low part is right in big-endian */
-# define SWLO swr /* low part is right in big-endian */
+L(aligned):
+
+/*
+ * Now dst/src are both aligned to (word or double word) aligned addresses
+ * Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ * chunks are copied and a3 to the dst pointer after all the 64/128 byte
+ * chunks have been copied. We will loop, incrementing a0 and a1 until a0
+ * equals a3.
+ */
+
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
+
+/* When in the loop we may prefetch with the 'prepare to store' hint,
+ * in this case the a0+x should not be past the "t0-32" address. This
+ * means: for x=128 the last "safe" a0 address is "t0-160". Alternatively,
+ * for x=64 the last "safe" a0 address is "t0-96" In the current version we
+ * will use "prefetch hint,128(a0)", so "t0-160" is the limit.
+ */
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+#endif
+ PREFETCH_FOR_LOAD (0, a1)
+ PREFETCH_FOR_LOAD (1, a1)
+ PREFETCH_FOR_LOAD (2, a1)
+ PREFETCH_FOR_LOAD (3, a1)
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+#endif
+#if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH)
+# if PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE
+ sltu v1,t9,a0
+ bgtz v1,L(skip_set)
+ nop
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4)
+L(skip_set):
+# else
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1)
+# endif
+#endif
+#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*3)
+# ifdef USE_DOUBLE
+ PTR_ADDIU v0,v0,32
+# endif
+#endif
+L(loop16w):
+ C_LD t0,UNIT(0)(a1)
+#if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */
+ bgtz v1,L(skip_pref)
+#endif
+ C_LD t1,UNIT(1)(a1)
+#ifdef R6_CODE
+ PREFETCH_FOR_STORE (2, a0)
#else
-# define LWHI lwr /* high part is right in little-endian */
-# define SWHI swr /* high part is right in little-endian */
-# define LWLO lwl /* low part is left in little-endian */
-# define SWLO swl /* low part is left in little-endian */
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
+#endif
+#if defined(RETURN_LAST_PREFETCH) && defined(USE_PREFETCH)
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*5)
+# ifdef USE_DOUBLE
+ PTR_ADDIU v0,v0,32
+# endif
#endif
+L(skip_pref):
+ C_LD REG2,UNIT(2)(a1)
+ C_LD REG3,UNIT(3)(a1)
+ C_LD REG4,UNIT(4)(a1)
+ C_LD REG5,UNIT(5)(a1)
+ C_LD REG6,UNIT(6)(a1)
+ C_LD REG7,UNIT(7)(a1)
+#ifdef R6_CODE
+ PREFETCH_FOR_LOAD (3, a1)
+#else
+ PREFETCH_FOR_LOAD (4, a1)
+#endif
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
-ENTRY (memcpy)
- .set noreorder
+ C_LD t0,UNIT(8)(a1)
+ C_LD t1,UNIT(9)(a1)
+ C_LD REG2,UNIT(10)(a1)
+ C_LD REG3,UNIT(11)(a1)
+ C_LD REG4,UNIT(12)(a1)
+ C_LD REG5,UNIT(13)(a1)
+ C_LD REG6,UNIT(14)(a1)
+ C_LD REG7,UNIT(15)(a1)
+#ifndef R6_CODE
+ PREFETCH_FOR_LOAD (5, a1)
+#endif
+ C_ST t0,UNIT(8)(a0)
+ C_ST t1,UNIT(9)(a0)
+ C_ST REG2,UNIT(10)(a0)
+ C_ST REG3,UNIT(11)(a0)
+ C_ST REG4,UNIT(12)(a0)
+ C_ST REG5,UNIT(13)(a0)
+ C_ST REG6,UNIT(14)(a0)
+ C_ST REG7,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(loop16w)
+ PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */
+ move a2,t8
+
+/* Here we have src and dest word-aligned but less than 64-bytes or
+ * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there
+ * is one. Otherwise jump down to L(chk1w) to handle the tail end of
+ * the copy.
+ */
+
+L(chkw):
+ PREFETCH_FOR_LOAD (0, a1)
+ andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */
+ /* The t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(chk1w) /* When a2=t8, no 32-byte chunk */
+ nop
+ C_LD t0,UNIT(0)(a1)
+ C_LD t1,UNIT(1)(a1)
+ C_LD REG2,UNIT(2)(a1)
+ C_LD REG3,UNIT(3)(a1)
+ C_LD REG4,UNIT(4)(a1)
+ C_LD REG5,UNIT(5)(a1)
+ C_LD REG6,UNIT(6)(a1)
+ C_LD REG7,UNIT(7)(a1)
+ PTR_ADDIU a1,a1,UNIT(8)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+
+/*
+ * Here we have less than 32(64) bytes to copy. Set up for a loop to
+ * copy one word (or double word) at a time. Set a2 to count how many
+ * bytes we have to copy after all the word (or double word) chunks are
+ * copied and a3 to the dst pointer after all the (d)word chunks have
+ * been copied. We will loop, incrementing a0 and a1 until a0 equals a3.
+ */
+L(chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(lastw)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
- slti t0, a2, 8 # Less than 8?
- bne t0, zero, L(last8)
- move v0, a0 # Setup exit value before too late
-
- xor t0, a1, a0 # Find a0/a1 displacement
- andi t0, 0x3
- bne t0, zero, L(shift) # Go handle the unaligned case
- subu t1, zero, a1
- andi t1, 0x3 # a0/a1 are aligned, but are we
- beq t1, zero, L(chk8w) # starting in the middle of a word?
- subu a2, t1
- LWHI t0, 0(a1) # Yes we are... take care of that
- addu a1, t1
- SWHI t0, 0(a0)
- addu a0, t1
-
-L(chk8w):
- andi t0, a2, 0x1f # 32 or more bytes left?
- beq t0, a2, L(chk1w)
- subu a3, a2, t0 # Yes
- addu a3, a1 # a3 = end address of loop
- move a2, t0 # a2 = what will be left after loop
-L(lop8w):
- lw t0, 0(a1) # Loop taking 8 words at a time
- lw t1, 4(a1)
- lw t2, 8(a1)
- lw t3, 12(a1)
- lw t4, 16(a1)
- lw t5, 20(a1)
- lw t6, 24(a1)
- lw t7, 28(a1)
- addiu a0, 32
- addiu a1, 32
- sw t0, -32(a0)
- sw t1, -28(a0)
- sw t2, -24(a0)
- sw t3, -20(a0)
- sw t4, -16(a0)
- sw t5, -12(a0)
- sw t6, -8(a0)
- bne a1, a3, L(lop8w)
- sw t7, -4(a0)
-
-L(chk1w):
- andi t0, a2, 0x3 # 4 or more bytes left?
- beq t0, a2, L(last8)
- subu a3, a2, t0 # Yes, handle them one word at a time
- addu a3, a1 # a3 again end address
- move a2, t0
-L(lop1w):
- lw t0, 0(a1)
- addiu a0, 4
- addiu a1, 4
- bne a1, a3, L(lop1w)
- sw t0, -4(a0)
-
-L(last8):
- blez a2, L(lst8e) # Handle last 8 bytes, one at a time
- addu a3, a2, a1
-L(lst8l):
- lb t0, 0(a1)
- addiu a0, 1
- addiu a1, 1
- bne a1, a3, L(lst8l)
- sb t0, -1(a0)
-L(lst8e):
- jr ra # Bye, bye
+/* copying in words (4-byte or 8-byte chunks) */
+L(wordCopy_loop):
+ C_LD REG3,UNIT(0)(a1)
+ PTR_ADDIU a0,a0,UNIT(1)
+ PTR_ADDIU a1,a1,UNIT(1)
+ bne a0,a3,L(wordCopy_loop)
+ C_ST REG3,UNIT(-1)(a0)
+
+/* If we have been copying double words, see if we can copy a single word
+ before doing byte copies. We can have, at most, one word to copy. */
+
+L(lastw):
+#ifdef USE_DOUBLE
+ andi t8,a2,3 /* a2 is the remainder past 4 byte chunks. */
+ beq t8,a2,L(lastb)
+ lw REG3,0(a1)
+ sw REG3,0(a0)
+ PTR_ADDIU a0,a0,4
+ PTR_ADDIU a1,a1,4
+ move a2,t8
+#endif
+
+/* Copy the last 8 (or 16) bytes */
+L(lastb):
+ blez a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(lastbloop):
+ lb v1,0(a1)
+ PTR_ADDIU a0,a0,1
+ PTR_ADDIU a1,a1,1
+ bne a0,a3,L(lastbloop)
+ sb v1,-1(a0)
+L(leave):
+ j ra
nop
-L(shift):
- subu a3, zero, a0 # Src and Dest unaligned
- andi a3, 0x3 # (unoptimized case...)
- beq a3, zero, L(shft1)
- subu a2, a3 # a2 = bytes left
- LWHI t0, 0(a1) # Take care of first odd part
- LWLO t0, 3(a1)
- addu a1, a3
- SWHI t0, 0(a0)
- addu a0, a3
-L(shft1):
- andi t0, a2, 0x3
- subu a3, a2, t0
- addu a3, a1
-L(shfth):
- LWHI t1, 0(a1) # Limp through, word by word
- LWLO t1, 3(a1)
- addiu a0, 4
- addiu a1, 4
- bne a1, a3, L(shfth)
- sw t1, -4(a0)
- b L(last8) # Handle anything which may be left
- move a2, t0
+/* We jump here with a memcpy of less than 8 or 16 bytes, depending on
+ whether or not USE_DOUBLE is defined. Instead of just doing byte
+ copies, check the alignment and size and use lw/sw if possible.
+ Otherwise, do byte copies. */
- .set reorder
-END (memcpy)
+L(lasts):
+ andi t8,a2,3
+ beq t8,a2,L(lastb)
+
+ andi t9,a0,3
+ bne t9,zero,L(lastb)
+ andi t9,a1,3
+ bne t9,zero,L(lastb)
+
+ PTR_SUBU a3,a2,t8
+ PTR_ADDU a3,a0,a3
+
+L(wcopy_loop):
+ lw REG3,0(a1)
+ PTR_ADDIU a0,a0,4
+ PTR_ADDIU a1,a1,4
+ bne a0,a3,L(wcopy_loop)
+ sw REG3,-4(a0)
-#endif /* !__mips64 */
+ b L(lastb)
+ move a2,t8
-libc_hidden_def(memcpy)
+#ifndef R6_CODE
+/*
+ * UNALIGNED case, got here with a3 = "negu a0"
+ * This code is nearly identical to the aligned code above
+ * but only the destination (not the source) gets aligned
+ * so we need to do partial loads of the source followed
+ * by normal stores to the destination (once we have aligned
+ * the destination).
+ */
+
+L(unaligned):
+ andi a3,a3,(NSIZE-1) /* copy a3 bytes to align a0/a1 */
+ beqz a3,L(ua_chk16w) /* if a3=0, it is already aligned */
+ PTR_SUBU a2,a2,a3 /* a2 is the remining bytes count */
+
+ C_LDHI v1,UNIT(0)(a1)
+ C_LDLO v1,UNITM1(1)(a1)
+ PTR_ADDU a1,a1,a3
+ C_STHI v1,UNIT(0)(a0)
+ PTR_ADDU a0,a0,a3
+
+/*
+ * Now the destination (but not the source) is aligned
+ * Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ * chunks are copied and a3 to the dst pointer after all the 64/128 byte
+ * chunks have been copied. We will loop, incrementing a0 and a1 until a0
+ * equals a3.
+ */
+
+L(ua_chk16w):
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(ua_chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
+
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+# endif
+ PREFETCH_FOR_LOAD (0, a1)
+ PREFETCH_FOR_LOAD (1, a1)
+ PREFETCH_FOR_LOAD (2, a1)
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+# endif
+# if defined(RETURN_FIRST_PREFETCH) && defined(USE_PREFETCH)
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0
+ bgtz v1,L(ua_skip_set)
+ nop
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*4)
+L(ua_skip_set):
+# else
+ PTR_ADDIU v0,a0,(PREFETCH_CHUNK*1)
+# endif
+# endif
+L(ua_loop16w):
+ PREFETCH_FOR_LOAD (3, a1)
+ C_LDHI t0,UNIT(0)(a1)
+ C_LDHI t1,UNIT(1)(a1)
+ C_LDHI REG2,UNIT(2)(a1)
+# if defined(USE_PREFETCH) && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0
+ bgtz v1,L(ua_skip_pref)
+# endif
+ C_LDHI REG3,UNIT(3)(a1)
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
+L(ua_skip_pref):
+ C_LDHI REG4,UNIT(4)(a1)
+ C_LDHI REG5,UNIT(5)(a1)
+ C_LDHI REG6,UNIT(6)(a1)
+ C_LDHI REG7,UNIT(7)(a1)
+ C_LDLO t0,UNITM1(1)(a1)
+ C_LDLO t1,UNITM1(2)(a1)
+ C_LDLO REG2,UNITM1(3)(a1)
+ C_LDLO REG3,UNITM1(4)(a1)
+ C_LDLO REG4,UNITM1(5)(a1)
+ C_LDLO REG5,UNITM1(6)(a1)
+ C_LDLO REG6,UNITM1(7)(a1)
+ C_LDLO REG7,UNITM1(8)(a1)
+ PREFETCH_FOR_LOAD (4, a1)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ C_LDHI t0,UNIT(8)(a1)
+ C_LDHI t1,UNIT(9)(a1)
+ C_LDHI REG2,UNIT(10)(a1)
+ C_LDHI REG3,UNIT(11)(a1)
+ C_LDHI REG4,UNIT(12)(a1)
+ C_LDHI REG5,UNIT(13)(a1)
+ C_LDHI REG6,UNIT(14)(a1)
+ C_LDHI REG7,UNIT(15)(a1)
+ C_LDLO t0,UNITM1(9)(a1)
+ C_LDLO t1,UNITM1(10)(a1)
+ C_LDLO REG2,UNITM1(11)(a1)
+ C_LDLO REG3,UNITM1(12)(a1)
+ C_LDLO REG4,UNITM1(13)(a1)
+ C_LDLO REG5,UNITM1(14)(a1)
+ C_LDLO REG6,UNITM1(15)(a1)
+ C_LDLO REG7,UNITM1(16)(a1)
+ PREFETCH_FOR_LOAD (5, a1)
+ C_ST t0,UNIT(8)(a0)
+ C_ST t1,UNIT(9)(a0)
+ C_ST REG2,UNIT(10)(a0)
+ C_ST REG3,UNIT(11)(a0)
+ C_ST REG4,UNIT(12)(a0)
+ C_ST REG5,UNIT(13)(a0)
+ C_ST REG6,UNIT(14)(a0)
+ C_ST REG7,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(ua_loop16w)
+ PTR_ADDIU a1,a1,UNIT(16) /* adding 64/128 to src */
+ move a2,t8
+
+/* Here we have src and dest word-aligned but less than 64-bytes or
+ * 128 bytes to go. Check for a 32(64) byte chunk and copy if if there
+ * is one. Otherwise jump down to L(ua_chk1w) to handle the tail end of
+ * the copy. */
+
+L(ua_chkw):
+ PREFETCH_FOR_LOAD (0, a1)
+ andi t8,a2,NSIZEMASK /* Is there a 32-byte/64-byte chunk. */
+ /* t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(ua_chk1w) /* When a2=t8, no 32-byte chunk */
+ nop
+ C_LDHI t0,UNIT(0)(a1)
+ C_LDHI t1,UNIT(1)(a1)
+ C_LDHI REG2,UNIT(2)(a1)
+ C_LDHI REG3,UNIT(3)(a1)
+ C_LDHI REG4,UNIT(4)(a1)
+ C_LDHI REG5,UNIT(5)(a1)
+ C_LDHI REG6,UNIT(6)(a1)
+ C_LDHI REG7,UNIT(7)(a1)
+ C_LDLO t0,UNITM1(1)(a1)
+ C_LDLO t1,UNITM1(2)(a1)
+ C_LDLO REG2,UNITM1(3)(a1)
+ C_LDLO REG3,UNITM1(4)(a1)
+ C_LDLO REG4,UNITM1(5)(a1)
+ C_LDLO REG5,UNITM1(6)(a1)
+ C_LDLO REG6,UNITM1(7)(a1)
+ C_LDLO REG7,UNITM1(8)(a1)
+ PTR_ADDIU a1,a1,UNIT(8)
+ C_ST t0,UNIT(0)(a0)
+ C_ST t1,UNIT(1)(a0)
+ C_ST REG2,UNIT(2)(a0)
+ C_ST REG3,UNIT(3)(a0)
+ C_ST REG4,UNIT(4)(a0)
+ C_ST REG5,UNIT(5)(a0)
+ C_ST REG6,UNIT(6)(a0)
+ C_ST REG7,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+/*
+ * Here we have less than 32(64) bytes to copy. Set up for a loop to
+ * copy one word (or double word) at a time.
+ */
+L(ua_chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(ua_smallCopy)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
+
+/* copying in words (4-byte or 8-byte chunks) */
+L(ua_wordCopy_loop):
+ C_LDHI v1,UNIT(0)(a1)
+ C_LDLO v1,UNITM1(1)(a1)
+ PTR_ADDIU a0,a0,UNIT(1)
+ PTR_ADDIU a1,a1,UNIT(1)
+ bne a0,a3,L(ua_wordCopy_loop)
+ C_ST v1,UNIT(-1)(a0)
+
+/* Copy the last 8 (or 16) bytes */
+L(ua_smallCopy):
+ beqz a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(ua_smallCopy_loop):
+ lb v1,0(a1)
+ PTR_ADDIU a0,a0,1
+ PTR_ADDIU a1,a1,1
+ bne a0,a3,L(ua_smallCopy_loop)
+ sb v1,-1(a0)
+
+ j ra
+ nop
+
+#else /* R6_CODE */
+
+# ifdef __MIPSEB
+# define SWAP_REGS(X,Y) X, Y
+# define ALIGN_OFFSET(N) (N)
+# else
+# define SWAP_REGS(X,Y) Y, X
+# define ALIGN_OFFSET(N) (NSIZE-N)
+# endif
+# define R6_UNALIGNED_WORD_COPY(BYTEOFFSET) \
+ andi REG7, a2, (NSIZE-1);/* REG7 is # of bytes to by bytes. */ \
+ beq REG7, a2, L(lastb); /* Check for bytes to copy by word */ \
+ PTR_SUBU a3, a2, REG7; /* a3 is number of bytes to be copied in */ \
+ /* (d)word chunks. */ \
+ move a2, REG7; /* a2 is # of bytes to copy byte by byte */ \
+ /* after word loop is finished. */ \
+ PTR_ADDU REG6, a0, a3; /* REG6 is the dst address after loop. */ \
+ PTR_SUBU REG2, a1, t8; /* REG2 is the aligned src address. */ \
+ PTR_ADDU a1, a1, a3; /* a1 is addr of source after word loop. */ \
+ C_LD t0, UNIT(0)(REG2); /* Load first part of source. */ \
+L(r6_ua_wordcopy##BYTEOFFSET): \
+ C_LD t1, UNIT(1)(REG2); /* Load second part of source. */ \
+ C_ALIGN REG3, SWAP_REGS(t1,t0), ALIGN_OFFSET(BYTEOFFSET); \
+ PTR_ADDIU a0, a0, UNIT(1); /* Increment destination pointer. */ \
+ PTR_ADDIU REG2, REG2, UNIT(1); /* Increment aligned source pointer.*/ \
+ move t0, t1; /* Move second part of source to first. */ \
+ bne a0, REG6,L(r6_ua_wordcopy##BYTEOFFSET); \
+ C_ST REG3, UNIT(-1)(a0); \
+ j L(lastb); \
+ nop
+
+ /* We are generating R6 code, the destination is 4 byte aligned and
+ the source is not 4 byte aligned. t8 is 1, 2, or 3 depending on the
+ alignment of the source. */
+
+L(r6_unaligned1):
+ R6_UNALIGNED_WORD_COPY(1)
+L(r6_unaligned2):
+ R6_UNALIGNED_WORD_COPY(2)
+L(r6_unaligned3):
+ R6_UNALIGNED_WORD_COPY(3)
+# ifdef USE_DOUBLE
+L(r6_unaligned4):
+ R6_UNALIGNED_WORD_COPY(4)
+L(r6_unaligned5):
+ R6_UNALIGNED_WORD_COPY(5)
+L(r6_unaligned6):
+ R6_UNALIGNED_WORD_COPY(6)
+L(r6_unaligned7):
+ R6_UNALIGNED_WORD_COPY(7)
+# endif
+#endif /* R6_CODE */
+
+ .set at
+ .set reorder
+END(MEMCPY_NAME)
+#ifndef ANDROID_CHANGES
+# ifdef _LIBC
+# ifdef __UCLIBC__
+libc_hidden_def(MEMCPY_NAME)
+# else
+libc_hidden_builtin_def (MEMCPY_NAME)
+# endif
+# endif
+#endif
diff --git a/libc/string/mips/memset.S b/libc/string/mips/memset.S
index 26b2598..ef8ab0b 100644
--- a/libc/string/mips/memset.S
+++ b/libc/string/mips/memset.S
@@ -1,6 +1,5 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Hartvig Ekner <hartvige(a)mips.com>, 2002.
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,145 +12,420 @@
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
+ License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <features.h>
-#include <sysdep.h>
-#include <endian.h>
+#ifdef ANDROID_CHANGES
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif _LIBC
+# include <sysdep.h>
+# include <regdef.h>
+# include <sys/asm.h>
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#elif defined _COMPILING_NEWLIB
+# include "machine/asm.h"
+# include "machine/regdef.h"
+# define PREFETCH_STORE_HINT PREFETCH_HINT_PREPAREFORSTORE
+#else
+# include <regdef.h>
+# include <sys/asm.h>
+#endif
+
+/* Check to see if the MIPS architecture we are compiling for supports
+ prefetching. */
+
+#if (__mips == 4) || (__mips == 5) || (__mips == 32) || (__mips == 64)
+# ifndef DISABLE_PREFETCH
+# define USE_PREFETCH
+# endif
+#endif
+
+#if defined(_MIPS_SIM) && ((_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32))
+# ifndef DISABLE_DOUBLE
+# define USE_DOUBLE
+# endif
+#endif
+
+#ifndef USE_DOUBLE
+# ifndef DISABLE_DOUBLE_ALIGN
+# define DOUBLE_ALIGN
+# endif
+#endif
+
+
+/* Some asm.h files do not have the L macro definition. */
+#ifndef L
+# if _MIPS_SIM == _ABIO32
+# define L(label) $L ## label
+# else
+# define L(label) .L ## label
+# endif
+#endif
+
+/* Some asm.h files do not have the PTR_ADDIU macro definition. */
+#ifndef PTR_ADDIU
+# ifdef USE_DOUBLE
+# define PTR_ADDIU daddiu
+# else
+# define PTR_ADDIU addiu
+# endif
+#endif
-/* void *memset(void *s, int c, size_t n). */
+/* New R6 instructions that may not be in asm.h. */
+#ifndef PTR_LSA
+# if _MIPS_SIM == _ABI64
+# define PTR_LSA dlsa
+# else
+# define PTR_LSA lsa
+# endif
+#endif
+
+/* Using PREFETCH_HINT_PREPAREFORSTORE instead of PREFETCH_STORE
+ or PREFETCH_STORE_STREAMED offers a large performance advantage
+ but PREPAREFORSTORE has some special restrictions to consider.
+
+ Prefetch with the 'prepare for store' hint does not copy a memory
+ location into the cache, it just allocates a cache line and zeros
+ it out. This means that if you do not write to the entire cache
+ line before writing it out to memory some data will get zero'ed out
+ when the cache line is written back to memory and data will be lost.
+
+ There are ifdef'ed sections of this memcpy to make sure that it does not
+ do prefetches on cache lines that are not going to be completely written.
+ This code is only needed and only used when PREFETCH_STORE_HINT is set to
+ PREFETCH_HINT_PREPAREFORSTORE. This code assumes that cache lines are
+ less than MAX_PREFETCH_SIZE bytes and if the cache line is larger it will
+ not work correctly. */
+
+#ifdef USE_PREFETCH
+# define PREFETCH_HINT_STORE 1
+# define PREFETCH_HINT_STORE_STREAMED 5
+# define PREFETCH_HINT_STORE_RETAINED 7
+# define PREFETCH_HINT_PREPAREFORSTORE 30
+
+/* If we have not picked out what hints to use at this point use the
+ standard load and store prefetch hints. */
+# ifndef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE
+# endif
+
+/* We double everything when USE_DOUBLE is true so we do 2 prefetches to
+ get 64 bytes in that case. The assumption is that each individual
+ prefetch brings in 32 bytes. */
+# ifdef USE_DOUBLE
+# define PREFETCH_CHUNK 64
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*64(reg); \
+ pref PREFETCH_STORE_HINT, ((chunk)*64)+32(reg)
+# else
+# define PREFETCH_CHUNK 32
+# define PREFETCH_FOR_STORE(chunk, reg) \
+ pref PREFETCH_STORE_HINT, (chunk)*32(reg)
+# endif
-#ifdef __mips64
+/* MAX_PREFETCH_SIZE is the maximum size of a prefetch, it must not be less
+ than PREFETCH_CHUNK, the assumed size of each prefetch. If the real size
+ of a prefetch is greater than MAX_PREFETCH_SIZE and the PREPAREFORSTORE
+ hint is used, the code will not work correctly. If PREPAREFORSTORE is not
+ used than MAX_PREFETCH_SIZE does not matter. */
+# define MAX_PREFETCH_SIZE 128
+/* PREFETCH_LIMIT is set based on the fact that we never use an offset greater
+ than 5 on a STORE prefetch and that a single prefetch can never be larger
+ than MAX_PREFETCH_SIZE. We add the extra 32 when USE_DOUBLE is set because
+ we actually do two prefetches in that case, one 32 bytes after the other. */
+# ifdef USE_DOUBLE
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + 32 + MAX_PREFETCH_SIZE
+# else
+# define PREFETCH_LIMIT (5 * PREFETCH_CHUNK) + MAX_PREFETCH_SIZE
+# endif
-#include <sys/asm.h>
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE) \
+ && ((PREFETCH_CHUNK * 4) < MAX_PREFETCH_SIZE)
+/* We cannot handle this because the initial prefetches may fetch bytes that
+ are before the buffer being copied. We start copies with an offset
+ of 4 so avoid this situation when using PREPAREFORSTORE. */
+# error "PREFETCH_CHUNK is too large and/or MAX_PREFETCH_SIZE is too small."
+# endif
+#else /* USE_PREFETCH not defined */
+# define PREFETCH_FOR_STORE(offset, reg)
+#endif
+
+#if __mips_isa_rev > 5
+# if (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+# undef PREFETCH_STORE_HINT
+# define PREFETCH_STORE_HINT PREFETCH_HINT_STORE_STREAMED
+# endif
+# define R6_CODE
+#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define SDHI sdl /* high part is left in big-endian */
+/* Allow the routine to be named something else if desired. */
+#ifndef MEMSET_NAME
+# define MEMSET_NAME memset
+#endif
+
+/* We load/store 64 bits at a time when USE_DOUBLE is true.
+ The C_ prefix stands for CHUNK and is used to avoid macro name
+ conflicts with system header files. */
+
+#ifdef USE_DOUBLE
+# define C_ST sd
+# ifdef __MIPSEB
+# define C_STHI sdl /* high part is left in big-endian */
+# else
+# define C_STHI sdr /* high part is right in little-endian */
+# endif
#else
-# define SDHI sdr /* high part is right in little-endian */
+# define C_ST sw
+# ifdef __MIPSEB
+# define C_STHI swl /* high part is left in big-endian */
+# else
+# define C_STHI swr /* high part is right in little-endian */
+# endif
#endif
-ENTRY (memset)
- .set noreorder
+/* Bookkeeping values for 32 vs. 64 bit mode. */
+#ifdef USE_DOUBLE
+# define NSIZE 8
+# define NSIZEMASK 0x3f
+# define NSIZEDMASK 0x7f
+#else
+# define NSIZE 4
+# define NSIZEMASK 0x1f
+# define NSIZEDMASK 0x3f
+#endif
+#define UNIT(unit) ((unit)*NSIZE)
+#define UNITM1(unit) (((unit)*NSIZE)-1)
- slti ta1, a2, 16 # Less than 16?
- bne ta1, zero, L(last16)
- move v0, a0 # Setup exit value before too late
-
- beq a1, zero, L(ueven) # If zero pattern, no need to extend
- andi a1, 0xff # Avoid problems with bogus arguments
- dsll ta0, a1, 8
- or a1, ta0
- dsll ta0, a1, 16
- or a1, ta0 # a1 is now pattern in full word
- dsll ta0, a1, 32
- or a1, ta0 # a1 is now pattern in double word
-
-L(ueven):
- PTR_SUBU ta0, zero, a0 # Unaligned address?
- andi ta0, 0x7
- beq ta0, zero, L(chkw)
- PTR_SUBU a2, ta0
- SDHI a1, 0(a0) # Yes, handle first unaligned part
- PTR_ADDU a0, ta0 # Now both a0 and a2 are updated
+#ifdef ANDROID_CHANGES
+LEAF(MEMSET_NAME,0)
+#else
+LEAF(MEMSET_NAME)
+#endif
-L(chkw):
- andi ta0, a2, 0xf # Enough left for one loop iteration?
- beq ta0, a2, L(chkl)
- PTR_SUBU a3, a2, ta0
- PTR_ADDU a3, a0 # a3 is last loop address +1
- move a2, ta0 # a2 is now # of bytes left after loop
-L(loopw):
- PTR_ADDIU a0, 16 # Handle 2 dwords pr. iteration
- sd a1, -16(a0)
- bne a0, a3, L(loopw)
- sd a1, -8(a0)
-
-L(chkl):
- andi ta0, a2, 0x8 # Check if there is at least a double
- beq ta0, zero, L(last16) # word remaining after the loop
- PTR_SUBU a2, ta0
- sd a1, 0(a0) # Yes...
- PTR_ADDIU a0, 8
-
-L(last16):
- blez a2, L(exit) # Handle last 16 bytes (if cnt>0)
- PTR_ADDU a3, a2, a0 # a3 is last address +1
-L(lst16l):
- PTR_ADDIU a0, 1
- bne a0, a3, L(lst16l)
- sb a1, -1(a0)
-L(exit):
- j ra # Bye, bye
+ .set nomips16
+ .set noreorder
+/* If the size is less than 2*NSIZE (8 or 16), go to L(lastb). Regardless of
+ size, copy dst pointer to v0 for the return value. */
+ slti t2,a2,(2 * NSIZE)
+ bne t2,zero,L(lastb)
+ move v0,a0
+
+/* If memset value is not zero, we copy it to all the bytes in a 32 or 64
+ bit word. */
+ beq a1,zero,L(set0) /* If memset value is zero no smear */
+ PTR_SUBU a3,zero,a0
nop
- .set reorder
-END (memset)
+ /* smear byte into 32 or 64 bit word */
+#if ((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)
+# ifdef USE_DOUBLE
+ dins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
+ dins a1, a1, 16, 16 /* Replicate fill byte into word. */
+ dins a1, a1, 32, 32 /* Replicate fill byte into dbl word. */
+# else
+ ins a1, a1, 8, 8 /* Replicate fill byte into half-word. */
+ ins a1, a1, 16, 16 /* Replicate fill byte into word. */
+# endif
+#else
+# ifdef USE_DOUBLE
+ and a1,0xff
+ dsll t2,a1,8
+ or a1,t2
+ dsll t2,a1,16
+ or a1,t2
+ dsll t2,a1,32
+ or a1,t2
+# else
+ and a1,0xff
+ sll t2,a1,8
+ or a1,t2
+ sll t2,a1,16
+ or a1,t2
+# endif
+#endif
+
+/* If the destination address is not aligned do a partial store to get it
+ aligned. If it is already aligned just jump to L(aligned). */
+L(set0):
+#ifndef R6_CODE
+ andi t2,a3,(NSIZE-1) /* word-unaligned address? */
+ beq t2,zero,L(aligned) /* t2 is the unalignment count */
+ PTR_SUBU a2,a2,t2
+ C_STHI a1,0(a0)
+ PTR_ADDU a0,a0,t2
+#else /* R6_CODE */
+ andi t2,a0,(NSIZE-1)
+ lapc t9,L(atable)
+ PTR_LSA t9,t2,t9,2
+ jrc t9
+L(atable):
+ bc L(aligned)
+# ifdef USE_DOUBLE
+ bc L(lb7)
+ bc L(lb6)
+ bc L(lb5)
+ bc L(lb4)
+# endif
+ bc L(lb3)
+ bc L(lb2)
+ bc L(lb1)
+L(lb7):
+ sb a1,6(a0)
+L(lb6):
+ sb a1,5(a0)
+L(lb5):
+ sb a1,4(a0)
+L(lb4):
+ sb a1,3(a0)
+L(lb3):
+ sb a1,2(a0)
+L(lb2):
+ sb a1,1(a0)
+L(lb1):
+ sb a1,0(a0)
+
+ li t9,NSIZE
+ subu t2,t9,t2
+ PTR_SUBU a2,a2,t2
+ PTR_ADDU a0,a0,t2
+#endif /* R6_CODE */
+
+L(aligned):
+/* If USE_DOUBLE is not set we may still want to align the data on a 16
+ byte boundry instead of an 8 byte boundry to maximize the opportunity
+ of proAptiv chips to do memory bonding (combining two sequential 4
+ byte stores into one 8 byte store). We know there are at least 4 bytes
+ left to store or we would have jumped to L(lastb) earlier in the code. */
+#ifdef DOUBLE_ALIGN
+ andi t2,a3,4
+ beq t2,zero,L(double_aligned)
+ PTR_SUBU a2,a2,t2
+ sw a1,0(a0)
+ PTR_ADDU a0,a0,t2
+L(double_aligned):
+#endif
-#else /* !__mips64 */
+/* Now the destination is aligned to (word or double word) aligned address
+ Set a2 to count how many bytes we have to copy after all the 64/128 byte
+ chunks are copied and a3 to the dest pointer after all the 64/128 byte
+ chunks have been copied. We will loop, incrementing a0 until it equals
+ a3. */
+ andi t8,a2,NSIZEDMASK /* any whole 64-byte/128-byte chunks? */
+ beq a2,t8,L(chkw) /* if a2==t8, no 64-byte/128-byte chunks */
+ PTR_SUBU a3,a2,t8 /* subtract from a2 the reminder */
+ PTR_ADDU a3,a0,a3 /* Now a3 is the final dst after loop */
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define SWHI swl /* high part is left in big-endian */
+/* When in the loop we may prefetch with the 'prepare to store' hint,
+ in this case the a0+x should not be past the "t0-32" address. This
+ means: for x=128 the last "safe" a0 address is "t0-160". Alternatively,
+ for x=64 the last "safe" a0 address is "t0-96" In the current version we
+ will use "prefetch hint,128(a0)", so "t0-160" is the limit. */
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ PTR_ADDU t0,a0,a2 /* t0 is the "past the end" address */
+ PTR_SUBU t9,t0,PREFETCH_LIMIT /* t9 is the "last safe pref" address */
+#endif
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT != PREFETCH_HINT_PREPAREFORSTORE)
+ PREFETCH_FOR_STORE (1, a0)
+ PREFETCH_FOR_STORE (2, a0)
+ PREFETCH_FOR_STORE (3, a0)
+#endif
+
+L(loop16w):
+#if defined(USE_PREFETCH) \
+ && (PREFETCH_STORE_HINT == PREFETCH_HINT_PREPAREFORSTORE)
+ sltu v1,t9,a0 /* If a0 > t9 don't use next prefetch */
+ bgtz v1,L(skip_pref)
+ nop
+#endif
+#ifdef R6_CODE
+ PREFETCH_FOR_STORE (2, a0)
#else
-# define SWHI swr /* high part is right in little-endian */
+ PREFETCH_FOR_STORE (4, a0)
+ PREFETCH_FOR_STORE (5, a0)
#endif
+L(skip_pref):
+ C_ST a1,UNIT(0)(a0)
+ C_ST a1,UNIT(1)(a0)
+ C_ST a1,UNIT(2)(a0)
+ C_ST a1,UNIT(3)(a0)
+ C_ST a1,UNIT(4)(a0)
+ C_ST a1,UNIT(5)(a0)
+ C_ST a1,UNIT(6)(a0)
+ C_ST a1,UNIT(7)(a0)
+ C_ST a1,UNIT(8)(a0)
+ C_ST a1,UNIT(9)(a0)
+ C_ST a1,UNIT(10)(a0)
+ C_ST a1,UNIT(11)(a0)
+ C_ST a1,UNIT(12)(a0)
+ C_ST a1,UNIT(13)(a0)
+ C_ST a1,UNIT(14)(a0)
+ C_ST a1,UNIT(15)(a0)
+ PTR_ADDIU a0,a0,UNIT(16) /* adding 64/128 to dest */
+ bne a0,a3,L(loop16w)
+ nop
+ move a2,t8
-ENTRY (memset)
- .set noreorder
+/* Here we have dest word-aligned but less than 64-bytes or 128 bytes to go.
+ Check for a 32(64) byte chunk and copy if if there is one. Otherwise
+ jump down to L(chk1w) to handle the tail end of the copy. */
+L(chkw):
+ andi t8,a2,NSIZEMASK /* is there a 32-byte/64-byte chunk. */
+ /* the t8 is the reminder count past 32-bytes */
+ beq a2,t8,L(chk1w)/* when a2==t8, no 32-byte chunk */
+ nop
+ C_ST a1,UNIT(0)(a0)
+ C_ST a1,UNIT(1)(a0)
+ C_ST a1,UNIT(2)(a0)
+ C_ST a1,UNIT(3)(a0)
+ C_ST a1,UNIT(4)(a0)
+ C_ST a1,UNIT(5)(a0)
+ C_ST a1,UNIT(6)(a0)
+ C_ST a1,UNIT(7)(a0)
+ PTR_ADDIU a0,a0,UNIT(8)
+
+/* Here we have less than 32(64) bytes to set. Set up for a loop to
+ copy one word (or double word) at a time. Set a2 to count how many
+ bytes we have to copy after all the word (or double word) chunks are
+ copied and a3 to the dest pointer after all the (d)word chunks have
+ been copied. We will loop, incrementing a0 until a0 equals a3. */
+L(chk1w):
+ andi a2,t8,(NSIZE-1) /* a2 is the reminder past one (d)word chunks */
+ beq a2,t8,L(lastb)
+ PTR_SUBU a3,t8,a2 /* a3 is count of bytes in one (d)word chunks */
+ PTR_ADDU a3,a0,a3 /* a3 is the dst address after loop */
- slti t1, a2, 8 # Less than 8?
- bne t1, zero, L(last8)
- move v0, a0 # Setup exit value before too late
-
- beq a1, zero, L(ueven) # If zero pattern, no need to extend
- andi a1, 0xff # Avoid problems with bogus arguments
- sll t0, a1, 8
- or a1, t0
- sll t0, a1, 16
- or a1, t0 # a1 is now pattern in full word
-
-L(ueven):
- subu t0, zero, a0 # Unaligned address?
- andi t0, 0x3
- beq t0, zero, L(chkw)
- subu a2, t0
- SWHI a1, 0(a0) # Yes, handle first unaligned part
- addu a0, t0 # Now both a0 and a2 are updated
-
-L(chkw):
- andi t0, a2, 0x7 # Enough left for one loop iteration?
- beq t0, a2, L(chkl)
- subu a3, a2, t0
- addu a3, a0 # a3 is last loop address +1
- move a2, t0 # a2 is now # of bytes left after loop
-L(loopw):
- addiu a0, 8 # Handle 2 words pr. iteration
- sw a1, -8(a0)
- bne a0, a3, L(loopw)
- sw a1, -4(a0)
-
-L(chkl):
- andi t0, a2, 0x4 # Check if there is at least a full
- beq t0, zero, L(last8) # word remaining after the loop
- subu a2, t0
- sw a1, 0(a0) # Yes...
- addiu a0, 4
-
-L(last8):
- blez a2, L(exit) # Handle last 8 bytes (if cnt>0)
- addu a3, a2, a0 # a3 is last address +1
-L(lst8l):
- addiu a0, 1
- bne a0, a3, L(lst8l)
- sb a1, -1(a0)
-L(exit):
- j ra # Bye, bye
+/* copying in words (4-byte or 8 byte chunks) */
+L(wordCopy_loop):
+ PTR_ADDIU a0,a0,UNIT(1)
+ bne a0,a3,L(wordCopy_loop)
+ C_ST a1,UNIT(-1)(a0)
+
+/* Copy the last 8 (or 16) bytes */
+L(lastb):
+ blez a2,L(leave)
+ PTR_ADDU a3,a0,a2 /* a3 is the last dst address */
+L(lastbloop):
+ PTR_ADDIU a0,a0,1
+ bne a0,a3,L(lastbloop)
+ sb a1,-1(a0)
+L(leave):
+ j ra
nop
+ .set at
.set reorder
-END (memset)
-
-#endif /* !__mips64 */
+END(MEMSET_NAME)
+#ifndef ANDROID_CHANGES
+# ifdef _LIBC
+# ifdef __UCLIBC__
+libc_hidden_def(MEMSET_NAME)
+# else
+libc_hidden_builtin_def (MEMSET_NAME)
+# endif
+# endif
+#endif
-libc_hidden_def(memset)
diff --git a/libc/sysdeps/linux/common/bits/in.h b/libc/sysdeps/linux/common/bits/in.h
index f4a340b..c67fbf8 100644
--- a/libc/sysdeps/linux/common/bits/in.h
+++ b/libc/sysdeps/linux/common/bits/in.h
@@ -120,7 +120,7 @@ struct in_pktinfo
};
#endif
-#ifdef __UCLIBC_HAS_IPV6__
+#if defined __UCLIBC_HAS_IPV6__ || !defined __UCLIBC_STRICT_HEADERS__
/* Options for use with `getsockopt' and `setsockopt' at the IPv6 level.
The first word in the comment at the right is the data type used;
"bool" means a boolean value stored in an `int'. */
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index bf19ce3..3f1dd28 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -30,6 +30,57 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask)
{
+#ifdef __NR_pselect6
+#define NSEC_PER_SEC 1000000000L
+ struct timespec _ts, *ts = 0;
+ if (timeout) {
+ /* The Linux kernel can in some situations update the timeout value.
+ * We do not want that so use a local variable.
+ */
+ _ts = *timeout;
+
+ /* GNU extension: allow for timespec values where the sub-sec
+ * field is equal to or more than 1 second. The kernel will
+ * reject this on us, so take care of the time shift ourself.
+ * Some applications (like readline and linphone) do this.
+ * See 'clarification on select() type calls and invalid timeouts'
+ * on the POSIX general list for more information.
+ */
+ if (_ts.tv_nsec >= NSEC_PER_SEC) {
+ _ts.tv_sec += _ts.tv_nsec / NSEC_PER_SEC;
+ _ts.tv_nsec %= NSEC_PER_SEC;
+ }
+
+ ts = &_ts;
+ }
+
+ /* The pselect6 syscall API is strange. It wants a 7th arg to be
+ * the sizeof(*sigmask). However syscalls with > 6 arguments aren't
+ * supported on linux. So arguments 6 and 7 are stuffed in a struct
+ * and a pointer to that struct is passed as the 6th argument to
+ * the syscall.
+ * Glibc stuffs arguments 6 and 7 in a ulong[2]. Linux reads
+ * them as if there were a struct { sigset_t*; size_t } in
+ * userspace. There woudl be trouble if userspace and the kernel are
+ * compiled differently enough that size_t isn't the same as ulong,
+ * but not enough to trigger the compat layer in linux. I can't
+ * think of such a case, so I'm using linux's struct.
+ * Furthermore Glibc sets the sigsetsize to _NSIG/8. However linux
+ * checks for sizeof(sigset_t), which internally is a ulong array.
+ * This means that if _NSIG isn't a multiple of BITS_PER_LONG then
+ * linux will refuse glibc's value. So I prefer sizeof(sigset_t) for
+ * the value of sigsetsize.
+ */
+ struct {
+ const sigset_t *sigmask;
+ size_t sigsetsize;
+ } args67 = {
+ sigmask,
+ sizeof(sigset_t),
+ };
+
+ return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, ts, &args67);
+#else
struct timeval tval;
int retval;
sigset_t savemask;
@@ -57,6 +108,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
sigprocmask (SIG_SETMASK, &savemask, NULL);
return retval;
+#endif
}
CANCELLABLE_SYSCALL(int, pselect, (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask),
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index bcd49ed..776bec7 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -382,6 +382,10 @@ __pthread_initialize_minimal_internal (void)
Use the minimal size acceptable. */
limit.rlim_cur = PTHREAD_STACK_MIN;
+ /* Do not exceed architecture specific default */
+ if (limit.rlim_cur > ARCH_STACK_DEFAULT_SIZE)
+ limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
+
/* Make sure it meets the minimum size that allocate_stack
(allocatestack.c) will demand, which depends on the page size. */
const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
hooks/post-receive
--
uClibc-ng - small C library for embedded systems