Merge "support _POSIX_REALTIME_SIGNALS"
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index 00250a5..5ce8542 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -32,7 +32,6 @@
 benchmark_src_files = \
     benchmark_main.cpp \
     math_benchmark.cpp \
-    property_benchmark.cpp \
     pthread_benchmark.cpp \
     semaphore_benchmark.cpp \
     stdio_benchmark.cpp \
@@ -41,7 +40,8 @@
     unistd_benchmark.cpp \
 
 # Build benchmarks for the device (with bionic's .so). Run with:
-#   adb shell bionic-benchmarks
+#   adb shell bionic-benchmarks32
+#   adb shell bionic-benchmarks64
 include $(CLEAR_VARS)
 LOCAL_MODULE := bionic-benchmarks
 LOCAL_MODULE_STEM_32 := bionic-benchmarks32
@@ -49,31 +49,46 @@
 LOCAL_MULTILIB := both
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(benchmark_c_flags)
-LOCAL_SRC_FILES := $(benchmark_src_files)
+LOCAL_SRC_FILES := $(benchmark_src_files) property_benchmark.cpp
 LOCAL_CXX_STL := libc++
 include $(BUILD_EXECUTABLE)
 
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-ifeq ($(TARGET_ARCH),x86)
-LINKER = linker
-NATIVE_SUFFIX=32
-else
-LINKER = linker64
-NATIVE_SUFFIX=64
-endif
+# We don't build a static benchmark executable because it's not usually
+# useful. If you're trying to run the current benchmarks on an older
+# release, it's (so far at least) always because you want to measure the
+# performance of the old release's libc, and a static benchmark isn't
+# going to let you do that.
 
-bionic-benchmarks-run-on-host: bionic-benchmarks $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
-	if [ ! -d /system -o ! -d /system/bin ]; then \
-	  echo "Attempting to create /system/bin"; \
-	  sudo mkdir -p -m 0777 /system/bin; \
-	fi
-	mkdir -p $(TARGET_OUT_DATA)/local/tmp
-	cp $(TARGET_OUT_EXECUTABLES)/$(LINKER) /system/bin
-	cp $(TARGET_OUT_EXECUTABLES)/sh /system/bin
+# Build benchmarks for the host (against glibc!). Run with:
+include $(CLEAR_VARS)
+LOCAL_MODULE := bionic-benchmarks-glibc
+LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
+LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
+LOCAL_MULTILIB := both
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_CFLAGS += $(benchmark_c_flags)
+LOCAL_LDFLAGS += -lrt
+LOCAL_SRC_FILES := $(benchmark_src_files)
+LOCAL_CXX_STL := libc++
+include $(BUILD_HOST_EXECUTABLE)
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+include $(LOCAL_PATH)/../build/run-on-host.mk
+
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
+bionic-benchmarks-run-on-host32: bionic-benchmarks bionic-prepare-run-on-host
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_ROOT=$(TARGET_OUT) \
-	LD_LIBRARY_PATH=$(TARGET_OUT_SHARED_LIBRARIES) \
-		$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks$(NATIVE_SUFFIX) $(BIONIC_BENCHMARKS_FLAGS)
-endif # linux-x86
+		$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks32 $(BIONIC_BENCHMARKS_FLAGS)
+endif
+
+ifeq ($(TARGET_IS_64_BIT),true)
+bionic-benchmarks-run-on-host64: bionic-benchmarks bionic-prepare-run-on-host
+	ANDROID_DATA=$(TARGET_OUT_DATA) \
+	ANDROID_ROOT=$(TARGET_OUT) \
+		$(TARGET_OUT_EXECUTABLES)/bionic-benchmarks64 $(BIONIC_BENCHMARKS_FLAGS)
+endif
+
+endif
 
 endif # !BUILD_TINY_ANDROID
diff --git a/benchmarks/benchmark_main.cpp b/benchmarks/benchmark_main.cpp
index d60670b..815d56b 100644
--- a/benchmarks/benchmark_main.cpp
+++ b/benchmarks/benchmark_main.cpp
@@ -19,6 +19,7 @@
 #include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 
 #include <string>
 #include <map>
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 11db56d..92e5998 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -80,7 +80,7 @@
 
 static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
   StopBenchmarkTiming();
