summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-11-27 12:43:33 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-11-27 12:43:33 +0000
commita0a280ecb5258d8a879777f48787838bd5f6a4bf (patch)
treeffabc83c1c9340d1767302dfe1727a33f08524b1 /lib
parentb7e954000bc39a0feca3b4a31415817aac9ed9e4 (diff)
[compiler-rt] [dfsan] Unify aarch64 mapping
This patch reorganize the platform specific mapping information to export the application mask on a external variable. This exported variable will be used by intrumentation phase to create code to be used on architecture with multiple VMA range. The patch creates a new header, dfsan_platform.h, and move all the mapping information and also create function accessors to the mapping value. Also for aarch64 it initialize application exported mask to the value based on runtime VMA detection. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@254197 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/dfsan/dfsan.cc59
-rw-r--r--lib/dfsan/dfsan.h13
-rw-r--r--lib/dfsan/dfsan_platform.h107
3 files changed, 138 insertions, 41 deletions
diff --git a/lib/dfsan/dfsan.cc b/lib/dfsan/dfsan.cc
index f4bef921a..7285f202d 100644
--- a/lib/dfsan/dfsan.cc
+++ b/lib/dfsan/dfsan.cc
@@ -42,6 +42,8 @@ Flags __dfsan::flags_data;
SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls;
SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];
+SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;
+
// On Linux/x86_64, memory is laid out as follows:
//
// +--------------------+ 0x800000000000 (top of memory)
@@ -114,35 +116,18 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];
typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels];
-#if defined(__x86_64__)
-static const uptr kShadowAddr = 0x10000;
-static const uptr kUnionTableAddr = 0x200000000000;
-static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t);
-static const uptr kAppAddr = 0x700000008000;
-#elif defined(__mips64)
-static const uptr kShadowAddr = 0x10000;
-static const uptr kUnionTableAddr = 0x2000000000;
-static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t);
-static const uptr kAppAddr = 0xF000008000;
-#elif defined(__aarch64__)
-static const uptr kShadowAddr = 0x10000;
-# if SANITIZER_AARCH64_VMA == 39
-static const uptr kUnionTableAddr = 0x1000000000;
-# elif SANITIZER_AARCH64_VMA == 42
-static const uptr kUnionTableAddr = 0x8000000000;
-# endif
-static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t);
-# if SANITIZER_AARCH64_VMA == 39
-static const uptr kAppAddr = 0x7000008000;
-# elif SANITIZER_AARCH64_VMA == 42
-static const uptr kAppAddr = 0x3ff00008000;
-# endif
-#else
-# error "DFSan not supported for this platform!"
+#ifdef DFSAN_RUNTIME_VMA
+// Runtime detected VMA size.
+int __dfsan::vmaSize;
#endif
+static uptr UnusedAddr() {
+ return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>()
+ + sizeof(dfsan_union_table_t);
+}
+
static atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) {
- return &(*(dfsan_union_table_t *) kUnionTableAddr)[l1][l2];
+ return &(*(dfsan_union_table_t *) UnionTableAddr())[l1][l2];
}
// Checks we do not run out of labels.
@@ -382,6 +367,20 @@ static void InitializeFlags() {
if (common_flags()->help) parser.PrintFlagDescriptions();
}
+static void InitializePlatformEarly() {
+#ifdef DFSAN_RUNTIME_VMA
+ __dfsan::vmaSize =
+ (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
+ if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42) {
+ __dfsan_shadow_ptr_mask = ShadowMask();
+ } else {
+ Printf("FATAL: DataFlowSanitizer: unsupported VMA range\n");
+ Printf("FATAL: Found %d - Supported 39 and 42\n", __dfsan::vmaSize);
+ Die();
+ }
+#endif
+}
+
static void dfsan_fini() {
if (internal_strcmp(flags().dump_labels_at_exit, "") != 0) {
fd_t fd = OpenFile(flags().dump_labels_at_exit, WrOnly);
@@ -401,9 +400,9 @@ static void dfsan_fini() {
static void dfsan_init(int argc, char **argv, char **envp) {
InitializeFlags();
- CheckVMASize();
+ InitializePlatformEarly();
- MmapFixedNoReserve(kShadowAddr, kUnusedAddr - kShadowAddr);
+ MmapFixedNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr());
// Protect the region of memory we don't use, to preserve the one-to-one
// mapping from application to shadow memory. But if ASLR is disabled, Linux
@@ -411,8 +410,8 @@ static void dfsan_init(int argc, char **argv, char **envp) {
// works so long as the program doesn't use too much memory. We support this
// case by disabling memory protection when ASLR is disabled.
uptr init_addr = (uptr)&dfsan_init;
- if (!(init_addr >= kUnusedAddr && init_addr < kAppAddr))
- MmapNoAccess(kUnusedAddr, kAppAddr - kUnusedAddr);
+ if (!(init_addr >= UnusedAddr() && init_addr < AppAddr()))
+ MmapNoAccess(UnusedAddr(), AppAddr() - UnusedAddr());
InitializeInterceptors();
diff --git a/lib/dfsan/dfsan.h b/lib/dfsan/dfsan.h
index df222e49b..81f949e30 100644
--- a/lib/dfsan/dfsan.h
+++ b/lib/dfsan/dfsan.h
@@ -16,6 +16,7 @@
#define DFSAN_H
#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "dfsan_platform.h"
// Copy declarations from public sanitizer/dfsan_interface.h header here.
typedef u16 dfsan_label;
@@ -44,17 +45,7 @@ namespace __dfsan {
void InitializeInterceptors();
inline dfsan_label *shadow_for(void *ptr) {
-#if defined(__x86_64__)
- return (dfsan_label *) ((((uptr) ptr) & ~0x700000000000) << 1);
-#elif defined(__mips64)
- return (dfsan_label *) ((((uptr) ptr) & ~0xF000000000) << 1);
-#elif defined(__aarch64__)
-# if SANITIZER_AARCH64_VMA == 39
- return (dfsan_label *) ((((uptr) ptr) & ~0x7800000000) << 1);
-# elif SANITIZER_AARCH64_VMA == 42
- return (dfsan_label *) ((((uptr) ptr) & ~0x3c000000000) << 1);
-# endif
-#endif
+ return (dfsan_label *) ((((uptr) ptr) & ShadowMask()) << 1);
}
inline const dfsan_label *shadow_for(const void *ptr) {
diff --git a/lib/dfsan/dfsan_platform.h b/lib/dfsan/dfsan_platform.h
new file mode 100644
index 000000000..f1d9f108e
--- /dev/null
+++ b/lib/dfsan/dfsan_platform.h
@@ -0,0 +1,107 @@
+//===-- dfsan_platform.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of DataFlowSanitizer.
+//
+// Platform specific information for DFSan.
+//===----------------------------------------------------------------------===//
+
+#ifndef DFSAN_PLATFORM_H
+#define DFSAN_PLATFORM_H
+
+namespace __dfsan {
+
+#if defined(__x86_64__)
+struct Mapping {
+ static const uptr kShadowAddr = 0x10000;
+ static const uptr kUnionTableAddr = 0x200000000000;
+ static const uptr kAppAddr = 0x700000008000;
+ static const uptr kShadowMask = ~0x700000000000;
+};
+#elif defined(__mips64)
+struct Mapping {
+ static const uptr kShadowAddr = 0x10000;
+ static const uptr kUnionTableAddr = 0x2000000000;
+ static const uptr kAppAddr = 0xF000008000;
+ static const uptr kShadowMask = ~0xF000000000;
+};
+#elif defined(__aarch64__)
+struct Mapping39 {
+ static const uptr kShadowAddr = 0x10000;
+ static const uptr kUnionTableAddr = 0x1000000000;
+ static const uptr kAppAddr = 0x7000008000;
+ static const uptr kShadowMask = ~0x7800000000;
+};
+
+struct Mapping42 {
+ static const uptr kShadowAddr = 0x10000;
+ static const uptr kUnionTableAddr = 0x8000000000;
+ static const uptr kAppAddr = 0x3ff00008000;
+ static const uptr kShadowMask = ~0x3c000000000;
+};
+
+extern int vmaSize;
+# define DFSAN_RUNTIME_VMA 1
+#else
+# error "DFSan not supported for this platform!"
+#endif
+
+enum MappingType {
+ MAPPING_SHADOW_ADDR,
+ MAPPING_UNION_TABLE_ADDR,
+ MAPPING_APP_ADDR,
+ MAPPING_SHADOW_MASK
+};
+
+template<typename Mapping, int Type>
+uptr MappingImpl(void) {
+ switch (Type) {
+ case MAPPING_SHADOW_ADDR: return Mapping::kShadowAddr;
+ case MAPPING_UNION_TABLE_ADDR: return Mapping::kUnionTableAddr;
+ case MAPPING_APP_ADDR: return Mapping::kAppAddr;
+ case MAPPING_SHADOW_MASK: return Mapping::kShadowMask;
+ }
+}
+
+template<int Type>
+uptr MappingArchImpl(void) {
+#ifdef __aarch64__
+ if (vmaSize == 39)
+ return MappingImpl<Mapping39, Type>();
+ else
+ return MappingImpl<Mapping42, Type>();
+ DCHECK(0);
+#else
+ return MappingImpl<Mapping, Type>();
+#endif
+}
+
+ALWAYS_INLINE
+uptr ShadowAddr() {
+ return MappingArchImpl<MAPPING_SHADOW_ADDR>();
+}
+
+ALWAYS_INLINE
+uptr UnionTableAddr() {
+ return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>();
+}
+
+ALWAYS_INLINE
+uptr AppAddr() {
+ return MappingArchImpl<MAPPING_APP_ADDR>();
+}
+
+ALWAYS_INLINE
+uptr ShadowMask() {
+ return MappingArchImpl<MAPPING_SHADOW_MASK>();
+}
+
+} // namespace __dfsan
+
+#endif