Merge "Regenerate binder header"
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 6468b2d..225a823 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -42,12 +42,14 @@
     kernel_new_action.sa_flags = bionic_new_action->sa_flags;
     kernel_new_action.sa_handler = bionic_new_action->sa_handler;
     kernel_new_action.sa_mask = bionic_new_action->sa_mask;
+#ifdef SA_RESTORER
     kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
 
     if (!(kernel_new_action.sa_flags & SA_RESTORER)) {
       kernel_new_action.sa_flags |= SA_RESTORER;
       kernel_new_action.sa_restorer = &__rt_sigreturn;
     }
+#endif
   }
 
   __kernel_sigaction kernel_old_action;
@@ -60,11 +62,13 @@
     bionic_old_action->sa_flags = kernel_old_action.sa_flags;
     bionic_old_action->sa_handler = kernel_old_action.sa_handler;
     bionic_old_action->sa_mask = kernel_old_action.sa_mask;
+#ifdef SA_RESTORER
     bionic_old_action->sa_restorer = kernel_old_action.sa_restorer;
 
     if (bionic_old_action->sa_restorer == &__rt_sigreturn) {
       bionic_old_action->sa_flags &= ~SA_RESTORER;
     }
+#endif
   }
 
   return result;
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
new file mode 100644
index 0000000..94b7a68
--- /dev/null
+++ b/libc/include/sys/ucontext.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2014 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 _SYS_UCONTEXT_H_
+#define _SYS_UCONTEXT_H_
+
+#include <signal.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+#if defined(__arm__)
+
+enum {
+  REG_R0 = 0,
+  REG_R1,
+  REG_R2,
+  REG_R3,
+  REG_R4,
+  REG_R5,
+  REG_R6,
+  REG_R7,
+  REG_R8,
+  REG_R9,
+  REG_R10,
+  REG_R11,
+  REG_R12,
+  REG_R13,
+  REG_R14,
+  REG_R15,
+};
+
+#define NGREG 18 /* Like glibc. */
+
+typedef int greg_t;
+typedef greg_t gregset_t[NGREG];
+
+/* TODO: fpregset_t. */
+
+#include <asm/sigcontext.h>
+typedef struct sigcontext mcontext_t;
+
+typedef struct ucontext {
+  unsigned long uc_flags;
+  struct ucontext* uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  sigset_t uc_sigmask;
+  /* TODO: uc_regspace */
+} ucontext_t;
+
+#elif defined(__aarch64__)
+
+/* TODO: gregset_t and fpregset_t. */
+
+#include <asm/sigcontext.h>
+typedef struct sigcontext mcontext_t;
+
+typedef struct ucontext {
+  unsigned long uc_flags;
+  struct ucontext *uc_link;
+  stack_t uc_stack;
+  sigset_t uc_sigmask;
+  mcontext_t uc_mcontext;
+} ucontext_t;
+
+#elif defined(__i386__)
+
+enum {
+  REG_GS = 0,
+  REG_FS,
+  REG_ES,
+  REG_DS,
+  REG_EDI,
+  REG_ESI,
+  REG_EBP,
+  REG_ESP,
+  REG_EBX,
+  REG_EDX,
+  REG_ECX,
+  REG_EAX,
+  REG_TRAPNO,
+  REG_ERR,
+  REG_EIP,
+  REG_CS,
+  REG_EFL,
+  REG_UESP,
+  REG_SS,
+  NGREG
+};
+
+typedef int greg_t;
+typedef greg_t gregset_t[NGREG];
+
+struct _libc_fpreg {
+  unsigned short significand[4];
+  unsigned short exponent;
+};
+
+struct _libc_fpstate {
+  unsigned long cw;
+  unsigned long sw;
+  unsigned long tag;
+  unsigned long ipoff;
+  unsigned long cssel;
+  unsigned long dataoff;
+  unsigned long datasel;
+  struct _libc_fpreg _st[8];
+  unsigned long status;
+};
+
+typedef struct _libc_fpstate* fpregset_t;
+
+typedef struct {
+  gregset_t gregs;
+  fpregset_t fpregs;
+  unsigned long oldmask;
+  unsigned long cr2;
+} mcontext_t;
+
+typedef struct ucontext {
+  unsigned long uc_flags;
+  struct ucontext* uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  sigset_t uc_sigmask;
+  /* TODO: __fpregs_mem? */
+} ucontext_t;
+
+#elif defined(__mips__)
+
+/* glibc doesn't have names for MIPS registers. */
+
+#define NGREG 32
+#define NFPREG 32
+
+typedef unsigned long long greg_t;
+typedef greg_t gregset_t[NGREG];
+
+typedef struct fpregset {
+  union {
+    double fp_dregs[NFPREG];
+    struct {
+      float _fp_fregs;
+      unsigned _fp_pad;
+    } fp_fregs[NFPREG];
+  } fp_r;
+} fpregset_t;
+
+typedef struct {
+  unsigned regmask;
+  unsigned status;
+  greg_t pc;
+  gregset_t gregs;
+  fpregset_t fpregs;
+  unsigned fp_owned;
+  unsigned fpc_csr;
+  unsigned fpc_eir;
+  unsigned used_math;
+  unsigned dsp;
+  greg_t mdhi;
+  greg_t mdlo;
+  unsigned long hi1;
+  unsigned long lo1;
+  unsigned long hi2;
+  unsigned long lo2;
+  unsigned long hi3;
+  unsigned long lo3;
+} mcontext_t;
+
+typedef struct ucontext {
+  unsigned long uc_flags;
+  struct ucontext* uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  sigset_t uc_sigmask;
+} ucontext_t;
+
+#elif defined(__mips64__)
+
+#error TODO
+
+#elif defined(__x86_64__)
+
+enum {
+  REG_R8 = 0,
+  REG_R9,
+  REG_R10,
+  REG_R11,
+  REG_R12,
+  REG_R13,
+  REG_R14,
+  REG_R15,
+  REG_RDI,
+  REG_RSI,
+  REG_RBP,
+  REG_RBX,
+  REG_RDX,
+  REG_RAX,
+  REG_RCX,
+  REG_RSP,
+  REG_RIP,
+  REG_EFL,
+  REG_CSGSFS,
+  REG_ERR,
+  REG_TRAPNO,
+  REG_OLDMASK,
+  REG_CR2,
+  NGREG
+};
+
+typedef long greg_t;
+typedef greg_t gregset_t[NGREG];
+
+typedef struct user_i387_struct* fpregset_t;
+
+typedef struct {
+  gregset_t gregs;
+  fpregset_t fpregs;
+  /* TODO: reserved space? */
+} mcontext_t;
+
+typedef struct ucontext {
+  unsigned long uc_flags;
+  struct ucontext* uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  sigset_t uc_sigmask;
+  /* TODO: __fpregs_mem? */
+} ucontext_t;
+
+#endif
+
+__END_DECLS
+
+#endif /* _SYS_UCONTEXT_H_ */
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index 9f11a83..90cce80 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -181,7 +181,7 @@
 
 #elif defined(__arm__)
 