-  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
+  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
   StartBenchmarkTiming();
 
   for (int i = 0; i < iters; ++i) {
@@ -94,7 +94,7 @@
 
 static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
   StopBenchmarkTiming();
-  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
   StartBenchmarkTiming();
 
   for (int i = 0; i < iters; ++i) {
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index e899df7..386ea04 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -25,14 +25,19 @@
     Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(64)->Arg(512)-> \
     Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
 
-static void BM_stdio_fread(int iters, int chunk_size) {
+template <typename Fn>
+static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
   StopBenchmarkTiming();
   FILE* fp = fopen("/dev/zero", "rw");
   char* buf = new char[chunk_size];
   StartBenchmarkTiming();
 
+  if (!buffered) {
+    setvbuf(fp, 0, _IONBF, 0);
+  }
+
   for (int i = 0; i < iters; ++i) {
-    fread(buf, chunk_size, 1, fp);
+    f(buf, chunk_size, 1, fp);
   }
 
   StopBenchmarkTiming();
@@ -40,22 +45,23 @@
   delete[] buf;
   fclose(fp);
 }
+
+static void BM_stdio_fread(int iters, int chunk_size) {
+  ReadWriteTest(iters, chunk_size, fread, true);
+}
 BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
 
-
 static void BM_stdio_fwrite(int iters, int chunk_size) {
-  StopBenchmarkTiming();
-  FILE* fp = fopen("/dev/zero", "rw");
-  char* buf = new char[chunk_size];
-  StartBenchmarkTiming();
-
-  for (int i = 0; i < iters; ++i) {
-      fwrite(buf, chunk_size, 1, fp);
-  }
-
-  StopBenchmarkTiming();
-  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
-  delete[] buf;
-  fclose(fp);
+  ReadWriteTest(iters, chunk_size, fwrite, true);
 }
 BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
+
+static void BM_stdio_fread_unbuffered(int iters, int chunk_size) {
+  ReadWriteTest(iters, chunk_size, fread, false);
+}
+BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
+
+static void BM_stdio_fwrite_unbuffered(int iters, int chunk_size) {
+  ReadWriteTest(iters, chunk_size, fwrite, false);
+}
+BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp
index 22f6e8e..f093ec1 100644
--- a/benchmarks/time_benchmark.cpp
+++ b/benchmarks/time_benchmark.cpp
@@ -16,7 +16,9 @@
 
 #include "benchmark.h"
 
+#include <unistd.h>
 #include <sys/syscall.h>
+#include <sys/time.h>
 #include <time.h>
 
 static void BM_time_clock_gettime(int iters) {
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
index 7e2ac30..94be1dd 100644
--- a/benchmarks/unistd_benchmark.cpp
+++ b/benchmarks/unistd_benchmark.cpp
@@ -41,6 +41,8 @@
 }
 BENCHMARK(BM_unistd_getpid_syscall);
 
+#if defined(__BIONIC__)
+
 // Stop GCC optimizing out our pure function.
 /* Must not be static! */ pid_t (*gettid_fp)() = gettid;
 
@@ -55,6 +57,8 @@
 }
 BENCHMARK(BM_unistd_gettid);
 
+#endif
+
 static void BM_unistd_gettid_syscall(int iters) {
   StartBenchmarkTiming();
 
diff --git a/build/run-on-host.mk b/build/run-on-host.mk
new file mode 100644
index 0000000..dc7e5d5
--- /dev/null
+++ b/build/run-on-host.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Include once
+ifneq ($(bionic_run_on_host_mk_included),true)
+bionic_run_on_host_mk_included:=true
+
+ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
+LINKER = linker64
+else
+LINKER = linker
+endif
+
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
+# gtest needs ANDROID_DATA/local/tmp for death test output.
+# Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
+# bionic itself should always work relative to ANDROID_DATA or ANDROID_ROOT.
+bionic-prepare-run-on-host: $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT)/etc/hosts $(TARGET_OUT_EXECUTABLES)/sh
+	if [ ! -d /system ]; then \
+	  echo "Attempting to create /system"; \
+	  sudo mkdir -p -m 0777 /system; \
+	fi
+	mkdir -p $(TARGET_OUT_DATA)/local/tmp
+	ln -fs `realpath $(TARGET_OUT)/bin` /system/
+	ln -fs `realpath $(TARGET_OUT)/etc` /system/
+	ln -fs `realpath $(TARGET_OUT)/lib` /system/
+	if [ -d "$(TARGET_OUT)/lib64" ]; then \
+	  ln -fs `realpath $(TARGET_OUT)/lib64` /system/; \
+	fi
+endif
+endif
diff --git a/libc/Android.mk b/libc/Android.mk
index 90c2e92..6863151 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -58,6 +58,7 @@
     bionic/sigsetmask.c \
     bionic/system_properties_compat.c \
     stdio/findfp.c \
+    stdio/fread.c \
     stdio/snprintf.c\
     stdio/sprintf.c \
     stdio/stdio_ext.cpp \
@@ -98,6 +99,7 @@
     bionic/chown.cpp \
     bionic/clearenv.cpp \
     bionic/clock.cpp \
+    bionic/clock_getcpuclockid.cpp \
     bionic/clock_nanosleep.cpp \
     bionic/clone.cpp \
     bionic/__cmsg_nxthdr.cpp \
@@ -151,6 +153,7 @@
     bionic/poll.cpp \
     bionic/posix_fadvise.cpp \
     bionic/posix_fallocate.cpp \
+    bionic/posix_madvise.cpp \
     bionic/posix_timers.cpp \
     bionic/pthread_atfork.cpp \
     bionic/pthread_attr.cpp \
@@ -408,7 +411,6 @@
     upstream-openbsd/lib/libc/stdio/fputs.c \
     upstream-openbsd/lib/libc/stdio/fputwc.c \
     upstream-openbsd/lib/libc/stdio/fputws.c \
-    upstream-openbsd/lib/libc/stdio/fread.c \
     upstream-openbsd/lib/libc/stdio/freopen.c \
     upstream-openbsd/lib/libc/stdio/fscanf.c \
     upstream-openbsd/lib/libc/stdio/fseek.c \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 35558c9..a648c9f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -101,7 +101,7 @@
 void*       mremap(void*, size_t, size_t, unsigned long)  all
 int         msync(const void*, size_t, int)    all
 int         mprotect(const void*, size_t, int)  all
-int         madvise(const void*, size_t, int)  all
+int         madvise(void*, size_t, int)  all
 int         mlock(const void* addr, size_t len)    all
 int         munlock(const void* addr, size_t len)   all
 int         mlockall(int flags)   all
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index cca4ed0..a4da9a6 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -60,9 +60,7 @@
     arch-arm/bionic/libgcc_compat.c \
     arch-arm/bionic/memcmp.S \
     arch-arm/bionic/__restore.S \
-    arch-arm/bionic/_setjmp.S \
     arch-arm/bionic/setjmp.S \
-    arch-arm/bionic/sigsetjmp.S \
     arch-arm/bionic/syscall.S \
 
 libc_arch_static_src_files_arm := arch-arm/bionic/exidx_static.c
diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S
deleted file mode 100644
index 7d637fd..0000000
--- a/libc/arch-arm/bionic/_setjmp.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/*	$OpenBSD: _setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $	*/
-/*	$NetBSD: _setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $	*/
-
-/*
- * Copyright (c) 1997 Mark Brinicombe
- * Copyright (c) 2010 Android Open Source Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Mark Brinicombe
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-#include <machine/cpu-features.h>
-
-/*
- * C library -- _setjmp, _longjmp
- *
- *	_longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	_setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- *
- * Note: r0 is the return value
- *       r1-r3 are scratch registers in functions
- */
-
-ENTRY(_setjmp)
-	ldr	r1, .L_setjmp_magic
-	str	r1, [r0, #(_JB_MAGIC * 4)]
-
-	/* Store core registers */
-	add     r1, r0, #(_JB_CORE_BASE * 4)
-	stmia   r1, {r4-r14}
-
-#ifdef __ARM_HAVE_VFP
-	/* Store floating-point registers */
-	add     r1, r0, #(_JB_FLOAT_BASE * 4)
-	vstmia  r1, {d8-d15}
-	/* Store floating-point state */
-	fmrx    r1, fpscr
-	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
-#endif  /* __ARM_HAVE_VFP */
-
-        mov	r0, #0x00000000
-        bx      lr
-END(_setjmp)
-
-.L_setjmp_magic:
-	.word	_JB_MAGIC__SETJMP
-
-ENTRY(_longjmp)
-	ldr	r2, .L_setjmp_magic
-	ldr	r3, [r0, #(_JB_MAGIC * 4)]
-	teq	r2, r3
-	bne	botch
-
-#ifdef __ARM_HAVE_VFP
-	/* Restore floating-point registers */
-	add     r2, r0, #(_JB_FLOAT_BASE * 4)
-	vldmia  r2, {d8-d15}
-	/* Restore floating-point state */
-	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
-	fmxr    fpscr, r2
-#endif /* __ARM_HAVE_VFP */
-
-	/* Restore core registers */
-	add     r2, r0, #(_JB_CORE_BASE * 4)
-	ldmia   r2, {r4-r14}
-
-	/* Validate sp and r14 */
-	teq	sp, #0
-	teqne	r14, #0
-	beq	botch
-
-	/* Set return value */
-	mov	r0, r1
-	teq	r0, #0x00000000
-	moveq	r0, #0x00000001
-	bx      lr
-
-	/* validation failed, die die die. */
-botch:
-	bl	longjmperror
-	bl	abort
-	b	. - 8		/* Cannot get here */
-END(_longjmp)
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 0c9082c..8d7786c 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -1,6 +1,3 @@
-/*	$OpenBSD: setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $	*/
-/*	$NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $	*/
-
 /*
  * Copyright (c) 1997 Mark Brinicombe
  * Copyright (c) 2010 Android Open Source Project.
@@ -35,119 +32,144 @@
  */
 
 #include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-#include <machine/cpu-features.h>
 
-/*
- * C library -- setjmp, longjmp
- *
- *	longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is restored.
- */
+// According to the ARM AAPCS document, we only need to save
+// the following registers:
+//
+//  Core   r4-r14
+//
+//  VFP    d8-d15  (see section 5.1.2.1)
+//
+//      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
+//      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
+//      (and can be used for passing arguments or returning results in standard
+//      procedure-call variants). Registers d16-d31 (q8-q15), if present, do
+//      not need to be preserved.
+//
+//  FPSCR  saved because glibc does.
+
+// The internal structure of a jmp_buf is totally private.
+// Current layout (may change in the future):
+//
+// word   name         description
+// 0      magic        magic number
+// 1      sigmask      signal mask (not used with _setjmp / _longjmp)
+// 2      float_base   base of float registers (d8 to d15)
+// 18     float_state  floating-point status and control register
+// 19     core_base    base of core registers (r4 to r14)
+// 30     reserved     reserved entries (room to grow)
+// 64
+//
+// NOTE: float_base must be at an even word index, since the
+//       FP registers will be loaded/stored with instructions
+//       that expect 8-byte alignment.
+
+#define _JB_SIGFLAG     0
+#define _JB_SIGMASK     (_JB_SIGFLAG+1)
+#define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
+#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
+#define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
 
 ENTRY(setjmp)
-	/* Block all signals and retrieve the old signal mask */
-	stmfd	sp!, {r0, r14}
-	.cfi_def_cfa_offset 8
-	.cfi_rel_offset r0, 0
-	.cfi_rel_offset r14, 4
-	mov	r0, #0x00000000
-
-	bl	sigblock
-	mov	r1, r0
-
-	ldmfd	sp!, {r0, r14}
-	.cfi_def_cfa_offset 0
-
-	/* Store signal mask */
-	str	r1, [r0, #(_JB_SIGMASK * 4)]
-
-	ldr	r1, .Lsetjmp_magic
-	str	r1, [r0, #(_JB_MAGIC * 4)]
-
-	/* Store core registers */
-	add     r1, r0, #(_JB_CORE_BASE * 4)
-	stmia   r1, {r4-r14}
-
-#ifdef __ARM_HAVE_VFP
-	/* Store floating-point registers */
-	add     r1, r0, #(_JB_FLOAT_BASE * 4)
-	vstmia  r1, {d8-d15}
-	/* Store floating-point state */
-	fmrx    r1, fpscr
-	str     r1, [r0, #(_JB_FLOAT_STATE * 4)]
-#endif  /* __ARM_HAVE_VFP */
-
-	mov	r0, #0x00000000
-	bx      lr
+  mov r1, #1
+  b sigsetjmp
 END(setjmp)
 
-.Lsetjmp_magic:
-	.word	_JB_MAGIC_SETJMP
+ENTRY(_setjmp)
+  mov r1, #0
+  b sigsetjmp
+END(_setjmp)
 
+// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
+ENTRY(sigsetjmp)
+  // Record whether or not we're saving the signal mask.
+  str r1, [r0, #(_JB_SIGFLAG * 4)]
 
-ENTRY(longjmp)
-	ldr	r2, .Lsetjmp_magic
-	ldr	r3, [r0, #(_JB_MAGIC * 4)]
-	teq	r2, r3
-	bne	botch
+  // Do we need to save the signal mask?
+  teq r1, #0
+  beq 1f
 
-	/* Fetch signal mask */
-	ldr	r2, [r0, #(_JB_SIGMASK * 4)]
+  // Get current signal mask.
+  stmfd sp!, {r0, r14}
+  .cfi_def_cfa_offset 8
+  .cfi_rel_offset r0, 0
+  .cfi_rel_offset r14, 4
+  mov r0, #0
+  bl sigblock
+  mov r1, r0
+  ldmfd sp!, {r0, r14}
+  .cfi_def_cfa_offset 0
 
-	/* Set signal mask */
-	stmfd	sp!, {r0, r1, r14}
-	.cfi_def_cfa_offset 12
-	.cfi_rel_offset r0, 0
-	.cfi_rel_offset r1, 4
-	.cfi_rel_offset r14, 8
-	sub	sp, sp, #4	/* align the stack */
-	.cfi_adjust_cfa_offset 4
+  // Save the signal mask.
+  str r1, [r0, #(_JB_SIGMASK * 4)]
 
-	mov	r0, r2
-	bl	sigsetmask
+1:
+  // Save core registers.
+  add r1, r0, #(_JB_CORE_BASE * 4)
+  stmia r1, {r4-r14}
 
-	add	sp, sp, #4	/* unalign the stack */
-	.cfi_adjust_cfa_offset -4
-	ldmfd	sp!, {r0, r1, r14}
-	.cfi_def_cfa_offset 0
+  // Save floating-point registers.
+  add r1, r0, #(_JB_FLOAT_BASE * 4)
+  vstmia  r1, {d8-d15}
 
-#ifdef __ARM_HAVE_VFP
-	/* Restore floating-point registers */
-	add     r2, r0, #(_JB_FLOAT_BASE * 4)
-	vldmia  r2, {d8-d15}
-	/* Restore floating-point state */
-	ldr     r2, [r0, #(_JB_FLOAT_STATE * 4)]
-	fmxr    fpscr, r2
-#endif /* __ARM_HAVE_VFP */
+  // Save floating-point state.
+  fmrx r1, fpscr
+  str r1, [r0, #(_JB_FLOAT_STATE * 4)]
 
-	/* Restore core registers */
-	add     r2, r0, #(_JB_CORE_BASE * 4)
-	ldmia   r2, {r4-r14}
+  mov r0, #0
+  bx lr
+END(sigsetjmp)
 
-	/* Validate sp and r14 */
-	teq	sp, #0
-	teqne	r14, #0
-	beq	botch
+// void siglongjmp(sigjmp_buf env, int value);
+ENTRY(siglongjmp)
+  // Do we need to restore the signal mask?
+  ldr r2, [r0, #(_JB_SIGFLAG * 4)]
+  teq r2, #0
+  beq 1f
 
-	/* Set return value */
+  // Restore the signal mask.
+  stmfd sp!, {r0, r1, r14}
+  .cfi_def_cfa_offset 12
+  .cfi_rel_offset r0, 0
+  .cfi_rel_offset r1, 4
+  .cfi_rel_offset r14, 8
+  sub sp, sp, #4 // Align the stack.
+  .cfi_adjust_cfa_offset 4
 
-	mov	r0, r1
-	teq	r0, #0x00000000
-	moveq	r0, #0x00000001
-        bx      lr
-#ifdef __ARM_26__
-	mov	r15, r14
-#else
-	mov	r15, r14
-#endif
+  ldr r0, [r0, #(_JB_SIGMASK * 4)]
+  bl sigsetmask
 
-	/* validation failed, die die die. */
-botch:
-	bl	longjmperror
-	bl	abort
-	b	. - 8		/* Cannot get here */
-END(longjmp)
+  add sp, sp, #4 // Unalign the stack.
+  .cfi_adjust_cfa_offset -4
+  ldmfd sp!, {r0, r1, r14}
+  .cfi_def_cfa_offset 0
+
+1:
+  // Restore floating-point registers.
+  add r2, r0, #(_JB_FLOAT_BASE * 4)
+  vldmia r2, {d8-d15}
+
+  // Restore floating-point state.
+  ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
+  fmxr fpscr, r2
+
+  // Restore core registers.
+  add r2, r0, #(_JB_CORE_BASE * 4)
+  ldmia r2, {r4-r14}
+
+  // Validate sp and r14.
+  teq sp, #0
+  teqne r14, #0
+  bleq longjmperror
+
+  // Set return value.
+  mov r0, r1
+  teq r0, #0
+  moveq r0, #1
+  bx lr
+END(siglongjmp)
+
+  .globl longjmp
+  .equ longjmp, siglongjmp
+  .globl _longjmp
+  .equ _longjmp, siglongjmp
diff --git a/libc/arch-arm/bionic/sigsetjmp.S b/libc/arch-arm/bionic/sigsetjmp.S
deleted file mode 100644
index 6a25a12..0000000
--- a/libc/arch-arm/bionic/sigsetjmp.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/*	$OpenBSD: sigsetjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $	*/
-/*	$NetBSD: sigsetjmp.S,v 1.3 2002/08/17 19:54:30 thorpej Exp $	*/
-
-/*
- * Copyright (c) 1997 Mark Brinicombe
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Mark Brinicombe
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-
-/*
- * C library -- sigsetjmp, siglongjmp
- *
- *	longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	setjmp(a, m)
- * by restoring registers from the stack.
- * The previous signal state is restored.
- */
-
-ENTRY(sigsetjmp)
-	teq	r1, #0
-	beq	_setjmp
-	b	setjmp
-END(sigsetjmp)
-
-.L_setjmp_magic:
-	.word	_JB_MAGIC__SETJMP
-
-ENTRY(siglongjmp)
-	ldr	r2, .L_setjmp_magic
-	ldr	r3, [r0]
-	teq	r2, r3
-	beq	_longjmp
-	b	longjmp
-END(siglongjmp)
diff --git a/libc/arch-arm/denver/bionic/memset.S b/libc/arch-arm/denver/bionic/memset.S
index bf3d9ad..d77c244 100644
--- a/libc/arch-arm/denver/bionic/memset.S
+++ b/libc/arch-arm/denver/bionic/memset.S
@@ -37,6 +37,7 @@
          * memset() returns its first argument.
          */
 
+        .cpu        cortex-a15
         .fpu        neon
         .syntax     unified
 
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index fc5a8fd..fc8c80d 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -28,14 +28,6 @@
 #ifndef _ARM_MACHINE_CPU_FEATURES_H
 #define _ARM_MACHINE_CPU_FEATURES_H
 
-/* The purpose of this file is to define several macros corresponding
- * to CPU features that may or may not be available at build time on
- * on the target CPU.
- *
- * This is done to abstract us from the various ARM Architecture
- * quirks and alphabet soup.
- */
-
 /* __ARM_ARCH__ is a number corresponding to the ARM revision
  * we're going to support. Our toolchain doesn't define __ARM_ARCH__
  * so try to guess it.
@@ -53,31 +45,4 @@
 #  endif
 #endif
 
-/* define __ARM_HAVE_HALFWORD_MULTIPLY when half-word multiply instructions
- * this means variants of: smul, smulw, smla, smlaw, smlal
- */
-#define  __ARM_HAVE_HALFWORD_MULTIPLY  1
-
-/* define __ARM_HAVE_LDREXD for ARMv7 architecture
- * (also present in ARMv6K, but not implemented in ARMv7-M, neither of which
- * we care about)
- */
-#if __ARM_ARCH__ >= 7
-#  define __ARM_HAVE_LDREXD
-#endif
-
-/* define _ARM_HAVE_VFP if we have VFPv3
- */
-#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
-#  define __ARM_HAVE_VFP
-#endif
-
-/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
- * Neon SIMD instruction set extensions. This also implies
- * that VFPv3-D32 is supported.
- */
-#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
-#  define __ARM_HAVE_NEON
-#endif
-
 #endif /* _ARM_MACHINE_CPU_FEATURES_H */
diff --git a/libc/arch-arm/include/machine/endian.h b/libc/arch-arm/include/machine/endian.h
deleted file mode 100644
index 04bba20..0000000
--- a/libc/arch-arm/include/machine/endian.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*	$OpenBSD: endian.h,v 1.3 2005/12/13 00:35:23 millert Exp $	*/
-
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _ARM_ENDIAN_H_
-#define _ARM_ENDIAN_H_
-
-#ifdef __GNUC__
-
-/* According to RealView Assembler User's Guide, REV and REV16 are available
- * in Thumb code and 16-bit instructions when used in Thumb-2 code.
- *
- * REV Rd, Rm
- *   Rd and Rm must both be Lo registers.
- *
- * REV16 Rd, Rm
- *   Rd and Rm must both be Lo registers.
- *
- * The +l constraint takes care of this without constraining us in ARM mode.
- */
-#define __swap16md(x) ({                                        \
-    register u_int16_t _x = (x);                                \
-    __asm__ __volatile__("rev16 %0, %0" : "+l" (_x));           \
-    _x;                                                         \
-})
-
-#define __swap32md(x) ({                                        \
-    register u_int32_t _x = (x);                                \
-    __asm__ __volatile__("rev %0, %0" : "+l" (_x));             \
-    _x;                                                         \
-})
-
-#define __swap64md(x) ({                                        \
-    u_int64_t _swap64md_x = (x);                                \
-    (u_int64_t) __swap32md(_swap64md_x >> 32) |                 \
-        (u_int64_t) __swap32md(_swap64md_x & 0xffffffff) << 32; \
-})
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif  /* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#define __STRICT_ALIGNMENT
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif  /* !_ARM_ENDIAN_H_ */
diff --git a/libc/arch-arm/include/machine/exec.h b/libc/arch-arm/include/machine/exec.h
deleted file mode 100644
index 227b207..0000000
--- a/libc/arch-arm/include/machine/exec.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $	*/
-/*	$NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $	*/
-
-/*
- * Copyright (c) 1993 Christopher G. Demetriou
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _ARM_EXEC_H_
-#define _ARM_EXEC_H_
-
-#define __LDPGSZ	4096
-
-#define NATIVE_EXEC_ELF
-
-#define ARCH_ELFSIZE		32
-
-#define ELF_TARG_CLASS		ELFCLASS32
-#define ELF_TARG_DATA		ELFDATA2LSB
-#define ELF_TARG_MACH		EM_ARM
-
-#define _NLIST_DO_AOUT
-#define _NLIST_DO_ELF
-
-#define _KERN_DO_AOUT
-#define _KERN_DO_ELF
-
-#endif  /* _ARM_EXEC_H_ */
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
index 0941202..cc9c347 100644
--- a/libc/arch-arm/include/machine/setjmp.h
+++ b/libc/arch-arm/include/machine/setjmp.h
@@ -26,10 +26,6 @@
  * SUCH DAMAGE.
  */
 
-/*
- * machine/setjmp.h: machine dependent setjmp-related information.
- */
-
 /* _JBLEN is the size of a jmp_buf in longs.
  * Do not modify this value or you will break the ABI !
  *
@@ -37,46 +33,3 @@
  * that was replaced by this one.
  */
 #define _JBLEN  64
-
-/* According to the ARM AAPCS document, we only need to save
- * the following registers:
- *
- *  Core   r4-r14
- *
- *  VFP    d8-d15  (see section 5.1.2.1)
- *
- *      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
- *      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
- *      (and can be used for passing arguments or returning results in standard
- *      procedure-call variants). Registers d16-d31 (q8-q15), if present, do
- *      not need to be preserved.
- *
- *  FPSCR  saved because GLibc does saves it too.
- *
- */
-
-/* The internal structure of a jmp_buf is totally private.
- * Current layout (may change in the future):
- *
- * word   name         description
- * 0      magic        magic number
- * 1      sigmask      signal mask (not used with _setjmp / _longjmp)
- * 2      float_base   base of float registers (d8 to d15)
- * 18     float_state  floating-point status and control register
- * 19     core_base    base of core registers (r4 to r14)
- * 30     reserved     reserved entries (room to grow)
- * 64
- *
- * NOTE: float_base must be at an even word index, since the
- *       FP registers will be loaded/stored with instructions
- *       that expect 8-byte alignment.
- */
-
-#define _JB_MAGIC       0
-#define _JB_SIGMASK     (_JB_MAGIC+1)
-#define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
-#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
-#define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
-
-#define _JB_MAGIC__SETJMP	0x4278f500
-#define _JB_MAGIC_SETJMP	0x4278f501
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index bb6ca63..ba78871 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -35,10 +35,8 @@
 libc_bionic_src_files_arm64 += \
     arch-arm64/bionic/__bionic_clone.S \
     arch-arm64/bionic/_exit_with_stack_teardown.S \
-    arch-arm64/bionic/_setjmp.S \
     arch-arm64/bionic/setjmp.S \
     arch-arm64/bionic/__set_tls.c \
-    arch-arm64/bionic/sigsetjmp.S \
     arch-arm64/bionic/syscall.S \
     arch-arm64/bionic/vfork.S \
 
diff --git a/libc/arch-arm64/bionic/_setjmp.S b/libc/arch-arm64/bionic/_setjmp.S
deleted file mode 100644
index e11ef68..0000000
--- a/libc/arch-arm64/bionic/_setjmp.S
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-
-/*
- * C library - _setjmp, _longjmp
- *
- * _longjmp(jmp_buf state, int value)
- * will generate a "return(v)" from the last call to _setjmp(state) by restoring
- * registers from the stack. The previous signal state is NOT restored.
- *
- * NOTE: x0 return value
- *       x9-x15 temporary registers
- */
-
-ENTRY(_setjmp)
-    /* store magic number */
-    ldr     w9, .L_setjmp_magic
-    str     w9, [x0, #(_JB_MAGIC * 4)]
-
-    /* store core registers */
-    mov     x10, sp
-    stp     x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
-    stp     x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
-    stp     x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
-    stp     x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
-    stp     x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
-    stp     x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
-    str     x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
-
-    /* store floating point registers */
-    stp     d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
-    stp     d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
-    stp     d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
-    stp     d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
-
-    mov     w0, wzr
-    ret
-END(_setjmp)
-
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
-
-ENTRY(_longjmp)
-    /* check magic */
-    ldr     w9, .L_setjmp_magic
-    ldr     w10, [x0, #(_JB_MAGIC * 4)]
-    cmp     w9, w10
-    b.ne    .L_fail
-
-    /* restore core registers */
-    ldp     x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
-    mov     sp, x10
-    ldp     x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
-    ldp     x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
-    ldp     x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
-    ldp     x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
-    ldp     x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
-    ldr     x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
-
-    /* restore floating point registers */
-    ldp     d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
-    ldp     d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
-    ldp     d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
-    ldp     d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
-
-    /* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */
-    tst     x30, #3
-    b.ne    .L_fail
-    mov     x10, sp
-    tst     x10, #15
-    b.ne    .L_fail
-
-    /* set return value */
-    cmp     w1, wzr
-    csinc   w0, w1, wzr, ne
-    ret
-
-    /* validation failed, die die die */
-.L_fail:
-    bl      longjmperror
-    bl      abort
-    b        . - 8       /* Cannot get here */
-END(_longjmp)
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index 35815a6..5c956ff 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -27,97 +27,126 @@
  */
 
 #include <private/bionic_asm.h>
-#include <machine/setjmp.h>
 
-/*
- * C library - _setjmp, _longjmp
- *
- * _longjmp(jmp_buf state, int value)
- * will generate a "return(v)" from the last call to _setjmp(state) by restoring
- * registers from the stack. The previous signal state is NOT restored.
- *
- * NOTE: x0 return value
- *       x9-x15 temporary registers
- */
+// According to AARCH64 PCS document we need to save the following
+// registers:
+//
+// Core     x19 - x30, sp (see section 5.1.1)
+// VFP      d8 - d15 (see section 5.1.2)
+//
+// NOTE: All the registers saved here will have 64 bit vales.
+//       AAPCS mandates that the higher part of q registers do not need to
+//       be saved by the callee.
+
+#define _JB_SIGFLAG     0
+#define _JB_SIGMASK     (_JB_SIGFLAG + 1)
+#define _JB_X30_SP      (_JB_SIGMASK + 1)
+#define _JB_X28_X29     (_JB_X30_SP  + 2)
+#define _JB_X26_X27     (_JB_X28_X29 + 2)
+#define _JB_X24_X25     (_JB_X26_X27 + 2)
+#define _JB_X22_X23     (_JB_X24_X25 + 2)
+#define _JB_X20_X21     (_JB_X22_X23 + 2)
+#define _JB_X19         (_JB_X20_X21 + 2)
+#define _JB_D14_D15     (_JB_X19 + 1)
+#define _JB_D12_D13     (_JB_D14_D15 + 2)
+#define _JB_D10_D11     (_JB_D12_D13 + 1)
+#define _JB_D8_D9       (_JB_D10_D11 + 1)
 
 ENTRY(setjmp)
-    /* block all signals an retrieve signal mask */
-    stp     x0, x30, [sp, #-16]!
-
-    mov     x0, xzr
-    bl      sigblock
-    mov     w1, w0
-
-    ldp     x0, x30, [sp], #16
-
-    /* store signal mask */
-    str     w1, [x0, #(_JB_SIGMASK *4)]
-
-    /* store magic number */
-    ldr     w9, .L_setjmp_magic
-    str     w9, [x0, #(_JB_MAGIC * 4)]
-
-    /* store core registers */
-    mov     x10, sp
-    stp     x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
-    stp     x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
-    stp     x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
-    stp     x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
-    stp     x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
-    stp     x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
-    str     x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
-
-    /* store floating point registers */
-    stp     d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
-    stp     d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
-    stp     d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
-    stp     d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
-
-    mov     w0, wzr
-    ret
+  mov w1, #1
+  b sigsetjmp
 END(setjmp)
 
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
+ENTRY(_setjmp)
+  mov w1, #0
+  b sigsetjmp
+END(_setjmp)
 
-ENTRY(longjmp)
-    /* check magic */
-    ldr     w9, .L_setjmp_magic
-    ldr     w10, [x0, #(_JB_MAGIC * 4)]
-    cmp     w9, w10
-    b.ne    .L_fail
+// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
+ENTRY(sigsetjmp)
+  // Record whether or not we're saving the signal mask.
+  str w1, [x0, #(_JB_SIGFLAG * 8)]
 
-    /* restore core registers */
-    ldp     x30, x10, [x0, #(_JB_CORE_BASE * 4 + 16 * 0)]
-    mov     sp, x10
-    ldp     x28, x29, [x0, #(_JB_CORE_BASE * 4 + 16 * 1)]
-    ldp     x26, x27, [x0, #(_JB_CORE_BASE * 4 + 16 * 2)]
-    ldp     x24, x25, [x0, #(_JB_CORE_BASE * 4 + 16 * 3)]
-    ldp     x22, x23, [x0, #(_JB_CORE_BASE * 4 + 16 * 4)]
-    ldp     x20, x21, [x0, #(_JB_CORE_BASE * 4 + 16 * 5)]
-    ldr     x19,      [x0, #(_JB_CORE_BASE * 4 + 16 * 6)]
+  // Do we need to save the signal mask?
+  cbz w1, 1f
 
-    /* restore floating point registers */
-    ldp     d14, d15, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 0)]
-    ldp     d12, d13, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 1)]
-    ldp     d10, d11, [x0, #(_JB_FLOAT_BASE * 4 + 16 * 2)]
-    ldp     d8,  d9,  [x0, #(_JB_FLOAT_BASE * 4 + 16 * 3)]
+  // Save current signal mask.
+  stp x0, x30, [sp, #-16]!
+  // The 'how' argument is ignored if new_mask is NULL.
+  mov x1, #0 // NULL.
+  add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
+  bl sigprocmask
+  ldp x0, x30, [sp], #16
 
-    /* validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0) */
-    tst     x30, #3
-    b.ne    .L_fail
-    mov     x10, sp
-    tst     x10, #15
-    b.ne    .L_fail
+1:
+  // Save core registers.
+  mov x10, sp
+  stp x30, x10, [x0, #(_JB_X30_SP  * 8)]
+  stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
+  stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
+  stp x24, x25, [x0, #(_JB_X24_X25 * 8)]
+  stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
+  stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
+  str x19,      [x0, #(_JB_X19     * 8)]
 
-    /* set return value */
-    cmp     w1, wzr
-    csinc   w0, w1, wzr, ne
-    ret
+  // Save floating point registers.
+  stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
+  stp d12, d13, [x0, #(_JB_D12_D13 * 8)]
+  stp d10, d11, [x0, #(_JB_D10_D11 * 8)]
+  stp d8,  d9,  [x0, #(_JB_D8_D9   * 8)]
 
-    /* validation failed, die die die */
-.L_fail:
-    bl      longjmperror
-    bl      abort
-    b       . - 8       /* Cannot get here */
-END(longjmp)
+  mov w0, #0
+  ret
+END(sigsetjmp)
+
+// void siglongjmp(sigjmp_buf env, int value);
+ENTRY(siglongjmp)
+  // Do we need to restore the signal mask?
+  ldr w9, [x0, #(_JB_SIGFLAG * 8)]
+  cbz w9, 1f
+
+  // Restore signal mask.
+  stp x0, x30, [sp, #-16]!
+  mov x19, x1 // Save 'value'.
+  mov x2, x0
+  mov x0, #2 // SIG_SETMASK
+  add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
+  mov x2, #0 // NULL.
+  bl sigprocmask
+  mov x1, x19 // Restore 'value'.
+  ldp x0, x30, [sp], #16
+
+1:
+  // Restore core registers.
+  ldp x30, x10, [x0, #(_JB_X30_SP  * 8)]
+  mov sp, x10
+  ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
+  ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
+  ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
+  ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
+  ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
+  ldr x19,      [x0, #(_JB_X19     * 8)]
+
+  // Restore floating point registers.
+  ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
+  ldp d12, d13, [x0, #(_JB_D12_D13 * 8)]
+  ldp d10, d11, [x0, #(_JB_D10_D11 * 8)]
+  ldp d8,  d9,  [x0, #(_JB_D8_D9   * 8)]
+
+  // Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0).
+  tst x30, #3
+  b.ne longjmperror
+  mov x10, sp
+  tst x10, #15
+  b.ne longjmperror
+
+  // Set return value.
+  cmp w1, wzr
+  csinc w0, w1, wzr, ne
+  ret
+END(siglongjmp)
+
+  .globl longjmp
+  .equ longjmp, siglongjmp
+  .globl _longjmp
+  .equ _longjmp, siglongjmp
diff --git a/libc/arch-arm64/include/machine/endian.h b/libc/arch-arm64/include/machine/endian.h
deleted file mode 100644
index 4743733..0000000
--- a/libc/arch-arm64/include/machine/endian.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _AARCH64_ENDIAN_H_
-#define _AARCH64_ENDIAN_H_
-
-#ifdef __GNUC__
-
-#define __swap16md(x) ({                                        \
-    register u_int16_t _x = (x);                                \
-    __asm volatile ("rev16 %0, %0" : "+r" (_x));                \
-    _x;                                                         \
-})
-
-/* Use GCC builtins */
-#define __swap32md(x) __builtin_bswap32(x)
-#define __swap64md(x) __builtin_bswap64(x)
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif  /* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif /* _AARCH64_ENDIAN_H_ */
diff --git a/libc/arch-arm64/include/machine/exec.h b/libc/arch-arm64/include/machine/exec.h
deleted file mode 100644
index 7437626..0000000
--- a/libc/arch-arm64/include/machine/exec.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $	*/
-/*	$NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $	*/
-
-/*
- * Copyright (c) 1993 Christopher G. Demetriou
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _AARCH64_EXEC_H_
-#define _AARCH64_EXEC_H_
-
-#define	__LDPGSZ		4096
-
-#define	NATIVE_EXEC_ELF
-
-#define	ARCH_ELFSIZE		64
-
-#define	ELF_TARG_CLASS		ELFCLASS64		/* 64-bit objects */
-#define	ELF_TARG_DATA		ELFDATA2LSB
-#define	ELF_TARG_MACH		EM_AARCH64
-
-#define	_NLIST_DO_AOUT
-#define	_NLIST_DO_ELF
-
-#define	_KERN_DO_AOUT
-#define	_KERN_DO_ELF64
-
-#endif  /* _AARCH64_EXEC_H_ */
diff --git a/libc/arch-arm64/include/machine/setjmp.h b/libc/arch-arm64/include/machine/setjmp.h
index 1c237da..27c2fe5 100644
--- a/libc/arch-arm64/include/machine/setjmp.h
+++ b/libc/arch-arm64/include/machine/setjmp.h
@@ -26,48 +26,5 @@
  * SUCH DAMAGE.
  */
 
-/*
- * machine/setjmp.h: machine dependent setjmp-related information.
- */
-
-/* _JBLEN is the size of a jmp_buf in longs(64bit on AArch64) */
+/* _JBLEN is the size of a jmp_buf in longs (64bit on AArch64) */
 #define _JBLEN 32
-
-/* According to AARCH64 PCS document we need to save the following
- * registers:
- *
- * Core     x19 - x30, sp (see section 5.1.1)
- * VFP      d8 - d15 (see section 5.1.2)
- *
- * NOTE: All the registers saved here will have 64bit vales (except FPSR).
- *       AAPCS mandates that the higher part of q registers does not need to
- *       be saveved by the callee.
- */
-
-/* The structure of jmp_buf for AArch64:
- *
- * NOTE: _JBLEN is the size of jmp_buf in longs(64bit on AArch64)! The table
- *      below computes the offsets in words(32bit).
- *
- *  word        name            description
- *  0       magic           magic number
- *  1       sigmask         signal mask (not used with _setjmp / _longjmp)
- *  2       core_base       base of core registers (x19-x30, sp)
- *  28      float_base      base of float registers (d8-d15)
- *  44      reserved        reserved entries (room to grow)
- *  64
- *
- *
- *  NOTE: The instructions that load/store core/vfp registers expect 8-byte
- *        alignment. Contrary to the previous setjmp header for ARM we do not
- *        need to save status/control registers for VFP (it is not a
- *        requirement for setjmp).
- */
-
-#define _JB_MAGIC       0
-#define _JB_SIGMASK     (_JB_MAGIC+1)
-#define _JB_CORE_BASE   (_JB_SIGMASK+1)
-#define _JB_FLOAT_BASE  (_JB_CORE_BASE + (31-19+1)*2)
-
-#define _JB_MAGIC__SETJMP   0x53657200
-#define _JB_MAGIC_SETJMP    0x53657201
diff --git a/libc/arch-mips/bionic/_setjmp.S b/libc/arch-mips/bionic/_setjmp.S
deleted file mode 100644
index d237e6d..0000000
--- a/libc/arch-mips/bionic/_setjmp.S
+++ /dev/null
@@ -1,150 +0,0 @@
-/*	$OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
-
-/*
- * Copyright (c) 2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opsycon AB nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/signal.h>
-
-/*
- * _setjmp, _longjmp (not restoring signal state)
- *
- * XXX FPSET should probably be taken from SR setting. hmmm...
- *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
- *
- */
-
-FRAMESZ= MKFSIZ(0,4)
-GPOFF= FRAMESZ-2*REGSZ
-
-LEAF(_setjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, _setjmp)
-	SAVE_GP(GPOFF)
-	.set	noreorder
-#if defined(__mips64)
-	dli	v0, 0xACEDBADE			# sigcontext magic number
-#else
-	li	v0, 0xACEDBADE			# sigcontext magic number
-#endif
-	REG_S	v0, SC_REGS+ZERO*REGSZ(a0)
-	REG_S	s0, SC_REGS+S0*REGSZ(a0)
-	REG_S	s1, SC_REGS+S1*REGSZ(a0)
-	REG_S	s2, SC_REGS+S2*REGSZ(a0)
-	REG_S	s3, SC_REGS+S3*REGSZ(a0)
-	REG_S	s4, SC_REGS+S4*REGSZ(a0)
-	REG_S	s5, SC_REGS+S5*REGSZ(a0)
-	REG_S	s6, SC_REGS+S6*REGSZ(a0)
-	REG_S	s7, SC_REGS+S7*REGSZ(a0)
-	REG_S	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	v0, GPOFF(sp)
-	REG_S	v0, SC_REGS+GP*REGSZ(a0)
-	PTR_ADDU v0, sp, FRAMESZ
-	REG_S	v0, SC_REGS+SP*REGSZ(a0)
-	REG_S	ra, SC_PC(a0)
-
-#if !defined(SOFTFLOAT)
-	li	v0, 1				# be nice if we could tell
-	REG_S	v0, SC_FPUSED(a0)		# sc_fpused = 1
-	cfc1	v0, $31
-	s.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	s.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	s.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	s.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	s.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	s.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	s.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	s.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	s.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	s.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	s.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	s.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-	REG_S	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-#endif /* !SOFTFLOAT */
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	ra
-	 move	v0, zero
-END(_setjmp)
-
-LEAF(_longjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, _longjmp)
-	SAVE_GP(GPOFF)
-	.set    noreorder
-	REG_L	v0, SC_REGS+ZERO*REGSZ(a0)
-	bne	v0, 0xACEDBADE, botch		# jump if error
-	REG_L	ra, SC_PC(a0)
-	REG_L	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-	REG_L	s0, SC_REGS+S0*REGSZ(a0)
-	REG_L	s1, SC_REGS+S1*REGSZ(a0)
-	REG_L	s2, SC_REGS+S2*REGSZ(a0)
-	REG_L	s3, SC_REGS+S3*REGSZ(a0)
-	REG_L	s4, SC_REGS+S4*REGSZ(a0)
-	REG_L	s5, SC_REGS+S5*REGSZ(a0)
-	REG_L	s6, SC_REGS+S6*REGSZ(a0)
-	REG_L	s7, SC_REGS+S7*REGSZ(a0)
-	REG_L	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	gp, SC_REGS+GP*REGSZ(a0)
-	REG_L	sp, SC_REGS+SP*REGSZ(a0)
-#if !defined(SOFTFLOAT)
-	ctc1	v0, $31
-	l.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	l.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	l.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	l.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	l.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	l.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	l.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	l.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	l.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	l.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	l.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	l.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-#endif /* !SOFTFLOAT */
-	bne	a1, zero, 1f
-	 nop
-	li	a1, 1			# never return 0!
-1:
-	j	ra
-	 move	v0, a1
-
-botch:
-	jal	longjmperror
-	nop
-	jal	abort
-	nop
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-END(_longjmp)
diff --git a/libc/arch-mips/bionic/setjmp.S b/libc/arch-mips/bionic/setjmp.S
index 31786be..05d0e25 100644
--- a/libc/arch-mips/bionic/setjmp.S
+++ b/libc/arch-mips/bionic/setjmp.S
@@ -1,5 +1,3 @@
-/*      $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
-
 /*
  * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
  *
@@ -28,14 +26,116 @@
  * SUCH DAMAGE.
  *
  */
+/*-
+ * Copyright (c) 1991, 1993, 1995,
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Havard Eidnes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ralph Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)signal.h	8.1 (Berkeley) 6/10/93
+ */
 
 #include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/signal.h>
+#include <machine/setjmp.h>
+
+/* On Mips32, jmpbuf begins with optional 4-byte filler so that
+ *  all saved FP regs are aligned on 8-byte boundary, despite this whole
+ *  struct being mis-declared to users as an array of (4-byte) longs.
+ *  All the following offsets are then from the rounded-up base addr
+ */
+
+/* Fields of same size on all MIPS abis: */
+#define	SC_MAGIC        (0*4)		/* 4 bytes, identify jmpbuf */
+#define	SC_MASK		(1*4)		/* 4 bytes, saved signal mask */
+#define	SC_FPSR		(2*4)		/* 4 bytes, floating point control/status reg */
+/*     	filler2		(3*4)		   4 bytes, pad to 8-byte boundary */
+
+/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */
+#define	SC_REGS_SAVED	12		/* ra,gp,sp,s0-s8 */
+#define	SC_REGS		(4*4)		/* SC_REGS_SAVED*REGSZ bytes */
+
+/* Floating pt registers are 8-bytes on all abis,
+ * but the number of saved fp regs varies for o32/n32 versus n64 abis:
+ */
+
+#ifdef __LP64__
+#define	SC_FPREGS_SAVED	8  /* all  fp regs f24,f25,f26,f27,f28,f29,f30,f31 */
+#else
+#define	SC_FPREGS_SAVED	6  /* even fp regs f20,f22,f24,f26,f28,f30 */
+#endif
+
+#define	SC_FPREGS	(SC_REGS + SC_REGS_SAVED*REGSZ)  /* SC_FPREGS_SAVED*REGSZ_FP bytes */
+
+#define	SC_BYTES	(SC_FPREGS + SC_FPREGS_SAVED*REGSZ_FP)
+#define	SC_LONGS	(SC_BYTES/REGSZ)
+
+#ifdef __LP64__
+/* SC_LONGS is 22, so _JBLEN should be 22 or larger */
+#else
+/* SC_LONGS is 28, but must also allocate dynamic-roundup filler.
+   so _JBLEN should be 29 or larger */
+#endif
 
 /*
- * setjmp, longjmp implementation for libc. this code depends
- * on the layout of the struct sigcontext in machine/signal.h.
+ * _setjmp, _longjmp (restoring signal state)
+ *
+ *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
  *
  */
 
@@ -51,124 +151,319 @@
 	SETUP_GP64(GPOFF, setjmp)
 	SAVE_GP(GPOFF)
 	.set	reorder
+
+#ifndef __LP64__
+	addiu   a0, 7				# roundup jmpbuf addr to 8-byte boundary
+	li      t0, ~7
+	and     a0, t0
+#endif
+
 	REG_S	ra, RAOFF(sp)			# save state
 	REG_S	a0, A0OFF(sp)
-
 	move	a0, zero			# get current signal mask
 	jal	sigblock
-
-	REG_L	v1, A0OFF(sp)			# v1 = jmpbuf
-	REG_S	v0, SC_MASK(v1)			# save sc_mask = sigblock(0)
-
-	REG_L	a0, A0OFF(sp)			# restore jmpbuf
+	REG_L	a0, A0OFF(sp)
 	REG_L	ra, RAOFF(sp)
-	REG_S	ra, SC_PC(a0)			# sc_pc = return address
-#if defined(__mips64)
-	dli	v0, 0xACEDBADE			# sigcontext magic number
-#else
-	li	v0, 0xACEDBADE			# sigcontext magic number
-#endif
-	REG_S	v0, SC_REGS+ZERO*REGSZ(a0)
-	REG_S	s0, SC_REGS+S0*REGSZ(a0)
-	REG_S	s1, SC_REGS+S1*REGSZ(a0)
-	REG_S	s2, SC_REGS+S2*REGSZ(a0)
-	REG_S	s3, SC_REGS+S3*REGSZ(a0)
-	REG_S	s4, SC_REGS+S4*REGSZ(a0)
-	REG_S	s5, SC_REGS+S5*REGSZ(a0)
-	REG_S	s6, SC_REGS+S6*REGSZ(a0)
-	REG_S	s7, SC_REGS+S7*REGSZ(a0)
-	REG_S	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	v0, GPOFF(sp)
-	REG_S	v0, SC_REGS+GP*REGSZ(a0)
-	PTR_ADDU v0, sp, FRAMESZ
-	REG_S	v0, SC_REGS+SP*REGSZ(a0)
 
-#if !defined(SOFTFLOAT)
-	li	v0, 1				# be nice if we could tell
-	REG_S	v0, SC_FPUSED(a0)		# sc_fpused = 1
+	REG_S	v0, SC_MASK(a0)			# save sc_mask = sigblock(0)
+
+	li	v0, 0xACEDBADE			# sigcontext magic number
+	sw	v0, SC_MAGIC(a0)
+	# callee-saved long-sized regs:
+	REG_S	ra, SC_REGS+0*REGSZ(a0)
+	REG_S	s0, SC_REGS+1*REGSZ(a0)
+	REG_S	s1, SC_REGS+2*REGSZ(a0)
+	REG_S	s2, SC_REGS+3*REGSZ(a0)
+	REG_S	s3, SC_REGS+4*REGSZ(a0)
+	REG_S	s4, SC_REGS+5*REGSZ(a0)
+	REG_S	s5, SC_REGS+6*REGSZ(a0)
+	REG_S	s6, SC_REGS+7*REGSZ(a0)
+	REG_S	s7, SC_REGS+8*REGSZ(a0)
+	REG_S	s8, SC_REGS+9*REGSZ(a0)
+	REG_L	v0, GPOFF(sp)
+	REG_S	v0, SC_REGS+10*REGSZ(a0)
+	PTR_ADDU v0, sp, FRAMESZ
+	REG_S	v0, SC_REGS+11*REGSZ(a0)
+
 	cfc1	v0, $31
-	s.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	s.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	s.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	s.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	s.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	s.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	s.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	s.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	s.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	s.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	s.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	s.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
+
+#ifdef __LP64__
+	# callee-saved fp regs on mips n64 ABI are $f24..$f31
+	s.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
+	s.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
+	s.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
+	s.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	s.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
+	s.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
+	s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+#else
+	# callee-saved fp regs on mips o32 ABI are
+	#   the even-numbered fp regs $f20,$f22,...$f30
+	s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
+	s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
+	s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
+	s.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 #endif
-	REG_S	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-#endif /* !SOFTFLOAT */
+	sw	v0, SC_FPSR(a0)
 	move	v0, zero
 	RESTORE_GP64
 	PTR_ADDU sp, FRAMESZ
 	j	ra
-
-botch:
-	jal	longjmperror
-	jal	abort
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
 END(setjmp)
 
-
-LEAF(longjmp, FRAMESZ)
+NON_LEAF(longjmp, FRAMESZ, ra)
+	.mask	0x80000000, RAOFF
 	PTR_SUBU sp, FRAMESZ
 	SETUP_GP64(GPOFF, longjmp)
 	SAVE_GP(GPOFF)
 	.set	reorder
-	sw	a1, A1OFF(sp)
-	sw	a0, A0OFF(sp)
 
+#ifndef __LP64__
+	addiu	a0, 7				# roundup jmpbuf addr to 8-byte boundary
+	li      t0, ~7
+	and	a0, t0
+#endif
+
+	REG_S	a1, A1OFF(sp)
+	REG_S	a0, A0OFF(sp)
 	lw	a0, SC_MASK(a0)
 	jal	sigsetmask
+	REG_L	a0, A0OFF(sp)
+	REG_L	a1, A1OFF(sp)
 
-	lw	a0, A0OFF(sp)
-	lw	a1, A1OFF(sp)
+	lw	v0, SC_MAGIC(a0)
+	li	t0, 0xACEDBADE
+	bne	v0, t0, longjmp_botch			# jump if error
 
-	.set	noreorder
-	REG_L	v0, SC_REGS+ZERO*REGSZ(a0)
-	bne	v0, 0xACEDBADE, botch		# jump if error
-	REG_L	ra, SC_PC(a0)
-	REG_L	s0, SC_REGS+S0*REGSZ(a0)
-	REG_L	s1, SC_REGS+S1*REGSZ(a0)
-	REG_L	s2, SC_REGS+S2*REGSZ(a0)
-	REG_L	s3, SC_REGS+S3*REGSZ(a0)
-	REG_L	s4, SC_REGS+S4*REGSZ(a0)
-	REG_L	s5, SC_REGS+S5*REGSZ(a0)
-	REG_L	s6, SC_REGS+S6*REGSZ(a0)
-	REG_L	s7, SC_REGS+S7*REGSZ(a0)
-	REG_L	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	gp, SC_REGS+GP*REGSZ(a0)
-	REG_L	sp, SC_REGS+SP*REGSZ(a0)
+	# callee-saved long-sized regs:
+	REG_L	ra, SC_REGS+0*REGSZ(a0)
+	REG_L	s0, SC_REGS+1*REGSZ(a0)
+	REG_L	s1, SC_REGS+2*REGSZ(a0)
+	REG_L	s2, SC_REGS+3*REGSZ(a0)
+	REG_L	s3, SC_REGS+4*REGSZ(a0)
+	REG_L	s4, SC_REGS+5*REGSZ(a0)
+	REG_L	s5, SC_REGS+6*REGSZ(a0)
+	REG_L	s6, SC_REGS+7*REGSZ(a0)
+	REG_L	s7, SC_REGS+8*REGSZ(a0)
+	REG_L	s8, SC_REGS+9*REGSZ(a0)
+	REG_L	gp, SC_REGS+10*REGSZ(a0)
+	REG_L	sp, SC_REGS+11*REGSZ(a0)
 
-#if !defined(SOFTFLOAT)
-	REG_L	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
+	lw	v0, SC_FPSR(a0)
 	ctc1	v0, $31
-	l.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	l.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	l.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	l.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	l.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	l.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	l.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	l.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	l.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	l.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	l.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	l.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
+#ifdef __LP64__
+	# callee-saved fp regs on mips n64 ABI are $f24..$f31
+	l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
+	l.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
+	l.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
+	l.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	l.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
+	l.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
+	l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+#else
+	# callee-saved fp regs on mips o32 ABI are
+	#   the even-numbered fp regs $f20,$f22,...$f30
+	l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
+	l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
+	l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
+	l.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	l.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
 #endif
-#endif /* !SOFTFLOAT */
 	bne	a1, zero, 1f
-	 nop
 	li	a1, 1			# never return 0!
 1:
+	move	v0, a1
 	j	ra
-	 move	v0, a1
 
+longjmp_botch:
+	jal	longjmperror
+	jal	abort
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
 END(longjmp)
+
+
+/*
+ * _setjmp, _longjmp (not restoring signal state)
+ *
+ *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
+ *
+ */
+
+FRAMESZ= MKFSIZ(0,4)
+GPOFF= FRAMESZ-2*REGSZ
+
+LEAF(_setjmp, FRAMESZ)
+	PTR_SUBU sp, FRAMESZ
+	SETUP_GP64(GPOFF, _setjmp)
+	SAVE_GP(GPOFF)
+	.set	reorder
+
+#ifndef __LP64__
+	addiu   a0, 7				# roundup jmpbuf addr to 8-byte boundary
+	li      t0, ~7
+	and     a0, t0
+#endif
+
+	# SC_MASK is unused here
+
+	li	v0, 0xACEDBADE			# sigcontext magic number
+	sw	v0, SC_MAGIC(a0)
+	# callee-saved long-sized regs:
+	REG_S	ra, SC_REGS+0*REGSZ(a0)
+	REG_S	s0, SC_REGS+1*REGSZ(a0)
+	REG_S	s1, SC_REGS+2*REGSZ(a0)
+	REG_S	s2, SC_REGS+3*REGSZ(a0)
+	REG_S	s3, SC_REGS+4*REGSZ(a0)
+	REG_S	s4, SC_REGS+5*REGSZ(a0)
+	REG_S	s5, SC_REGS+6*REGSZ(a0)
+	REG_S	s6, SC_REGS+7*REGSZ(a0)
+	REG_S	s7, SC_REGS+8*REGSZ(a0)
+	REG_S	s8, SC_REGS+9*REGSZ(a0)
+	REG_L	v0, GPOFF(sp)
+	REG_S	v0, SC_REGS+10*REGSZ(a0)
+	PTR_ADDU v0, sp, FRAMESZ
+	REG_S	v0, SC_REGS+11*REGSZ(a0)
+
+	cfc1	v0, $31
+
+#ifdef __LP64__
+	# callee-saved fp regs on mips n64 ABI are $f24..$f31
+	s.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
+	s.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
+	s.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
+	s.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	s.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
+	s.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
+	s.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+#else
+	# callee-saved fp regs on mips o32 ABI are
+	#   the even-numbered fp regs $f20,$f22,...$f30
+	s.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
+	s.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
+	s.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
+	s.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
+	s.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	s.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
+#endif
+	sw	v0, SC_FPSR(a0)
+	move	v0, zero
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+	j	ra
+END(_setjmp)
+
+
+LEAF(_longjmp, FRAMESZ)
+	PTR_SUBU sp, FRAMESZ
+	SETUP_GP64(GPOFF, _longjmp)
+	SAVE_GP(GPOFF)
+	.set	reorder
+
+#ifndef __LP64__
+	addiu	a0, 7				# roundup jmpbuf addr to 8-byte boundary
+	li      t0, ~7
+	and	a0, t0
+#endif
+
+	# SC_MASK is unused here
+
+	lw	v0, SC_MAGIC(a0)
+	li	t0, 0xACEDBADE
+	bne	v0, t0, _longjmp_botch			# jump if error
+
+	# callee-saved long-sized regs:
+	REG_L	ra, SC_REGS+0*REGSZ(a0)
+	REG_L	s0, SC_REGS+1*REGSZ(a0)
+	REG_L	s1, SC_REGS+2*REGSZ(a0)
+	REG_L	s2, SC_REGS+3*REGSZ(a0)
+	REG_L	s3, SC_REGS+4*REGSZ(a0)
+	REG_L	s4, SC_REGS+5*REGSZ(a0)
+	REG_L	s5, SC_REGS+6*REGSZ(a0)
+	REG_L	s6, SC_REGS+7*REGSZ(a0)
+	REG_L	s7, SC_REGS+8*REGSZ(a0)
+	REG_L	s8, SC_REGS+9*REGSZ(a0)
+	REG_L	gp, SC_REGS+10*REGSZ(a0)
+	REG_L	sp, SC_REGS+11*REGSZ(a0)
+
+	lw	v0, SC_FPSR(a0)
+	ctc1	v0, $31
+#ifdef __LP64__
+	# callee-saved fp regs on mips n64 ABI are $f24..$f31
+	l.d	$f24, SC_FPREGS+0*REGSZ_FP(a0)
+	l.d	$f25, SC_FPREGS+1*REGSZ_FP(a0)
+	l.d	$f26, SC_FPREGS+2*REGSZ_FP(a0)
+	l.d	$f27, SC_FPREGS+3*REGSZ_FP(a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	l.d	$f29, SC_FPREGS+5*REGSZ_FP(a0)
+	l.d	$f30, SC_FPREGS+6*REGSZ_FP(a0)
+	l.d	$f31, SC_FPREGS+7*REGSZ_FP(a0)
+#else
+	# callee-saved fp regs on mips o32 ABI are
+	#   the even-numbered fp regs $f20,$f22,...$f30
+	l.d	$f20, SC_FPREGS+0*REGSZ_FP(a0)
+	l.d	$f22, SC_FPREGS+1*REGSZ_FP(a0)
+	l.d	$f24, SC_FPREGS+2*REGSZ_FP(a0)
+	l.d	$f26, SC_FPREGS+3*REGSZ_FP(a0)
+	l.d	$f28, SC_FPREGS+4*REGSZ_FP(a0)
+	l.d	$f30, SC_FPREGS+5*REGSZ_FP(a0)
+#endif
+	bne	a1, zero, 1f
+	li	a1, 1			# never return 0!
+1:
+	move	v0, a1
+	j	ra
+
+_longjmp_botch:
+	jal	longjmperror
+	jal	abort
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+END(_longjmp)
+
+/*
+ * trampolines for sigsetjmp and  siglongjmp save and restore mask.
+ *
+ */
+FRAMESZ= MKFSIZ(1,1)
+GPOFF= FRAMESZ-2*REGSZ
+
+LEAF(sigsetjmp, FRAMESZ)
+	PTR_SUBU sp, FRAMESZ
+	SETUP_GP64(GPOFF, sigsetjmp)
+	.set	reorder
+	sw	a1, _JBLEN*REGSZ(a0)		# save "savemask"
+	bne	a1, 0x0, 1f			# do saving of signal mask?
+	LA	t9, _setjmp
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+	jr t9
+
+1:	LA	t9, setjmp
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+	jr t9
+END(sigsetjmp)
+
+LEAF(siglongjmp, FRAMESZ)
+	PTR_SUBU sp, FRAMESZ
+	SETUP_GP64(GPOFF, siglongjmp)
+	.set	reorder
+	lw	t0, _JBLEN*REGSZ(a0)		# get "savemask"
+	bne	t0, 0x0, 1f			# restore signal mask?
+	LA	t9, _longjmp
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+	jr	t9
+1:
+	LA	t9, longjmp
+	RESTORE_GP64
+	PTR_ADDU sp, FRAMESZ
+	jr	t9
+END(siglongjmp)
diff --git a/libc/arch-mips/bionic/sigsetjmp.S b/libc/arch-mips/bionic/sigsetjmp.S
deleted file mode 100644
index 9d2e5ea..0000000
--- a/libc/arch-mips/bionic/sigsetjmp.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenBSD: sigsetjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
-/*-
- * Copyright (c) 1991, 1993, 1995,
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Havard Eidnes.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/setjmp.h>
-
-/*
- * trampolines for sigsetjmp and  siglongjmp save and restore mask.
- *
- */
-FRAMESZ= MKFSIZ(1,1)
-GPOFF= FRAMESZ-2*REGSZ
-
-LEAF(sigsetjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, sigsetjmp)
-	.set	reorder
-	REG_S	a1, (_JBLEN*REGSZ)(a0)		# save "savemask"
-	bne	a1, 0x0, 1f			# do saving of signal mask?
-	LA	t9, _setjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr t9
-
-1:	LA	t9, setjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr t9
-END(sigsetjmp)
-
-LEAF(siglongjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, siglongjmp)
-	.set	reorder
-	REG_L	t0, (_JBLEN*REGSZ)(a0)		# get "savemask"
-	bne	t0, 0x0, 1f			# restore signal mask?
-	LA	t9, _longjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr	t9
-1:
-	LA	t9, longjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr	t9
-END(siglongjmp)
diff --git a/libc/arch-mips/include/machine/endian.h b/libc/arch-mips/include/machine/endian.h
deleted file mode 100644
index 9270e9d..0000000
--- a/libc/arch-mips/include/machine/endian.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*	$OpenBSD: endian.h,v 1.5 2006/02/27 23:35:59 miod Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_ENDIAN_H_
-#define _MIPS64_ENDIAN_H_
-
-#ifdef __GNUC__
-
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-#define __swap16md(x) ({					\
-    register uint16_t _x = (x);					\
-    register uint16_t _r;					\
-    __asm volatile ("wsbh %0, %1" : "=r" (_r) : "r" (_x));	\
-    _r;								\
-})
-
-#define __swap32md(x) ({					\
-    register uint32_t _x = (x);					\
-    register uint32_t _r;					\
-    __asm volatile ("wsbh %0, %1; rotr %0, %0, 16" : "=r" (_r) : "r" (_x)); \
-    _r;								\
-})
-
-#define __swap64md(x) ({					\
-    uint64_t _swap64md_x = (x);					\
-    (uint64_t) __swap32md(_swap64md_x >> 32) |			\
-        (uint64_t) __swap32md(_swap64md_x & 0xffffffff) << 32;	\
-})
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif  /* __mips32r2__ */
-#endif  /* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#define __STRICT_ALIGNMENT
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif /* _MIPS64_ENDIAN_H_ */
diff --git a/libc/arch-mips/include/machine/exec.h b/libc/arch-mips/include/machine/exec.h
deleted file mode 100644
index 3c63f74..0000000
--- a/libc/arch-mips/include/machine/exec.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.1 2004/10/18 19:05:36 grange Exp $	*/
-
-/*
- * Copyright (c) 1996-2004 Per Fogelstrom, Opsycon AB
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_EXEC_H_
-#define _MIPS64_EXEC_H_
-
-#define	__LDPGSZ	4096
-
-/*
- *  Define what exec "formats" we should handle.
- */
-#define NATIVE_EXEC_ELF
-#define NATIVE_ELFSIZE 64
-#define	EXEC_SCRIPT
-
-/*
- *  If included from sys/exec.h define kernels ELF format.
- */
-#ifdef __LP64__
-#define	ARCH_ELFSIZE 64
-#define DB_ELFSIZE 64
-#define ELF_TARG_CLASS  ELFCLASS64
-#else
-#define	ARCH_ELFSIZE 32
-#define DB_ELFSIZE 32
-#define ELF_TARG_CLASS  ELFCLASS32
-#endif
-
-#if defined(__MIPSEB__)
-#define ELF_TARG_DATA		ELFDATA2MSB
-#else
-#define ELF_TARG_DATA		ELFDATA2LSB
-#endif
-#define ELF_TARG_MACH		EM_MIPS
-
-#define _NLIST_DO_ELF
-
-#if defined(_LP64)
-#define _KERN_DO_ELF64
-#if defined(COMPAT_O32)
-#define _KERN_DO_ELF
-#endif
-#else
-#define _KERN_DO_ELF
-#endif
-
-/* Information taken from MIPS ABI supplemental */
-
-/* Architecture dependent Segment types - p_type */
-#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
-
-/* Architecture dependent d_tag field for Elf32_Dyn.  */
-#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime Linker Interface ID */
-#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
-#define DT_MIPS_ICHECKSUM    0x70000003 /* Cksum of ext. str. and com. sizes */
-#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
-#define DT_MIPS_FLAGS        0x70000005 /* Flags */
-#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */
-#define DT_MIPS_CONFLICT     0x70000008 /* Adr of .conflict section */
-#define DT_MIPS_LIBLIST      0x70000009 /* Address of .liblist section */
-#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local .GOT entries */
-#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of .conflict entries */
-#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of .liblist entries */
-#define DT_MIPS_SYMTABNO     0x70000011 /* Number of .dynsym entries */
-#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
-#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in .dynsym */
-#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
-#define DT_MIPS_RLD_MAP      0x70000016 /* Address of debug map pointer */
-
-#define DT_PROCNUM (DT_MIPS_RLD_MAP - DT_LOPROC + 1)
-
-/*
- * Legal values for e_flags field of Elf32_Ehdr.
- */
-#define EF_MIPS_NOREORDER	0x00000001	/* .noreorder was used */
-#define EF_MIPS_PIC		0x00000002	/* Contains PIC code */
-#define EF_MIPS_CPIC		0x00000004	/* Uses PIC calling sequence */
-#define	EF_MIPS_ABI2		0x00000020	/* -n32 on Irix 6 */
-#define	EF_MIPS_32BITMODE	0x00000100	/* 64 bit in 32 bit mode... */
-#define EF_MIPS_ARCH		0xf0000000	/* MIPS architecture level */
-#define	E_MIPS_ARCH_1		0x00000000
-#define	E_MIPS_ARCH_2		0x10000000
-#define	E_MIPS_ARCH_3		0x20000000
-#define	E_MIPS_ARCH_4		0x30000000
-#define	EF_MIPS_ABI		0x0000f000	/* ABI level */
-#define	E_MIPS_ABI_NONE		0x00000000	/* ABI level not set */
-#define	E_MIPS_ABI_O32		0x00001000
-#define	E_MIPS_ABI_O64		0x00002000
-#define	E_MIPS_ABI_EABI32	0x00004000
-#define	E_MIPS_ABI_EABI64	0x00004000
-
-/*
- * Mips special sections.
- */
-#define	SHN_MIPS_ACOMMON	0xff00		/* Allocated common symbols */
-#define	SHN_MIPS_SCOMMON	0xff03		/* Small common symbols */
-#define	SHN_MIPS_SUNDEFINED	0xff04		/* Small undefined symbols */
-
-/*
- * Legal values for sh_type field of Elf32_Shdr.
- */
-#define	SHT_MIPS_LIBLIST  0x70000000	/* Shared objects used in link */
-#define	SHT_MIPS_CONFLICT 0x70000002	/* Conflicting symbols */
-#define	SHT_MIPS_GPTAB    0x70000003	/* Global data area sizes */
-#define	SHT_MIPS_UCODE    0x70000004	/* Reserved for SGI/MIPS compilers */
-#define	SHT_MIPS_DEBUG    0x70000005	/* MIPS ECOFF debugging information */
-#define	SHT_MIPS_REGINFO  0x70000006	/* Register usage information */
-
-/*
- * Legal values for sh_flags field of Elf32_Shdr.
- */
-#define	SHF_MIPS_GPREL	0x10000000	/* Must be part of global data area */
-
-#if 0
-/*
- * Entries found in sections of type SHT_MIPS_GPTAB.
- */
-typedef union {
-	struct {
-		Elf32_Word gt_current_g_value;	/* -G val used in compilation */
-		Elf32_Word gt_unused;	/* Not used */
-	} gt_header;			/* First entry in section */
-	struct {
-		Elf32_Word gt_g_value;	/* If this val were used for -G */
-		Elf32_Word gt_bytes;	/* This many bytes would be used */
-	} gt_entry;			/* Subsequent entries in section */
-} Elf32_gptab;
-
-/*
- * Entry found in sections of type SHT_MIPS_REGINFO.
- */
-typedef struct {
-	Elf32_Word	ri_gprmask;	/* General registers used */
-	Elf32_Word	ri_cprmask[4];	/* Coprocessor registers used */
-	Elf32_Sword	ri_gp_value;	/* $gp register value */
-} Elf32_RegInfo;
-#endif
-
-
-/*
- * Mips relocations.
- */
-
-#define	R_MIPS_NONE	0	/* No reloc */
-#define	R_MIPS_16	1	/* Direct 16 bit */
-#define	R_MIPS_32	2	/* Direct 32 bit */
-#define	R_MIPS_REL32	3	/* PC relative 32 bit */
-#define	R_MIPS_26	4	/* Direct 26 bit shifted */
-#define	R_MIPS_HI16	5	/* High 16 bit */
-#define	R_MIPS_LO16	6	/* Low 16 bit */
-#define	R_MIPS_GPREL16	7	/* GP relative 16 bit */
-#define	R_MIPS_LITERAL	8	/* 16 bit literal entry */
-#define	R_MIPS_GOT16	9	/* 16 bit GOT entry */
-#define	R_MIPS_PC16	10	/* PC relative 16 bit */
-#define	R_MIPS_CALL16	11	/* 16 bit GOT entry for function */
-#define	R_MIPS_GPREL32	12	/* GP relative 32 bit */
-
-#define	R_MIPS_64	18
-
-#define	R_MIPS_REL32_64	((R_MIPS_64 << 8) | R_MIPS_REL32)
-
-
-#endif	/* !_MIPS64_EXEC_H_ */
diff --git a/libc/arch-mips/include/machine/regdef.h b/libc/arch-mips/include/machine/regdef.h
index ae18392..3a7cd68 100644
--- a/libc/arch-mips/include/machine/regdef.h
+++ b/libc/arch-mips/include/machine/regdef.h
@@ -37,6 +37,13 @@
 #ifndef _MIPS_REGDEF_H_
 #define _MIPS_REGDEF_H_
 
+#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64)
+#define __mips_n64 1
+#endif
+#if (_MIPS_SIM == _ABIN32) &&  !defined(__mips_n32)
+#define __mips_n32 1
+#endif
+
 #define zero	$0	/* always zero */
 #define AT	$at	/* assembler temp */
 #define v0	$2	/* return value */
diff --git a/libc/arch-mips/include/machine/regnum.h b/libc/arch-mips/include/machine/regnum.h
deleted file mode 100644
index bfe1280..0000000
--- a/libc/arch-mips/include/machine/regnum.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*	$OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_REGNUM_H_
-#define _MIPS64_REGNUM_H_
-
-/*
- * Location of the saved registers relative to ZERO.
- * Usage is p->p_regs[XX].
- */
-#define ZERO	0
-#define AST	1
-#define V0	2
-#define V1	3
-#define A0	4
-#define A1	5
-#define A2	6
-#define A3	7
-#define T0	8
-#define T1	9
-#define T2	10
-#define T3	11
-#define T4	12
-#define T5	13
-#define T6	14
-#define T7	15
-#define S0	16
-#define S1	17
-#define S2	18
-#define S3	19
-#define S4	20
-#define S5	21
-#define S6	22
-#define S7	23
-#define T8	24
-#define T9	25
-#define K0	26
-#define K1	27
-#define GP	28
-#define SP	29
-#define S8	30
-#define RA	31
-#define	SR	32
-#define	PS	SR	/* alias for SR */
-#define MULLO	33
-#define MULHI	34
-#define BADVADDR 35
-#define CAUSE	36
-#define	PC	37
-#define	IC	38
-#define	CPL	39
-
-#define	NUMSAVEREGS 40		/* Number of registers saved in trap */
-
-#define FPBASE	NUMSAVEREGS
-#define F0	(FPBASE+0)
-#define F1	(FPBASE+1)
-#define F2	(FPBASE+2)
-#define F3	(FPBASE+3)
-#define F4	(FPBASE+4)
-#define F5	(FPBASE+5)
-#define F6	(FPBASE+6)
-#define F7	(FPBASE+7)
-#define F8	(FPBASE+8)
-#define F9	(FPBASE+9)
-#define F10	(FPBASE+10)
-#define F11	(FPBASE+11)
-#define F12	(FPBASE+12)
-#define F13	(FPBASE+13)
-#define F14	(FPBASE+14)
-#define F15	(FPBASE+15)
-#define F16	(FPBASE+16)
-#define F17	(FPBASE+17)
-#define F18	(FPBASE+18)
-#define F19	(FPBASE+19)
-#define F20	(FPBASE+20)
-#define F21	(FPBASE+21)
-#define F22	(FPBASE+22)
-#define F23	(FPBASE+23)
-#define F24	(FPBASE+24)
-#define F25	(FPBASE+25)
-#define F26	(FPBASE+26)
-#define F27	(FPBASE+27)
-#define F28	(FPBASE+28)
-#define F29	(FPBASE+29)
-#define F30	(FPBASE+30)
-#define F31	(FPBASE+31)
-#define	FSR	(FPBASE+32)
-
-#define	NUMFPREGS 33
-
-#define	NREGS	(NUMSAVEREGS + NUMFPREGS)
-
-#endif /* !_MIPS64_REGNUM_H_ */
diff --git a/libc/arch-mips/include/machine/setjmp.h b/libc/arch-mips/include/machine/setjmp.h
index 55ba7be..a9707dc 100644
--- a/libc/arch-mips/include/machine/setjmp.h
+++ b/libc/arch-mips/include/machine/setjmp.h
@@ -5,6 +5,10 @@
 #ifndef _MIPS_SETJMP_H_
 #define _MIPS_SETJMP_H_
 
-#define	_JBLEN	157		/* size, in longs, of a jmp_buf */
+#ifdef __LP64__
+#define	_JBLEN	22		/* size, in 8-byte longs, of a mips64 jmp_buf */
+#else
+#define	_JBLEN	29		/* size, in 4-byte longs, of a mips32 jmp_buf */
+#endif
 
 #endif /* !_MIPS_SETJMP_H_ */
diff --git a/libc/arch-mips/include/machine/signal.h b/libc/arch-mips/include/machine/signal.h
deleted file mode 100644
index b31715c..0000000
--- a/libc/arch-mips/include/machine/signal.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*	$OpenBSD: signal.h,v 1.8 2006/01/09 18:18:37 millert Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)signal.h	8.1 (Berkeley) 6/10/93
- */
-
-#ifndef _MIPS_SIGNAL_H_
-#define _MIPS_SIGNAL_H_
-
-#define	SC_REGMASK	(0*REGSZ)
-#define	SC_STATUS	(1*REGSZ)
-#define	SC_PC		(2*REGSZ)
-#define	SC_REGS		(SC_PC+8)
-#define	SC_FPREGS	(SC_REGS+32*8)
-#define	SC_ACX		(SC_FPREGS+32*REGSZ_FP)
-#define	SC_USED_MATH	(SC_ACX+3*REGSZ)
-/* OpenBSD compatibility */
-#define	SC_MASK		SC_REGMASK
-#define	SC_FPUSED	SC_USED_MATH
-
-#endif	/* !_MIPS_SIGNAL_H_ */
diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk
index ac75a4b..d558baa 100644
--- a/libc/arch-mips/mips.mk
+++ b/libc/arch-mips/mips.mk
@@ -67,9 +67,7 @@
     arch-mips/bionic/bzero.S \
     arch-mips/bionic/cacheflush.cpp \
     arch-mips/bionic/_exit_with_stack_teardown.S \
-    arch-mips/bionic/_setjmp.S \
     arch-mips/bionic/setjmp.S \
-    arch-mips/bionic/sigsetjmp.S \
     arch-mips/bionic/syscall.S \
     arch-mips/bionic/vfork.S \
 
diff --git a/libc/arch-mips64/bionic/_setjmp.S b/libc/arch-mips64/bionic/_setjmp.S
deleted file mode 100644
index d237e6d..0000000
--- a/libc/arch-mips64/bionic/_setjmp.S
+++ /dev/null
@@ -1,150 +0,0 @@
-/*	$OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */
-
-/*
- * Copyright (c) 2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opsycon AB nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/signal.h>
-
-/*
- * _setjmp, _longjmp (not restoring signal state)
- *
- * XXX FPSET should probably be taken from SR setting. hmmm...
- *  GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp!
- *
- */
-
-FRAMESZ= MKFSIZ(0,4)
-GPOFF= FRAMESZ-2*REGSZ
-
-LEAF(_setjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, _setjmp)
-	SAVE_GP(GPOFF)
-	.set	noreorder
-#if defined(__mips64)
-	dli	v0, 0xACEDBADE			# sigcontext magic number
-#else
-	li	v0, 0xACEDBADE			# sigcontext magic number
-#endif
-	REG_S	v0, SC_REGS+ZERO*REGSZ(a0)
-	REG_S	s0, SC_REGS+S0*REGSZ(a0)
-	REG_S	s1, SC_REGS+S1*REGSZ(a0)
-	REG_S	s2, SC_REGS+S2*REGSZ(a0)
-	REG_S	s3, SC_REGS+S3*REGSZ(a0)
-	REG_S	s4, SC_REGS+S4*REGSZ(a0)
-	REG_S	s5, SC_REGS+S5*REGSZ(a0)
-	REG_S	s6, SC_REGS+S6*REGSZ(a0)
-	REG_S	s7, SC_REGS+S7*REGSZ(a0)
-	REG_S	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	v0, GPOFF(sp)
-	REG_S	v0, SC_REGS+GP*REGSZ(a0)
-	PTR_ADDU v0, sp, FRAMESZ
-	REG_S	v0, SC_REGS+SP*REGSZ(a0)
-	REG_S	ra, SC_PC(a0)
-
-#if !defined(SOFTFLOAT)
-	li	v0, 1				# be nice if we could tell
-	REG_S	v0, SC_FPUSED(a0)		# sc_fpused = 1
-	cfc1	v0, $31
-	s.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	s.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	s.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	s.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	s.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	s.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	s.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	s.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	s.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	s.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	s.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	s.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-	REG_S	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-#endif /* !SOFTFLOAT */
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	ra
-	 move	v0, zero
-END(_setjmp)
-
-LEAF(_longjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, _longjmp)
-	SAVE_GP(GPOFF)
-	.set    noreorder
-	REG_L	v0, SC_REGS+ZERO*REGSZ(a0)
-	bne	v0, 0xACEDBADE, botch		# jump if error
-	REG_L	ra, SC_PC(a0)
-	REG_L	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-	REG_L	s0, SC_REGS+S0*REGSZ(a0)
-	REG_L	s1, SC_REGS+S1*REGSZ(a0)
-	REG_L	s2, SC_REGS+S2*REGSZ(a0)
-	REG_L	s3, SC_REGS+S3*REGSZ(a0)
-	REG_L	s4, SC_REGS+S4*REGSZ(a0)
-	REG_L	s5, SC_REGS+S5*REGSZ(a0)
-	REG_L	s6, SC_REGS+S6*REGSZ(a0)
-	REG_L	s7, SC_REGS+S7*REGSZ(a0)
-	REG_L	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	gp, SC_REGS+GP*REGSZ(a0)
-	REG_L	sp, SC_REGS+SP*REGSZ(a0)
-#if !defined(SOFTFLOAT)
-	ctc1	v0, $31
-	l.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	l.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	l.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	l.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	l.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	l.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	l.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	l.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	l.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	l.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	l.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	l.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-#endif /* !SOFTFLOAT */
-	bne	a1, zero, 1f
-	 nop
-	li	a1, 1			# never return 0!
-1:
-	j	ra
-	 move	v0, a1
-
-botch:
-	jal	longjmperror
-	nop
-	jal	abort
-	nop
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-END(_longjmp)
diff --git a/libc/arch-mips64/bionic/setjmp.S b/libc/arch-mips64/bionic/setjmp.S
deleted file mode 100644
index 31786be..0000000
--- a/libc/arch-mips64/bionic/setjmp.S
+++ /dev/null
@@ -1,174 +0,0 @@
-/*      $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Opsycon AB nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/signal.h>
-
-/*
- * setjmp, longjmp implementation for libc. this code depends
- * on the layout of the struct sigcontext in machine/signal.h.
- *
- */
-
-FRAMESZ= MKFSIZ(2,6)
-A1OFF= FRAMESZ-4*REGSZ
-A0OFF= FRAMESZ-3*REGSZ
-GPOFF= FRAMESZ-2*REGSZ
-RAOFF= FRAMESZ-1*REGSZ
-
-NON_LEAF(setjmp, FRAMESZ, ra)
-	.mask	0x80000000, RAOFF
-	PTR_SUBU sp, FRAMESZ			# allocate stack frame
-	SETUP_GP64(GPOFF, setjmp)
-	SAVE_GP(GPOFF)
-	.set	reorder
-	REG_S	ra, RAOFF(sp)			# save state
-	REG_S	a0, A0OFF(sp)
-
-	move	a0, zero			# get current signal mask
-	jal	sigblock
-
-	REG_L	v1, A0OFF(sp)			# v1 = jmpbuf
-	REG_S	v0, SC_MASK(v1)			# save sc_mask = sigblock(0)
-
-	REG_L	a0, A0OFF(sp)			# restore jmpbuf
-	REG_L	ra, RAOFF(sp)
-	REG_S	ra, SC_PC(a0)			# sc_pc = return address
-#if defined(__mips64)
-	dli	v0, 0xACEDBADE			# sigcontext magic number
-#else
-	li	v0, 0xACEDBADE			# sigcontext magic number
-#endif
-	REG_S	v0, SC_REGS+ZERO*REGSZ(a0)
-	REG_S	s0, SC_REGS+S0*REGSZ(a0)
-	REG_S	s1, SC_REGS+S1*REGSZ(a0)
-	REG_S	s2, SC_REGS+S2*REGSZ(a0)
-	REG_S	s3, SC_REGS+S3*REGSZ(a0)
-	REG_S	s4, SC_REGS+S4*REGSZ(a0)
-	REG_S	s5, SC_REGS+S5*REGSZ(a0)
-	REG_S	s6, SC_REGS+S6*REGSZ(a0)
-	REG_S	s7, SC_REGS+S7*REGSZ(a0)
-	REG_S	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	v0, GPOFF(sp)
-	REG_S	v0, SC_REGS+GP*REGSZ(a0)
-	PTR_ADDU v0, sp, FRAMESZ
-	REG_S	v0, SC_REGS+SP*REGSZ(a0)
-
-#if !defined(SOFTFLOAT)
-	li	v0, 1				# be nice if we could tell
-	REG_S	v0, SC_FPUSED(a0)		# sc_fpused = 1
-	cfc1	v0, $31
-	s.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	s.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	s.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	s.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	s.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	s.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	s.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	s.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	s.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	s.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	s.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	s.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-	REG_S	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-#endif /* !SOFTFLOAT */
-	move	v0, zero
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	j	ra
-
-botch:
-	jal	longjmperror
-	jal	abort
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-END(setjmp)
-
-
-LEAF(longjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, longjmp)
-	SAVE_GP(GPOFF)
-	.set	reorder
-	sw	a1, A1OFF(sp)
-	sw	a0, A0OFF(sp)
-
-	lw	a0, SC_MASK(a0)
-	jal	sigsetmask
-
-	lw	a0, A0OFF(sp)
-	lw	a1, A1OFF(sp)
-
-	.set	noreorder
-	REG_L	v0, SC_REGS+ZERO*REGSZ(a0)
-	bne	v0, 0xACEDBADE, botch		# jump if error
-	REG_L	ra, SC_PC(a0)
-	REG_L	s0, SC_REGS+S0*REGSZ(a0)
-	REG_L	s1, SC_REGS+S1*REGSZ(a0)
-	REG_L	s2, SC_REGS+S2*REGSZ(a0)
-	REG_L	s3, SC_REGS+S3*REGSZ(a0)
-	REG_L	s4, SC_REGS+S4*REGSZ(a0)
-	REG_L	s5, SC_REGS+S5*REGSZ(a0)
-	REG_L	s6, SC_REGS+S6*REGSZ(a0)
-	REG_L	s7, SC_REGS+S7*REGSZ(a0)
-	REG_L	s8, SC_REGS+S8*REGSZ(a0)
-	REG_L	gp, SC_REGS+GP*REGSZ(a0)
-	REG_L	sp, SC_REGS+SP*REGSZ(a0)
-
-#if !defined(SOFTFLOAT)
-	REG_L	v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
-	ctc1	v0, $31
-	l.d	$f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
-	l.d	$f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
-	l.d	$f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
-	l.d	$f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
-	l.d	$f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
-	l.d	$f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
-#if _MIPS_FPSET == 32
-	l.d	$f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
-	l.d	$f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
-	l.d	$f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
-	l.d	$f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
-	l.d	$f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
-	l.d	$f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
-#endif
-#endif /* !SOFTFLOAT */
-	bne	a1, zero, 1f
-	 nop
-	li	a1, 1			# never return 0!
-1:
-	j	ra
-	 move	v0, a1
-
-END(longjmp)
diff --git a/libc/arch-mips64/bionic/setjmp.S b/libc/arch-mips64/bionic/setjmp.S
new file mode 120000
index 0000000..b117bb6
--- /dev/null
+++ b/libc/arch-mips64/bionic/setjmp.S
@@ -0,0 +1 @@
+../../arch-mips/bionic/setjmp.S
\ No newline at end of file
diff --git a/libc/arch-mips64/bionic/sigsetjmp.S b/libc/arch-mips64/bionic/sigsetjmp.S
deleted file mode 100644
index 9d2e5ea..0000000
--- a/libc/arch-mips64/bionic/sigsetjmp.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenBSD: sigsetjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */
-/*-
- * Copyright (c) 1991, 1993, 1995,
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Havard Eidnes.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/regnum.h>
-#include <machine/setjmp.h>
-
-/*
- * trampolines for sigsetjmp and  siglongjmp save and restore mask.
- *
- */
-FRAMESZ= MKFSIZ(1,1)
-GPOFF= FRAMESZ-2*REGSZ
-
-LEAF(sigsetjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, sigsetjmp)
-	.set	reorder
-	REG_S	a1, (_JBLEN*REGSZ)(a0)		# save "savemask"
-	bne	a1, 0x0, 1f			# do saving of signal mask?
-	LA	t9, _setjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr t9
-
-1:	LA	t9, setjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr t9
-END(sigsetjmp)
-
-LEAF(siglongjmp, FRAMESZ)
-	PTR_SUBU sp, FRAMESZ
-	SETUP_GP64(GPOFF, siglongjmp)
-	.set	reorder
-	REG_L	t0, (_JBLEN*REGSZ)(a0)		# get "savemask"
-	bne	t0, 0x0, 1f			# restore signal mask?
-	LA	t9, _longjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr	t9
-1:
-	LA	t9, longjmp
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	jr	t9
-END(siglongjmp)
diff --git a/libc/arch-mips64/include/machine b/libc/arch-mips64/include/machine
new file mode 120000
index 0000000..36466ee
--- /dev/null
+++ b/libc/arch-mips64/include/machine
@@ -0,0 +1 @@
+../../arch-mips/include/machine
\ No newline at end of file
diff --git a/libc/arch-mips64/include/machine/asm.h b/libc/arch-mips64/include/machine/asm.h
deleted file mode 100644
index cdc7914..0000000
--- a/libc/arch-mips64/include/machine/asm.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*	$OpenBSD: asm.h,v 1.7 2004/10/20 12:49:15 pefo Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-#ifndef _MIPS64_ASM_H
-#define _MIPS64_ASM_H
-
-#define __bionic_asm_align 4
-
-#undef __bionic_asm_custom_entry
-#undef __bionic_asm_custom_end
-#define __bionic_asm_custom_entry(f) .ent f
-#define __bionic_asm_custom_end(f) .end f
-
-#include <machine/regdef.h>
-
-#define	_MIPS_ISA_MIPS1	1	/* R2000/R3000 */
-#define	_MIPS_ISA_MIPS2	2	/* R4000/R6000 */
-#define	_MIPS_ISA_MIPS3	3	/* R4000 */
-#define	_MIPS_ISA_MIPS4	4	/* TFP (R1x000) */
-#define	_MIPS_ISA_MIPS5 5
-#define	_MIPS_ISA_MIPS32 6
-#define	_MIPS_ISA_MIPS64 7
-
-#if !defined(ABICALLS) && !defined(_NO_ABICALLS)
-#define	ABICALLS	.abicalls
-#endif
-
-#if defined(ABICALLS) && !defined(_KERNEL)
-	ABICALLS
-#endif
-
-#if !defined(__MIPSEL__) && !defined(__MIPSEB__)
-#error "__MIPSEL__ or __MIPSEB__ must be defined"
-#endif
-/*
- * Define how to access unaligned data word
- */
-#if defined(__MIPSEL__)
-#define LWLO    lwl
-#define LWHI    lwr
-#define	SWLO	swl
-#define	SWHI	swr
-#define LDLO    ldl
-#define LDHI    ldr
-#define	SDLO	sdl
-#define	SDHI	sdr
-#endif
-#if defined(__MIPSEB__)
-#define LWLO    lwr
-#define LWHI    lwl
-#define	SWLO	swr
-#define	SWHI	swl
-#define LDLO    ldr
-#define LDHI    ldl
-#define	SDLO	sdr
-#define	SDHI	sdl
-#endif
-
-/*
- *  Define programming environment for ABI.
- */
-#if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
-
-#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
-#define NARGSAVE	4
-
-#define	SETUP_GP		\
-	.set	noreorder;	\
-	.cpload	t9;		\
-	.set	reorder;
-
-#define	SAVE_GP(x)		\
-	.cprestore x
-
-#define	SETUP_GP64(gpoff, name)
-#define	RESTORE_GP64
-#endif
-
-#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
-#define NARGSAVE	0
-
-#define	SETUP_GP
-#define	SAVE_GP(x)
-#define	SETUP_GP64(gpoff, name)	\
-	.cpsetup t9, gpoff, name
-#define	RESTORE_GP64		\
-	.cpreturn
-#endif
-
-#define	MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
-
-#else /* defined(ABICALLS) && !defined(_KERNEL) */
-
-#define	NARGSAVE	4
-#define	SETUP_GP
-#define	SAVE_GP(x)
-
-#define	ALIGNSZ		16	/* Stack layout alignment */
-#define	FRAMESZ(sz)	(((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
-
-#endif
-
-/*
- *  Basic register operations based on selected ISA
- */
-#if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || _MIPS_ISA == _MIPS_ISA_MIPS32)
-#define REGSZ		4	/* 32 bit mode register size */
-#define LOGREGSZ	2	/* log rsize */
-#define	REG_S	sw
-#define	REG_L	lw
-#define	CF_SZ		24	/* Call frame size */
-#define	CF_ARGSZ	16	/* Call frame arg size */
-#define	CF_RA_OFFS	20	/* Call ra save offset */
-#endif
-
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || _MIPS_ISA == _MIPS_ISA_MIPS64)
-#define REGSZ		8	/* 64 bit mode register size */
-#define LOGREGSZ	3	/* log rsize */
-#define	REG_S	sd
-#define	REG_L	ld
-#define	CF_SZ		48	/* Call frame size (multiple of ALIGNSZ) */
-#define	CF_ARGSZ	32	/* Call frame arg size */
-#define	CF_RA_OFFS	40	/* Call ra save offset */
-#endif
-
-#define REGSZ_FP	 8	/* 64 bit FP register size */
-
-#ifndef __LP64__
-#define	PTR_L		lw
-#define	PTR_S		sw
-#define	PTR_SUB		sub
-#define	PTR_ADD		add
-#define	PTR_SUBU	subu
-#define	PTR_ADDU	addu
-#define LI		li
-#define	LA		la
-#define	PTR_SLL		sll
-#define	PTR_SRL		srl
-#define	PTR_VAL		.word
-#else
-#define	PTR_L		ld
-#define	PTR_S		sd
-#define	PTR_ADD		dadd
-#define	PTR_SUB		dsub
-#define	PTR_SUBU	dsubu
-#define	PTR_ADDU	daddu
-#define LI		dli
-#define LA		dla
-#define	PTR_SLL		dsll
-#define	PTR_SRL		dsrl
-#define	PTR_VAL		.dword
-#endif
-
-/*
- * LEAF(x, fsize)
- *
- *	Declare a leaf routine.
- */
-#define LEAF(x, fsize)		\
-	.align	3;		\
-	.globl x;		\
-	.ent x, 0;		\
-x: ;				\
-	.cfi_startproc; \
-	.frame sp, fsize, ra;	\
-	SETUP_GP		\
-
-/*
- * NON_LEAF(x)
- *
- *	Declare a non-leaf routine (a routine that makes other C calls).
- */
-#define NON_LEAF(x, fsize, retpc) \
-	.align	3;		\
-	.globl x;		\
-	.ent x, 0;		\
-x: ;				\
-	.cfi_startproc; \
-	.frame sp, fsize, retpc; \
-	SETUP_GP		\
-
-#endif /* !_MIPS_ASM_H */
diff --git a/libc/arch-mips64/include/machine/elf_machdep.h b/libc/arch-mips64/include/machine/elf_machdep.h
deleted file mode 100644
index d27d431..0000000
--- a/libc/arch-mips64/include/machine/elf_machdep.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*	$NetBSD: elf_machdep.h,v 1.15 2011/03/15 07:39:22 matt Exp $	*/
-
-#ifndef _MIPS_ELF_MACHDEP_H_
-#define  _MIPS_ELF_MACHDEP_H_
-
-#ifdef _LP64
-#define ARCH_ELFSIZE		64	/* MD native binary size */
-#else
-#define ARCH_ELFSIZE		32	/* MD native binary size */
-#endif
-
-#if ELFSIZE == 32
-#define	ELF32_MACHDEP_ID_CASES						\
-		case EM_MIPS:						\
-			break;
-
-#define	ELF32_MACHDEP_ID	EM_MIPS
-#elif ELFSIZE == 64
-#define	ELF64_MACHDEP_ID_CASES						\
-		case EM_MIPS:						\
-			break;
-
-#define	ELF64_MACHDEP_ID	EM_MIPS
-#endif
-
-/* mips relocs.  */
-
-#define R_MIPS_NONE		0
-#define R_MIPS_16		1
-#define R_MIPS_32		2
-#define R_MIPS_REL32		3
-#define R_MIPS_REL		R_MIPS_REL32
-#define R_MIPS_26		4
-#define R_MIPS_HI16		5	/* high 16 bits of symbol value */
-#define R_MIPS_LO16		6	/* low 16 bits of symbol value */
-#define R_MIPS_GPREL16		7  	/* GP-relative reference  */
-#define R_MIPS_LITERAL		8 	/* Reference to literal section  */
-#define R_MIPS_GOT16		9	/* Reference to global offset table */
-#define R_MIPS_GOT		R_MIPS_GOT16
-#define R_MIPS_PC16		10  	/* 16 bit PC relative reference */
-#define R_MIPS_CALL16 		11  	/* 16 bit call thru glbl offset tbl */
-#define R_MIPS_CALL		R_MIPS_CALL16
-#define R_MIPS_GPREL32		12
-
-/* 13, 14, 15 are not defined at this point. */
-#define R_MIPS_UNUSED1		13
-#define R_MIPS_UNUSED2		14
-#define R_MIPS_UNUSED3		15
-
-/*
- * The remaining relocs are apparently part of the 64-bit Irix ELF ABI.
- */
-#define R_MIPS_SHIFT5		16
-#define R_MIPS_SHIFT6		17
-
-#define R_MIPS_64		18
-#define R_MIPS_GOT_DISP		19
-#define R_MIPS_GOT_PAGE		20
-#define R_MIPS_GOT_OFST		21
-#define R_MIPS_GOT_HI16		22
-#define R_MIPS_GOT_LO16		23
-#define R_MIPS_SUB 		24
-#define R_MIPS_INSERT_A		25
-#define R_MIPS_INSERT_B		26
-#define R_MIPS_DELETE		27
-#define R_MIPS_HIGHER		28
-#define R_MIPS_HIGHEST		29
-#define R_MIPS_CALL_HI16	30
-#define R_MIPS_CALL_LO16	31
-#define R_MIPS_SCN_DISP		32
-#define R_MIPS_REL16		33
-#define R_MIPS_ADD_IMMEDIATE	34
-#define R_MIPS_PJUMP		35
-#define R_MIPS_RELGOT		36
-#define	R_MIPS_JALR		37
-/* TLS relocations */
-
-#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
-#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
-#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
-#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
-#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
-#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
-#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
-#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
-#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
-#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
-#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
-#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
-#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
-
-#define R_MIPS_max		51
-
-#define R_TYPE(name)		__CONCAT(R_MIPS_,name)
-
-#define	R_MIPS16_min		100
-#define	R_MIPS16_26		100
-#define	R_MIPS16_GPREL		101
-#define	R_MIPS16_GOT16		102
-#define	R_MIPS16_CALL16		103
-#define	R_MIPS16_HI16		104
-#define	R_MIPS16_LO16		105
-#define	R_MIPS16_max		106
-
-
-/* mips dynamic tags */
-
-#define DT_MIPS_RLD_VERSION	0x70000001
-#define DT_MIPS_TIME_STAMP	0x70000002
-#define DT_MIPS_ICHECKSUM	0x70000003
-#define DT_MIPS_IVERSION	0x70000004
-#define DT_MIPS_FLAGS		0x70000005
-#define DT_MIPS_BASE_ADDRESS	0x70000006
-#define DT_MIPS_CONFLICT	0x70000008
-#define DT_MIPS_LIBLIST		0x70000009
-#define DT_MIPS_CONFLICTNO	0x7000000b
-#define	DT_MIPS_LOCAL_GOTNO	0x7000000a	/* number of local got ents */
-#define DT_MIPS_LIBLISTNO	0x70000010
-#define	DT_MIPS_SYMTABNO	0x70000011	/* number of .dynsym entries */
-#define DT_MIPS_UNREFEXTNO	0x70000012
-#define	DT_MIPS_GOTSYM		0x70000013	/* first dynamic sym in got */
-#define DT_MIPS_HIPAGENO	0x70000014
-#define	DT_MIPS_RLD_MAP		0x70000016	/* address of loader map */
-
-/*
- * ELF Flags
- */
-#define	EF_MIPS_PIC		0x00000002	/* Contains PIC code */
-#define	EF_MIPS_CPIC		0x00000004	/* STD PIC calling sequence */
-#define	EF_MIPS_ABI2		0x00000020	/* N32 */
-
-#define	EF_MIPS_ARCH_ASE	0x0f000000	/* Architectural extensions */
-#define	EF_MIPS_ARCH_MDMX	0x08000000	/* MDMX multimedia extension */
-#define	EF_MIPS_ARCH_M16	0x04000000	/* MIPS-16 ISA extensions */
-
-#define	EF_MIPS_ARCH		0xf0000000	/* Architecture field */
-#define	EF_MIPS_ARCH_1		0x00000000	/* -mips1 code */
-#define	EF_MIPS_ARCH_2		0x10000000	/* -mips2 code */
-#define	EF_MIPS_ARCH_3		0x20000000	/* -mips3 code */
-#define	EF_MIPS_ARCH_4		0x30000000	/* -mips4 code */
-#define	EF_MIPS_ARCH_5		0x40000000	/* -mips5 code */
-#define	EF_MIPS_ARCH_32		0x50000000	/* -mips32 code */
-#define	EF_MIPS_ARCH_64		0x60000000	/* -mips64 code */
-#define	EF_MIPS_ARCH_32R2	0x70000000	/* -mips32r2 code */
-#define	EF_MIPS_ARCH_64R2	0x80000000	/* -mips64r2 code */
-
-#define	EF_MIPS_ABI		0x0000f000
-#define	EF_MIPS_ABI_O32		0x00001000
-#define	EF_MIPS_ABI_O64		0x00002000
-#define	EF_MIPS_ABI_EABI32	0x00003000
-#define	EF_MIPS_ABI_EABI64	0x00004000
-
-#if defined(__MIPSEB__)
-#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2MSB
-#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2MSB
-#elif defined(__MIPSEL__)
-#define	ELF32_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#define	ELF64_MACHDEP_ENDIANNESS	ELFDATA2LSB
-#elif !defined(HAVE_NBTOOL_CONFIG_H)
-#error neither __MIPSEL__ nor __MIPSEB__ are defined.
-#endif
-
-#ifdef _KERNEL
-#ifdef _KERNEL_OPT
-#include "opt_compat_netbsd.h"
-#endif
-#ifdef COMPAT_16
-/*
- * Up to 1.6, the ELF dynamic loader (ld.elf_so) was not relocatable.
- * Tell the kernel ELF exec code not to try relocating the interpreter
- * for dynamically-linked ELF binaries.
- */
-#define ELF_INTERP_NON_RELOCATABLE
-#endif /* COMPAT_16 */
-
-/*
- * We need to be able to include the ELF header so we can pick out the
- * ABI being used.
- */
-#ifdef ELFSIZE
-#define	ELF_MD_PROBE_FUNC	ELFNAME2(mips_netbsd,probe)
-#define	ELF_MD_COREDUMP_SETUP	ELFNAME2(coredump,setup)
-#endif
-
-struct exec_package;
-
-int mips_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *, char *,
-	vaddr_t *);
-void coredump_elf32_setup(struct lwp *, void *);
-
-int mips_netbsd_elf64_probe(struct lwp *, struct exec_package *, void *, char *,
-	vaddr_t *);
-void coredump_elf64_setup(struct lwp *, void *);
-#endif /* _KERNEL */
-
-#endif /* _MIPS_ELF_MACHDEP_H_ */
diff --git a/libc/arch-mips64/include/machine/endian.h b/libc/arch-mips64/include/machine/endian.h
deleted file mode 100644
index 9270e9d..0000000
--- a/libc/arch-mips64/include/machine/endian.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*	$OpenBSD: endian.h,v 1.5 2006/02/27 23:35:59 miod Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_ENDIAN_H_
-#define _MIPS64_ENDIAN_H_
-
-#ifdef __GNUC__
-
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-#define __swap16md(x) ({					\
-    register uint16_t _x = (x);					\
-    register uint16_t _r;					\
-    __asm volatile ("wsbh %0, %1" : "=r" (_r) : "r" (_x));	\
-    _r;								\
-})
-
-#define __swap32md(x) ({					\
-    register uint32_t _x = (x);					\
-    register uint32_t _r;					\
-    __asm volatile ("wsbh %0, %1; rotr %0, %0, 16" : "=r" (_r) : "r" (_x)); \
-    _r;								\
-})
-
-#define __swap64md(x) ({					\
-    uint64_t _swap64md_x = (x);					\
-    (uint64_t) __swap32md(_swap64md_x >> 32) |			\
-        (uint64_t) __swap32md(_swap64md_x & 0xffffffff) << 32;	\
-})
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif  /* __mips32r2__ */
-#endif  /* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#define __STRICT_ALIGNMENT
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif /* _MIPS64_ENDIAN_H_ */
diff --git a/libc/arch-mips64/include/machine/exec.h b/libc/arch-mips64/include/machine/exec.h
deleted file mode 100644
index 3c63f74..0000000
--- a/libc/arch-mips64/include/machine/exec.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.1 2004/10/18 19:05:36 grange Exp $	*/
-
-/*
- * Copyright (c) 1996-2004 Per Fogelstrom, Opsycon AB
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_EXEC_H_
-#define _MIPS64_EXEC_H_
-
-#define	__LDPGSZ	4096
-
-/*
- *  Define what exec "formats" we should handle.
- */
-#define NATIVE_EXEC_ELF
-#define NATIVE_ELFSIZE 64
-#define	EXEC_SCRIPT
-
-/*
- *  If included from sys/exec.h define kernels ELF format.
- */
-#ifdef __LP64__
-#define	ARCH_ELFSIZE 64
-#define DB_ELFSIZE 64
-#define ELF_TARG_CLASS  ELFCLASS64
-#else
-#define	ARCH_ELFSIZE 32
-#define DB_ELFSIZE 32
-#define ELF_TARG_CLASS  ELFCLASS32
-#endif
-
-#if defined(__MIPSEB__)
-#define ELF_TARG_DATA		ELFDATA2MSB
-#else
-#define ELF_TARG_DATA		ELFDATA2LSB
-#endif
-#define ELF_TARG_MACH		EM_MIPS
-
-#define _NLIST_DO_ELF
-
-#if defined(_LP64)
-#define _KERN_DO_ELF64
-#if defined(COMPAT_O32)
-#define _KERN_DO_ELF
-#endif
-#else
-#define _KERN_DO_ELF
-#endif
-
-/* Information taken from MIPS ABI supplemental */
-
-/* Architecture dependent Segment types - p_type */
-#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
-
-/* Architecture dependent d_tag field for Elf32_Dyn.  */
-#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime Linker Interface ID */
-#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
-#define DT_MIPS_ICHECKSUM    0x70000003 /* Cksum of ext. str. and com. sizes */
-#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
-#define DT_MIPS_FLAGS        0x70000005 /* Flags */
-#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Segment base address */
-#define DT_MIPS_CONFLICT     0x70000008 /* Adr of .conflict section */
-#define DT_MIPS_LIBLIST      0x70000009 /* Address of .liblist section */
-#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local .GOT entries */
-#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of .conflict entries */
-#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of .liblist entries */
-#define DT_MIPS_SYMTABNO     0x70000011 /* Number of .dynsym entries */
-#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
-#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in .dynsym */
-#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
-#define DT_MIPS_RLD_MAP      0x70000016 /* Address of debug map pointer */
-
-#define DT_PROCNUM (DT_MIPS_RLD_MAP - DT_LOPROC + 1)
-
-/*
- * Legal values for e_flags field of Elf32_Ehdr.
- */
-#define EF_MIPS_NOREORDER	0x00000001	/* .noreorder was used */
-#define EF_MIPS_PIC		0x00000002	/* Contains PIC code */
-#define EF_MIPS_CPIC		0x00000004	/* Uses PIC calling sequence */
-#define	EF_MIPS_ABI2		0x00000020	/* -n32 on Irix 6 */
-#define	EF_MIPS_32BITMODE	0x00000100	/* 64 bit in 32 bit mode... */
-#define EF_MIPS_ARCH		0xf0000000	/* MIPS architecture level */
-#define	E_MIPS_ARCH_1		0x00000000
-#define	E_MIPS_ARCH_2		0x10000000
-#define	E_MIPS_ARCH_3		0x20000000
-#define	E_MIPS_ARCH_4		0x30000000
-#define	EF_MIPS_ABI		0x0000f000	/* ABI level */
-#define	E_MIPS_ABI_NONE		0x00000000	/* ABI level not set */
-#define	E_MIPS_ABI_O32		0x00001000
-#define	E_MIPS_ABI_O64		0x00002000
-#define	E_MIPS_ABI_EABI32	0x00004000
-#define	E_MIPS_ABI_EABI64	0x00004000
-
-/*
- * Mips special sections.
- */
-#define	SHN_MIPS_ACOMMON	0xff00		/* Allocated common symbols */
-#define	SHN_MIPS_SCOMMON	0xff03		/* Small common symbols */
-#define	SHN_MIPS_SUNDEFINED	0xff04		/* Small undefined symbols */
-
-/*
- * Legal values for sh_type field of Elf32_Shdr.
- */
-#define	SHT_MIPS_LIBLIST  0x70000000	/* Shared objects used in link */
-#define	SHT_MIPS_CONFLICT 0x70000002	/* Conflicting symbols */
-#define	SHT_MIPS_GPTAB    0x70000003	/* Global data area sizes */
-#define	SHT_MIPS_UCODE    0x70000004	/* Reserved for SGI/MIPS compilers */
-#define	SHT_MIPS_DEBUG    0x70000005	/* MIPS ECOFF debugging information */
-#define	SHT_MIPS_REGINFO  0x70000006	/* Register usage information */
-
-/*
- * Legal values for sh_flags field of Elf32_Shdr.
- */
-#define	SHF_MIPS_GPREL	0x10000000	/* Must be part of global data area */
-
-#if 0
-/*
- * Entries found in sections of type SHT_MIPS_GPTAB.
- */
-typedef union {
-	struct {
-		Elf32_Word gt_current_g_value;	/* -G val used in compilation */
-		Elf32_Word gt_unused;	/* Not used */
-	} gt_header;			/* First entry in section */
-	struct {
-		Elf32_Word gt_g_value;	/* If this val were used for -G */
-		Elf32_Word gt_bytes;	/* This many bytes would be used */
-	} gt_entry;			/* Subsequent entries in section */
-} Elf32_gptab;
-
-/*
- * Entry found in sections of type SHT_MIPS_REGINFO.
- */
-typedef struct {
-	Elf32_Word	ri_gprmask;	/* General registers used */
-	Elf32_Word	ri_cprmask[4];	/* Coprocessor registers used */
-	Elf32_Sword	ri_gp_value;	/* $gp register value */
-} Elf32_RegInfo;
-#endif
-
-
-/*
- * Mips relocations.
- */
-
-#define	R_MIPS_NONE	0	/* No reloc */
-#define	R_MIPS_16	1	/* Direct 16 bit */
-#define	R_MIPS_32	2	/* Direct 32 bit */
-#define	R_MIPS_REL32	3	/* PC relative 32 bit */
-#define	R_MIPS_26	4	/* Direct 26 bit shifted */
-#define	R_MIPS_HI16	5	/* High 16 bit */
-#define	R_MIPS_LO16	6	/* Low 16 bit */
-#define	R_MIPS_GPREL16	7	/* GP relative 16 bit */
-#define	R_MIPS_LITERAL	8	/* 16 bit literal entry */
-#define	R_MIPS_GOT16	9	/* 16 bit GOT entry */
-#define	R_MIPS_PC16	10	/* PC relative 16 bit */
-#define	R_MIPS_CALL16	11	/* 16 bit GOT entry for function */
-#define	R_MIPS_GPREL32	12	/* GP relative 32 bit */
-
-#define	R_MIPS_64	18
-
-#define	R_MIPS_REL32_64	((R_MIPS_64 << 8) | R_MIPS_REL32)
-
-
-#endif	/* !_MIPS64_EXEC_H_ */
diff --git a/libc/arch-mips64/include/machine/regdef.h b/libc/arch-mips64/include/machine/regdef.h
deleted file mode 100644
index 3a7cd68..0000000
--- a/libc/arch-mips64/include/machine/regdef.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*	$OpenBSD: regdef.h,v 1.3 2005/08/07 07:29:44 miod Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell. This file is derived from the MIPS RISC
- * Architecture book by Gerry Kane.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)regdef.h	8.1 (Berkeley) 6/10/93
- */
-#ifndef _MIPS_REGDEF_H_
-#define _MIPS_REGDEF_H_
-
-#if (_MIPS_SIM == _ABI64) && !defined(__mips_n64)
-#define __mips_n64 1
-#endif
-#if (_MIPS_SIM == _ABIN32) &&  !defined(__mips_n32)
-#define __mips_n32 1
-#endif
-
-#define zero	$0	/* always zero */
-#define AT	$at	/* assembler temp */
-#define v0	$2	/* return value */
-#define v1	$3
-#define a0	$4	/* argument registers */
-#define a1	$5
-#define a2	$6
-#define a3	$7
-#if defined(__mips_n32) || defined(__mips_n64)
-#define a4	$8	/* expanded register arguments */
-#define a5	$9
-#define a6	$10
-#define a7	$11
-#define ta0	$8	/* alias */
-#define ta1	$9
-#define ta2	$10
-#define ta3	$11
-#define t0	$12	/* temp registers (not saved across subroutine calls) */
-#define t1	$13
-#define t2	$14
-#define t3	$15
-#else
-#define t0	$8	/* temp registers (not saved across subroutine calls) */
-#define t1	$9
-#define t2	$10
-#define t3	$11
-#define t4	$12
-#define t5	$13
-#define t6	$14
-#define t7	$15
-#define ta0	$12	/* alias */
-#define ta1	$13
-#define ta2	$14
-#define ta3	$15
-#endif
-#define s0	$16	/* saved across subroutine calls (callee saved) */
-#define s1	$17
-#define s2	$18
-#define s3	$19
-#define s4	$20
-#define s5	$21
-#define s6	$22
-#define s7	$23
-#define t8	$24	/* two more temp registers */
-#define t9	$25
-#define k0	$26	/* kernel temporary */
-#define k1	$27
-#define gp	$28	/* global pointer */
-#define sp	$29	/* stack pointer */
-#define s8	$30	/* one more callee saved */
-#define ra	$31	/* return address */
-
-#endif /* !_MIPS_REGDEF_H_ */
diff --git a/libc/arch-mips64/include/machine/regnum.h b/libc/arch-mips64/include/machine/regnum.h
deleted file mode 100644
index bfe1280..0000000
--- a/libc/arch-mips64/include/machine/regnum.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*	$OpenBSD: regnum.h,v 1.3 2004/08/10 20:28:13 deraadt Exp $ */
-
-/*
- * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _MIPS64_REGNUM_H_
-#define _MIPS64_REGNUM_H_
-
-/*
- * Location of the saved registers relative to ZERO.
- * Usage is p->p_regs[XX].
- */
-#define ZERO	0
-#define AST	1
-#define V0	2
-#define V1	3
-#define A0	4
-#define A1	5
-#define A2	6
-#define A3	7
-#define T0	8
-#define T1	9
-#define T2	10
-#define T3	11
-#define T4	12
-#define T5	13
-#define T6	14
-#define T7	15
-#define S0	16
-#define S1	17
-#define S2	18
-#define S3	19
-#define S4	20
-#define S5	21
-#define S6	22
-#define S7	23
-#define T8	24
-#define T9	25
-#define K0	26
-#define K1	27
-#define GP	28
-#define SP	29
-#define S8	30
-#define RA	31
-#define	SR	32
-#define	PS	SR	/* alias for SR */
-#define MULLO	33
-#define MULHI	34
-#define BADVADDR 35
-#define CAUSE	36
-#define	PC	37
-#define	IC	38
-#define	CPL	39
-
-#define	NUMSAVEREGS 40		/* Number of registers saved in trap */
-
-#define FPBASE	NUMSAVEREGS
-#define F0	(FPBASE+0)
-#define F1	(FPBASE+1)
-#define F2	(FPBASE+2)
-#define F3	(FPBASE+3)
-#define F4	(FPBASE+4)
-#define F5	(FPBASE+5)
-#define F6	(FPBASE+6)
-#define F7	(FPBASE+7)
-#define F8	(FPBASE+8)
-#define F9	(FPBASE+9)
-#define F10	(FPBASE+10)
-#define F11	(FPBASE+11)
-#define F12	(FPBASE+12)
-#define F13	(FPBASE+13)
-#define F14	(FPBASE+14)
-#define F15	(FPBASE+15)
-#define F16	(FPBASE+16)
-#define F17	(FPBASE+17)
-#define F18	(FPBASE+18)
-#define F19	(FPBASE+19)
-#define F20	(FPBASE+20)
-#define F21	(FPBASE+21)
-#define F22	(FPBASE+22)
-#define F23	(FPBASE+23)
-#define F24	(FPBASE+24)
-#define F25	(FPBASE+25)
-#define F26	(FPBASE+26)
-#define F27	(FPBASE+27)
-#define F28	(FPBASE+28)
-#define F29	(FPBASE+29)
-#define F30	(FPBASE+30)
-#define F31	(FPBASE+31)
-#define	FSR	(FPBASE+32)
-
-#define	NUMFPREGS 33
-
-#define	NREGS	(NUMSAVEREGS + NUMFPREGS)
-
-#endif /* !_MIPS64_REGNUM_H_ */
diff --git a/libc/arch-mips64/include/machine/setjmp.h b/libc/arch-mips64/include/machine/setjmp.h
deleted file mode 100644
index 55ba7be..0000000
--- a/libc/arch-mips64/include/machine/setjmp.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*	$OpenBSD: setjmp.h,v 1.2 2004/08/10 21:10:56 pefo Exp $	*/
-
-/* Public domain */
-
-#ifndef _MIPS_SETJMP_H_
-#define _MIPS_SETJMP_H_
-
-#define	_JBLEN	157		/* size, in longs, of a jmp_buf */
-
-#endif /* !_MIPS_SETJMP_H_ */
diff --git a/libc/arch-mips64/include/machine/signal.h b/libc/arch-mips64/include/machine/signal.h
deleted file mode 100644
index b31715c..0000000
--- a/libc/arch-mips64/include/machine/signal.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*	$OpenBSD: signal.h,v 1.8 2006/01/09 18:18:37 millert Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)signal.h	8.1 (Berkeley) 6/10/93
- */
-
-#ifndef _MIPS_SIGNAL_H_
-#define _MIPS_SIGNAL_H_
-
-#define	SC_REGMASK	(0*REGSZ)
-#define	SC_STATUS	(1*REGSZ)
-#define	SC_PC		(2*REGSZ)
-#define	SC_REGS		(SC_PC+8)
-#define	SC_FPREGS	(SC_REGS+32*8)
-#define	SC_ACX		(SC_FPREGS+32*REGSZ_FP)
-#define	SC_USED_MATH	(SC_ACX+3*REGSZ)
-/* OpenBSD compatibility */
-#define	SC_MASK		SC_REGMASK
-#define	SC_FPUSED	SC_USED_MATH
-
-#endif	/* !_MIPS_SIGNAL_H_ */
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index b962283..6fa7d33 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -49,9 +49,7 @@
 libc_bionic_src_files_mips64 += \
     arch-mips64/bionic/__bionic_clone.S \
     arch-mips64/bionic/_exit_with_stack_teardown.S \
-    arch-mips64/bionic/_setjmp.S \
     arch-mips64/bionic/setjmp.S \
-    arch-mips64/bionic/sigsetjmp.S \
     arch-mips64/bionic/syscall.S \
     arch-mips64/bionic/vfork.S \
 
diff --git a/libc/arch-x86/bionic/_setjmp.S b/libc/arch-x86/bionic/_setjmp.S
deleted file mode 100644
index 0b256a2..0000000
--- a/libc/arch-x86/bionic/_setjmp.S
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $OpenBSD: _setjmp.S,v 1.5 2005/08/07 11:30:38 espie Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-/*
- * C library -- _setjmp, _longjmp
- *
- *	_longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	_setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- */
-
-ENTRY(_setjmp)
-	movl	4(%esp),%eax
-	movl	0(%esp),%edx
-	movl	%edx, 0(%eax)		/* rta */
-	movl	%ebx, 4(%eax)
-	movl	%esp, 8(%eax)
-	movl	%ebp,12(%eax)
-	movl	%esi,16(%eax)
-	movl	%edi,20(%eax)
-	xorl	%eax,%eax
-	ret
-END(_setjmp)
-
-ENTRY(_longjmp)
-	movl	4(%esp),%edx
-	movl	8(%esp),%eax
-	movl	0(%edx),%ecx
-	movl	4(%edx),%ebx
-	movl	8(%edx),%esp
-	movl	12(%edx),%ebp
-	movl	16(%edx),%esi
-	movl	20(%edx),%edi
-	testl	%eax,%eax
-	jnz	1f
-	incl	%eax
-1:	movl	%ecx,0(%esp)
-	ret
-END(_longjmp)
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index 8f9d67c..25a016d 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -1,4 +1,3 @@
-/* $OpenBSD: setjmp.S,v 1.8 2005/08/07 11:30:38 espie Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -33,55 +32,98 @@
 
 #include <private/bionic_asm.h>
 
-/*
- * C library -- setjmp, longjmp
- *
- *	longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is restored.
- */
+#define _JB_EDX 0
+#define _JB_EBX 1
+#define _JB_ESP 2
+#define _JB_EBP 3
+#define _JB_ESI 4
+#define _JB_EDI 5
+#define _JB_SIGMASK 6
+#define _JB_SIGFLAG 7
 
 ENTRY(setjmp)
-	PIC_PROLOGUE
-	pushl	$0
-	call	PIC_PLT(sigblock)
-	addl	$4,%esp
-	PIC_EPILOGUE
-
-	movl	4(%esp),%ecx
-	movl	0(%esp),%edx
-	movl	%edx, 0(%ecx)
-	movl	%ebx, 4(%ecx)
-	movl	%esp, 8(%ecx)
-	movl	%ebp,12(%ecx)
-	movl	%esi,16(%ecx)
-	movl	%edi,20(%ecx)
-	movl	%eax,24(%ecx)
-	xorl	%eax,%eax
-	ret
+  movl 4(%esp),%ecx
+  movl $1,(_JB_SIGFLAG * 4)(%ecx)
+  jmp .L_sigsetjmp_signal_mask
 END(setjmp)
 
-ENTRY(longjmp)
-	movl	4(%esp),%edx
-	PIC_PROLOGUE
-	pushl	24(%edx)
-	call	PIC_PLT(sigsetmask)
-	addl	$4,%esp
-	PIC_EPILOGUE
+ENTRY(_setjmp)
+  movl 4(%esp),%ecx
+  movl $0,(_JB_SIGFLAG * 4)(%ecx)
+  jmp .L_sigsetjmp_no_signal_mask
+END(_setjmp)
 
-	movl	4(%esp),%edx
-	movl	8(%esp),%eax
-	movl	0(%edx),%ecx
-	movl	4(%edx),%ebx
-	movl	8(%edx),%esp
-	movl	12(%edx),%ebp
-	movl	16(%edx),%esi
-	movl	20(%edx),%edi
-	testl	%eax,%eax
-	jnz	1f
-	incl	%eax
-1:	movl	%ecx,0(%esp)
-	ret
-END(longjmp)
+ENTRY(sigsetjmp)
+  movl 4(%esp),%ecx
+  movl 8(%esp),%eax
+
+  // Record whether or not the signal mask is valid.
+  movl %eax,(_JB_SIGFLAG * 4)(%ecx)
+
+  // Do we need to save the signal mask?
+  testl %eax,%eax
+  jz 1f
+
+.L_sigsetjmp_signal_mask:
+  // Get the current signal mask.
+  PIC_PROLOGUE
+  pushl $0
+  call PIC_PLT(sigblock)
+  addl $4,%esp
+  PIC_EPILOGUE
+
+  // Save the signal mask.
+  movl 4(%esp),%ecx
+  movl %eax,(_JB_SIGMASK * 4)(%ecx)
+
+.L_sigsetjmp_no_signal_mask:
+1:
+  // Save the callee-save registers.
+  movl 0(%esp),%edx
+  movl %edx,(_JB_EDX * 4)(%ecx)
+  movl %ebx,(_JB_EBX * 4)(%ecx)
+  movl %esp,(_JB_ESP * 4)(%ecx)
+  movl %ebp,(_JB_EBP * 4)(%ecx)
+  movl %esi,(_JB_ESI * 4)(%ecx)
+  movl %edi,(_JB_EDI * 4)(%ecx)
+
+  xorl %eax,%eax
+  ret
+END(sigsetjmp)
+
+ENTRY(siglongjmp)
+  // Do we have a signal mask to restore?
+  movl 4(%esp),%edx
+  cmpl $0,(_JB_SIGFLAG * 4)(%edx)
+  jz 1f
+
+  // Restore the signal mask.
+  PIC_PROLOGUE
+  pushl (_JB_SIGMASK * 4)(%edx)
+  call PIC_PLT(sigsetmask)
+  addl $4,%esp
+  PIC_EPILOGUE
+
+1:
+  // Restore the callee-save registers.
+  movl 4(%esp),%edx
+  movl 8(%esp),%eax
+  movl (_JB_EDX * 4)(%edx),%ecx
+  movl (_JB_EBX * 4)(%edx),%ebx
+  movl (_JB_ESP * 4)(%edx),%esp
+  movl (_JB_EBP * 4)(%edx),%ebp
+  movl (_JB_ESI * 4)(%edx),%esi
+  movl (_JB_EDI * 4)(%edx),%edi
+
+  testl %eax,%eax
+  jnz 2f
+  incl %eax
+2:
+  movl %ecx,0(%esp)
+  ret
+END(siglongjmp)
+
+  .globl longjmp
+  .equ longjmp, siglongjmp
+  .globl _longjmp
+  .equ _longjmp, siglongjmp
diff --git a/libc/arch-x86/bionic/sigsetjmp.S b/libc/arch-x86/bionic/sigsetjmp.S
deleted file mode 100644
index 250c606..0000000
--- a/libc/arch-x86/bionic/sigsetjmp.S
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $OpenBSD: sigsetjmp.S,v 1.7 2005/08/07 11:30:38 espie Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(sigsetjmp)
-	movl	4(%esp),%ecx
-	movl	8(%esp),%eax
-	movl	%eax,28(%ecx)
-	testl	%eax,%eax
-	jz	1f
-
-	PIC_PROLOGUE
-	pushl	$0
-	call	PIC_PLT(sigblock)
-	addl	$4,%esp
-	PIC_EPILOGUE
-
-	movl	4(%esp),%ecx
-	movl	%eax,24(%ecx)
-1:	movl	0(%esp),%edx
-	movl	%edx, 0(%ecx)
-	movl	%ebx, 4(%ecx)
-	movl	%esp, 8(%ecx)
-	movl	%ebp,12(%ecx)
-	movl	%esi,16(%ecx)
-	movl	%edi,20(%ecx)
-	xorl	%eax,%eax
-	ret
-END(sigsetjmp)
-
-ENTRY(siglongjmp)
-	movl	4(%esp),%edx
-	cmpl	$0,28(%edx)
-	jz	1f
-
-	PIC_PROLOGUE
-	pushl	24(%edx)
-	call	PIC_PLT(sigsetmask)
-	addl	$4,%esp
-	PIC_EPILOGUE
-
-1:	movl	4(%esp),%edx
-	movl	8(%esp),%eax
-	movl	0(%edx),%ecx
-	movl	4(%edx),%ebx
-	movl	8(%edx),%esp
-	movl	12(%edx),%ebp
-	movl	16(%edx),%esi
-	movl	20(%edx),%edi
-	testl	%eax,%eax
-	jnz	2f
-	incl	%eax
-2:	movl	%ecx,0(%esp)
-	ret
-END(siglongjmp)
diff --git a/libc/arch-x86/include/machine/endian.h b/libc/arch-x86/include/machine/endian.h
deleted file mode 100644
index e1506b1..0000000
--- a/libc/arch-x86/include/machine/endian.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*	$OpenBSD: endian.h,v 1.17 2011/03/12 04:03:04 guenther Exp $	*/
-
-/*-
- * Copyright (c) 1997 Niklas Hallqvist.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_ENDIAN_H_
-#define _MACHINE_ENDIAN_H_
-
-#ifdef __GNUC__
-
-#define	__swap32md(x) __statement({					\
-	uint32_t __swap32md_x = (x);					\
-									\
-	__asm ("bswap %0" : "+r" (__swap32md_x));			\
-	__swap32md_x;							\
-})
-
-#define	__swap64md(x) __statement({					\
-	uint64_t __swap64md_x = (x);					\
-									\
-	(uint64_t)__swap32md(__swap64md_x >> 32) |			\
-	    (uint64_t)__swap32md(__swap64md_x & 0xffffffff) << 32;	\
-})
-#define	__swap16md(x) __statement({					\
-	uint16_t __swap16md_x = (x);					\
-									\
-	__asm ("rorw $8, %w0" : "+r" (__swap16md_x));			\
-	__swap16md_x;							\
-})
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif	/* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/libc/arch-x86/include/machine/exec.h b/libc/arch-x86/include/machine/exec.h
deleted file mode 100644
index d091741..0000000
--- a/libc/arch-x86/include/machine/exec.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $	*/
-/*	$NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $	*/
-
-/*
- * Copyright (c) 1993 Christopher G. Demetriou
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _I386_EXEC_H_
-#define _I386_EXEC_H_
-
-#define __LDPGSZ	4096
-
-#define NATIVE_EXEC_ELF
-
-#define ARCH_ELFSIZE		32
-
-#define ELF_TARG_CLASS		ELFCLASS32
-#define ELF_TARG_DATA		ELFDATA2LSB
-#define ELF_TARG_MACH		EM_386 /* XXX - EM_486 is currently unused
-                                          by all OSs/compilers/linkers */
-
-#define _NLIST_DO_AOUT
-#define _NLIST_DO_ELF
-
-#define _KERN_DO_AOUT
-#define _KERN_DO_ELF
-
-#endif  /* _I386_EXEC_H_ */
diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk
index 2c90317..989690c 100644
--- a/libc/arch-x86/x86.mk
+++ b/libc/arch-x86/x86.mk
@@ -40,10 +40,8 @@
     arch-x86/bionic/_exit_with_stack_teardown.S \
     arch-x86/bionic/libgcc_compat.c \
     arch-x86/bionic/__restore.S \
-    arch-x86/bionic/_setjmp.S \
     arch-x86/bionic/setjmp.S \
     arch-x86/bionic/__set_tls.c \
-    arch-x86/bionic/sigsetjmp.S \
     arch-x86/bionic/syscall.S \
     arch-x86/bionic/vfork.S \
 
diff --git a/libc/arch-x86_64/bionic/_setjmp.S b/libc/arch-x86_64/bionic/_setjmp.S
deleted file mode 100644
index c617030..0000000
--- a/libc/arch-x86_64/bionic/_setjmp.S
+++ /dev/null
@@ -1,83 +0,0 @@
-/*	$OpenBSD: _setjmp.S,v 1.1 2004/01/28 01:44:45 mickey Exp $	*/
-/*	$NetBSD: _setjmp.S,v 1.1 2001/06/19 00:25:02 fvdl Exp $	*/
-
-/*
- * Copyright (c) 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Frank van der Linden for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed for the NetBSD Project by
- *      Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- *    or promote products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-
-/*
- * C library -- _setjmp, _longjmp
- *
- *	_longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	_setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- */
-
-ENTRY(_setjmp)
-	movq    (%rsp),%r11
-	movq    %rbx,(_JB_RBX * 8)(%rdi)
-	movq    %rbp,(_JB_RBP * 8)(%rdi)
-	movq    %r12,(_JB_R12 * 8)(%rdi)
-	movq    %r13,(_JB_R13 * 8)(%rdi)
-	movq    %r14,(_JB_R14 * 8)(%rdi)
-	movq    %r15,(_JB_R15 * 8)(%rdi)
-	movq    %rsp,(_JB_RSP * 8)(%rdi)
-	movq    %r11,(_JB_PC  * 8)(%rdi)
-
-	xorl	%eax,%eax
-	ret
-END(_setjmp)
-
-ENTRY(_longjmp)
-	movq    (_JB_RBX * 8)(%rdi),%rbx
-	movq    (_JB_RBP * 8)(%rdi),%rbp
-	movq    (_JB_R12 * 8)(%rdi),%r12
-	movq    (_JB_R13 * 8)(%rdi),%r13
-	movq    (_JB_R14 * 8)(%rdi),%r14
-	movq    (_JB_R15 * 8)(%rdi),%r15
-	movq    (_JB_RSP * 8)(%rdi),%rsp
-	movq    (_JB_PC  * 8)(%rdi),%r11
-
-	movl	%esi,%eax
-	testl	%eax,%eax
-	jnz	1f
-	incl	%eax
-1:	movq	%r11,0(%rsp)
-	ret
-END(_longjmp)
diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S
index f356877..28981fa 100644
--- a/libc/arch-x86_64/bionic/setjmp.S
+++ b/libc/arch-x86_64/bionic/setjmp.S
@@ -1,6 +1,3 @@
-/*	$OpenBSD: setjmp.S,v 1.3 2012/08/22 17:19:34 pascal Exp $	*/
-/*	$NetBSD: __setjmp14.S,v 1.1 2001/06/19 00:25:02 fvdl Exp $	*/
-
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
  * All rights reserved.
@@ -37,60 +34,102 @@
  */
 
 #include <private/bionic_asm.h>
-#include <machine/setjmp.h>
 
-/*
- * C library -- _setjmp, _longjmp
- *
- *	longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is restored.
- */
+// These are only the callee-saved registers. Code calling setjmp
+// will expect the rest to be clobbered anyway.
+
+#define _JB_RBX 0
+#define _JB_RBP 1
+#define _JB_R12 2
+#define _JB_R13 3
+#define _JB_R14 4
+#define _JB_R15 5
+#define _JB_RSP 6
+#define _JB_PC 7
+#define _JB_SIGFLAG 8
+#define _JB_SIGMASK 9
+#define _JB_SIGMASK_RT 10 // sigprocmask will write here too.
 
 ENTRY(setjmp)
-	pushq	%rdi
-	xorq	%rdi,%rdi
-	call	PIC_PLT(sigblock)
-	popq	%rdi
-	movq	%rax,(_JB_SIGMASK * 8)(%rdi)
-
-	movq	(%rsp),%r11
-	movq	%rbx,(_JB_RBX * 8)(%rdi)
-	movq	%rbp,(_JB_RBP * 8)(%rdi)
-	movq	%r12,(_JB_R12 * 8)(%rdi)
-	movq	%r13,(_JB_R13 * 8)(%rdi)
-	movq	%r14,(_JB_R14 * 8)(%rdi)
-	movq	%r15,(_JB_R15 * 8)(%rdi)
-	movq	%rsp,(_JB_RSP * 8)(%rdi)
-	movq	%r11,(_JB_PC  * 8)(%rdi)
-
-2:	xorl	%eax,%eax
-	ret
+  movl $1,%esi
+  jmp PIC_PLT(sigsetjmp)
 END(setjmp)
 
-ENTRY(longjmp)
-	movq	%rdi,%r12
-	movl	%esi,%r8d
+ENTRY(_setjmp)
+  movl $0,%esi
+  jmp PIC_PLT(sigsetjmp)
+END(_setjmp)
 
-	movq	(_JB_SIGMASK * 8)(%rdi),%rdi
-	pushq	%r8
-	call	PIC_PLT(sigsetmask)
-	popq	%r8
-	movq	(_JB_RBX * 8)(%r12),%rbx
-	movq	(_JB_RBP * 8)(%r12),%rbp
-	movq	(_JB_R13 * 8)(%r12),%r13
-	movq	(_JB_R14 * 8)(%r12),%r14
-	movq	(_JB_R15 * 8)(%r12),%r15
-	movq	(_JB_RSP * 8)(%r12),%rsp
-	movq	(_JB_PC  * 8)(%r12),%r11
-	movq	(_JB_R12 * 8)(%r12),%r12
+// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
+ENTRY(sigsetjmp)
+  // Record whether or not we're saving the signal mask.
+  movl %esi,(_JB_SIGFLAG * 8)(%rdi)
 
-	movl	%r8d,%eax
-	testl	%eax,%eax
-	jnz	1f
-	incl	%eax
-1:	movq	%r11,0(%rsp)
-	ret
-END(longjmp)
+  // Do we need to save the signal mask?
+  testl %esi,%esi
+  jz 2f
+
+  // Save current signal mask.
+  pushq %rdi // Push 'env'.
+  // The 'how' argument is ignored if new_mask is NULL.
+  xorq %rsi,%rsi // NULL.
+  leaq (_JB_SIGMASK * 8)(%rdi),%rdx // old_mask.
+  call PIC_PLT(sigprocmask)
+  popq %rdi // Pop 'env'.
+
+2:
+  // Save the callee-save registers.
+  movq (%rsp),%r11
+  movq %rbx,(_JB_RBX * 8)(%rdi)
+  movq %rbp,(_JB_RBP * 8)(%rdi)
+  movq %r12,(_JB_R12 * 8)(%rdi)
+  movq %r13,(_JB_R13 * 8)(%rdi)
+  movq %r14,(_JB_R14 * 8)(%rdi)
+  movq %r15,(_JB_R15 * 8)(%rdi)
+  movq %rsp,(_JB_RSP * 8)(%rdi)
+  movq %r11,(_JB_PC  * 8)(%rdi)
+
+  xorl %eax,%eax
+  ret
+END(sigsetjmp)
+
+// void siglongjmp(sigjmp_buf env, int value);
+ENTRY(siglongjmp)
+  movq %rdi,%r12
+  pushq %rsi // Push 'value'.
+
+  // Do we need to restore the signal mask?
+  cmpl $0,(_JB_SIGFLAG * 8)(%rdi)
+  jz 2f
+
+  // Restore the signal mask.
+  movq $2,%rdi // SIG_SETMASK.
+  leaq (_JB_SIGMASK * 8)(%r12),%rsi // new_mask.
+  xorq %rdx,%rdx // NULL.
+  call PIC_PLT(sigprocmask)
+
+2:
+  popq %rax // Pop 'value'.
+
+  // Restore the callee-save registers.
+  movq (_JB_RBX * 8)(%r12),%rbx
+  movq (_JB_RBP * 8)(%r12),%rbp
+  movq (_JB_R13 * 8)(%r12),%r13
+  movq (_JB_R14 * 8)(%r12),%r14
+  movq (_JB_R15 * 8)(%r12),%r15
+  movq (_JB_RSP * 8)(%r12),%rsp
+  movq (_JB_PC  * 8)(%r12),%r11
+  movq (_JB_R12 * 8)(%r12),%r12
+
+  testl %eax,%eax
+  jnz 1f
+  incl %eax
+1:
+  movq %r11,0(%rsp)
+  ret
+END(siglongjmp)
+
+  .globl longjmp
+  .equ longjmp, siglongjmp
+  .globl _longjmp
+  .equ _longjmp, siglongjmp
diff --git a/libc/arch-x86_64/bionic/sigsetjmp.S b/libc/arch-x86_64/bionic/sigsetjmp.S
deleted file mode 100644
index 571fea3..0000000
--- a/libc/arch-x86_64/bionic/sigsetjmp.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/*	$OpenBSD: sigsetjmp.S,v 1.3 2012/08/22 17:19:34 pascal Exp $	*/
-/*	$NetBSD: __setjmp14.S,v 1.1 2001/06/19 00:25:02 fvdl Exp $	*/
-
-/*
- * Copyright (c) 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Frank van der Linden for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed for the NetBSD Project by
- *      Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- *    or promote products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
-
-/*
- * C library -- _setjmp, _longjmp
- *
- *	longjmp(a,v)
- * will generate a "return(v)" from the last call to
- *	setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is restored.
- */
-
-ENTRY(sigsetjmp)
-	movl    %esi,(_JB_SIGFLAG  * 8)(%rdi)
-	testl   %esi,%esi
-	jz      2f
-
-	pushq	%rdi
-	xorq	%rdi,%rdi
-	call	PIC_PLT(sigblock)
-	popq	%rdi
-	movq	%rax,(_JB_SIGMASK * 8)(%rdi)
-
-2:	movq	(%rsp),%r11
-	movq	%rbx,(_JB_RBX * 8)(%rdi)
-	movq	%rbp,(_JB_RBP * 8)(%rdi)
-	movq	%r12,(_JB_R12 * 8)(%rdi)
-	movq	%r13,(_JB_R13 * 8)(%rdi)
-	movq	%r14,(_JB_R14 * 8)(%rdi)
-	movq	%r15,(_JB_R15 * 8)(%rdi)
-	movq	%rsp,(_JB_RSP * 8)(%rdi)
-	movq	%r11,(_JB_PC  * 8)(%rdi)
-
-2:	xorl	%eax,%eax
-	ret
-END(sigsetjmp)
-
-ENTRY(siglongjmp)
-	movq	%rdi,%r12
-	pushq   %rsi
-	cmpl    $0, (_JB_SIGFLAG * 8)(%rdi)
-	jz      2f
-
-	movq	(_JB_SIGMASK * 8)(%rdi),%rdi
-	call	PIC_PLT(sigsetmask)
-2:	popq	%rax
-	movq	(_JB_RBX * 8)(%r12),%rbx
-	movq	(_JB_RBP * 8)(%r12),%rbp
-	movq	(_JB_R13 * 8)(%r12),%r13
-	movq	(_JB_R14 * 8)(%r12),%r14
-	movq	(_JB_R15 * 8)(%r12),%r15
-	movq	(_JB_RSP * 8)(%r12),%rsp
-	movq	(_JB_PC  * 8)(%r12),%r11
-	movq	(_JB_R12 * 8)(%r12),%r12
-
-	testl	%eax,%eax
-	jnz	1f
-	incl	%eax
-1:	movq	%r11,0(%rsp)
-	ret
-END(siglongjmp)
diff --git a/libc/arch-x86_64/include/machine/endian.h b/libc/arch-x86_64/include/machine/endian.h
deleted file mode 100644
index 8a3b0c5..0000000
--- a/libc/arch-x86_64/include/machine/endian.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*	$OpenBSD: endian.h,v 1.5 2011/03/12 22:27:48 guenther Exp $	*/
-
-/*-
- * Copyright (c) 1997 Niklas Hallqvist.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MACHINE_ENDIAN_H_
-#define _MACHINE_ENDIAN_H_
-
-#ifdef __GNUC__
-
-#define	__swap32md(x) __statement({					\
-	u_int32_t __swap32md_x = (x);					\
-									\
-	__asm ("bswap %0" : "+r" (__swap32md_x));			\
-	__swap32md_x;							\
-})
-
-#define	__swap64md(x) __statement({					\
-	u_int64_t __swap64md_x = (x);					\
-									\
-	__asm ("bswapq %0" : "+r" (__swap64md_x));			\
-	__swap64md_x;							\
-})
-
-#define	__swap16md(x) __statement({					\
-	u_int16_t __swap16md_x = (x);					\
-									\
-	__asm ("rorw $8, %w0" : "+r" (__swap16md_x));			\
-	__swap16md_x;							\
-})
-
-/* Tell sys/endian.h we have MD variants of the swap macros.  */
-#define MD_SWAP
-
-#endif	/* __GNUC__ */
-
-#define _BYTE_ORDER _LITTLE_ENDIAN
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/libc/arch-x86_64/include/machine/exec.h b/libc/arch-x86_64/include/machine/exec.h
deleted file mode 100644
index 829351c..0000000
--- a/libc/arch-x86_64/include/machine/exec.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*	$OpenBSD: exec.h,v 1.4 2012/09/11 15:44:17 deraadt Exp $	*/
-/*
- * Written by Artur Grabowski <art@openbsd.org> Public Domain
- */
-
-#ifndef _MACHINE_EXEC_H_
-#define _MACHINE_EXEC_H_
-
-#define __LDPGSZ 4096
-
-#define ARCH_ELFSIZE 64
-
-#define ELF_TARG_CLASS		ELFCLASS64
-#define ELF_TARG_DATA		ELFDATA2LSB
-#define ELF_TARG_MACH		EM_X86_64
-
-#define _NLIST_DO_ELF
-#define _KERN_DO_ELF64
-
-#endif
diff --git a/libc/arch-x86_64/include/machine/setjmp.h b/libc/arch-x86_64/include/machine/setjmp.h
index 01d6066..46ddd4b 100644
--- a/libc/arch-x86_64/include/machine/setjmp.h
+++ b/libc/arch-x86_64/include/machine/setjmp.h
@@ -1,21 +1,4 @@
 /*	$OpenBSD: setjmp.h,v 1.1 2004/01/28 01:39:39 mickey Exp $	*/
 /*	$NetBSD: setjmp.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $	*/
 
-/*
- * machine/setjmp.h: machine dependent setjmp-related information.
- * These are only the callee-saved registers, code calling setjmp
- * will expect the rest to be clobbered anyway.
- */
-
-#define _JB_RBX		0
-#define _JB_RBP		1
-#define _JB_R12		2
-#define _JB_R13		3
-#define _JB_R14		4
-#define _JB_R15		5
-#define _JB_RSP		6
-#define _JB_PC		7
-#define _JB_SIGFLAG	8
-#define _JB_SIGMASK	9
-
 #define	_JBLEN	11		/* size, in longs, of a jmp_buf */
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 00a3763..ae01d2a 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -33,10 +33,8 @@
     arch-x86_64/bionic/__bionic_clone.S \
     arch-x86_64/bionic/_exit_with_stack_teardown.S \
     arch-x86_64/bionic/__restore_rt.S \
-    arch-x86_64/bionic/_setjmp.S \
     arch-x86_64/bionic/setjmp.S \
     arch-x86_64/bionic/__set_tls.c \
-    arch-x86_64/bionic/sigsetjmp.S \
     arch-x86_64/bionic/syscall.S \
     arch-x86_64/bionic/vfork.S \
 
diff --git a/libc/arch-arm64/bionic/sigsetjmp.S b/libc/bionic/clock_getcpuclockid.cpp
similarity index 68%
copy from libc/arch-arm64/bionic/sigsetjmp.S
copy to libc/bionic/clock_getcpuclockid.cpp
index be7cecb..5511eb4 100644
--- a/libc/arch-arm64/bionic/sigsetjmp.S
+++ b/libc/bionic/clock_getcpuclockid.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,26 +26,25 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
+#include <errno.h>
+#include <time.h>
 
-/*
- * int sigsetjmp(sigjmp_buf env, int savesigs);
- * void siglongjmp(sigjmp_buf env, int val);
- */
+#include "private/ErrnoRestorer.h"
 
-ENTRY(sigsetjmp)
-    cbz     w1, _setjmp
-    b       setjmp
-END(sigsetjmp)
+int clock_getcpuclockid(pid_t pid, clockid_t* clockid) {
+  ErrnoRestorer errno_restorer;
 
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
+  // The tid is stored in the top bits, but negated.
+  clockid_t result = ~static_cast<clockid_t>(pid) << 3;
+  // Bits 0 and 1: clock type (0 = CPUCLOCK_PROF, 1 = CPUCLOCK_VIRT, 2 = CPUCLOCK_SCHED).
+  result |= 2;
+  // Bit 2: thread (set) or process (clear). Bit 2 already 0.
 
-ENTRY(siglongjmp)
-    ldr     w2, .L_setjmp_magic
-    ldr     w3, [x0]
-    cmp     w2, w3
-    b.eq    _longjmp
-    b       longjmp
-END(siglongjmp)
+  timespec ts;
+  if (clock_getres(result, &ts) == -1) {
+    return ESRCH;
+  }
+
+  *clockid = result;
+  return 0;
+}
diff --git a/libc/arch-arm64/bionic/sigsetjmp.S b/libc/bionic/posix_madvise.cpp
similarity index 72%
rename from libc/arch-arm64/bionic/sigsetjmp.S
rename to libc/bionic/posix_madvise.cpp
index be7cecb..d77be01 100644
--- a/libc/arch-arm64/bionic/sigsetjmp.S
+++ b/libc/bionic/posix_madvise.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,26 +26,17 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
+#include <errno.h>
+#include <sys/mman.h>
 
-/*
- * int sigsetjmp(sigjmp_buf env, int savesigs);
- * void siglongjmp(sigjmp_buf env, int val);
- */
+#include "private/ErrnoRestorer.h"
 
-ENTRY(sigsetjmp)
-    cbz     w1, _setjmp
-    b       setjmp
-END(sigsetjmp)
+int posix_madvise(void* addr, size_t len, int advice) {
+  ErrnoRestorer errno_restorer;
 
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
-
-ENTRY(siglongjmp)
-    ldr     w2, .L_setjmp_magic
-    ldr     w3, [x0]
-    cmp     w2, w3
-    b.eq    _longjmp
-    b       longjmp
-END(siglongjmp)
+  // Don't call madvise() on POSIX_MADV_DONTNEED, it will make the space not available.
+  if (advice == POSIX_MADV_DONTNEED) {
+    return 0;
+  }
+  return (madvise(addr, len, advice) == 0 ? 0 : errno);
+}
diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp
index 82e2b59..d1c4ad0 100644
--- a/libc/bionic/pthread_atfork.cpp
+++ b/libc/bionic/pthread_atfork.cpp
@@ -44,7 +44,7 @@
   atfork_t* last;
 };
 
-static pthread_mutex_t g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+static pthread_mutex_t g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 static atfork_list_t g_atfork_list = { NULL, NULL };
 
 void __bionic_atfork_run_prepare() {
@@ -73,7 +73,7 @@
     }
   }
 
-  g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+  g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 }
 
 void __bionic_atfork_run_parent() {
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index fc8afa2..8bb1be9 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -158,9 +158,8 @@
   // Inform the rest of the C library that at least one thread was created.
   __isthreaded = 1;
 
-  pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(calloc(sizeof(*thread), 1));
+  pthread_internal_t* thread = __create_thread_struct();
   if (thread == NULL) {
-    __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't allocate thread");
     return EAGAIN;
   }
 
@@ -179,7 +178,7 @@
     // The caller didn't provide a stack, so allocate one.
     thread->attr.stack_base = __create_thread_stack(thread);
     if (thread->attr.stack_base == NULL) {
-      free(thread);
+      __free_thread_struct(thread);
       return EAGAIN;
     }
   } else {
@@ -230,7 +229,7 @@
     if (!thread->user_allocated_stack()) {
       munmap(thread->attr.stack_base, thread->attr.stack_size);
     }
-    free(thread);
+    __free_thread_struct(thread);
     __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s", strerror(errno));
     return clone_errno;
   }
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 6cd5311..a6bb363 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -112,12 +112,6 @@
   }
   pthread_mutex_unlock(&g_thread_list_lock);
 
-  // Perform a second key cleanup. When using jemalloc, a call to free from
-  // _pthread_internal_remove_locked causes the memory associated with a key
-  // to be reallocated.
-  // TODO: When b/16847284 is fixed this call can be removed.
-  pthread_key_clean_all();
-
   if (user_allocated_stack) {
     // Cleaning up this thread's stack is the creator's responsibility, not ours.
     __exit(0);
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 392e781..c5136c9 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -94,6 +94,8 @@
   char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
 };
 
+__LIBC_HIDDEN__ pthread_internal_t* __create_thread_struct();
+__LIBC_HIDDEN__ void __free_thread_struct(pthread_internal_t*);
 __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list);
 __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);
diff --git a/libc/bionic/pthread_internals.cpp b/libc/bionic/pthread_internals.cpp
index 2270d96..33cddd7 100644
--- a/libc/bionic/pthread_internals.cpp
+++ b/libc/bionic/pthread_internals.cpp
@@ -28,15 +28,38 @@
 
 #include "pthread_internal.h"
 
+#include <errno.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
 
 #include "private/bionic_futex.h"
 #include "private/bionic_tls.h"
+#include "private/libc_logging.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
 pthread_internal_t* g_thread_list = NULL;
 pthread_mutex_t g_thread_list_lock = PTHREAD_MUTEX_INITIALIZER;
 
+pthread_internal_t* __create_thread_struct() {
+  void* result = mmap(NULL, sizeof(pthread_internal_t), PROT_READ | PROT_WRITE,
+                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+  if (result == MAP_FAILED) {
+    __libc_format_log(ANDROID_LOG_WARN, "libc",
+                      "__create_thread_struct() failed: %s", strerror(errno));
+    return NULL;
+  }
+  return reinterpret_cast<pthread_internal_t*>(result);
+}
+
+void __free_thread_struct(pthread_internal_t* thread) {
+  int result = munmap(thread, sizeof(pthread_internal_t));
+  if (result != 0) {
+    __libc_format_log(ANDROID_LOG_WARN, "libc",
+                      "__free_thread_struct() failed: %s", strerror(errno));
+  }
+}
+
 void _pthread_internal_remove_locked(pthread_internal_t* thread) {
   if (thread->next != NULL) {
     thread->next->prev = thread->prev;
@@ -50,7 +73,7 @@
   // The main thread is not heap-allocated. See __libc_init_tls for the declaration,
   // and __libc_init_common for the point where it's added to the thread list.
   if ((thread->attr.flags & PTHREAD_ATTR_FLAG_MAIN_THREAD) == 0) {
-    free(thread);
+    __free_thread_struct(thread);
   }
 }
 
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index 995e006..2c86180 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -28,13 +28,15 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <pty.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <termios.h>
 #include <unistd.h>
+#include <utmp.h>
 
-int getpt(void) {
+int getpt() {
   return posix_openpt(O_RDWR|O_NOCTTY);
 }
 
@@ -47,7 +49,7 @@
 }
 
 char* ptsname(int fd) {
-  static char buf[64];
+  static char buf[32];
   return ptsname_r(fd, buf, sizeof(buf)) == 0 ? buf : NULL;
 }
 
@@ -105,3 +107,83 @@
   int unlock = 0;
   return ioctl(fd, TIOCSPTLCK, &unlock);
 }
+
+int openpty(int* master, int* slave, char* name, const termios* t, const winsize* ws) {
+  *master = getpt();
+  if (*master == -1) {
+    return -1;
+  }
+
+  if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
+    close(*master);
+    return -1;
+  }
+
+  char buf[32];
+  if (name == NULL) {
+    name = buf;
+  }
+  if (ptsname_r(*master, name, sizeof(buf)) != 0) {
+    close(*master);
+    return -1;
+  }
+
+  *slave = open(name, O_RDWR|O_NOCTTY);
+  if (*slave == -1) {
+    close(*master);
+    return -1;
+  }
+
+  if (t != NULL) {
+    tcsetattr(*slave, TCSAFLUSH, t);
+  }
+  if (ws != NULL) {
+    ioctl(*slave, TIOCSWINSZ, ws);
+  }
+
+  return 0;
+}
+
+int forkpty(int* master, char* name, const termios* t, const winsize* ws) {
+  int slave;
+  if (openpty(master, &slave, name, t, ws) == -1) {
+    return -1;
+  }
+
+  pid_t pid = fork();
+  if (pid == -1) {
+    close(*master);
+    close(slave);
+    return -1;
+  }
+
+  if (pid == 0) {
+    // Child.
+    close(*master);
+    if (login_tty(slave) == -1) {
+      _exit(1);
+    }
+    return 0;
+  }
+
+  // Parent.
+  close(slave);
+  return pid;
+}
+
+int login_tty(int fd) {
+  setsid();
+
+  if (ioctl(fd, TIOCSCTTY, NULL) == -1) {
+    return -1;
+  }
+
+  dup2(fd, STDIN_FILENO);
+  dup2(fd, STDOUT_FILENO);
+  dup2(fd, STDERR_FILENO);
+  if (fd > STDERR_FILENO) {
+    close(fd);
+  }
+
+  return 0;
+}
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 67f48e7..411c23a 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -46,6 +46,10 @@
   return (rc == -1) ? -1 : _POSIX_VERSION;
 }
 
+static bool __sysconf_has_clock(clockid_t clock_id) {
+  return clock_getres(clock_id, NULL) == 0;
+}
+
 long sysconf(int name) {
   switch (name) {
     case _SC_ARG_MAX:           return ARG_MAX;
@@ -144,7 +148,9 @@
     case _SC_ADVISORY_INFO:     return _POSIX_ADVISORY_INFO;
     case _SC_BARRIERS:          return _POSIX_BARRIERS;
     case _SC_CLOCK_SELECTION:   return _POSIX_CLOCK_SELECTION;
-    case _SC_CPUTIME:           return _POSIX_CPUTIME;
+    case _SC_CPUTIME:
+      return __sysconf_has_clock(CLOCK_PROCESS_CPUTIME_ID) ?_POSIX_VERSION : -1;
+
     case _SC_HOST_NAME_MAX:     return _POSIX_HOST_NAME_MAX;    // Minimum requirement.
     case _SC_IPV6:              return _POSIX_IPV6;
     case _SC_RAW_SOCKETS:       return _POSIX_RAW_SOCKETS;
@@ -156,7 +162,9 @@
     case _SC_SPORADIC_SERVER:   return _POSIX_SPORADIC_SERVER;
     case _SC_SS_REPL_MAX:       return -1;
     case _SC_SYMLOOP_MAX:       return _POSIX_SYMLOOP_MAX;      // Minimum requirement.
-    case _SC_THREAD_CPUTIME:    return _POSIX_THREAD_CPUTIME;
+    case _SC_THREAD_CPUTIME:
+      return __sysconf_has_clock(CLOCK_THREAD_CPUTIME_ID) ? _POSIX_VERSION : -1;
+
     case _SC_THREAD_PROCESS_SHARED: return _POSIX_THREAD_PROCESS_SHARED;
     case _SC_THREAD_ROBUST_PRIO_INHERIT:  return _POSIX_THREAD_ROBUST_PRIO_INHERIT;
     case _SC_THREAD_ROBUST_PRIO_PROTECT:  return _POSIX_THREAD_ROBUST_PRIO_PROTECT;
@@ -178,6 +186,24 @@
     case _SC_XOPEN_STREAMS:     return -1;            // Obsolescent in POSIX.1-2008.
     case _SC_XOPEN_UUCP:        return -1;
 
+    // We do not have actual implementations for cache queries.
+    // It's valid to return 0 as the result is unknown.
+    case _SC_LEVEL1_ICACHE_SIZE:      return 0;
+    case _SC_LEVEL1_ICACHE_ASSOC:     return 0;
+    case _SC_LEVEL1_ICACHE_LINESIZE:  return 0;
+    case _SC_LEVEL1_DCACHE_SIZE:      return 0;
+    case _SC_LEVEL1_DCACHE_ASSOC:     return 0;
+    case _SC_LEVEL1_DCACHE_LINESIZE:  return 0;
+    case _SC_LEVEL2_CACHE_SIZE:       return 0;
+    case _SC_LEVEL2_CACHE_ASSOC:      return 0;
+    case _SC_LEVEL2_CACHE_LINESIZE:   return 0;
+    case _SC_LEVEL3_CACHE_SIZE:       return 0;
+    case _SC_LEVEL3_CACHE_ASSOC:      return 0;
+    case _SC_LEVEL3_CACHE_LINESIZE:   return 0;
+    case _SC_LEVEL4_CACHE_SIZE:       return 0;
+    case _SC_LEVEL4_CACHE_ASSOC:      return 0;
+    case _SC_LEVEL4_CACHE_LINESIZE:   return 0;
+
     default:
       // Posix says EINVAL is the only error that shall be returned,
       // but glibc uses ENOSYS.
diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c
index 132a090..1ebd222 100644
--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -463,6 +463,15 @@
 
 	// Send the request.
 	proxy = fdopen(sock, "r+");
+	if (proxy == NULL) {
+		// Failed to map sock to FILE*. Check errno for the cause.
+		// @sonymobile.com saw failures in automated testing, but
+		// couldn't reproduce it for debugging.
+		// Fail with EAI_SYSTEM and let callers handle the failure.
+		close(sock);
+		return EAI_SYSTEM;
+	}
+
 	if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d %u",
 		    hostname == NULL ? "^" : hostname,
 		    servname == NULL ? "^" : servname,
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index f27e4e5..90daf30 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -18,7 +18,9 @@
 #define __ANDROID_DLEXT_H__
 
 #include <stddef.h>
+#include <stdint.h>
 #include <sys/cdefs.h>
+#include <sys/types.h>  /* for off64_t */
 
 __BEGIN_DECLS
 
diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h
index a87ac91..91561ce 100644
--- a/libc/include/arpa/nameser.h
+++ b/libc/include/arpa/nameser.h
@@ -518,9 +518,8 @@
 	(cp) += NS_INT32SZ; \
 } while (/*CONSTCOND*/0)
 
-/*
- * ANSI C identifier hiding for bind's lib/nameser.
- */
+#if !defined(__LP64__)
+/* Annoyingly, LP32 shipped with __ names. */
 #define	ns_msg_getflag		__ns_msg_getflag
 #define ns_get16		__ns_get16
 #define ns_get32		__ns_get32
@@ -564,101 +563,73 @@
 #define	ns_subdomain		__ns_subdomain
 #define	ns_makecanon		__ns_makecanon
 #define	ns_samename		__ns_samename
-#define	ns_newmsg_init		__ns_newmsg_init
-#define	ns_newmsg_copy		__ns_newmsg_copy
-#define	ns_newmsg_id		__ns_newmsg_id
-#define	ns_newmsg_flag		__ns_newmsg_flag
-#define	ns_newmsg_q		__ns_newmsg_q
-#define	ns_newmsg_rr		__ns_newmsg_rr
-#define	ns_newmsg_done		__ns_newmsg_done
-#define	ns_rdata_unpack		__ns_rdata_unpack
-#define	ns_rdata_equal		__ns_rdata_equal
-#define	ns_rdata_refers		__ns_rdata_refers
+#endif
 
 __BEGIN_DECLS
-int		ns_msg_getflag(ns_msg, int);
-uint16_t	ns_get16(const u_char *);
-uint32_t	ns_get32(const u_char *);
-void		ns_put16(uint16_t, u_char *);
-void		ns_put32(uint32_t, u_char *);
-int		ns_initparse(const u_char *, int, ns_msg *);
-int		ns_skiprr(const u_char *, const u_char *, ns_sect, int);
-int		ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
-int		ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *);
+int		ns_msg_getflag(ns_msg, int) __LIBC_ABI_PUBLIC__;
+uint16_t	ns_get16(const u_char *) __LIBC_ABI_PUBLIC__;
+uint32_t	ns_get32(const u_char *) __LIBC_ABI_PUBLIC__;
+void		ns_put16(uint16_t, u_char *) __LIBC_ABI_PUBLIC__;
+void		ns_put32(uint32_t, u_char *) __LIBC_ABI_PUBLIC__;
+int		ns_initparse(const u_char *, int, ns_msg *) __LIBC_ABI_PUBLIC__;
+int		ns_skiprr(const u_char *, const u_char *, ns_sect, int) __LIBC_ABI_PUBLIC__;
+int		ns_parserr(ns_msg *, ns_sect, int, ns_rr *) __LIBC_ABI_PUBLIC__;
+int		ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *) __LIBC_HIDDEN__;
 int		ns_sprintrr(const ns_msg *, const ns_rr *,
-				 const char *, const char *, char *, size_t);
+				 const char *, const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
 int		ns_sprintrrf(const u_char *, size_t, const char *,
 				  ns_class, ns_type, u_long, const u_char *,
 				  size_t, const char *, const char *,
-				  char *, size_t);
-int		ns_format_ttl(u_long, char *, size_t);
-int		ns_parse_ttl(const char *, u_long *);
-uint32_t	ns_datetosecs(const char *cp, int *errp);
-int		ns_name_ntol(const u_char *, u_char *, size_t);
-int		ns_name_ntop(const u_char *, char *, size_t);
-int		ns_name_pton(const char *, u_char *, size_t);
-int		ns_name_pton2(const char *, u_char *, size_t, size_t *);
+				  char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_format_ttl(u_long, char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_parse_ttl(const char *, u_long *) __LIBC_ABI_PUBLIC__;
+uint32_t	ns_datetosecs(const char *cp, int *errp) __LIBC_ABI_PUBLIC__;
+int		ns_name_ntol(const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_name_ntop(const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_name_pton(const char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_name_pton2(const char *, u_char *, size_t, size_t *) __LIBC_HIDDEN__;
 int		ns_name_unpack(const u_char *, const u_char *,
-				    const u_char *, u_char *, size_t);
+				    const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
 int		ns_name_unpack2(const u_char *, const u_char *,
 				     const u_char *, u_char *, size_t,
-				     size_t *);
+				     size_t *) __LIBC_HIDDEN__;
 int		ns_name_pack(const u_char *, u_char *, int,
-				  const u_char **, const u_char **);
+				  const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
 int		ns_name_uncompress(const u_char *, const u_char *,
-					const u_char *, char *, size_t);
+					const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
 int		ns_name_compress(const char *, u_char *, size_t,
-				      const u_char **, const u_char **);
-int		ns_name_skip(const u_char **, const u_char *);
+				      const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
+int		ns_name_skip(const u_char **, const u_char *) __LIBC_ABI_PUBLIC__;
 void		ns_name_rollback(const u_char *, const u_char **,
-				      const u_char **);
+				      const u_char **) __LIBC_ABI_PUBLIC__;
 int		ns_sign(u_char *, int *, int, int, void *,
-			     const u_char *, int, u_char *, int *, time_t);
+			     const u_char *, int, u_char *, int *, time_t) __LIBC_ABI_PUBLIC__;
 int		ns_sign2(u_char *, int *, int, int, void *,
 			      const u_char *, int, u_char *, int *, time_t,
-			      u_char **, u_char **);
-ssize_t		ns_name_length(ns_nname_ct, size_t);
-int		ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t);
-int		ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int);
-int		ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int);
-int		ns_name_labels(ns_nname_ct, size_t);
+			      u_char **, u_char **) __LIBC_ABI_PUBLIC__;
+ssize_t		ns_name_length(ns_nname_ct, size_t) __LIBC_HIDDEN__;
+int		ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t) __LIBC_HIDDEN__;
+int		ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int) __LIBC_HIDDEN__;
+int		ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int) __LIBC_HIDDEN__;
+int		ns_name_labels(ns_nname_ct, size_t) __LIBC_HIDDEN__;
 int		ns_sign_tcp(u_char *, int *, int, int,
-				 ns_tcp_tsig_state *, int);
+				 ns_tcp_tsig_state *, int) __LIBC_ABI_PUBLIC__;
 int		ns_sign_tcp2(u_char *, int *, int, int,
 				  ns_tcp_tsig_state *, int,
-				  u_char **, u_char **);
+				  u_char **, u_char **) __LIBC_ABI_PUBLIC__;
 int		ns_sign_tcp_init(void *, const u_char *, int,
-					ns_tcp_tsig_state *);
-u_char		*ns_find_tsig(u_char *, u_char *);
+					ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
+u_char		*ns_find_tsig(u_char *, u_char *) __LIBC_ABI_PUBLIC__;
 int		ns_verify(u_char *, int *, void *,
 			       const u_char *, int, u_char *, int *,
-			       time_t *, int);
+			       time_t *, int) __LIBC_ABI_PUBLIC__;
 int		ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
 int		ns_verify_tcp_init(void *, const u_char *, int,
-					ns_tcp_tsig_state *);
-int		ns_samedomain(const char *, const char *);
-int		ns_subdomain(const char *, const char *);
-int		ns_makecanon(const char *, char *, size_t);
-int		ns_samename(const char *, const char *);
-int		ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *);
-int		ns_newmsg_copy(ns_newmsg *, ns_msg *);
-void		ns_newmsg_id(ns_newmsg *handle, uint16_t id);
-void		ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value);
-int		ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname,
-			    ns_type qtype, ns_class qclass);
-int		ns_newmsg_rr(ns_newmsg *handle, ns_sect sect,
-			     ns_nname_ct name, ns_type type,
-			     ns_class rr_class, uint32_t ttl,
-			     uint16_t rdlen, const u_char *rdata);
-size_t		ns_newmsg_done(ns_newmsg *handle);
-ssize_t		ns_rdata_unpack(const u_char *, const u_char *, ns_type,
-				const u_char *, size_t, u_char *, size_t);
-int		ns_rdata_equal(ns_type,
-			       const u_char *, size_t,
-			       const u_char *, size_t);
-int		ns_rdata_refers(ns_type,
-				const u_char *, size_t,
-				const u_char *);
+					ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
+int		ns_samedomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
+int		ns_subdomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
+int		ns_makecanon(const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
+int		ns_samename(const char *, const char *) __LIBC_ABI_PUBLIC__;
 __END_DECLS
 
 #ifdef BIND_4_COMPAT
diff --git a/libc/include/arpa/nameser_compat.h b/libc/include/arpa/nameser_compat.h
index e060f60..539864e 100644
--- a/libc/include/arpa/nameser_compat.h
+++ b/libc/include/arpa/nameser_compat.h
@@ -44,53 +44,6 @@
 
 #include <endian.h>
 
-#ifndef BYTE_ORDER
-#if (BSD >= 199103)
-# include <machine/endian.h>
-#else
-#ifdef __linux__
-# include <endian.h>
-#else
-#define	LITTLE_ENDIAN	1234	/* least-significant byte first (vax, pc) */
-#define	BIG_ENDIAN	4321	/* most-significant byte first (IBM, net) */
-#define	PDP_ENDIAN	3412	/* LSB first in word, MSW first in long (pdp)*/
-
-#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
-    defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
-    defined(__i386__) || defined(__i386) || defined(__amd64__) || \
-    defined(__x86_64__) || defined(MIPSEL) || defined(_MIPSEL) || \
-    defined(BIT_ZERO_ON_RIGHT) || defined(__alpha__) || defined(__alpha) || \
-    (defined(__Lynx__) && defined(__x86__))
-#define BYTE_ORDER	LITTLE_ENDIAN
-#endif
-
-#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
-    defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
-    defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
-    defined(apollo) || defined(__convex__) || defined(_CRAY) || \
-    defined(__hppa) || defined(__hp9000) || \
-    defined(__hp9000s300) || defined(__hp9000s700) || \
-    defined(__hp3000s900) || defined(__hpux) || defined(MPE) || \
-    defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) ||  \
-    (defined(__Lynx__) && \
-     (defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
-#define BYTE_ORDER	BIG_ENDIAN
-#endif
-#endif /* __linux */
-#endif /* BSD */
-#endif /* BYTE_ORDER */
-
-#if !defined(BYTE_ORDER) || \
-    (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
-    BYTE_ORDER != PDP_ENDIAN)
-	/* you must determine what the correct bit order is for
-	 * your compiler - the next line is an intentional error
-	 * which will force your compiles to bomb until you fix
-	 * the above macros.
-	 */
-  #error "Undefined or invalid BYTE_ORDER";
-#endif
-
 /*
  * Structure for query header.  The order of the fields is machine- and
  * compiler-dependent, depending on the byte/bit order and the layout
diff --git a/libc/include/fts.h b/libc/include/fts.h
index da26a88..cde0349 100644
--- a/libc/include/fts.h
+++ b/libc/include/fts.h
@@ -35,6 +35,8 @@
 #ifndef	_FTS_H_
 #define	_FTS_H_
 
+#include <sys/types.h>
+
 typedef struct {
 	struct _ftsent *fts_cur;	/* current node */
 	struct _ftsent *fts_child;	/* linked list of children */
@@ -111,8 +113,6 @@
 	char fts_name[1];		/* file name */
 } FTSENT;
 
-#include <sys/cdefs.h>
-
 __BEGIN_DECLS
 FTSENT	*fts_children(FTS *, int);
 int	 fts_close(FTS *);
diff --git a/libc/arch-arm64/bionic/sigsetjmp.S b/libc/include/machine/endian.h
similarity index 72%
copy from libc/arch-arm64/bionic/sigsetjmp.S
copy to libc/include/machine/endian.h
index be7cecb..ac89519 100644
--- a/libc/arch-arm64/bionic/sigsetjmp.S
+++ b/libc/include/machine/endian.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,26 +26,10 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
+#ifndef _MACHINE_ENDIAN_H_
+#define _MACHINE_ENDIAN_H_
 
-/*
- * int sigsetjmp(sigjmp_buf env, int savesigs);
- * void siglongjmp(sigjmp_buf env, int val);
- */
+/* This file is for BSD source compatibility only. Use <endian.h> or <sys/endian.h> instead. */
+#include <sys/endian.h>
 
-ENTRY(sigsetjmp)
-    cbz     w1, _setjmp
-    b       setjmp
-END(sigsetjmp)
-
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
-
-ENTRY(siglongjmp)
-    ldr     w2, .L_setjmp_magic
-    ldr     w3, [x0]
-    cmp     w2, w3
-    b.eq    _longjmp
-    b       longjmp
-END(siglongjmp)
+#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/libc/include/machine/posix_limits.h b/libc/include/machine/posix_limits.h
index 073d0df..787af5c 100644
--- a/libc/include/machine/posix_limits.h
+++ b/libc/include/machine/posix_limits.h
@@ -32,7 +32,7 @@
 
 /* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
 /* Keep it sorted. */
-#define _POSIX_ADVISORY_INFO        -1  /* posix_madvise() not implemented */
+#define _POSIX_ADVISORY_INFO        200809L
 #define _POSIX_AIO_LISTIO_MAX       2
 #define _POSIX_AIO_MAX              1
 #define _POSIX_ARG_MAX              4096
@@ -41,7 +41,7 @@
 #define _POSIX_CHILD_MAX            25
 #define _POSIX_CHOWN_RESTRICTED     1  /* yes, chown requires appropriate privileges */
 #define _POSIX_CLOCK_SELECTION      200809L
-#define _POSIX_CPUTIME              -1  /* clock_getcpuclockid() not implemented */
+#define _POSIX_CPUTIME              0  /* Use sysconf to detect support at runtime. */
 #define _POSIX_DELAYTIMER_MAX       32
 #define _POSIX_FSYNC                200809L  /* fdatasync() supported */
 #define _POSIX_HOST_NAME_MAX        255
@@ -90,7 +90,7 @@
 #define _POSIX_THREADS              200809L  /* we support threads */
 #define _POSIX_THREAD_ATTR_STACKADDR  200809L
 #define _POSIX_THREAD_ATTR_STACKSIZE  200809L
-#define _POSIX_THREAD_CPUTIME       200809L
+#define _POSIX_THREAD_CPUTIME       0  /* Use sysconf to detect support at runtime. */
 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
 #define _POSIX_THREAD_KEYS_MAX      128
 #define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 24dba1b..2178789 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -53,9 +53,13 @@
 #define  __PTHREAD_RECURSIVE_MUTEX_INIT_VALUE  0x4000
 #define  __PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE 0x8000
 
-#define  PTHREAD_MUTEX_INITIALIZER             {__PTHREAD_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
-#define  PTHREAD_RECURSIVE_MUTEX_INITIALIZER   {__PTHREAD_RECURSIVE_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
-#define  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER  {__PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
+#define PTHREAD_MUTEX_INITIALIZER {__PTHREAD_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP {__PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {__PTHREAD_RECURSIVE_MUTEX_INIT_VALUE __RESERVED_INITIALIZER}
+
+/* TODO: remove this namespace pollution. */
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
 enum {
     PTHREAD_MUTEX_NORMAL = 0,
diff --git a/libc/arch-arm64/bionic/sigsetjmp.S b/libc/include/pty.h
similarity index 72%
copy from libc/arch-arm64/bionic/sigsetjmp.S
copy to libc/include/pty.h
index be7cecb..bca1137 100644
--- a/libc/arch-arm64/bionic/sigsetjmp.S
+++ b/libc/include/pty.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,26 +26,19 @@
  * SUCH DAMAGE.
  */
 
-#include <private/bionic_asm.h>
-#include <machine/setjmp.h>
+#ifndef _PTY_H
+#define _PTY_H
 
-/*
- * int sigsetjmp(sigjmp_buf env, int savesigs);
- * void siglongjmp(sigjmp_buf env, int val);
- */
+#include <sys/cdefs.h>
 
-ENTRY(sigsetjmp)
-    cbz     w1, _setjmp
-    b       setjmp
-END(sigsetjmp)
+#include <termios.h>
+#include <sys/ioctl.h>
 
-.L_setjmp_magic:
-    .word   _JB_MAGIC__SETJMP
+__BEGIN_DECLS
 
-ENTRY(siglongjmp)
-    ldr     w2, .L_setjmp_magic
-    ldr     w3, [x0]
-    cmp     w2, w3
-    b.eq    _longjmp
-    b       longjmp
-END(siglongjmp)
+int openpty(int*, int*, char*, const struct termios*, const struct winsize*);
+int forkpty(int*, char*, const struct termios*, const struct winsize*);
+
+__END_DECLS
+
+#endif /* _PTY_H */
diff --git a/libc/include/sys/endian.h b/libc/include/sys/endian.h
index be4c905..c62ba7f 100644
--- a/libc/include/sys/endian.h
+++ b/libc/include/sys/endian.h
@@ -1,5 +1,3 @@
-/*	$OpenBSD: endian.h,v 1.17 2006/01/06 18:53:05 millert Exp $	*/
-
 /*-
  * Copyright (c) 1997 Niklas Hallqvist.  All rights reserved.
  *
@@ -24,155 +22,44 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*
- * Generic definitions for little- and big-endian systems.  Other endianesses
- * has to be dealt with in the specific machine/endian.h file for that port.
- *
- * This file is meant to be included from a little- or big-endian port's
- * machine/endian.h after setting _BYTE_ORDER to either 1234 for little endian
- * or 4321 for big..
- */
-
 #ifndef _SYS_ENDIAN_H_
 #define _SYS_ENDIAN_H_
 
 #include <sys/cdefs.h>
-#include <machine/endian.h>
 
 #include <stdint.h>
 
 #define _LITTLE_ENDIAN	1234
 #define _BIG_ENDIAN	4321
 #define _PDP_ENDIAN	3412
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#define __LITTLE_ENDIAN_BITFIELD
 
 #if __BSD_VISIBLE
-#define LITTLE_ENDIAN	_LITTLE_ENDIAN
-#define BIG_ENDIAN	_BIG_ENDIAN
-#define PDP_ENDIAN	_PDP_ENDIAN
-#define BYTE_ORDER	_BYTE_ORDER
+#define LITTLE_ENDIAN _LITTLE_ENDIAN
+#define BIG_ENDIAN _BIG_ENDIAN
+#define PDP_ENDIAN _PDP_ENDIAN
+#define BYTE_ORDER _BYTE_ORDER
 #endif
 
-#ifdef __GNUC__
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+#endif
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN _BIG_ENDIAN
+#endif
+#define __BYTE_ORDER _BYTE_ORDER
 
-#define __swap16gen(x) __statement({					\
-	__uint16_t __swap16gen_x = (x);					\
-									\
-	(__uint16_t)((__swap16gen_x & 0xff) << 8 |			\
-	    (__swap16gen_x & 0xff00) >> 8);				\
-})
-
-#define __swap32gen(x) __statement({					\
-	__uint32_t __swap32gen_x = (x);					\
-									\
-	(__uint32_t)((__swap32gen_x & 0xff) << 24 |			\
-	    (__swap32gen_x & 0xff00) << 8 |				\
-	    (__swap32gen_x & 0xff0000) >> 8 |				\
-	    (__swap32gen_x & 0xff000000) >> 24);			\
-})
-
-#define __swap64gen(x) __statement({					\
-	__uint64_t __swap64gen_x = (x);					\
-									\
-	(__uint64_t)((__swap64gen_x & 0xff) << 56 |			\
-	    (__swap64gen_x & 0xff00ULL) << 40 |				\
-	    (__swap64gen_x & 0xff0000ULL) << 24 |			\
-	    (__swap64gen_x & 0xff000000ULL) << 8 |			\
-	    (__swap64gen_x & 0xff00000000ULL) >> 8 |			\
-	    (__swap64gen_x & 0xff0000000000ULL) >> 24 |			\
-	    (__swap64gen_x & 0xff000000000000ULL) >> 40 |		\
-	    (__swap64gen_x & 0xff00000000000000ULL) >> 56);		\
-})
-
-#else /* __GNUC__ */
-
-/* Note that these macros evaluate their arguments several times.  */
-#define __swap16gen(x)							\
-    (__uint16_t)(((__uint16_t)(x) & 0xff) << 8 | ((__uint16_t)(x) & 0xff00) >> 8)
-
-#define __swap32gen(x)							\
-    (__uint32_t)(((__uint32_t)(x) & 0xff) << 24 |			\
-    ((__uint32_t)(x) & 0xff00) << 8 | ((__uint32_t)(x) & 0xff0000) >> 8 |\
-    ((__uint32_t)(x) & 0xff000000) >> 24)
-
-#define __swap64gen(x)							\
-	(__uint64_t)((((__uint64_t)(x) & 0xff) << 56) |			\
-	    ((__uint64_t)(x) & 0xff00ULL) << 40 |			\
-	    ((__uint64_t)(x) & 0xff0000ULL) << 24 |			\
-	    ((__uint64_t)(x) & 0xff000000ULL) << 8 |			\
-	    ((__uint64_t)(x) & 0xff00000000ULL) >> 8 |			\
-	    ((__uint64_t)(x) & 0xff0000000000ULL) >> 24 |		\
-	    ((__uint64_t)(x) & 0xff000000000000ULL) >> 40 |		\
-	    ((__uint64_t)(x) & 0xff00000000000000ULL) >> 56)
-
-#endif /* __GNUC__ */
-
-/*
- * Define MD_SWAP if you provide swap{16,32}md functions/macros that are
- * optimized for your architecture,  These will be used for swap{16,32}
- * unless the argument is a constant and we are using GCC, where we can
- * take advantage of the CSE phase much better by using the generic version.
- */
-#ifdef MD_SWAP
-#if __GNUC__
-
-#define __swap16(x) __statement({					\
-	__uint16_t __swap16_x = (x);					\
-									\
-	__builtin_constant_p(x) ? __swap16gen(__swap16_x) :		\
-	    __swap16md(__swap16_x);					\
-})
-
-#define __swap32(x) __statement({					\
-	__uint32_t __swap32_x = (x);					\
-									\
-	__builtin_constant_p(x) ? __swap32gen(__swap32_x) :		\
-	    __swap32md(__swap32_x);					\
-})
-
-#define __swap64(x) __statement({					\
-	__uint64_t __swap64_x = (x);					\
-									\
-	__builtin_constant_p(x) ? __swap64gen(__swap64_x) :		\
-	    __swap64md(__swap64_x);					\
-})
-
-#endif /* __GNUC__  */
-
-#else /* MD_SWAP */
-#define __swap16 __swap16gen
-#define __swap32 __swap32gen
-#define __swap64 __swap64gen
-#endif /* MD_SWAP */
-
-#define __swap16_multi(v, n) do {						\
-	__size_t __swap16_multi_n = (n);				\
-	__uint16_t *__swap16_multi_v = (v);				\
-									\
-	while (__swap16_multi_n) {					\
-		*__swap16_multi_v = swap16(*__swap16_multi_v);		\
-		__swap16_multi_v++;					\
-		__swap16_multi_n--;					\
-	}								\
-} while (0)
+#define __swap16 __builtin_bswap16
+#define __swap32 __builtin_bswap32
+#define __swap64 __builtin_bswap64
 
 #if __BSD_VISIBLE
 #define swap16 __swap16
 #define swap32 __swap32
 #define swap64 __swap64
 #define swap16_multi __swap16_multi
