xref: /openbsd-src/gnu/llvm/compiler-rt/lib/dfsan/dfsan_platform.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- dfsan_platform.h ----------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of DataFlowSanitizer.
103cab2bb3Spatrick //
113cab2bb3Spatrick // Platform specific information for DFSan.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick 
143cab2bb3Spatrick #ifndef DFSAN_PLATFORM_H
153cab2bb3Spatrick #define DFSAN_PLATFORM_H
163cab2bb3Spatrick 
17d89ec533Spatrick #include "sanitizer_common/sanitizer_common.h"
18d89ec533Spatrick #include "sanitizer_common/sanitizer_platform.h"
19d89ec533Spatrick 
203cab2bb3Spatrick namespace __dfsan {
213cab2bb3Spatrick 
22d89ec533Spatrick using __sanitizer::uptr;
23d89ec533Spatrick 
24d89ec533Spatrick // TODO: The memory mapping code to setup a 1:1 shadow is based on msan.
25d89ec533Spatrick // Consider refactoring these into a shared implementation.
26d89ec533Spatrick 
27d89ec533Spatrick struct MappingDesc {
28d89ec533Spatrick   uptr start;
29d89ec533Spatrick   uptr end;
30d89ec533Spatrick   enum Type { INVALID, APP, SHADOW, ORIGIN } type;
31d89ec533Spatrick   const char *name;
323cab2bb3Spatrick };
333cab2bb3Spatrick 
34d89ec533Spatrick #if SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
353cab2bb3Spatrick 
36*810390e3Srobert #  if defined(__aarch64__)
37*810390e3Srobert // The mapping assumes 48-bit VMA. AArch64 maps:
38*810390e3Srobert // - 0x0000000000000-0x0100000000000: 39/42/48-bits program own segments
39*810390e3Srobert // - 0x0a00000000000-0x0b00000000000: 48-bits PIE program segments
40*810390e3Srobert //   Ideally, this would extend to 0x0c00000000000 (2^45 bytes - the
41*810390e3Srobert //   maximum ASLR region for 48-bit VMA) but it is too hard to fit in
42*810390e3Srobert //   the larger app/shadow/origin regions.
43*810390e3Srobert // - 0x0e00000000000-0x1000000000000: 48-bits libraries segments
44*810390e3Srobert const MappingDesc kMemoryLayout[] = {
45*810390e3Srobert     {0X0000000000000, 0X0100000000000, MappingDesc::APP, "app-10-13"},
46*810390e3Srobert     {0X0100000000000, 0X0200000000000, MappingDesc::SHADOW, "shadow-14"},
47*810390e3Srobert     {0X0200000000000, 0X0300000000000, MappingDesc::INVALID, "invalid"},
48*810390e3Srobert     {0X0300000000000, 0X0400000000000, MappingDesc::ORIGIN, "origin-14"},
49*810390e3Srobert     {0X0400000000000, 0X0600000000000, MappingDesc::SHADOW, "shadow-15"},
50*810390e3Srobert     {0X0600000000000, 0X0800000000000, MappingDesc::ORIGIN, "origin-15"},
51*810390e3Srobert     {0X0800000000000, 0X0A00000000000, MappingDesc::INVALID, "invalid"},
52*810390e3Srobert     {0X0A00000000000, 0X0B00000000000, MappingDesc::APP, "app-14"},
53*810390e3Srobert     {0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"},
54*810390e3Srobert     {0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"},
55*810390e3Srobert     {0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"},
56*810390e3Srobert     {0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"},
57*810390e3Srobert };
58*810390e3Srobert #    define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL)
59*810390e3Srobert #    define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL)
60*810390e3Srobert 
61*810390e3Srobert #  else
62d89ec533Spatrick // All of the following configurations are supported.
63d89ec533Spatrick // ASLR disabled: main executable and DSOs at 0x555550000000
64d89ec533Spatrick // PIE and ASLR: main executable and DSOs at 0x7f0000000000
65d89ec533Spatrick // non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000
66d89ec533Spatrick // Heap at 0x700000000000.
67d89ec533Spatrick const MappingDesc kMemoryLayout[] = {
68d89ec533Spatrick     {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"},
69d89ec533Spatrick     {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
70d89ec533Spatrick     {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
71d89ec533Spatrick     {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
72d89ec533Spatrick     {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
73d89ec533Spatrick     {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
74d89ec533Spatrick     {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
75d89ec533Spatrick     {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"},
76d89ec533Spatrick     {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
77d89ec533Spatrick     {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
78d89ec533Spatrick     {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
79d89ec533Spatrick     {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
80d89ec533Spatrick #    define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
81d89ec533Spatrick #    define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)
82*810390e3Srobert #  endif
833cab2bb3Spatrick 
843cab2bb3Spatrick #else
85d89ec533Spatrick #  error "Unsupported platform"
863cab2bb3Spatrick #endif
873cab2bb3Spatrick 
88d89ec533Spatrick const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
893cab2bb3Spatrick 
90d89ec533Spatrick #define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
913cab2bb3Spatrick 
92d89ec533Spatrick #ifndef __clang__
93d89ec533Spatrick __attribute__((optimize("unroll-loops")))
943cab2bb3Spatrick #endif
95d89ec533Spatrick inline bool
addr_is_type(uptr addr,MappingDesc::Type mapping_type)96d89ec533Spatrick addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
97d89ec533Spatrick // It is critical for performance that this loop is unrolled (because then it is
98d89ec533Spatrick // simplified into just a few constant comparisons).
99d89ec533Spatrick #ifdef __clang__
100d89ec533Spatrick #  pragma unroll
101d89ec533Spatrick #endif
102d89ec533Spatrick   for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
103d89ec533Spatrick     if (kMemoryLayout[i].type == mapping_type &&
104d89ec533Spatrick         addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
105d89ec533Spatrick       return true;
106d89ec533Spatrick   return false;
1073cab2bb3Spatrick }
1083cab2bb3Spatrick 
109d89ec533Spatrick #define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
110d89ec533Spatrick #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
111d89ec533Spatrick #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
1123cab2bb3Spatrick 
1133cab2bb3Spatrick }  // namespace __dfsan
1143cab2bb3Spatrick 
1153cab2bb3Spatrick #endif
116