Reviewers: Yang, ulan, danno, Sven Panne,

Message:
Thanks, just got back from vacation, will work on it.

Description:
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).

BUG=
TEST=


Please review this at https://chromiumcodereview.appspot.com/10690163/

SVN Base: git://github.com/v8/v8.git@master

Affected files:
  M src/platform-linux.cc


Index: src/platform-linux.cc
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 9028fd0238a9d5b1cae6672c7cb10cf77c05046a..08a52a2241583b3fb00f4ef4ffca41689f939d6b 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -904,32 +904,36 @@ 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.
+
+#if defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
+
+// 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(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
+#include <asm/sigcontext.h>
+#endif

-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 uint32_t kernel_sigset_t[2]; // ARM 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;
+  kernel_sigset_t uc_sigmask;
 } 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;
@@ -948,44 +952,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 uint32_t kernel_sigset_t[4]; // MIPS kernel uses 128-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;
+  kernel_sigset_t uc_sigmask;
 } 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;
+  kernel_sigset_t uc_sigmask;
 } 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
 }
@@ -1024,12 +1028,15 @@ 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))
+#if defined(__GLIBC__) && \
+    (__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]);
 #else
+ // Recent ARM GLibc and Android's Bionic use explicit named fields instead.
   sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
   sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
   sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to