-#endif /* __BSD_VISIBLE */
 
-#if _BYTE_ORDER == _LITTLE_ENDIAN
-
-/* Can be overridden by machine/endian.h before inclusion of this file.  */
-#ifndef _QUAD_HIGHWORD
-#define _QUAD_HIGHWORD 1
-#endif
-#ifndef _QUAD_LOWWORD
-#define _QUAD_LOWWORD 0
-#endif
-
-#if __BSD_VISIBLE
 #define htobe16 __swap16
 #define htobe32 __swap32
 #define htobe64 __swap64
@@ -205,49 +92,6 @@
 #define htonq(x) __swap64(x)
 #define ntohq(x) __swap64(x)
 
-#define __LITTLE_ENDIAN_BITFIELD
-
-#endif /* _BYTE_ORDER */
-
-#if _BYTE_ORDER == _BIG_ENDIAN
-
-/* Can be overridden by machine/endian.h before inclusion of this file.  */
-#ifndef _QUAD_HIGHWORD
-#define _QUAD_HIGHWORD 0
-#endif
-#ifndef _QUAD_LOWWORD
-#define _QUAD_LOWWORD 1
-#endif
-
-#if __BSD_VISIBLE
-#define htole16 __swap16
-#define htole32 __swap32
-#define htole64 __swap64
-#define letoh16 __swap16
-#define letoh32 __swap32
-#define letoh64 __swap64
-
-#define htobe16(x) (x)
-#define htobe32(x) (x)
-#define htobe64(x) (x)
-#define betoh16(x) (x)
-#define betoh32(x) (x)
-#define betoh64(x) (x)
-#endif /* __BSD_VISIBLE */
-
-#define htons(x) (x)
-#define htonl(x) (x)
-#define ntohs(x) (x)
-#define ntohl(x) (x)
-
-/* Bionic additions */
-#define ntohq(x) (x)
-#define htonq(x) (x)
-
-#define __BIG_ENDIAN_BITFIELD
-
-#endif /* _BYTE_ORDER */
-
 #if __BSD_VISIBLE
 #define	NTOHL(x) (x) = ntohl((u_int32_t)(x))
 #define	NTOHS(x) (x) = ntohs((u_int16_t)(x))
