//===-- asan_shadow_setup.cc ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// Set up the shadow memory.
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"

// asan_fuchsia.cc and asan_rtems.cc have their own
// InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS

#include "asan_internal.h"
#include "asan_mapping.h"

namespace __asan {

// ---------------------- mmap -------------------- {{{1
// Reserve memory range [beg, end].
// We need to use inclusive range because end+1 may not be representable.
void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
  CHECK_EQ((beg % GetMmapGranularity()), 0);
  CHECK_EQ(((end + 1) % GetMmapGranularity()), 0);
  uptr size = end - beg + 1;
  DecreaseTotalMmap(size);  // Don't count the shadow against mmap_limit_mb.
  if (!MmapFixedNoReserve(beg, size, name)) {
    Report(
        "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
        "Perhaps you're using ulimit -v\n",
        size);
    Abort();
  }
  if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size);
  if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size);
}

static void ProtectGap(uptr addr, uptr size) {
  if (!flags()->protect_shadow_gap) {
    // The shadow gap is unprotected, so there is a chance that someone
    // is actually using this memory. Which means it needs a shadow...
    uptr GapShadowBeg = RoundDownTo(MEM_TO_SHADOW(addr), GetPageSizeCached());
    uptr GapShadowEnd =
        RoundUpTo(MEM_TO_SHADOW(addr + size), GetPageSizeCached()) - 1;
    if (Verbosity())
      Printf(
          "protect_shadow_gap=0:"
          " not protecting shadow gap, allocating gap's shadow\n"
          "|| `[%p, %p]` || ShadowGap's shadow ||\n",
          GapShadowBeg, GapShadowEnd);
    ReserveShadowMemoryRange(GapShadowBeg, GapShadowEnd,
                             "unprotected gap shadow");
    return;
  }
  void *res = MmapFixedNoAccess(addr, size, "shadow gap");
  if (addr == (uptr)res) return;
  // A few pages at the start of the address space can not be protected.
  // But we really want to protect as much as possible, to prevent this memory
  // being returned as a result of a non-FIXED mmap().
  if (addr == kZeroBaseShadowStart) {
    uptr step = GetMmapGranularity();
    while (size > step && addr < kZeroBaseMaxShadowStart) {
      addr += step;
      size -= step;
      void *res = MmapFixedNoAccess(addr, size, "shadow gap");
      if (addr == (uptr)res) return;
    }
  }

  Report(
      "ERROR: Failed to protect the shadow gap. "
      "ASan cannot proceed correctly. ABORTING.\n");
  DumpProcessMap();
  Die();
}

static void MaybeReportLinuxPIEBug() {
#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__aarch64__))
  Report("This might be related to ELF_ET_DYN_BASE change in Linux 4.12.\n");
  Report(
      "See https://github.com/google/sanitizers/issues/856 for possible "
      "workarounds.\n");
#endif
}

void InitializeShadowMemory() {
  // Set the shadow memory address to uninitialized.
  __asan_shadow_memory_dynamic_address = kDefaultShadowSentinel;

  uptr shadow_start = kLowShadowBeg;
  // Detect if a dynamic shadow address must used and find a available location
  // when necessary. When dynamic address is used, the macro |kLowShadowBeg|
  // expands to |__asan_shadow_memory_dynamic_address| which is
  // |kDefaultShadowSentinel|.
  bool full_shadow_is_available = false;
  if (shadow_start == kDefaultShadowSentinel) {
    __asan_shadow_memory_dynamic_address = 0;
    CHECK_EQ(0, kLowShadowBeg);
    shadow_start = FindDynamicShadowStart();
    if (SANITIZER_LINUX) full_shadow_is_available = true;
  }
  // Update the shadow memory address (potentially) used by instrumentation.
  __asan_shadow_memory_dynamic_address = shadow_start;

  if (kLowShadowBeg) shadow_start -= GetMmapGranularity();

  if (!full_shadow_is_available)
    full_shadow_is_available =
        MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);

#if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \
    !ASAN_FIXED_MAPPING
  if (!full_shadow_is_available) {
    kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
    kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
  }
#endif

  if (Verbosity()) PrintAddressSpaceLayout();

  if (full_shadow_is_available) {
    // mmap the low shadow plus at least one page at the left.
    if (kLowShadowBeg)
      ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
    // mmap the high shadow.
    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
    // protect the gap.
    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
    CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
  } else if (kMidMemBeg &&
             MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
             MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
    CHECK(kLowShadowBeg != kLowShadowEnd);
    // mmap the low shadow plus at least one page at the left.
    ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
    // mmap the mid shadow.
    ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
    // mmap the high shadow.
    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
    // protect the gaps.
    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
    ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
    ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
  } else {
    Report(
        "Shadow memory range interleaves with an existing memory mapping. "
        "ASan cannot proceed correctly. ABORTING.\n");
    Report("ASan shadow was supposed to be located in the [%p-%p] range.\n",
           shadow_start, kHighShadowEnd);
    MaybeReportLinuxPIEBug();
    DumpProcessMap();
    Die();
  }
}

}  // namespace __asan

#endif  // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
