[compiler-rt] r256184 - [compiler-rt] [tsan] Add support for PIE build on AArch64

Adhemerval Zanella via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 21 11:27:57 PST 2015


Author: azanella
Date: Mon Dec 21 13:27:57 2015
New Revision: 256184

URL: http://llvm.org/viewvc/llvm-project?rev=256184&view=rev
Log:
[compiler-rt] [tsan] Add support for PIE build on AArch64

This patch adds PIE executable support for aarch64-linux.  It adds
two more segments:

- 0x05500000000-0x05600000000: 39-bits PIE program segments
- 0x2aa00000000-0x2ab00000000: 42-bits PIE program segments

Fortunately it is possible to use the same transformation formula for
the new segments range with some adjustments in shadow to memory
formula (it adds a constant offset based on the VMA size).

A simple testcase is also added, however it is disabled on x86 due the
fact it might fail on newer kernels [1].

[1] https://git.kernel.org/linus/d1fd836dcf00d2028c700c7e44d2c23404062c90

Added:
    compiler-rt/trunk/test/tsan/pie_test.cc
Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform_posix.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=256184&r1=256183&r2=256184&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Mon Dec 21 13:27:57 2015
@@ -101,10 +101,12 @@ struct Mapping {
 C/C++ on linux/aarch64 (39-bit VMA)
 0000 0010 00 - 0100 0000 00: main binary
 0100 0000 00 - 0800 0000 00: -
-0800 0000 00 - 1F00 0000 00: shadow memory
-1C00 0000 00 - 3100 0000 00: -
+0800 0000 00 - 2000 0000 00: shadow memory
+2000 0000 00 - 3100 0000 00: -
 3100 0000 00 - 3400 0000 00: metainfo
-3400 0000 00 - 6000 0000 00: -
+3400 0000 00 - 5500 0000 00: -
+5500 0000 00 - 5600 0000 00: main binary (PIE)
+5600 0000 00 - 6000 0000 00: -
 6000 0000 00 - 6200 0000 00: traces
 6200 0000 00 - 7d00 0000 00: -
 7c00 0000 00 - 7d00 0000 00: heap
@@ -114,14 +116,17 @@ struct Mapping39 {
   static const uptr kLoAppMemBeg   = 0x0000001000ull;
   static const uptr kLoAppMemEnd   = 0x0100000000ull;
   static const uptr kShadowBeg     = 0x0800000000ull;
-  static const uptr kShadowEnd     = 0x1F00000000ull;
+  static const uptr kShadowEnd     = 0x2000000000ull;
   static const uptr kMetaShadowBeg = 0x3100000000ull;
   static const uptr kMetaShadowEnd = 0x3400000000ull;
+  static const uptr kMidAppMemBeg  = 0x5500000000ull;
+  static const uptr kMidAppMemEnd  = 0x5600000000ull;
+  static const uptr kMidShadowOff  = 0x5000000000ull;
   static const uptr kTraceMemBeg   = 0x6000000000ull;
   static const uptr kTraceMemEnd   = 0x6200000000ull;
   static const uptr kHeapMemBeg    = 0x7c00000000ull;
   static const uptr kHeapMemEnd    = 0x7d00000000ull;
-  static const uptr kHiAppMemBeg   = 0x7d00000000ull;
+  static const uptr kHiAppMemBeg   = 0x7e00000000ull;
   static const uptr kHiAppMemEnd   = 0x7fffffffffull;
   static const uptr kAppMemMsk     = 0x7800000000ull;
   static const uptr kAppMemXor     = 0x0200000000ull;
@@ -135,7 +140,9 @@ C/C++ on linux/aarch64 (42-bit VMA)
 10000 0000 00 - 20000 0000 00: shadow memory
 20000 0000 00 - 26000 0000 00: -
 26000 0000 00 - 28000 0000 00: metainfo
-28000 0000 00 - 36200 0000 00: -
+28000 0000 00 - 2aa00 0000 00: -
+2aa00 0000 00 - 2ab00 0000 00: main binary (PIE)
+2ab00 0000 00 - 36200 0000 00: -
 36200 0000 00 - 36240 0000 00: traces
 36240 0000 00 - 3e000 0000 00: -
 3e000 0000 00 - 3f000 0000 00: heap
@@ -148,6 +155,9 @@ struct Mapping42 {
   static const uptr kShadowEnd     = 0x20000000000ull;
   static const uptr kMetaShadowBeg = 0x26000000000ull;
   static const uptr kMetaShadowEnd = 0x28000000000ull;
+  static const uptr kMidAppMemBeg  = 0x2aa00000000ull;
+  static const uptr kMidAppMemEnd  = 0x2ab00000000ull;
+  static const uptr kMidShadowOff  = 0x28000000000ull;
   static const uptr kTraceMemBeg   = 0x36200000000ull;
   static const uptr kTraceMemEnd   = 0x36400000000ull;
   static const uptr kHeapMemBeg    = 0x3e000000000ull;
@@ -161,6 +171,8 @@ struct Mapping42 {
 
 // Indicates the runtime will define the memory regions at runtime.
 #define TSAN_RUNTIME_VMA 1
+// Indicates that mapping defines a mid range memory segment.
+#define TSAN_MID_APP_RANGE 1
 #elif defined(__powerpc64__)
 // PPC64 supports multiple VMA which leads to multiple address transformation
 // functions.  To support these multiple VMAS transformations and mappings TSAN
@@ -302,6 +314,10 @@ enum MappingType {
   MAPPING_LO_APP_END,
   MAPPING_HI_APP_BEG,
   MAPPING_HI_APP_END,
+#ifdef TSAN_MID_APP_RANGE
+  MAPPING_MID_APP_BEG,
+  MAPPING_MID_APP_END,
+#endif
   MAPPING_HEAP_BEG,
   MAPPING_HEAP_END,
   MAPPING_APP_BEG,
@@ -321,6 +337,10 @@ uptr MappingImpl(void) {
 #ifndef SANITIZER_GO
     case MAPPING_LO_APP_BEG: return Mapping::kLoAppMemBeg;
     case MAPPING_LO_APP_END: return Mapping::kLoAppMemEnd;
+# ifdef TSAN_MID_APP_RANGE
+    case MAPPING_MID_APP_BEG: return Mapping::kMidAppMemBeg;
+    case MAPPING_MID_APP_END: return Mapping::kMidAppMemEnd;
+# endif
     case MAPPING_HI_APP_BEG: return Mapping::kHiAppMemBeg;
     case MAPPING_HI_APP_END: return Mapping::kHiAppMemEnd;
     case MAPPING_HEAP_BEG: return Mapping::kHeapMemBeg;
@@ -368,6 +388,17 @@ uptr LoAppMemEnd(void) {
   return MappingArchImpl<MAPPING_LO_APP_END>();
 }
 
+#ifdef TSAN_MID_APP_RANGE
+ALWAYS_INLINE
+uptr MidAppMemBeg(void) {
+  return MappingArchImpl<MAPPING_MID_APP_BEG>();
+}
+ALWAYS_INLINE
+uptr MidAppMemEnd(void) {
+  return MappingArchImpl<MAPPING_MID_APP_END>();
+}
+#endif
+
 ALWAYS_INLINE
 uptr HeapMemBeg(void) {
   return MappingArchImpl<MAPPING_HEAP_BEG>();
@@ -422,6 +453,12 @@ bool GetUserRegion(int i, uptr *start, u
     *start = HeapMemBeg();
     *end = HeapMemEnd();
     return true;
+# ifdef TSAN_MID_APP_RANGE
+  case 3:
+    *start = MidAppMemBeg();
+    *end = MidAppMemEnd();
+    return true;
+# endif
 #else
   case 0:
     *start = AppMemBeg();
@@ -463,6 +500,9 @@ template<typename Mapping>
 bool IsAppMemImpl(uptr mem) {
 #ifndef SANITIZER_GO
   return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
+# ifdef TSAN_MID_APP_RANGE
+         (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
+# endif
          (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
          (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
 #else
@@ -611,6 +651,11 @@ uptr ShadowToMemImpl(uptr s) {
   if (s >= MemToShadow(Mapping::kLoAppMemBeg)
       && s <= MemToShadow(Mapping::kLoAppMemEnd - 1))
     return (s / kShadowCnt) ^ Mapping::kAppMemXor;
+# ifdef TSAN_MID_APP_RANGE
+  if (s >= MemToShadow(Mapping::kMidAppMemBeg)
+      && s <= MemToShadow(Mapping::kMidAppMemEnd - 1))
+    return ((s / kShadowCnt) ^ Mapping::kAppMemXor) + Mapping::kMidShadowOff;
+# endif
   else
     return ((s / kShadowCnt) ^ Mapping::kAppMemXor) | Mapping::kAppMemMsk;
 #else

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_posix.cc?rev=256184&r1=256183&r2=256184&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_posix.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_posix.cc Mon Dec 21 13:27:57 2015
@@ -132,7 +132,12 @@ void CheckAndProtect() {
 
   ProtectRange(LoAppMemEnd(), ShadowBeg());
   ProtectRange(ShadowEnd(), MetaShadowBeg());
+#ifdef TSAN_MID_APP_RANGE
+  ProtectRange(MetaShadowEnd(), MidAppMemBeg());
+  ProtectRange(MidAppMemEnd(), TraceMemBeg());
+#else
   ProtectRange(MetaShadowEnd(), TraceMemBeg());
+#endif
   // Memory for traces is mapped lazily in MapThreadTrace.
   // Protect the whole range for now, so that user does not map something here.
   ProtectRange(TraceMemBeg(), TraceMemEnd());

Added: compiler-rt/trunk/test/tsan/pie_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/pie_test.cc?rev=256184&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/pie_test.cc (added)
+++ compiler-rt/trunk/test/tsan/pie_test.cc Mon Dec 21 13:27:57 2015
@@ -0,0 +1,12 @@
+// Check if tsan work with PIE binaries.
+// RUN: %clang_tsan %s -pie -fpic -o %t && %run %t
+
+// Some kernels might map PIE segments outside the current segment
+// mapping defined for x86 [1].
+// [1] https://git.kernel.org/linus/d1fd836dcf00d2028c700c7e44d2c23404062c90
+
+// UNSUPPORTED: x86
+
+int main(void) {
+  return 0;
+}




More information about the llvm-commits mailing list