@@ -255,16 +99,6 @@
 #define	HTONS(x) (x) = htons((u_int16_t)(x))
 #endif
 
-
-#define  __BYTE_ORDER       _BYTE_ORDER
-#ifndef  __LITTLE_ENDIAN
-#define  __LITTLE_ENDIAN    _LITTLE_ENDIAN
-#endif
-#ifndef  __BIG_ENDIAN
-#define  __BIG_ENDIAN       _BIG_ENDIAN
-#endif
-
-
 #ifdef __BSD_VISIBLE
 /*
  * glibc-compatible beXXtoh/leXXtoh synonyms for htobeXX/htoleXX.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 5a8c985..1663222 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -43,6 +43,12 @@
 #define MREMAP_MAYMOVE  1
 #define MREMAP_FIXED    2
 
+#define POSIX_MADV_NORMAL     MADV_NORMAL
+#define POSIX_MADV_RANDOM     MADV_RANDOM
+#define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL
+#define POSIX_MADV_WILLNEED   MADV_WILLNEED
+#define POSIX_MADV_DONTNEED   MADV_DONTNEED
+
 extern void* mmap(void*, size_t, int, int, int, off_t);
 extern void* mmap64(void*, size_t, int, int, int, off64_t);
 extern int munmap(void*, size_t);
@@ -54,13 +60,15 @@
 extern int munlockall(void);
 extern int mlock(const void*, size_t);
 extern int munlock(const void*, size_t);
-extern int madvise(const void*, size_t, int);
+extern int madvise(void*, size_t, int);
 
 extern int mlock(const void*, size_t);
 extern int munlock(const void*, size_t);
 
 extern int mincore(void*, size_t, unsigned char*);
 
+extern int posix_madvise(void*, size_t, int);
+
 __END_DECLS
 
 #endif /* _SYS_MMAN_H_ */
