android: refine custom ucontext_t definitions.

This is a forward-compatible change to avoid type/naming
conflicts when the Android platform/NDK will update its
<signal.h> header to properly define 'struct sigcontext',
'mcontext_t' and 'ucontext_t'.

In particular:

  - Do not define 'struct sigcontext.h' to avoid
    conflicts with the C library definition (which
    is different, see below).

  - Only provide custom ucontext_t declarations if
    the Android <signal.h> doesn't provide it. This can
    be tested with a macro check (__BIONIC_HAVE_UCONTEXT_T)

+ Use 'gettid()' on Android since it is available (at all
  API levels).

See http://code.google.com/p/android/issues/detail?id=34784

Review URL: https://chromiumcodereview.appspot.com/10829122
Patch from David Turner <digit@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12250 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c6d4094e
......@@ -53,6 +53,13 @@
#include <errno.h>
#include <stdarg.h>
// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
// Old versions of the C library <signal.h> didn't define the type.
#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) && \
defined(__arm__) && !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
#include <asm/sigcontext.h>
#endif
#undef MAP_TYPE
#include "v8.h"
......@@ -907,32 +914,30 @@ Semaphore* OS::CreateSemaphore(int count) {
}
#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
// Android runs a fairly new Linux kernel, so signal info is there,
// but the C library doesn't have the structs defined.
#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
// Not all versions of Android's C library provide ucontext_t.
// Detect this and provide custom but compatible definitions. Note that these
// follow the GLibc naming convention to access register values from
// mcontext_t.
//
// See http://code.google.com/p/android/issues/detail?id=34784
#if defined(__arm__)
struct sigcontext {
uint32_t trap_no;
uint32_t error_code;
uint32_t oldmask;
uint32_t gregs[16];
uint32_t arm_cpsr;
uint32_t fault_address;
};
typedef uint32_t __sigset_t;
typedef struct sigcontext mcontext_t;
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
// Other fields are not used by V8, don't define them here.
} ucontext_t;
enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
#elif !defined(__GLIBC__) && defined(__mips__)
#elif defined(__mips__)
// MIPS version of sigcontext, for Android bionic.
struct sigcontext {
typedef struct {
uint32_t regmask;
uint32_t status;
uint64_t pc;
......@@ -951,44 +956,44 @@ struct sigcontext {
uint32_t lo2;
uint32_t hi3;
uint32_t lo3;
};
typedef uint32_t __sigset_t;
typedef struct sigcontext mcontext_t;
} mcontext_t;
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
// Other fields are not used by V8, don't define them here.
} ucontext_t;
#elif !defined(__GLIBC__) && defined(__i386__)
#elif defined(__i386__)
// x86 version for Android.
struct sigcontext {
typedef struct {
uint32_t gregs[19];
void* fpregs;
uint32_t oldmask;
uint32_t cr2;
};
} mcontext_t;
typedef uint32_t __sigset_t;
typedef struct sigcontext mcontext_t;
typedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
// Other fields are not used by V8, don't define them here.
} ucontext_t;
enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
#endif
#endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T)
static int GetThreadID() {
// Glibc doesn't provide a wrapper for gettid(2).
#if defined(ANDROID)
return syscall(__NR_gettid);
#if defined(__ANDROID__)
// Android's C library provides gettid(2).
return gettid();
#else
// Glibc doesn't provide a wrapper for gettid(2).
return syscall(SYS_gettid);
#endif
}
......@@ -1027,9 +1032,10 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
#elif V8_HOST_ARCH_ARM
// An undefined macro evaluates to 0, so this applies to Android's Bionic also.
#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3) && \
!defined(__UCLIBC__))
#if defined(__GLIBC__) && !defined(__UCLIBC__) && \
(__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
// Old GLibc ARM versions used a gregs[] array to access the register
// values from mcontext_t.
sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
......@@ -1037,8 +1043,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);
#endif // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3) &&
// !defined(__UCLIBC__))
#endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
// (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
#elif V8_HOST_ARCH_MIPS
sample->pc = reinterpret_cast<Address>(mcontext.pc);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment