1*3d4bba30STeresa Johnson //===-- memprof_shadow_setup.cpp -----------------------------------------===//
2*3d4bba30STeresa Johnson //
3*3d4bba30STeresa Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*3d4bba30STeresa Johnson // See https://llvm.org/LICENSE.txt for license information.
5*3d4bba30STeresa Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*3d4bba30STeresa Johnson //
7*3d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
8*3d4bba30STeresa Johnson //
9*3d4bba30STeresa Johnson // This file is a part of MemProfiler, a memory profiler.
10*3d4bba30STeresa Johnson //
11*3d4bba30STeresa Johnson // Set up the shadow memory.
12*3d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
13*3d4bba30STeresa Johnson 
14*3d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_platform.h"
15*3d4bba30STeresa Johnson 
16*3d4bba30STeresa Johnson #include "memprof_internal.h"
17*3d4bba30STeresa Johnson #include "memprof_mapping.h"
18*3d4bba30STeresa Johnson 
19*3d4bba30STeresa Johnson namespace __memprof {
20*3d4bba30STeresa Johnson 
ProtectGap(uptr addr,uptr size)21*3d4bba30STeresa Johnson static void ProtectGap(uptr addr, uptr size) {
22*3d4bba30STeresa Johnson   if (!flags()->protect_shadow_gap) {
23*3d4bba30STeresa Johnson     // The shadow gap is unprotected, so there is a chance that someone
24*3d4bba30STeresa Johnson     // is actually using this memory. Which means it needs a shadow...
25*3d4bba30STeresa Johnson     uptr GapShadowBeg = RoundDownTo(MEM_TO_SHADOW(addr), GetPageSizeCached());
26*3d4bba30STeresa Johnson     uptr GapShadowEnd =
27*3d4bba30STeresa Johnson         RoundUpTo(MEM_TO_SHADOW(addr + size), GetPageSizeCached()) - 1;
28*3d4bba30STeresa Johnson     if (Verbosity())
29*3d4bba30STeresa Johnson       Printf("protect_shadow_gap=0:"
30*3d4bba30STeresa Johnson              " not protecting shadow gap, allocating gap's shadow\n"
31*3d4bba30STeresa Johnson              "|| `[%p, %p]` || ShadowGap's shadow ||\n",
32*3d4bba30STeresa Johnson              GapShadowBeg, GapShadowEnd);
33*3d4bba30STeresa Johnson     ReserveShadowMemoryRange(GapShadowBeg, GapShadowEnd,
34*3d4bba30STeresa Johnson                              "unprotected gap shadow");
35*3d4bba30STeresa Johnson     return;
36*3d4bba30STeresa Johnson   }
37*3d4bba30STeresa Johnson   __sanitizer::ProtectGap(addr, size, kZeroBaseShadowStart,
38*3d4bba30STeresa Johnson                           kZeroBaseMaxShadowStart);
39*3d4bba30STeresa Johnson }
40*3d4bba30STeresa Johnson 
InitializeShadowMemory()41*3d4bba30STeresa Johnson void InitializeShadowMemory() {
42*3d4bba30STeresa Johnson   uptr shadow_start = FindDynamicShadowStart();
43*3d4bba30STeresa Johnson   // Update the shadow memory address (potentially) used by instrumentation.
44*3d4bba30STeresa Johnson   __memprof_shadow_memory_dynamic_address = shadow_start;
45*3d4bba30STeresa Johnson 
46*3d4bba30STeresa Johnson   if (kLowShadowBeg)
47*3d4bba30STeresa Johnson     shadow_start -= GetMmapGranularity();
48*3d4bba30STeresa Johnson 
49*3d4bba30STeresa Johnson   if (Verbosity())
50*3d4bba30STeresa Johnson     PrintAddressSpaceLayout();
51*3d4bba30STeresa Johnson 
52*3d4bba30STeresa Johnson   // mmap the low shadow plus at least one page at the left.
53*3d4bba30STeresa Johnson   if (kLowShadowBeg)
54*3d4bba30STeresa Johnson     ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
55*3d4bba30STeresa Johnson   // mmap the high shadow.
56*3d4bba30STeresa Johnson   ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
57*3d4bba30STeresa Johnson   // protect the gap.
58*3d4bba30STeresa Johnson   ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
59*3d4bba30STeresa Johnson   CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
60*3d4bba30STeresa Johnson }
61*3d4bba30STeresa Johnson 
62*3d4bba30STeresa Johnson } // namespace __memprof
63