diff --git a/libc/include/sys/sysconf.h b/libc/include/sys/sysconf.h
index 8aa506e..ca32132 100644
--- a/libc/include/sys/sysconf.h
+++ b/libc/include/sys/sysconf.h
@@ -172,6 +172,22 @@
 #define _SC_XOPEN_STREAMS       0x008d
 #define _SC_XOPEN_UUCP          0x008e
 
+#define _SC_LEVEL1_ICACHE_SIZE      0x008f
+#define _SC_LEVEL1_ICACHE_ASSOC     0x0090
+#define _SC_LEVEL1_ICACHE_LINESIZE  0x0091
+#define _SC_LEVEL1_DCACHE_SIZE      0x0092
+#define _SC_LEVEL1_DCACHE_ASSOC     0x0093
+#define _SC_LEVEL1_DCACHE_LINESIZE  0x0094
+#define _SC_LEVEL2_CACHE_SIZE       0x0095
+#define _SC_LEVEL2_CACHE_ASSOC      0x0096
+#define _SC_LEVEL2_CACHE_LINESIZE   0x0097
+#define _SC_LEVEL3_CACHE_SIZE       0x0098
+#define _SC_LEVEL3_CACHE_ASSOC      0x0099
+#define _SC_LEVEL3_CACHE_LINESIZE   0x009a
+#define _SC_LEVEL4_CACHE_SIZE       0x009b
+#define _SC_LEVEL4_CACHE_ASSOC      0x009c
+#define _SC_LEVEL4_CACHE_LINESIZE   0x009d
+
 long sysconf(int);
 
 __END_DECLS
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index 0e36825..b370add 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -31,6 +31,7 @@
 
 #include <sys/cdefs.h>
 #include <limits.h> /* For PAGE_SIZE. */
