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