1//===-- copyprof_shadow.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// This file declares the shadow memory interface and template helpers for
10/// mapping application memory to CopyProf shadow memory.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef COPYPROF_SHADOW_H
15#define COPYPROF_SHADOW_H
16
17#include "sanitizer_common/sanitizer_common.h"
18#include "sanitizer_common/sanitizer_internal_defs.h"
19
20namespace __copyprof {
21
22// FIXME: copyprof uses a 1:8 mapping but this may lead to data races on shadow
23// memory for concurrent stores within the same 8 byte region. Consider using a
24// 1:1 mapping or reducing granularity (e.g. atomically store whole bytes for
25// each update to an 8 byte region).
26constexpr uptr kShadowScale = 3;
27
28// Helper for mapping application addresses to shadow memory.
29struct ShadowMemory {
30 static uptr MemToShadowSize(uptr size) { return size >> kShadowScale; }
31 static ShadowMemory Create(const char* name) {
32 uptr max_user_va = GetMaxUserVirtualAddress();
33 uptr shadow_size_bytes =
34 RoundUpTo(size: MemToShadowSize(size: max_user_va), boundary: GetMmapGranularity());
35 uptr mapped = MapDynamicShadow(shadow_size_bytes, shadow_scale: kShadowScale,
36 /*min_shadow_base_alignment=*/min_shadow_base_alignment: 0, high_mem_end&: max_user_va,
37 granularity: GetMmapGranularity());
38 ReserveShadowMemoryRange(beg: mapped, end: mapped + shadow_size_bytes - 1, name,
39 /*madvise_shadow=*/madvise_shadow: true);
40 return ShadowMemory(mapped);
41 }
42 ShadowMemory() = default;
43 uptr MemToShadow(uptr p) const { return (p >> kShadowScale) + shadow_base_; }
44
45 private:
46 explicit ShadowMemory(uptr shadow_base) : shadow_base_(shadow_base) {}
47 uptr shadow_base_ = 0;
48};
49
50// Must be called exactly once at program startup.
51void InitializeShadowMemory();
52
53// Given an application memory block starting at `app_addr` of size `num_bytes`,
54// marks the corresponding shadow memory as a copy or non-copy.
55void MarkApplicationMemory(const void* app_addr, uptr num_bytes, bool is_copy);
56
57// Whether the application memory block starting at `app_addr` of size
58// `num_bytes` is marked as a copy in shadow memory.
59bool IsMarkedAsCopy(const void* app_addr, uptr num_bytes);
60
61} // namespace __copyprof
62
63#endif // COPYPROF_SHADOW_H
64