+#include <stddef.h> /* For size_t. */
 
 __BEGIN_DECLS
 
diff --git a/libc/include/time.h b/libc/include/time.h
index e34eb34..1b0f6a1 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -85,6 +85,8 @@
 
 extern clock_t clock(void) __LIBC_ABI_PUBLIC__;
 
+extern int clock_getcpuclockid(pid_t, clockid_t*) __LIBC_ABI_PUBLIC__;
+
 extern int clock_getres(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;
 extern int clock_gettime(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;
 extern int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index d764227..ebf2372 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -91,6 +91,8 @@
 void setutent();
 struct utmp* getutent();
 
+int login_tty(int);
+
 __END_DECLS
 
 #endif /* _UTMP_H_ */
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fread.c b/libc/stdio/fread.c
similarity index 84%
rename from libc/upstream-openbsd/lib/libc/stdio/fread.c
rename to libc/stdio/fread.c
index 8a592f6..e052128 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -68,7 +68,23 @@
 		fp->_r = 0;
 	total = resid;
 	p = buf;
-	while (resid > (r = fp->_r)) {
+
+	// BEGIN android-added
+	// Avoid pathological behavior on unbuffered files. OpenBSD
+	// will loop reading one byte then memcpying one byte!
+	if ((fp->_flags & __SNBF) != 0) {
+		// We know if we're unbuffered that our buffer is empty, so
+		// we can just read directly.
+		while (resid > 0 && (r = (*fp->_read)(fp->_cookie, p, resid)) > 0) {
+			p += r;
+			resid -= r;
+		}
+		FUNLOCKFILE(fp);
+		return ((total - resid) / size);
+	}
+	// END android-added
+
+	while (resid > (size_t)(r = fp->_r)) {
 		(void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
 		fp->_p += r;
 		/* fp->_r = 0 ... done in __srefill */
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 0c7e28e..153b840 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -81,12 +81,12 @@
   '__xpg_basename': '__gnu_basename',
 }
 
-glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*')
+glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*', 'libutil.so.*')
 bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
 posix = GetSymbolsFromTxt(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'posix-2013.txt'))
 ndk_ignored = GetNdkIgnored()
 
-glibc = map(MangleGlibcNameToBionic, glibc)
+glibc = set(map(MangleGlibcNameToBionic, glibc))
 
 # bionic includes various BSD symbols to ease porting other BSD-licensed code.
 bsd_stuff = set([
@@ -189,21 +189,26 @@
 ])
 
 if not only_unwanted:
-  print 'glibc:'
-  for symbol in sorted(glibc):
-    print symbol
+  #print 'glibc:'
+  #for symbol in sorted(glibc):
+  #  print symbol
+  #print
 
-  print
-  print 'bionic:'
-  for symbol in sorted(bionic):
-    print symbol
+  #print 'bionic:'
+  #for symbol in sorted(bionic):
+  #  print symbol
+  #print
 
-  print
-  print 'in posix but not bionic:'
-  for symbol in sorted(posix.difference(bionic)):
+  print 'in glibc (but not posix) but not bionic:'
+  for symbol in sorted((glibc - posix).difference(bionic)):
     print symbol
-
   print
+
+  print 'in posix (and implemented in glibc) but not bionic:'
+  for symbol in sorted((posix.intersection(glibc)).difference(bionic)):
+    print symbol
+  print
+
   print 'in bionic but not glibc:'
 
 allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
diff --git a/libc/arch-x86_64/include/machine/fpu.h b/libm/include/amd64/machine/fpu.h
similarity index 100%
rename from libc/arch-x86_64/include/machine/fpu.h
rename to libm/include/amd64/machine/fpu.h
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 2486e02..7ef94c0 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -29,7 +29,7 @@
 
 /* This file hijacks the symbols stubbed out in libdl.so. */
 
-static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
 static const char* __bionic_set_dlerror(char* new_value) {
   char** dlerror_slot = &reinterpret_cast<char**>(__get_tls())[TLS_SLOT_DLERROR];
@@ -236,16 +236,17 @@
 
 // This is used by the dynamic linker. Every process gets these symbols for free.
 soinfo* get_libdl_info() {
-  if ((__libdl_info.flags & FLAG_LINKED) == 0) {
-    __libdl_info.flags |= FLAG_LINKED;
+  if ((__libdl_info.flags_ & FLAG_LINKED) == 0) {
+    __libdl_info.flags_ |= FLAG_LINKED;
     __libdl_info.strtab_ = ANDROID_LIBDL_STRTAB;
     __libdl_info.symtab_ = g_libdl_symtab;
     __libdl_info.nbucket_ = sizeof(g_libdl_buckets)/sizeof(unsigned);
     __libdl_info.nchain_ = sizeof(g_libdl_chains)/sizeof(unsigned);
     __libdl_info.bucket_ = g_libdl_buckets;
     __libdl_info.chain_ = g_libdl_chains;
-    __libdl_info.ref_count = 1;
+    __libdl_info.ref_count_ = 1;
     __libdl_info.strtab_size_ = sizeof(ANDROID_LIBDL_STRTAB);
+    __libdl_info.local_group_root_ = &__libdl_info;
   }
 
   return &__libdl_info;
diff --git a/linker/linked_list.h b/linker/linked_list.h
index b088061..a72b73c 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -81,6 +81,14 @@
     return element;
   }
 
+  T* front() const {
+    if (head_ == nullptr) {
+      return nullptr;
+    }
+
+    return head_->element;
+  }
+
   void clear() {
     while (head_ != nullptr) {
       LinkedListEntry<T>* p = head_;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 1d68db5..3409931 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -230,7 +230,7 @@
 }
 
 static void notify_gdb_of_load(soinfo* info) {
-  if (info->flags & FLAG_EXE) {
+  if (info->is_main_executable()) {
     // GDB already knows about the main executable
     return;
   }
@@ -247,7 +247,7 @@
 }
 
 static void notify_gdb_of_unload(soinfo* info) {
-  if (info->flags & FLAG_EXE) {
+  if (info->is_main_executable()) {
     // GDB already knows about the main executable
     return;
   }
@@ -320,7 +320,7 @@
 
   if (trav == nullptr) {
     // si was not in solist
-    DL_ERR("name \"%s\" is not in solist!", si->name);
+    DL_ERR("name \"%s\"@%p is not in solist!", si->name, si);
     return;
   }
 
@@ -490,7 +490,7 @@
   memset(this, 0, sizeof(*this));
 
   strlcpy(this->name, name, sizeof(this->name));
-  flags = FLAG_NEW_SOINFO;
+  flags_ = FLAG_NEW_SOINFO;
   version_ = SOINFO_VERSION;
 
   if (file_stat != nullptr) {
@@ -986,21 +986,6 @@
 
 static void soinfo_unload(soinfo* si);
 
-static bool is_recursive(soinfo* si, soinfo* parent) {
-  if (parent == nullptr) {
-    return false;
-  }
-
-  if (si == parent) {
-    DL_ERR("recursive link to \"%s\"", si->name);
-    return true;
-  }
-
-  return !parent->get_parents().visit([&](soinfo* grandparent) {
-    return !is_recursive(si, grandparent);
-  });
-}
-
 // TODO: this is slightly unusual way to construct
 // the global group for relocation. Not every RTLD_GLOBAL
 // library is included in this group for backwards-compatibility
@@ -1067,15 +1052,14 @@
 
     soinfo* needed_by = task->get_needed_by();
 
-    if (is_recursive(si, needed_by)) {
-      return false;
-    }
-
-    si->ref_count++;
     if (needed_by != nullptr) {
       needed_by->add_child(si);
     }
 
+    if (si->is_linked()) {
+      si->increment_ref_count();
+    }
+
     // When ld_preloads is not null, the first
     // ld_preloads_count libs are in fact ld_preloads.
     if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
@@ -1102,12 +1086,16 @@
     return true;
   });
 
+  // We need to increment ref_count in case
+  // the root of the local group was not linked.
+  bool was_local_group_root_linked = local_group.front()->is_linked();
+
   bool linked = local_group.visit([&](soinfo* si) {
-    if ((si->flags & FLAG_LINKED) == 0) {
+    if (!si->is_linked()) {
       if (!si->link_image(global_group, local_group, extinfo)) {
         return false;
       }
-      si->flags |= FLAG_LINKED;
+      si->set_linked();
     }
 
     return true;
@@ -1117,72 +1105,111 @@
     failure_guard.disable();
   }
 
+  if (!was_local_group_root_linked) {
+    local_group.front()->increment_ref_count();
+  }
+
   return linked;
 }
 
 static soinfo* find_library(const char* name, int rtld_flags, const android_dlextinfo* extinfo) {
-  if (name == nullptr) {
-    somain->ref_count++;
-    return somain;
-  }
-
   soinfo* si;
 
-  if (!find_libraries(nullptr, &name, 1, &si, nullptr, 0, rtld_flags, extinfo)) {
+  if (name == nullptr) {
+    si = somain;
+  } else if (!find_libraries(nullptr, &name, 1, &si, nullptr, 0, rtld_flags, extinfo)) {
     return nullptr;
   }
 
   return si;
 }
 
-static void soinfo_unload_schedule(soinfo::soinfo_list_t& unload_list, soinfo* si) {
-  if (!si->can_unload()) {
-    TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->name);
+static void soinfo_unload(soinfo* root) {
+  // Note that the library can be loaded but not linked;
+  // in which case there is no root but we still need
+  // to walk the tree and unload soinfos involved.
+  //
+  // This happens on unsuccessful dlopen, when one of
+  // the DT_NEEDED libraries could not be linked/found.
+  if (root->is_linked()) {
+    root = root->get_local_group_root();
+  }
+
+  if (!root->can_unload()) {
+    TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->name);
     return;
   }
 
-  if (si->ref_count == 1) {
-    unload_list.push_back(si);
+  size_t ref_count = root->is_linked() ? root->decrement_ref_count() : 0;
 
-    if (si->has_min_version(0)) {
-      soinfo* child = nullptr;
-      while ((child = si->get_children().pop_front()) != nullptr) {
-        TRACE("%s needs to unload %s", si->name, child->name);
-        soinfo_unload_schedule(unload_list, child);
+  if (ref_count == 0) {
+    soinfo::soinfo_list_t local_unload_list;
+    soinfo::soinfo_list_t external_unload_list;
+    soinfo::soinfo_list_t depth_first_list;
+    depth_first_list.push_back(root);
+    soinfo* si = nullptr;
+
+    while ((si = depth_first_list.pop_front()) != nullptr) {
+      if (local_unload_list.contains(si)) {
+        continue;
       }
-    } else {
-      for_each_dt_needed(si, [&] (const char* library_name) {
-        TRACE("deprecated (old format of soinfo): %s needs to unload %s", si->name, library_name);
-        soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
-        if (needed != nullptr) {
-          soinfo_unload_schedule(unload_list, needed);
-        } else {
-          // Not found: for example if symlink was deleted between dlopen and dlclose
-          // Since we cannot really handle errors at this point - print and continue.
-          PRINT("warning: couldn't find %s needed by %s on unload.", library_name, si->name);
+
+      local_unload_list.push_back(si);
+
+      if (si->has_min_version(0)) {
+        soinfo* child = nullptr;
+        while ((child = si->get_children().pop_front()) != nullptr) {
+          TRACE("%s@%p needs to unload %s@%p", si->name, si, child->name, child);
+          if (local_unload_list.contains(child)) {
+            continue;
+          } else if (child->is_linked() && child->get_local_group_root() != root) {
+            external_unload_list.push_back(child);
+          } else {
+            depth_first_list.push_front(child);
+          }
         }
-      });
+      } else {
+#ifdef __LP64__
+        __libc_fatal("soinfo for \"%s\"@%p has no version", si->name, si);
+#else
+        PRINT("warning: soinfo for \"%s\"@%p has no version", si->name, si);
+        for_each_dt_needed(si, [&] (const char* library_name) {
+          TRACE("deprecated (old format of soinfo): %s needs to unload %s", si->name, library_name);
+          soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
+          if (needed != nullptr) {
+            // Not found: for example if symlink was deleted between dlopen and dlclose
+            // Since we cannot really handle errors at this point - print and continue.
+            PRINT("warning: couldn't find %s needed by %s on unload.", library_name, si->name);
+            return;
+          } else if (local_unload_list.contains(needed)) {
+            // already visited
+            return;
+          } else if (needed->is_linked() && needed->get_local_group_root() != root) {
+            // external group
+            external_unload_list.push_back(needed);
+          } else {
+            // local group
+            depth_first_list.push_front(needed);
+          }
+        });
+#endif
+      }
     }
 
-    si->ref_count = 0;
+    local_unload_list.for_each([](soinfo* si) {
+      si->call_destructors();
+    });
+
+    while ((si = local_unload_list.pop_front()) != nullptr) {
+      notify_gdb_of_unload(si);
+      soinfo_free(si);
+    }
+
+    while ((si = external_unload_list.pop_front()) != nullptr) {
+      soinfo_unload(si);
+    }
   } else {
-    si->ref_count--;
-    TRACE("not unloading '%s', decrementing ref_count to %zd", si->name, si->ref_count);
-  }
-}
-
-static void soinfo_unload(soinfo* root) {
-  soinfo::soinfo_list_t unload_list;
-  soinfo_unload_schedule(unload_list, root);
-  unload_list.for_each([](soinfo* si) {
-    si->call_destructors();
-  });
-
-  soinfo* si = nullptr;
-  while ((si = unload_list.pop_front()) != nullptr) {
-    TRACE("unloading '%s'", si->name);
-    notify_gdb_of_unload(si);
-    soinfo_free(si);
+    TRACE("not unloading '%s' group, decrementing ref_count to %zd", root->name, ref_count);
   }
 }
 
@@ -1743,7 +1770,7 @@
   // got[1] may be used for a GNU extension.
   // Set it to a recognizable address in case someone calls it (should be _rtld_bind_start).
   // FIXME: maybe this should be in a separate routine?
-  if ((flags & FLAG_LINKER) == 0) {
+  if ((flags_ & FLAG_LINKER) == 0) {
     size_t g = 0;
     got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadbeef);
     if (reinterpret_cast<intptr_t>(got[g]) < 0) {
@@ -1838,7 +1865,7 @@
   //    out above, the libc constructor will be called again (recursively!).
   constructors_called = true;
 
-  if ((flags & FLAG_EXE) == 0 && preinit_array_ != nullptr) {
+  if (!is_main_executable() && preinit_array_ != nullptr) {
     // The GNU dynamic linker silently ignores these, but we warn the developer.
     PRINT("\"%s\": ignoring %zd-entry DT_PREINIT_ARRAY in shared library!",
           name, preinit_array_count_);
@@ -1992,13 +2019,45 @@
 }
 
 bool soinfo::is_gnu_hash() const {
-  return (flags & FLAG_GNU_HASH) != 0;
+  return (flags_ & FLAG_GNU_HASH) != 0;
 }
 
 bool soinfo::can_unload() const {
   return (get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0;
 }
 
+bool soinfo::is_linked() const {
+  return (flags_ & FLAG_LINKED) != 0;
+}
+
+bool soinfo::is_main_executable() const {
+  return (flags_ & FLAG_EXE) != 0;
+}
+
+void soinfo::set_linked() {
+  flags_ |= FLAG_LINKED;
+}
+
+void soinfo::set_linker_flag() {
+  flags_ |= FLAG_LINKER;
+}
+
+void soinfo::set_main_executable() {
+  flags_ |= FLAG_EXE;
+}
+
+void soinfo::increment_ref_count() {
+  local_group_root_->ref_count_++;
+}
+
+size_t soinfo::decrement_ref_count() {
+  return --local_group_root_->ref_count_;
+}
+
+soinfo* soinfo::get_local_group_root() const {
+  return local_group_root_;
+}
+
 /* Force any of the closed stdin, stdout and stderr to be associated with
    /dev/null. */
 static int nullify_closed_stdio() {
@@ -2066,10 +2125,10 @@
   phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
 
   /* We can't log anything until the linker is relocated */
-  bool relocating_linker = (flags & FLAG_LINKER) != 0;
+  bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
   if (!relocating_linker) {
     INFO("[ linking %s ]", name);
-    DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags);
+    DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
   }
 
   if (dynamic == nullptr) {
@@ -2133,7 +2192,7 @@
         }
         --gnu_maskwords_;
 
-        flags |= FLAG_GNU_HASH;
+        flags_ |= FLAG_GNU_HASH;
         break;
 
       case DT_STRTAB:
@@ -2370,6 +2429,8 @@
       case DT_VERSYM:
       case DT_VERDEF:
       case DT_VERDEFNUM:
+      case DT_VERNEED:
+      case DT_VERNEEDNUM:
         break;
 
       default:
@@ -2406,6 +2467,11 @@
 
 bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group, const android_dlextinfo* extinfo) {
 
+  local_group_root_ = local_group.front();
+  if (local_group_root_ == nullptr) {
+    local_group_root_ = this;
+  }
+
 #if !defined(__LP64__)
   if (has_text_relocations) {
     // Make segments writable to allow text relocations to work properly. We will later call
@@ -2598,7 +2664,7 @@
   }
 
   /* bootstrap the link map, the main exe always needs to be first */
-  si->flags |= FLAG_EXE;
+  si->set_main_executable();
   link_map* map = &(si->link_map_head);
 
   map->l_addr = 0;
@@ -2631,7 +2697,6 @@
     }
   }
   si->dynamic = nullptr;
-  si->ref_count = 1;
 
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
   if (elf_hdr->e_type != ET_DYN) {
@@ -2672,6 +2737,12 @@
   if (needed_libraries_count > 0 && !find_libraries(si, needed_library_names, needed_libraries_count, nullptr, g_ld_preloads, ld_preloads_count, RTLD_GLOBAL, nullptr)) {
     __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
     exit(EXIT_FAILURE);
+  } else if (needed_libraries_count == 0) {
+    if (!si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr)) {
+      __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
+      exit(EXIT_FAILURE);
+    }
+    si->increment_ref_count();
   }
 
   add_vdso(args);
@@ -2791,7 +2862,7 @@
   linker_so.dynamic = nullptr;
   linker_so.phdr = phdr;
   linker_so.phnum = elf_hdr->e_phnum;
-  linker_so.flags |= FLAG_LINKER;
+  linker_so.set_linker_flag();
 
   // This might not be obvious... The reasons why we pass g_empty_list
   // in place of local_group here are (1) we do not really need it, because
diff --git a/linker/linker.h b/linker/linker.h
index d28f70e..f7aa11c 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -161,9 +161,9 @@
 #endif
 
   soinfo* next;
-  uint32_t flags;
-
  private:
+  uint32_t flags_;
+
   const char* strtab_;
   ElfW(Sym)* symtab_;
 
@@ -203,22 +203,21 @@
   linker_function_t init_func_;
   linker_function_t fini_func_;
 
- public:
 #if defined(__arm__)
+ public:
   // ARM EABI section used for stack unwinding.
   uint32_t* ARM_exidx;
   size_t ARM_exidx_count;
-#elif defined(__mips__)
  private:
+#elif defined(__mips__)
   uint32_t mips_symtabno_;
   uint32_t mips_local_gotno_;
   uint32_t mips_gotsym_;
   bool mips_relocate_got(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
 
 #endif
-
+  size_t ref_count_;
  public:
-  size_t ref_count;
   link_map link_map_head;
 
   bool constructors_called;
@@ -264,9 +263,21 @@
   bool is_gnu_hash() const;
 
   bool inline has_min_version(uint32_t min_version) const {
-    return (flags & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
+    return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
   }
 
+  bool is_linked() const;
+  bool is_main_executable() const;
+
+  void set_linked();
+  void set_linker_flag();
+  void set_main_executable();
+
+  void increment_ref_count();
+  size_t decrement_ref_count();
+
+  soinfo* get_local_group_root() const;
+
  private:
   ElfW(Sym)* elf_lookup(SymbolName& symbol_name);
   ElfW(Sym)* elf_addr_lookup(const void* addr);
@@ -303,9 +314,10 @@
   // version >= 2
   uint32_t gnu_maskwords_;
   uint32_t gnu_shift2_;
-
   ElfW(Addr)* gnu_bloom_filter_;
 
+  soinfo* local_group_root_;
+
   friend soinfo* get_libdl_info();
 };
 
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 61ae5ab..ffd4de2 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -29,7 +29,6 @@
 #include "linker_phdr.h"
 
 #include <errno.h>
-#include <machine/exec.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -38,6 +37,20 @@
 #include "linker.h"
 #include "linker_debug.h"
 
+static int GetTargetElfMachine() {
+#if defined(__arm__)
+  return EM_ARM;
+#elif defined(__aarch64__)
+  return EM_AARCH64;
+#elif defined(__i386__)
+  return EM_386;
+#elif defined(__mips__)
+  return EM_MIPS;
+#elif defined(__x86_64__)
+  return EM_X86_64;
+#endif
+}
+
 /**
   TECHNICAL NOTE ON ELF LOADING.
 
@@ -200,7 +213,7 @@
     return false;
   }
 
-  if (header_.e_machine != ELF_TARG_MACH) {
+  if (header_.e_machine != GetTargetElfMachine()) {
     DL_ERR("\"%s\" has unexpected e_machine: %d", name_, header_.e_machine);
     return false;
   }
diff --git a/tests/Android.mk b/tests/Android.mk
index 92d7976..3f5a112 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -72,10 +72,12 @@
     mntent_test.cpp \
     netdb_test.cpp \
     pthread_test.cpp \
+    pty_test.cpp \
     regex_test.cpp \
     sched_test.cpp \
     search_test.cpp \
     semaphore_test.cpp \
+    setjmp_test.cpp \
     signal_test.cpp \
     stack_protector_test.cpp \
     stack_unwinding_test.cpp \
@@ -107,6 +109,7 @@
     uchar_test.cpp \
     uniqueptr_test.cpp \
     unistd_test.cpp \
+    utmp_test.cpp \
     wchar_test.cpp \
 
 libBionicStandardTests_cflags := \
@@ -308,7 +311,7 @@
     libBionicStandardTests \
 
 bionic-unit-tests-glibc_ldlibs := \
-    -lrt -ldl \
+    -lrt -ldl -lutil \
 
 bionic-unit-tests-glibc_c_includes := \
     bionic/libc \
@@ -372,14 +375,6 @@
 # Host glibc tests.
 # -----------------------------------------------------------------------------
 
-ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
-LINKER = linker64
-NATIVE_TEST_SUFFIX=64
-else
-LINKER = linker
-NATIVE_TEST_SUFFIX=32
-endif
-
 # gtest needs ANDROID_DATA/local/tmp for death test output.
 # Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
 # Use the current target out directory as ANDROID_DATA.
@@ -388,44 +383,32 @@
 	mkdir -p $(TARGET_OUT_DATA)/local/tmp
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_ROOT=$(TARGET_OUT) \
-		$(HOST_OUT_EXECUTABLES)/bionic-unit-tests-glibc$(NATIVE_TEST_SUFFIX) $(BIONIC_TEST_FLAGS)
+		$(HOST_OUT_EXECUTABLES)/bionic-unit-tests-glibc64 $(BIONIC_TEST_FLAGS)
 
 # -----------------------------------------------------------------------------
 # Run the unit tests built against x86 bionic on an x86 host.
 # -----------------------------------------------------------------------------
 
+include $(LOCAL_PATH)/../build/run-on-host.mk
+
 ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
-# gtest needs ANDROID_DATA/local/tmp for death test output.
-# Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
-# bionic itself should always work relative to ANDROID_DATA or ANDROID_ROOT.
 # BIONIC_TEST_FLAGS is either empty or it comes from the user.
-bionic-unit-tests-run-on-host-prepare: $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT)/etc/hosts $(TARGET_OUT_EXECUTABLES)/sh
-	if [ ! -d /system ]; then \
-	  echo "Attempting to create /system"; \
-	  sudo mkdir -p -m 0777 /system; \
-	fi
-	mkdir -p $(TARGET_OUT_DATA)/local/tmp
-	ln -fs `realpath $(TARGET_OUT)/bin` /system/
-	ln -fs `realpath $(TARGET_OUT)/etc` /system/
-
-bionic-unit-tests-run-on-host: bionic-unit-tests bionic-unit-tests-run-on-host-prepare
+bionic-unit-tests-run-on-host32: bionic-unit-tests bionic-prepare-run-on-host
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_DNS_MODE=local \
 	ANDROID_ROOT=$(TARGET_OUT) \
-	LD_LIBRARY_PATH=$(TARGET_OUT_SHARED_LIBRARIES) \
-		$(TARGET_OUT_DATA_NATIVE_TESTS)/bionic-unit-tests/bionic-unit-tests$(NATIVE_TEST_SUFFIX) $(BIONIC_TEST_FLAGS)
-endif
+		$(TARGET_OUT_DATA)/nativetest/bionic-unit-tests/bionic-unit-tests32 $(BIONIC_TEST_FLAGS)
 
-ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
-# add target to run lp32 tests
-bionic-unit-tests-run-on-host32: bionic-unit-tests_32 bionic-unit-tests-run-on-host-prepare
+ifeq ($(TARGET_IS_64_BIT),true)
+# add target to run lp64 tests
+bionic-unit-tests-run-on-host64: bionic-unit-tests bionic-prepare-run-on-host
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_DNS_MODE=local \
 	ANDROID_ROOT=$(TARGET_OUT) \
-	LD_LIBRARY_PATH=$(2ND_TARGET_OUT_SHARED_LIBRARIES) \
-		$(2ND_TARGET_OUT_DATA_NATIVE_TESTS)/bionic-unit-tests/bionic-unit-tests32 $(BIONIC_TEST_FLAGS)
+		$(TARGET_OUT_DATA)/nativetest64/bionic-unit-tests/bionic-unit-tests64 $(BIONIC_TEST_FLAGS)
 endif
 
+endif # x86 x86_64
 endif # linux-x86
 
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index ea20869..c988d29 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdint.h>
 
+#include "gtest_ex.h"
 #include "private/ScopeGuard.h"
 
 #include <string>
@@ -362,6 +363,48 @@
   ASSERT_EQ(0, dlclose(handle));
 }
 
+TEST(dlfcn, check_unload_after_reloc) {
+  // This is how this one works:
+  // libtest_two_parents_parent1 <- answer_impl() used by libtest_two_parents_child
+  // |
+  // +-> libtest_two_parents_child
+  //
+  // libtest_two_parents_parent2 <- answer_impl() not used by libtest_two_parents_child
+  // |
+  // +-> libtest_two_parents_child
+  //
+  // Test dlopens parent1 which loads and relocates libtest_two_parents_child.so
+  // as a second step it dlopens parent2 and dlcloses parent1...
+
+  test_isolated([] {
+    void* handle = dlopen("libtest_two_parents_parent1.so", RTLD_NOW | RTLD_LOCAL);
+    ASSERT_TRUE(handle != nullptr) << dlerror();
+
+    void* handle2 = dlopen("libtest_two_parents_parent2.so", RTLD_NOW | RTLD_LOCAL);
+    ASSERT_TRUE(handle2 != nullptr) << dlerror();
+
+    typedef int (*fn_t) (void);
+    fn_t fn = reinterpret_cast<fn_t>(dlsym(handle2, "check_order_reloc_get_answer"));
+    ASSERT_TRUE(fn != nullptr) << dlerror();
+    ASSERT_EQ(42, fn());
+
+    ASSERT_EQ(0, dlclose(handle));
+
+    handle = dlopen("libtest_two_parents_parent1.so", RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD);
+    ASSERT_TRUE(handle != nullptr);
+    ASSERT_EQ(0, dlclose(handle));
+
+    fn = reinterpret_cast<fn_t>(dlsym(handle2, "check_order_reloc_get_answer"));
+    ASSERT_TRUE(fn != nullptr) << dlerror();
+    ASSERT_EQ(42, fn());
+
+    ASSERT_EQ(0, dlclose(handle2));
+
+    handle = dlopen("libtest_two_parents_parent1.so", RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD);
+    ASSERT_TRUE(handle == nullptr);
+  });
+}
+
 extern "C" int check_order_reloc_root_get_answer_impl() {
   return 42;
 }
@@ -442,25 +485,25 @@
 // libtest_with_dependency_loop_b.so -> libtest_with_dependency_loop_c.so ->
 // libtest_with_dependency_loop_a.so
 TEST(dlfcn, dlopen_check_loop) {
-  void* handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW);
-#if defined(__BIONIC__)
-  ASSERT_TRUE(handle == nullptr);
-  ASSERT_STREQ("dlopen failed: recursive link to \"libtest_with_dependency_loop_a.so\"", dlerror());
-  // This symbol should never be exposed
-  void* f = dlsym(RTLD_DEFAULT, "dlopen_test_invalid_function");
-  ASSERT_TRUE(f == nullptr);
-  ASSERT_SUBSTR("undefined symbol: dlopen_test_invalid_function", dlerror());
+  test_isolated([] {
+    void* handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW);
+    ASSERT_TRUE(handle != nullptr) << dlerror();
+    void* f = dlsym(handle, "dlopen_test_loopy_function");
+    ASSERT_TRUE(f != nullptr) << dlerror();
+    EXPECT_TRUE(reinterpret_cast<bool (*)(void)>(f)());
+    ASSERT_EQ(0, dlclose(handle));
 
-  // dlopen second time to make sure that the library wasn't loaded even though dlopen returned null.
-  // This may happen if during cleanup the root library or one of the depended libs were not removed
-  // from soinfo list.
-  handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW | RTLD_NOLOAD);
-  ASSERT_TRUE(handle == nullptr);
-  ASSERT_STREQ("dlopen failed: library \"libtest_with_dependency_loop.so\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
-#else // glibc allows recursive links
-  ASSERT_TRUE(handle != nullptr);
-  dlclose(handle);
+    // dlopen second time to make sure that the library was unloaded correctly
+    handle = dlopen("libtest_with_dependency_loop.so", RTLD_NOW | RTLD_NOLOAD);
+    ASSERT_TRUE(handle == nullptr);
+#ifdef __BIONIC__
+    // TODO: glibc returns nullptr on dlerror() here. Is it bug?
+    ASSERT_STREQ("dlopen failed: library \"libtest_with_dependency_loop.so\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
 #endif
+
+    handle = dlopen("libtest_with_dependency_a.so", RTLD_NOW | RTLD_NOLOAD);
+    ASSERT_TRUE(handle == nullptr);
+  });
 }
 
 TEST(dlfcn, dlopen_nodelete) {
diff --git a/tests/libs/Android.build.dlopen_2_parents_reloc.mk b/tests/libs/Android.build.dlopen_2_parents_reloc.mk
new file mode 100644
index 0000000..29ae10d
--- /dev/null
+++ b/tests/libs/Android.build.dlopen_2_parents_reloc.mk
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# -----------------------------------------------------------------------------
+# Libraries used by dlfcn tests to verify local group ref_counting
+# libtest_two_parents*.so
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# ..._child.so - correct answer
+# -----------------------------------------------------------------------------
+libtest_two_parents_child_src_files := \
+    dlopen_2_parents_reloc_answer.cpp
+
+module := libtest_two_parents_child
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# ..._parent1.so - correct answer
+# -----------------------------------------------------------------------------
+libtest_two_parents_parent1_src_files := \
+    dlopen_check_order_reloc_answer_impl.cpp
+
+libtest_two_parents_parent1_shared_libraries := libtest_two_parents_child
+libtest_two_parents_parent1_cflags := -D__ANSWER=42
+module := libtest_two_parents_parent1
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# ..._parent2.so - incorrect answer
+# -----------------------------------------------------------------------------
+libtest_two_parents_parent2_src_files := \
+    dlopen_check_order_reloc_answer_impl.cpp
+
+libtest_two_parents_parent2_shared_libraries := libtest_two_parents_child
+libtest_two_parents_parent2_cflags := -D__ANSWER=1
+module := libtest_two_parents_parent2
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index fafb9e0..e4620f5 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -21,6 +21,7 @@
 common_additional_dependencies := \
     $(LOCAL_PATH)/Android.mk \
     $(LOCAL_PATH)/Android.build.dlext_testzip.mk \
+    $(LOCAL_PATH)/Android.build.dlopen_2_parents_reloc.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_dlsym.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_reloc_siblings.mk \
     $(LOCAL_PATH)/Android.build.dlopen_check_order_reloc_main_executable.mk \
@@ -166,6 +167,11 @@
 include $(LOCAL_PATH)/Android.build.testlib.mk
 
 # -----------------------------------------------------------------------------
+# Build library with two parents
+# -----------------------------------------------------------------------------
+include $(LOCAL_PATH)/Android.build.dlopen_2_parents_reloc.mk
+
+# -----------------------------------------------------------------------------
 # Build libtest_check_order_dlsym.so with its dependencies.
 # -----------------------------------------------------------------------------
 include $(LOCAL_PATH)/Android.build.dlopen_check_order_dlsym.mk
@@ -185,7 +191,7 @@
 #
 # libtest_with_dependency_loop -> a -> b -> c -> a
 # -----------------------------------------------------------------------------
-libtest_with_dependency_loop_src_files := dlopen_testlib_invalid.cpp
+libtest_with_dependency_loop_src_files := dlopen_testlib_loopy_root.cpp
 
 libtest_with_dependency_loop_shared_libraries := \
     libtest_with_dependency_loop_a
@@ -196,7 +202,7 @@
 # -----------------------------------------------------------------------------
 # libtest_with_dependency_loop_a.so
 # -----------------------------------------------------------------------------
-libtest_with_dependency_loop_a_src_files := dlopen_testlib_invalid.cpp
+libtest_with_dependency_loop_a_src_files := dlopen_testlib_loopy_a.cpp
 
 libtest_with_dependency_loop_a_shared_libraries := \
     libtest_with_dependency_loop_b_tmp
@@ -209,7 +215,7 @@
 #
 # this is temporary placeholder - will be removed
 # -----------------------------------------------------------------------------
-libtest_with_dependency_loop_b_tmp_src_files := dlopen_testlib_invalid.cpp
+libtest_with_dependency_loop_b_tmp_src_files := dlopen_testlib_loopy_invalid.cpp
 libtest_with_dependency_loop_b_tmp_ldflags := -Wl,-soname=libtest_with_dependency_loop_b.so
 
 module := libtest_with_dependency_loop_b_tmp
@@ -218,7 +224,7 @@
 # -----------------------------------------------------------------------------
 # libtest_with_dependency_loop_b.so
 # -----------------------------------------------------------------------------
-libtest_with_dependency_loop_b_src_files := dlopen_testlib_invalid.cpp
+libtest_with_dependency_loop_b_src_files := dlopen_testlib_loopy_b.cpp
 libtest_with_dependency_loop_b_shared_libraries := libtest_with_dependency_loop_c
 
 module := libtest_with_dependency_loop_b
@@ -227,7 +233,7 @@
 # -----------------------------------------------------------------------------
 # libtest_with_dependency_loop_c.so
 # -----------------------------------------------------------------------------
-libtest_with_dependency_loop_c_src_files := dlopen_testlib_invalid.cpp
+libtest_with_dependency_loop_c_src_files := dlopen_testlib_loopy_c.cpp
 
 libtest_with_dependency_loop_c_shared_libraries := \
     libtest_with_dependency_loop_a
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_2_parents_reloc_answer.cpp
similarity index 69%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/libs/dlopen_2_parents_reloc_answer.cpp
index f2039c6..036670b 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_2_parents_reloc_answer.cpp
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#include <stdlib.h>
+extern "C" int __attribute__((weak)) check_order_reloc_get_answer_impl() {
+  return 0;
+}
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+extern "C" int check_order_reloc_get_answer() {
+  return check_order_reloc_get_answer_impl();
 }
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_testlib_loopy_a.cpp
similarity index 71%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/libs/dlopen_testlib_loopy_a.cpp
index f2039c6..4c08764 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_testlib_loopy_a.cpp
@@ -16,9 +16,10 @@
 
 #include <stdlib.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+extern "C" bool __attribute__((weak)) dlopen_test_loopy_function_impl() {
+  return false;
+}
+
+extern "C" bool dlopen_test_loopy_function() {
+  return dlopen_test_loopy_function_impl();
 }
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_testlib_loopy_b.cpp
similarity index 71%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/libs/dlopen_testlib_loopy_b.cpp
index f2039c6..01dcda9 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_testlib_loopy_b.cpp
@@ -16,9 +16,6 @@
 
 #include <stdlib.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+extern "C" bool dlopen_test_loopy_function_impl() {
+  return false;
 }
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_testlib_loopy_c.cpp
similarity index 71%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/libs/dlopen_testlib_loopy_c.cpp
index f2039c6..01dcda9 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_testlib_loopy_c.cpp
@@ -16,9 +16,6 @@
 
 #include <stdlib.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+extern "C" bool dlopen_test_loopy_function_impl() {
+  return false;
 }
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_testlib_loopy_invalid.cpp
similarity index 72%
rename from tests/libs/dlopen_testlib_invalid.cpp
rename to tests/libs/dlopen_testlib_loopy_invalid.cpp
index f2039c6..5aa11f8 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_testlib_loopy_invalid.cpp
@@ -16,9 +16,8 @@
 
 #include <stdlib.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
+// This library should never be loaded
+static void __attribute__((constructor)) panic() {
   abort();
 }
+
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/libs/dlopen_testlib_loopy_root.cpp
similarity index 71%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/libs/dlopen_testlib_loopy_root.cpp
index f2039c6..c9459f0 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/libs/dlopen_testlib_loopy_root.cpp
@@ -16,9 +16,6 @@
 
 #include <stdlib.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+extern "C" bool dlopen_test_loopy_function_impl() {
+  return true;
 }
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
new file mode 100644
index 0000000..7fe97e9
--- /dev/null
+++ b/tests/pty_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <pty.h>
+#include <sys/ioctl.h>
+
+TEST(pty, openpty) {
+  int master, slave;
+  char name[32];
+  struct winsize w = { 123, 456, 9999, 999 };
+  ASSERT_EQ(0, openpty(&master, &slave, name, NULL, &w));
+  ASSERT_NE(-1, master);
+  ASSERT_NE(-1, slave);
+  ASSERT_NE(master, slave);
+
+  char tty_name[32];
+  ASSERT_EQ(0, ttyname_r(slave, tty_name, sizeof(tty_name)));
+  ASSERT_STREQ(tty_name, name);
+
+  struct winsize w_actual;
+  ASSERT_EQ(0, ioctl(slave, TIOCGWINSZ, &w_actual));
+  ASSERT_EQ(w_actual.ws_row, w.ws_row);
+  ASSERT_EQ(w_actual.ws_col, w.ws_col);
+  ASSERT_EQ(w_actual.ws_xpixel, w.ws_xpixel);
+  ASSERT_EQ(w_actual.ws_ypixel, w.ws_ypixel);
+
+  close(master);
+  close(slave);
+}
+
+TEST(pty, forkpty) {
+  pid_t sid = getsid(0);
+
+  int master;
+  pid_t pid = forkpty(&master, NULL, NULL, NULL);
+  ASSERT_NE(-1, pid);
+
+  if (pid == 0) {
+    // We're the child.
+    ASSERT_NE(sid, getsid(0));
+    _exit(0);
+  }
+
+  ASSERT_EQ(sid, getsid(0));
+
+  int status;
+  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(0, WEXITSTATUS(status));
+
+  close(master);
+}
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
new file mode 100644
index 0000000..2ea01b3
--- /dev/null
+++ b/tests/setjmp_test.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+TEST(setjmp, setjmp_smoke) {
+  int value;
+  jmp_buf jb;
+  if ((value = setjmp(jb)) == 0) {
+    longjmp(jb, 123);
+    FAIL(); // Unreachable.
+  } else {
+    ASSERT_EQ(123, value);
+  }
+}
+
+TEST(setjmp, _setjmp_smoke) {
+  int value;
+  jmp_buf jb;
+  if ((value = _setjmp(jb)) == 0) {
+    _longjmp(jb, 456);
+    FAIL(); // Unreachable.
+  } else {
+    ASSERT_EQ(456, value);
+  }
+}
+
+TEST(setjmp, sigsetjmp_0_smoke) {
+  int value;
+  sigjmp_buf jb;
+  if ((value = sigsetjmp(jb, 0)) == 0) {
+    siglongjmp(jb, 789);
+    FAIL(); // Unreachable.
+  } else {
+    ASSERT_EQ(789, value);
+  }
+}
+
+TEST(setjmp, sigsetjmp_1_smoke) {
+  int value;
+  sigjmp_buf jb;
+  if ((value = sigsetjmp(jb, 0)) == 0) {
+    siglongjmp(jb, 0xabc);
+    FAIL(); // Unreachable.
+  } else {
+    ASSERT_EQ(0xabc, value);
+  }
+}
+
+static sigset_t SigSetOf(int signal, int rt_signal = 0) {
+  sigset_t ss;
+  sigemptyset(&ss);
+  sigaddset(&ss, signal);
+  if (rt_signal != 0) {
+    sigaddset(&ss, rt_signal);
+  }
+  return ss;
+}
+
+void AssertSigmaskEquals(const sigset_t& expected) {
+  sigset_t actual;
+  sigprocmask(0 /* ignored */, NULL, &actual);
+  size_t end = sizeof(sigset_t) * 8;
+  for (size_t i = 1; i <= end; ++i) {
+    EXPECT_EQ(sigismember(&expected, i), sigismember(&actual, i)) << i;
+  }
+}
+
+TEST(setjmp, _setjmp_signal_mask) {
+  // _setjmp/_longjmp do not save/restore the signal mask.
+  sigset_t ss1(SigSetOf(SIGUSR1, SIGRTMIN + 8));
+  sigset_t ss2(SigSetOf(SIGUSR2, SIGRTMIN + 9));
+  sigset_t original_set;
+  sigprocmask(SIG_SETMASK, &ss1, &original_set);
+  jmp_buf jb;
+  if (_setjmp(jb) == 0) {
+    sigprocmask(SIG_SETMASK, &ss2, NULL);
+    _longjmp(jb, 1);
+    FAIL(); // Unreachable.
+  } else {
+    AssertSigmaskEquals(ss2);
+  }
+  sigprocmask(SIG_SETMASK, &original_set, NULL);
+}
+
+TEST(setjmp, setjmp_signal_mask) {
+  // setjmp/longjmp do save/restore the signal mask on bionic, but not on glibc.
+  // This is a BSD versus System V historical accident. POSIX leaves the
+  // behavior unspecified, so any code that cares needs to use sigsetjmp.
+  sigset_t ss1(SigSetOf(SIGUSR1, SIGRTMIN + 8));
+  sigset_t ss2(SigSetOf(SIGUSR2, SIGRTMIN + 9));
+  sigset_t original_set;
+  sigprocmask(SIG_SETMASK, &ss1, &original_set);
+  jmp_buf jb;
+  if (setjmp(jb) == 0) {
+    sigprocmask(SIG_SETMASK, &ss2, NULL);
+    longjmp(jb, 1);
+    FAIL(); // Unreachable.
+  } else {
+#if defined(__BIONIC__)
+    // bionic behaves like BSD and does save/restore the signal mask.
+    AssertSigmaskEquals(ss1);
+#else
+    // glibc behaves like System V and doesn't save/restore the signal mask.
+    AssertSigmaskEquals(ss2);
+#endif
+  }
+  sigprocmask(SIG_SETMASK, &original_set, NULL);
+}
+
+TEST(setjmp, sigsetjmp_0_signal_mask) {
+  // sigsetjmp(0)/siglongjmp do not save/restore the signal mask.
+  sigset_t ss1(SigSetOf(SIGUSR1, SIGRTMIN + 8));
+  sigset_t ss2(SigSetOf(SIGUSR2, SIGRTMIN + 9));
+  sigset_t original_set;
+  sigprocmask(SIG_SETMASK, &ss1, &original_set);
+  sigjmp_buf sjb;
+  if (sigsetjmp(sjb, 0) == 0) {
+    sigprocmask(SIG_SETMASK, &ss2, NULL);
+    siglongjmp(sjb, 1);
+    FAIL(); // Unreachable.
+  } else {
+    AssertSigmaskEquals(ss2);
+  }
+  sigprocmask(SIG_SETMASK, &original_set, NULL);
+}
+
+TEST(setjmp, sigsetjmp_1_signal_mask) {
+  // sigsetjmp(1)/siglongjmp does save/restore the signal mask.
+  sigset_t ss1(SigSetOf(SIGUSR1, SIGRTMIN + 8));
+  sigset_t ss2(SigSetOf(SIGUSR2, SIGRTMIN + 9));
+  sigset_t original_set;
+  sigprocmask(SIG_SETMASK, &ss1, &original_set);
+  sigjmp_buf sjb;
+  if (sigsetjmp(sjb, 1) == 0) {
+    sigprocmask(SIG_SETMASK, &ss2, NULL);
+    siglongjmp(sjb, 1);
+    FAIL(); // Unreachable.
+  } else {
+    AssertSigmaskEquals(ss1);
+  }
+  sigprocmask(SIG_SETMASK, &original_set, NULL);
+}
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 3fc45c5..3d3f22d 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -73,6 +73,7 @@
   ASSERT_EQ(count + 1, deeper_count);
 }
 
+static volatile bool signal_handler_run = false;
 static int killer_count = 0;
 static int handler_count = 0;
 static int handler_one_deeper_count = 0;
@@ -83,6 +84,7 @@
 
   handler_one_deeper_count = unwind_one_frame_deeper();
   ASSERT_EQ(handler_count + 1, handler_one_deeper_count);
+  signal_handler_run = true;
 }
 
 TEST(stack_unwinding, unwind_through_signal_frame) {
@@ -90,8 +92,9 @@
   ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
 
   _Unwind_Backtrace(FrameCounter, &killer_count);
-
+  signal_handler_run = false;
   ASSERT_EQ(0, kill(getpid(), SIGUSR1));
+  while (!signal_handler_run) {}
 }
 
 // On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
@@ -100,6 +103,7 @@
   ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);
 
   _Unwind_Backtrace(FrameCounter, &killer_count);
-
+  signal_handler_run = false;
   ASSERT_EQ(0, kill(getpid(), SIGUSR1));
+  while (!signal_handler_run) {}
 }
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 6be372c..854fc7b 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -813,3 +813,34 @@
 
   fclose(fp);
 }
+
+// https://code.google.com/p/android/issues/detail?id=81155
+// http://b/18556607
+TEST(stdio, fread_unbuffered_pathological_performance) {
+  FILE* fp = fopen("/dev/zero", "r");
+  ASSERT_TRUE(fp != NULL);
+
+  // Make this stream unbuffered.
+  setvbuf(fp, 0, _IONBF, 0);
+
+  char buf[65*1024];
+  memset(buf, 0xff, sizeof(buf));
+
+  time_t t0 = time(NULL);
+  for (size_t i = 0; i < 1024; ++i) {
+    fread(buf, 64*1024, 1, fp);
+  }
+  time_t t1 = time(NULL);
+
+  fclose(fp);
+
+  // 1024 64KiB reads should have been very quick.
+  ASSERT_LE(t1 - t0, 1);
+
+  for (size_t i = 0; i < 64*1024; ++i) {
+    ASSERT_EQ('\0', buf[i]);
+  }
+  for (size_t i = 64*1024; i < 65*1024; ++i) {
+    ASSERT_EQ('\xff', buf[i]);
+  }
+}
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index 75ccfa3..b0e40fd 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -172,3 +172,46 @@
   ASSERT_STREQ(NEWPAGE2_MSG, buf);
   ASSERT_STREQ(END_MSG, buf+pagesize-sizeof(END_MSG));
 }
+
+TEST(sys_mman, posix_madvise) {
+  TemporaryFile tempfile;
+  size_t pagesize = sysconf(_SC_PAGESIZE);
+  char buf[pagesize];
+
+  // Prepare environment.
+  ASSERT_EQ(static_cast<ssize_t>(pagesize), write(tempfile.fd, buf, pagesize));
+  void* map = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, tempfile.fd, 0);
+  ASSERT_NE(MAP_FAILED, map);
+
+  // Verify different options of posix_madvise.
+  ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_NORMAL));
+  ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_SEQUENTIAL));
+  ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_RANDOM));
+  ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_WILLNEED));
+
+  ASSERT_EQ(0, munmap(map, pagesize));
+}
+
+// Verify that memory can still access after posix_madvise(POSIX_MADV_DONTNEED).
+// We should test on MAP_ANONYMOUS memory to verify whether the memory is discarded,
+// because the content of non MAP_ANONYMOUS memory can be reread from file.
+TEST(sys_mman, posix_madvise_POSIX_MADV_DONTNEED) {
+  size_t pagesize = sysconf(_SC_PAGESIZE);
+
+  void* map = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  ASSERT_NE(MAP_FAILED, map);
+
+  int* int_ptr = reinterpret_cast<int*>(map);
+  for (int i = 0; i < static_cast<int>(pagesize / sizeof(int)); ++i) {
+    *int_ptr++ = i;
+  }
+
+  ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_DONTNEED));
+
+  int_ptr = reinterpret_cast<int*>(map);
+  for (int i = 0; i < static_cast<int>(pagesize / sizeof(int)); ++i) {
+    ASSERT_EQ(i, *int_ptr++);
+  }
+
+  ASSERT_EQ(0, munmap(map, pagesize));
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index e0231b1..691d8ff 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -23,6 +23,7 @@
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 #include "ScopedSignalHandler.h"
 
