Quantcast

Valgrind: r16215 - in /trunk: NEWS coregrind/m_gdbserver/target.c

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Valgrind: r16215 - in /trunk: NEWS coregrind/m_gdbserver/target.c

svn-2
Author: petarj
Date: Mon Jan 30 19:33:47 2017
New Revision: 16215

Log:
mips: implement calculation for static TLS

Extend valgrind_get_tls_addr() with static TLS calculation for MIPS.

Related issue #375514.

Patch by Aleksandar Rikalo.

Modified:
    trunk/NEWS
    trunk/coregrind/m_gdbserver/target.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Jan 30 19:33:47 2017
@@ -110,6 +110,7 @@
 373192  Calling posix_spawn in glibc 2.24 completely broken
 373555  Rename BBPTR to GSPTR as it denotes guest state pointer only
 373938  const IRExpr arguments for matchIRExpr()
+375514  valgrind_get_tls_addr() does not work in case of static TLS
 
 Release 3.12.0 (20 October 2016)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Modified: trunk/coregrind/m_gdbserver/target.c
==============================================================================
--- trunk/coregrind/m_gdbserver/target.c (original)
+++ trunk/coregrind/m_gdbserver/target.c Mon Jan 30 19:33:47 2017
@@ -716,9 +716,48 @@
    // Check we can access the dtv entry for modid
    CHECK_DEREF(dtv + 2 * modid, sizeof(CORE_ADDR), "dtv[2*modid]");
 
-   // And finally compute the address of the tls variable.
-   *tls_addr = *(dtv + 2 * modid) + offset;
-  
+   // Compute the base address of the tls block.
+   *tls_addr = *(dtv + 2 * modid);
+
+#if defined(VGA_mips32) || defined(VGA_mips64)
+   if (*tls_addr & 1) {
+      /* This means that computed address is not valid, most probably
+         because given module uses Static TLS.
+         However, the best we can is to try to compute address using
+         static TLS. This is what libthread_db does.
+         Ref. GLIBC/nptl_db/td_thr_tlsbase.c:td_thr_tlsbase().
+      */
+
+      CORE_ADDR tls_offset_addr;
+      PtrdiffT tls_offset;
+
+      dlog(1, "computing tls_addr using static TLS\n");
+
+      /* Assumes that tls_offset is placed right before tls_modid.
+         To check the assumption, start a gdb on none/tests/tls and do:
+         p &((struct link_map*)0x0)->l_tls_modid
+         p &((struct link_map*)0x0)->l_tls_offset */
+      tls_offset_addr = lm + lm_modid_offset - sizeof(PtrdiffT);
+
+      // Check we can read the tls_offset.
+      CHECK_DEREF(tls_offset_addr, sizeof(PtrdiffT), "link_map tls_offset");
+      tls_offset = *(PtrdiffT *)(tls_offset_addr);
+
+      /* Following two values represent platform dependent constants
+         NO_TLS_OFFSET and FORCED_DYNAMIC_TLS_OFFSET, respectively. */
+      if ((tls_offset == -1) || (tls_offset == -2)) {
+         dlog(2, "link_map tls_offset is not valid for static TLS\n");
+         return False;
+      }
+
+      // This calculation is also platform dependent.
+      *tls_addr = ((CORE_ADDR)dtv_loc + 2 * sizeof(CORE_ADDR) + tls_offset);
+   }
+#endif
+
+   // Finally, add tls variable offset to tls block base address.
+   *tls_addr += offset;
+
    return True;
 
 #undef CHECK_DEREF


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers
Loading...