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;