@@ -458,6 +459,34 @@
   ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
 }
 
+pid_t GetInvalidPid() {
+  FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
+  long pid_max;
+  fscanf(fp, "%ld", &pid_max);
+  pid_t invalid_pid = static_cast<pid_t>(pid_max + 1);
+  fclose(fp);
+  return invalid_pid;
+}
+
+TEST(time, clock_getcpuclockid) {
+  // For current process.
+  clockid_t clockid;
+  ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
+
+  timespec ts;
+  ASSERT_EQ(0, clock_gettime(clockid, &ts));
+
+  // For parent process.
+  ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
+  ASSERT_EQ(0, clock_gettime(clockid, &ts));
+
+  // For invalid process.
+  // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
+  errno = 0;
+  ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid));
+  ASSERT_EQ(0, errno);
+}
+
 TEST(time, clock_settime) {
   errno = 0;
   timespec ts;
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 433c1b5..96d66e4 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -523,12 +523,14 @@
   // Verify according to POSIX.1-2008.
   EXPECT_EQ(200809L, _POSIX_VERSION);
 
+  EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO);
   EXPECT_GT(_POSIX_AIO_LISTIO_MAX, 0);
   EXPECT_GT(_POSIX_AIO_MAX, 0);
   EXPECT_GT(_POSIX_ARG_MAX, 0);
   EXPECT_GT(_POSIX_CHILD_MAX, 0);
   EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
