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