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 `AddressSpaveView` 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 // instansiated 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 31 namespace __sanitizer { 32 struct 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