+  EXPECT_EQ(0, _POSIX_CPUTIME);             // Use sysconf to detect support at runtime.
   EXPECT_GT(_POSIX_DELAYTIMER_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
   EXPECT_GT(_POSIX_HOST_NAME_MAX, 0);
@@ -572,7 +574,7 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
-  EXPECT_TRUE(_POSIX_VERSION ==  _POSIX_THREAD_CPUTIME || 0 == _POSIX_THREAD_CPUTIME);
+  EXPECT_EQ(0, _POSIX_THREAD_CPUTIME);       // Use sysconf to detect support at runtime.
   EXPECT_GT(_POSIX_THREAD_DESTRUCTOR_ITERATIONS, 0);
   EXPECT_GT(_POSIX_THREAD_KEYS_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
@@ -611,11 +613,9 @@
 
 #if defined(__BIONIC__)
   // These tests only pass on bionic, as bionic and glibc has different support on these macros.
-  // Macros like _POSIX_ADVISORY_INFO are not supported on bionic yet.
-  EXPECT_EQ(-1, _POSIX_ADVISORY_INFO);
+  // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
   EXPECT_EQ(-1, _POSIX_ASYNCHRONOUS_IO);
   EXPECT_EQ(-1, _POSIX_BARRIERS);
-  EXPECT_EQ(-1, _POSIX_CPUTIME);
   EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
   EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO);
   EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS);
@@ -658,6 +658,7 @@
 }
 
 TEST(unistd, sysconf) {
+  VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO);
   VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_BC_DIM_MAX);
@@ -665,6 +666,7 @@
   VERIFY_SYSCONF_POSITIVE(_SC_CHILD_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_CLK_TCK);
   VERIFY_SYSCONF_POSITIVE(_SC_COLL_WEIGHTS_MAX);
+  VERIFY_SYSCONF_POSIX_VERSION(_SC_CPUTIME);
   VERIFY_SYSCONF_POSITIVE(_SC_EXPR_NEST_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_LINE_MAX);
   VERIFY_SYSCONF_POSITIVE(_SC_NGROUPS_MAX);
@@ -773,10 +775,8 @@
 #if defined(__BIONIC__)
   // Tests can only run on bionic, as bionic and glibc have different support for these options.
   // Below options are not supported on bionic yet.
-  VERIFY_SYSCONF_NOT_SUPPORT(_SC_ADVISORY_INFO);
   VERIFY_SYSCONF_NOT_SUPPORT(_SC_ASYNCHRONOUS_IO);
   VERIFY_SYSCONF_NOT_SUPPORT(_SC_BARRIERS);
-  VERIFY_SYSCONF_NOT_SUPPORT(_SC_CPUTIME);
   VERIFY_SYSCONF_NOT_SUPPORT(_SC_MESSAGE_PASSING);
   VERIFY_SYSCONF_NOT_SUPPORT(_SC_PRIORITIZED_IO);
   VERIFY_SYSCONF_NOT_SUPPORT(_SC_SHARED_MEMORY_OBJECTS);
diff --git a/tests/libs/dlopen_testlib_invalid.cpp b/tests/utmp_test.cpp
similarity index 68%
copy from tests/libs/dlopen_testlib_invalid.cpp
copy to tests/utmp_test.cpp
index f2039c6..b61110d 100644
--- a/tests/libs/dlopen_testlib_invalid.cpp
+++ b/tests/utmp_test.cpp
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#include <stdlib.h>
+#include <gtest/gtest.h>
 
-// This file is used for libraries that are not supposed to
-// be successfully loaded/linked - therefore, this function should
-// not be visible via dlsym - (we are going to use this fact in tests)
-extern "C" int dlopen_test_invalid_function() {
-  abort();
+#include <utmp.h>
+
+TEST(utmp, login_tty) {
+  // login_tty is tested indirectly by the openpty and forkpty tests.
+  // This test just checks that we're exporting the symbol independently.
+  ASSERT_EQ(-1, login_tty(-1));
 }