-struct user_fp {
+struct user_fpregs {
   struct fp_reg {
     unsigned int sign1:1;
     unsigned int unused:15;
@@ -196,6 +196,9 @@
   unsigned char ftype[8];
   unsigned int init_flag;
 };
+struct user_regs {
+  unsigned long uregs[18];
+};
 struct user_vfp {
   unsigned long long fpregs[32];
   unsigned long fpscr;
@@ -206,7 +209,7 @@
   unsigned long fpinst2;
 };
 struct user {
-  struct pt_regs regs;
+  struct user_regs regs;
   int u_fpvalid;
   unsigned long int u_tsize;
   unsigned long int u_dsize;
@@ -215,12 +218,12 @@
   unsigned long start_stack;
   long int signal;
   int reserved;
-  unsigned long u_ar0;
+  struct user_regs* u_ar0;
   unsigned long magic;
   char u_comm[32];
   int u_debugreg[8];
-  struct user_fp u_fp;
-  struct user_fp_struct* u_fp0;
+  struct user_fpregs u_fp;
+  struct user_fpregs* u_fp0;
 };
 
 #elif defined(__aarch64__)
diff --git a/libc/include/ucontext.h b/libc/include/ucontext.h
new file mode 100644
index 0000000..5ea2982
--- /dev/null
+++ b/libc/include/ucontext.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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 _UCONTEXT_H_
+#define _UCONTEXT_H_
+
+#include <sys/ucontext.h>
+
+#endif /* _UCONTEXT_H_ */
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index 92e9dac..aee9aa9 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -40,7 +40,11 @@
 
 extern "C" int tgkill(int tgid, int tid, int sig);
 
+#if __LP64__
+#define DEBUGGER_SOCKET_NAME "android:debuggerd64"
+#else
 #define DEBUGGER_SOCKET_NAME "android:debuggerd"
+#endif
 
 enum debugger_action_t {
     // dump a crash
@@ -92,10 +96,10 @@
         return -1;
     }
 
-    int err = TEMP_FAILURE_RETRY(connect(s, reinterpret_cast<sockaddr*>(&addr), alen));
-    if (err == -1) {
+    int rc = TEMP_FAILURE_RETRY(connect(s, reinterpret_cast<sockaddr*>(&addr), alen));
+    if (rc == -1) {
         close(s);
-        s = -1;
+        return -1;
     }
 
     return s;
@@ -176,69 +180,64 @@
  * Catches fatal signals so we can ask debuggerd to ptrace us before
  * we crash.
  */
-void debuggerd_signal_handler(int n, siginfo_t* info, void*) {
-    /*
-     * It's possible somebody cleared the SA_SIGINFO flag, which would mean
-     * our "info" arg holds an undefined value.
-     */
-    if (!have_siginfo(n)) {
+void debuggerd_signal_handler(int signal_number, siginfo_t* info, void*) {
+    // It's possible somebody cleared the SA_SIGINFO flag, which would mean
+    // our "info" arg holds an undefined value.
+    if (!have_siginfo(signal_number)) {
         info = NULL;
     }
 
-    log_signal_summary(n, info);
+    log_signal_summary(signal_number, info);
 
-    pid_t tid = gettid();
     int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
-
-    if (s >= 0) {
+    if (s != -1) {
         // debuggerd knows our pid from the credentials on the
         // local socket but we need to tell it the tid of the crashing thread.
         // debuggerd will be paranoid and verify that we sent a tid
         // that's actually in our process.
         debugger_msg_t msg;
         msg.action = DEBUGGER_ACTION_CRASH;
-        msg.tid = tid;
+        msg.tid = gettid();
         msg.abort_msg_address = reinterpret_cast<uintptr_t>(gAbortMessage);
         int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
         if (ret == sizeof(msg)) {
-            // if the write failed, there is no point trying to read a response.
-            ret = TEMP_FAILURE_RETRY(read(s, &tid, 1));
+            // If the write failed, there is no point trying to read a response.
+            char debuggerd_ack;
+            ret = TEMP_FAILURE_RETRY(read(s, &debuggerd_ack, 1));
             int saved_errno = errno;
             notify_gdb_of_libraries();
             errno = saved_errno;
         }
 
         if (ret < 0) {
-            /* read or write failed -- broken connection? */
+            // read or write failed -- broken connection?
             __libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed while talking to debuggerd: %s",
                               strerror(errno));
         }
 
         close(s);
     } else {
-        /* socket failed; maybe process ran out of fds */
+        // socket failed; maybe process ran out of fds?
         __libc_format_log(ANDROID_LOG_FATAL, "libc", "Unable to open connection to debuggerd: %s",
                           strerror(errno));
     }
 
-    /* remove our net so we fault for real when we return */
-    signal(n, SIG_DFL);
+    // Remove our net so we fault for real when we return.
+    signal(signal_number, SIG_DFL);
 
-    /*
-     * These signals are not re-thrown when we resume.  This means that
-     * crashing due to (say) SIGPIPE doesn't work the way you'd expect it
-     * to.  We work around this by throwing them manually.  We don't want
-     * to do this for *all* signals because it'll screw up the address for
-     * faults like SIGSEGV.
-     */
-    switch (n) {
+    // These signals are not re-thrown when we resume.  This means that
+    // crashing due to (say) SIGPIPE doesn't work the way you'd expect it
+    // to.  We work around this by throwing them manually.  We don't want
+    // to do this for *all* signals because it'll screw up the address for
+    // faults like SIGSEGV.
+    switch (signal_number) {
         case SIGABRT:
         case SIGFPE:
         case SIGPIPE:
 #if defined(SIGSTKFLT)
         case SIGSTKFLT:
 #endif
-            (void) tgkill(getpid(), gettid(), n);
+            tgkill(getpid(), gettid(), signal_number);
             break;
         default:    // SIGILL, SIGBUS, SIGSEGV
             break;