blob: 0a7334dd2d164609c0bfab34e98f7d228524c79b [file] [edit]
//===-- copyprof_shadow.h -------------------------------------*- C++ -*-===//
//
// 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 declares the shadow memory interface and template helpers for
/// mapping application memory to CopyProf shadow memory.
///
//===----------------------------------------------------------------------===//
#ifndef COPYPROF_SHADOW_H
#define COPYPROF_SHADOW_H
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
namespace __copyprof {
// FIXME: copyprof uses a 1:8 mapping but this may lead to data races on shadow
// memory for concurrent stores within the same 8 byte region. Consider using a
// 1:1 mapping or reducing granularity (e.g. atomically store whole bytes for
// each update to an 8 byte region).
constexpr uptr kShadowScale = 3;
// Helper for mapping application addresses to shadow memory.
struct ShadowMemory {
static uptr MemToShadowSize(uptr size) { return size >> kShadowScale; }
static ShadowMemory Create(const char* name) {
uptr max_user_va = GetMaxUserVirtualAddress();
uptr shadow_size_bytes =
RoundUpTo(MemToShadowSize(max_user_va), GetMmapGranularity());
uptr mapped = MapDynamicShadow(shadow_size_bytes, kShadowScale,
/*min_shadow_base_alignment=*/0, max_user_va,
GetMmapGranularity());
ReserveShadowMemoryRange(mapped, mapped + shadow_size_bytes - 1, name,
/*madvise_shadow=*/true);
return ShadowMemory(mapped);
}
ShadowMemory() = default;
uptr MemToShadow(uptr p) const { return (p >> kShadowScale) + shadow_base_; }
private:
explicit ShadowMemory(uptr shadow_base) : shadow_base_(shadow_base) {}
uptr shadow_base_ = 0;
};
// Must be called exactly once at program startup.
void InitializeShadowMemory();
// Given an application memory block starting at `app_addr` of size `num_bytes`,
// marks the corresponding shadow memory as a copy or non-copy.
void MarkApplicationMemory(const void* app_addr, uptr num_bytes, bool is_copy);
// Whether the application memory block starting at `app_addr` of size
// `num_bytes` is marked as a copy in shadow memory.
bool IsMarkedAsCopy(const void* app_addr, uptr num_bytes);
} // namespace __copyprof
#endif // COPYPROF_SHADOW_H