summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_posix_libcdep.cc
diff options
context:
space:
mode:
authorPetr Hosek <phosek@chromium.org>2017-10-11 23:41:32 +0000
committerPetr Hosek <phosek@chromium.org>2017-10-11 23:41:32 +0000
commit8c026f72295bb6b6a9aa0e2673baba6c17b33e26 (patch)
tree60820c68144049f0928dac60d582af664c49e2b4 /lib/sanitizer_common/sanitizer_posix_libcdep.cc
parente3e1659d13986a80ea90f480ddf5af45f1134c48 (diff)
Reland "[sanitizer] Introduce ReservedAddressRange to sanitizer_common"
In Fuchsia, MmapNoAccess/MmapFixedOrDie are implemented using a global VMAR, which means that MmapNoAccess can only be called once. This works for the sanitizer allocator but *not* for the Scudo allocator. Hence, this changeset introduces a new ReservedAddressRange object to serve as the new API for these calls. In this changeset, the object still calls into the old Mmap implementations. The next changeset two changesets will convert the sanitizer and scudo allocators to use the new APIs, respectively. (ReservedAddressRange will replace the SecondaryHeader in Scudo.) Finally, a last changeset will update the Fuchsia implementation. Patch by Julia Hansbrough Differential Revision: https://reviews.llvm.org/D38437 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315533 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_posix_libcdep.cc')
-rw-r--r--lib/sanitizer_common/sanitizer_posix_libcdep.cc36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 4214d91c5..b6b09b5e4 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -337,6 +337,42 @@ void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
return (void *)p;
}
+uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
+ if (fixed_addr) {
+ base_ = MmapFixedNoAccess(fixed_addr, size, name);
+ } else {
+ base_ = MmapNoAccess(size);
+ }
+ size_ = size;
+ name_ = name;
+ return reinterpret_cast<uptr>(base_);
+}
+
+// Uses fixed_addr for now.
+// Will use offset instead once we've implemented this function for real.
+uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size,
+ bool tolerate_enomem) {
+ if (tolerate_enomem) {
+ return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
+ }
+ return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
+}
+
+void ReservedAddressRange::Unmap(uptr addr, uptr size) {
+ void* addr_as_void = reinterpret_cast<void*>(addr);
+ uptr base_as_uptr = reinterpret_cast<uptr>(base_);
+ // Only unmap at the beginning or end of the range.
+ CHECK_EQ((addr_as_void == base_) || (addr + size == base_as_uptr + size_),
+ true);
+ // Detect overflows.
+ CHECK_LE(size, (base_as_uptr + size_) - addr);
+ UnmapOrDie(reinterpret_cast<void*>(addr), size);
+ if (addr_as_void == base_) {
+ base_ = reinterpret_cast<void*>(addr + size);
+ }
+ size_ = size_ - size;
+}
+
void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
int fd = name ? GetNamedMappingFd(name, size) : -1;
unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;