1//===-- sanitizer_local_address_space_view.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// `LocalAddressSpaceView` provides the local (i.e. target and current address
10// space are the same) implementation of the `AddressSpaceView` interface which
11// provides a simple interface to load memory from another process (i.e.
12// out-of-process)
13//
14// The `AddressSpaceView` interface requires that the type can be used as a
15// template parameter to objects that wish to be able to operate in an
16// out-of-process manner. In normal usage, objects are in-process and are thus
17// instantiated with the `LocalAddressSpaceView` type. This type is used to
18// load any pointers in instance methods. This implementation is effectively
19// a no-op. When an object is to be used in an out-of-process manner it is
20// instantiated with the `RemoteAddressSpaceView` type.
21//
22// By making `AddressSpaceView` a template parameter of an object, it can
23// change its implementation at compile time which has no run time overhead.
24// This also allows unifying in-process and out-of-process code which avoids
25// code duplication.
26//
27//===----------------------------------------------------------------------===//
28#ifndef SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H
29#define SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H
30
31namespace __sanitizer {
32struct LocalAddressSpaceView {
33 // Load memory `sizeof(T) * num_elements` bytes of memory from the target
34 // process (always local for this implementation) starting at address
35 // `target_address`. The local copy of this memory is returned as a pointer.
36 // The caller should not write to this memory. The behaviour when doing so is
37 // undefined. Callers should use `LoadWritable()` to get access to memory
38 // that is writable.
39 //
40 // The lifetime of loaded memory is implementation defined.
41 template <typename T>
42 static const T *Load(const T *target_address, uptr num_elements = 1) {
43 // The target address space is the local address space so
44 // nothing needs to be copied. Just return the pointer.
45 return target_address;
46 }
47
48 // Load memory `sizeof(T) * num_elements` bytes of memory from the target
49 // process (always local for this implementation) starting at address
50 // `target_address`. The local copy of this memory is returned as a pointer.
51 // The memory returned may be written to.
52 //
53 // Writes made to the returned memory will be visible in the memory returned
54 // by subsequent `Load()` or `LoadWritable()` calls provided the
55 // `target_address` parameter is the same. It is not guaranteed that the
56 // memory returned by previous calls to `Load()` will contain any performed
57 // writes. If two or more overlapping regions of memory are loaded via
58 // separate calls to `LoadWritable()`, it is implementation defined whether
59 // writes made to the region returned by one call are visible in the regions
60 // returned by other calls.
61 //
62 // Given the above it is recommended to load the largest possible object
63 // that requires modification (e.g. a class) rather than individual fields
64 // from a class to avoid issues with overlapping writable regions.
65 //
66 // The lifetime of loaded memory is implementation defined.
67 template <typename T>
68 static T *LoadWritable(T *target_address, uptr num_elements = 1) {
69 // The target address space is the local address space so
70 // nothing needs to be copied. Just return the pointer.
71 return target_address;
72 }
73};
74} // namespace __sanitizer
75
76#endif
77