]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/blobdiff - libthread_db/libthread_db.c
Upgrade to tzdata2013i.
[android-sdk/platform-bionic.git] / libthread_db / libthread_db.c
index 2cf4d385645e9fa2ac194f6f4468a82c296e4b4c..bd78ae6ca34d1412b51580ccff643e4f87293170 100644 (file)
@@ -81,6 +81,25 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
 {
     void * pc;
 
+#ifdef __i386__
+    /* Get the eip from offset 12*4 = 48 as defined in the struct
+     * user_regs_struct in user_32.h
+     */
+    pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
+    /* FIXME - pc is a non-decremented breakpoint address, hence the
+     * addition of 1 on test.  This seems to work for the thread hook
+     * function in libc.so but should be properly fixed.
+     */
+    if (pc == ((int)bkpt_addr + 1)) {
+        /* The hook function takes the id of the new thread as it's first
+         * param, so grab it from ecx at offset 4 in struct user_regs_struct
+         * (using fastcall convention for x86)
+         */
+        gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
+        gEventMsgHandle.tid = gEventMsgHandle.pid;
+        return 0x42;
+    }
+#elif defined(__arm__)
     pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
 
     if (pc == bkpt_addr) {
@@ -90,6 +109,16 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
         gEventMsgHandle.tid = gEventMsgHandle.pid;
         return 0x42;
     }
+#elif defined(__mips__)
+    pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
+    if (pc == bkpt_addr) {
+        // The hook function takes the id of the new thread as it's first param,
+        // so grab it from a0
+        gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(4*4) /* a0 */, NULL);
+        gEventMsgHandle.tid = gEventMsgHandle.pid;
+        return 0x42;
+    }
+#endif
     return 0;
 }
 
@@ -132,7 +161,7 @@ td_err_e
 td_thr_get_info(td_thrhandle_t const * handle, td_thrinfo_t * info)
 {
     info->ti_tid = handle->tid;
-    info->ti_lid = handle->tid; // Our pthreads uses kernel ids for tids
+    info->ti_lid = handle->tid;
     info->ti_state = TD_THR_SLEEP; /* XXX this needs to be read from /proc/<pid>/task/<tid>.
                                       This is only used to see if the thread is a zombie or not */
     return TD_OK;
@@ -156,7 +185,7 @@ td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * no
 {
     int32_t err;
 
-    /* 
+    /*
      * This is nasty, ps_pglobal_lookup is implemented in gdbserver and looks up
      * the symbol from it's cache, which is populated at start time with the
      * symbols returned from td_symbol_list via calls back to the host.