dfsan: Enable 48-bit VMA support on aarch64
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 25 Aug 2016 17:07:43 +0000 (17:07 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 25 Aug 2016 17:07:43 +0000 (17:07 +0000)
This patch adds 48-bits VMA support for msan on aarch64. As current
mappings for aarch64, 48-bit VMA also supports PIE executable.

Tested on 39 and 48-bit VMA kernels on aarch64.

llvm-svn: 279753

compiler-rt/lib/dfsan/dfsan.cc
compiler-rt/lib/dfsan/dfsan_platform.h

index 4156000..3aa99b7 100644 (file)
@@ -114,6 +114,26 @@ SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;
 // | reserved by kernel |
 // +--------------------+ 0x0000000000
 
+// On Linux/AArch64 (48-bit VMA), memory is laid out as follow:
+//
+// +--------------------+ 0x1000000000000 (top of memory)
+// | application memory |
+// +--------------------+ 0xffff00008000 (kAppAddr)
+// |       unused       |
+// +--------------------+ 0xaaaab0000000 (top of PIE address)
+// | application PIE    |
+// +--------------------+ 0xaaaaa0000000 (top of PIE address)
+// |                    |
+// |       unused       |
+// |                    |
+// +--------------------+ 0x1200000000 (kUnusedAddr)
+// |    union table     |
+// +--------------------+ 0x8000000000 (kUnionTableAddr)
+// |   shadow memory    |
+// +--------------------+ 0x0000010000 (kShadowAddr)
+// | reserved by kernel |
+// +--------------------+ 0x0000000000
+
 typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels];
 
 #ifdef DFSAN_RUNTIME_VMA
@@ -372,11 +392,12 @@ static void InitializePlatformEarly() {
 #ifdef DFSAN_RUNTIME_VMA
   __dfsan::vmaSize =
     (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
-  if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42) {
+  if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42 ||
+      __dfsan::vmaSize == 48) {
     __dfsan_shadow_ptr_mask = ShadowMask();
   } else {
     Printf("FATAL: DataFlowSanitizer: unsupported VMA range\n");
-    Printf("FATAL: Found %d - Supported 39 and 42\n", __dfsan::vmaSize);
+    Printf("FATAL: Found %d - Supported 39, 42, and 48\n", __dfsan::vmaSize);
     Die();
   }
 #endif
index f1d9f10..98284ba 100644 (file)
@@ -46,6 +46,13 @@ struct Mapping42 {
   static const uptr kShadowMask = ~0x3c000000000;
 };
 
+struct Mapping48 {
+  static const uptr kShadowAddr = 0x10000;
+  static const uptr kUnionTableAddr = 0x8000000000;
+  static const uptr kAppAddr = 0xffff00008000;
+  static const uptr kShadowMask = ~0xfffff0000000;
+};
+
 extern int vmaSize;
 # define DFSAN_RUNTIME_VMA 1
 #else
@@ -72,11 +79,13 @@ uptr MappingImpl(void) {
 template<int Type>
 uptr MappingArchImpl(void) {
 #ifdef __aarch64__
-  if (vmaSize == 39)
-    return MappingImpl<Mapping39, Type>();
-  else
-    return MappingImpl<Mapping42, Type>();
+  switch (vmaSize) {
+    case 39: return MappingImpl<Mapping39, Type>();
+    case 42: return MappingImpl<Mapping42, Type>();
+    case 48: return MappingImpl<Mapping48, Type>();
+  }
   DCHECK(0);
+  return 0;
 #else
   return MappingImpl<Mapping, Type>();
 #endif