Index: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt +++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt @@ -144,6 +144,7 @@ sanitizer_libignore.h sanitizer_linux.h sanitizer_list.h + sanitizer_local_address_space_view.h sanitizer_mac.h sanitizer_malloc_mac.inc sanitizer_mutex.h Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h @@ -14,12 +14,13 @@ #ifndef SANITIZER_ALLOCATOR_H #define SANITIZER_ALLOCATOR_H -#include "sanitizer_internal_defs.h" #include "sanitizer_common.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_lfstack.h" #include "sanitizer_libc.h" #include "sanitizer_list.h" +#include "sanitizer_local_address_space_view.h" #include "sanitizer_mutex.h" -#include "sanitizer_lfstack.h" #include "sanitizer_procmaps.h" namespace __sanitizer { Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_secondary.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_secondary.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_secondary.h @@ -68,7 +68,8 @@ // The main purpose of this allocator is to cover large and rare allocation // sizes not covered by more efficient allocators (e.g. SizeClassAllocator64). template + class PtrArrayT = DefaultLargeMmapAllocatorPtrArray, + class AddressSpaceView = LocalAddressSpaceView> class LargeMmapAllocator { public: void InitLinkerInitialized() { @@ -202,9 +203,10 @@ void EnsureSortedChunks() { if (chunks_sorted_) return; - Sort(reinterpret_cast(chunks_), n_chunks_); + Header **chunks = AddressSpaceView::Load(chunks_, n_chunks_); + Sort(reinterpret_cast(chunks), n_chunks_); for (uptr i = 0; i < n_chunks_; i++) - chunks_[i]->chunk_idx = i; + AddressSpaceView::Load(chunks[i])->chunk_idx = i; chunks_sorted_ = true; } @@ -272,12 +274,13 @@ // The allocator must be locked when calling this function. void ForEachChunk(ForEachChunkCallback callback, void *arg) { EnsureSortedChunks(); // Avoid doing the sort while iterating. + Header **chunks = AddressSpaceView::Load(chunks_, n_chunks_); for (uptr i = 0; i < n_chunks_; i++) { - auto t = chunks_[i]; + Header *t = chunks[i]; callback(reinterpret_cast(GetUser(t)), arg); // Consistency check: verify that the array did not change. - CHECK_EQ(chunks_[i], t); - CHECK_EQ(chunks_[i]->chunk_idx, i); + CHECK_EQ(chunks[i], t); + CHECK_EQ(AddressSpaceView::Load(chunks[i])->chunk_idx, i); } } @@ -316,4 +319,3 @@ } stats; StaticSpinMutex mutex_; }; - Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_local_address_space_view.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_local_address_space_view.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_local_address_space_view.h @@ -0,0 +1,53 @@ +//===-- sanitizer_local_address_space_view.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// `LocalAddressSpaceView` provides the local (i.e. target and current address +// space are the same) implementation of the `AddressSpaveView` interface which +// provides a simple interface to load memory from another process (i.e. +// out-of-process) +// +// The `AddressSpaveView` interface requires that the type can be used as a +// template parameter to objects that wish to be able to operate in an +// out-of-process manner. In normal usage, objects are in-process and are thus +// instantiated with the `LocalAddressSpaceView` type. This type is used to +// load any pointers in instance methods. This implementation is effectively +// a no-op. When an object is to be used in an out-of-process manner it is +// instansiated with the `RemoteAddressSpaceView` type. +// +// By making `AddressSpaceView` a template parameter of an object, it can +// change its implementation at compile time which has no run time overhead. +// This also allows unifying in-process and out-of-process code which avoids +// code duplication. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H +#define SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H + +namespace __sanitizer { +struct LocalAddressSpaceView { + // Load memory `sizeof(T) * num_elements` bytes of memory + // from the target process (always local for this implementation) + // starting at address `target_address`. The local copy of + // this memory is returned as a pointer. It is guaranteed that + // + // * That the function will always return the same value + // for a given set of arguments. + // * That the memory returned is writable and that writes will persist. + // + // The lifetime of loaded memory is implementation defined. + template + static T *Load(T *target_address, uptr num_elements = 1) { + // The target address space is the local address space so + // nothing needs to be copied. Just return the pointer. + return target_address; + } +}; +} // namespace __sanitizer + +#endif