summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-11-27 19:53:53 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-11-27 19:53:53 +0000
commitdc8c0dd36ba2c119772ec7e614ca33ec6463214e (patch)
treeb2fbe385f30c1b5fb71975d37610d9ef18be74eb /lib
parent47ee90b8a3d5b4b9a358aed092f63799f7de9dd5 (diff)
[fuchsia] Update Fuchsia with a new mmap implementation.
Summary: Now that the sanitizer_common interface for MmapNoAccess / MmapFixed have been refactored to allow a more OO-esque access pattern, update the Fuchsia mmap implementation to take advantage of this. Previously MmapNoAccess / MmapFixed relied on a global allocator_vmar, since the sanitizer_allocator only called MmapNoAccess once. Now, we create a new VMAR per ReservedAddressRange object. This allows the sanitizer allocator to work in tandem with the Scudo secondary allocator. This is part 4 of a 4 part changeset: * part 1 https://reviews.llvm.org/D38593 * part 2 https://reviews.llvm.org/D38592 * part 3 https://reviews.llvm.org/D38593 Reviewers: mcgrathr, cryptoad Reviewed By: cryptoad Subscribers: alekseyshl, mcgrathr, kubamracek, mehdi_amini Differential Revision: https://reviews.llvm.org/D38595 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/sanitizer_common/sanitizer_common.h1
-rw-r--r--lib/sanitizer_common/sanitizer_fuchsia.cc162
-rw-r--r--lib/sanitizer_common/sanitizer_posix_libcdep.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc1
4 files changed, 73 insertions, 92 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 2633a9816..ceec58cd5 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -142,6 +142,7 @@ class ReservedAddressRange {
void* base_;
uptr size_;
const char* name_;
+ uptr os_handle_;
};
typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc
index 23df9aad5..511d55e1d 100644
--- a/lib/sanitizer_common/sanitizer_fuchsia.cc
+++ b/lib/sanitizer_common/sanitizer_fuchsia.cc
@@ -191,9 +191,7 @@ uptr GetMaxUserVirtualAddress() {
return ShadowBounds.memory_limit - 1;
}
-uptr GetMaxVirtualAddress() {
- return GetMaxUserVirtualAddress();
-}
+uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); }
static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type,
bool raw_report, bool die_for_nomem) {
@@ -240,108 +238,96 @@ void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
return DoAnonymousMmapOrDie(size, mem_type, false, false);
}
-uptr ReservedAddressRange::Init(uptr init_size, const char* name,
+uptr ReservedAddressRange::Init(uptr init_size, const char *name,
uptr fixed_addr) {
- base_ = MmapNoAccess(init_size);
- size_ = init_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 map_size) {
- return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr,
- map_size));
-}
-
-uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) {
- return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, map_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((addr_as_void == base_) || (addr + size == base_as_uptr + size_));
- CHECK_LE(size, size_);
- UnmapOrDie(reinterpret_cast<void*>(addr), size);
- if (addr_as_void == base_) {
- base_ = reinterpret_cast<void*>(addr + size);
- }
- size_ = size_ - size;
-}
-
-// MmapNoAccess and MmapFixedOrDie are used only by sanitizer_allocator.
-// Instead of doing exactly what they say, we make MmapNoAccess actually
-// just allocate a VMAR to reserve the address space. Then MmapFixedOrDie
-// uses that VMAR instead of the root.
-
-zx_handle_t allocator_vmar = ZX_HANDLE_INVALID;
-uintptr_t allocator_vmar_base;
-size_t allocator_vmar_size;
-
-void *MmapNoAccess(uptr size) {
- size = RoundUpTo(size, PAGE_SIZE);
- CHECK_EQ(allocator_vmar, ZX_HANDLE_INVALID);
+ init_size = RoundUpTo(init_size, PAGE_SIZE);
+ DCHECK_EQ(os_handle_, ZX_HANDLE_INVALID);
uintptr_t base;
+ zx_handle_t vmar;
zx_status_t status =
- _zx_vmar_allocate(_zx_vmar_root_self(), 0, size,
+ _zx_vmar_allocate(_zx_vmar_root_self(), 0, init_size,
ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE |
ZX_VM_FLAG_CAN_MAP_SPECIFIC,
- &allocator_vmar, &base);
+ &vmar, &base);
if (status != ZX_OK)
- ReportMmapFailureAndDie(size, "sanitizer allocator address space",
- "zx_vmar_allocate", status);
+ ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status);
+ base_ = reinterpret_cast<void *>(base);
+ size_ = init_size;
+ name_ = name;
+ os_handle_ = vmar;
- allocator_vmar_base = base;
- allocator_vmar_size = size;
- return reinterpret_cast<void *>(base);
+ return reinterpret_cast<uptr>(base_);
}
-constexpr const char kAllocatorVmoName[] = "sanitizer_allocator";
-
-static void *DoMmapFixedOrDie(uptr fixed_addr, uptr size, bool die_for_nomem) {
- size = RoundUpTo(size, PAGE_SIZE);
-
+static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size,
+ void *base, const char *name, bool die_for_nomem) {
+ uptr offset = fixed_addr - reinterpret_cast<uptr>(base);
+ map_size = RoundUpTo(map_size, PAGE_SIZE);
zx_handle_t vmo;
- zx_status_t status = _zx_vmo_create(size, 0, &vmo);
+ zx_status_t status = _zx_vmo_create(map_size, 0, &vmo);
if (status != ZX_OK) {
if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
- ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmo_create", status);
- return nullptr;
+ ReportMmapFailureAndDie(map_size, name, "zx_vmo_create", status);
+ return 0;
}
- _zx_object_set_property(vmo, ZX_PROP_NAME, kAllocatorVmoName,
- sizeof(kAllocatorVmoName) - 1);
-
- DCHECK_GE(fixed_addr, allocator_vmar_base);
- uintptr_t offset = fixed_addr - allocator_vmar_base;
- DCHECK_LE(size, allocator_vmar_size);
- DCHECK_GE(allocator_vmar_size - offset, size);
-
+ _zx_object_set_property(vmo, ZX_PROP_NAME, name, sizeof(name) - 1);
+ DCHECK_GE(base + size_, map_size + offset);
uintptr_t addr;
+
status = _zx_vmar_map(
- allocator_vmar, offset, vmo, 0, size,
+ vmar, offset, vmo, 0, map_size,
ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_SPECIFIC,
&addr);
_zx_handle_close(vmo);
if (status != ZX_OK) {
- if (status != ZX_ERR_NO_MEMORY || die_for_nomem)
- ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmar_map", status);
- return nullptr;
+ if (status != ZX_ERR_NO_MEMORY || die_for_nomem) {
+ ReportMmapFailureAndDie(map_size, name, "zx_vmar_map", status);
+ }
+ return 0;
}
+ IncreaseTotalMmap(map_size);
+ return addr;
+}
- IncreaseTotalMmap(size);
+uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) {
+ return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
+ name_, false);
+}
- return reinterpret_cast<void *>(addr);
+uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) {
+ return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
+ name_, true);
}
-void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
- return DoMmapFixedOrDie(fixed_addr, size, true);
+void UnmapOrDieVmar(void *addr, uptr size, zx_handle_t target_vmar) {
+ if (!addr || !size) return;
+ size = RoundUpTo(size, PAGE_SIZE);
+
+ zx_status_t status =
+ _zx_vmar_unmap(target_vmar, reinterpret_cast<uintptr_t>(addr), size);
+ if (status != ZX_OK) {
+ Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n",
+ SanitizerToolName, size, size, addr);
+ CHECK("unable to unmap" && 0);
+ }
+
+ DecreaseTotalMmap(size);
}
-void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
- return DoMmapFixedOrDie(fixed_addr, size, false);
+void ReservedAddressRange::Unmap(uptr fixed_addr, uptr size) {
+ uptr offset = fixed_addr - reinterpret_cast<uptr>(base_);
+ uptr addr = reinterpret_cast<uptr>(base_) + offset;
+ 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((addr_as_void == base_) || (addr + size == base_as_uptr + size_));
+ CHECK_LE(size, size_);
+ UnmapOrDieVmar(reinterpret_cast<void *>(addr), size,
+ static_cast<zx_handle_t>(os_handle_));
+ if (addr_as_void == base_) {
+ base_ = reinterpret_cast<void *>(addr + size);
+ }
+ size_ = size_ - size;
}
// This should never be called.
@@ -413,18 +399,7 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
}
void UnmapOrDie(void *addr, uptr size) {
- if (!addr || !size) return;
- size = RoundUpTo(size, PAGE_SIZE);
-
- zx_status_t status = _zx_vmar_unmap(_zx_vmar_root_self(),
- reinterpret_cast<uintptr_t>(addr), size);
- if (status != ZX_OK) {
- Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n",
- SanitizerToolName, size, size, addr);
- CHECK("unable to unmap" && 0);
- }
-
- DecreaseTotalMmap(size);
+ UnmapOrDieVmar(addr, size, _zx_vmar_root_self());
}
// This is used on the shadow mapping, which cannot be changed.
@@ -432,7 +407,8 @@ void UnmapOrDie(void *addr, uptr size) {
void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
void DumpProcessMap() {
- UNIMPLEMENTED(); // TODO(mcgrathr): write it
+ // TODO(mcgrathr): write it
+ return;
}
bool IsAccessibleMemoryRange(uptr beg, uptr size) {
@@ -532,6 +508,8 @@ u32 GetNumberOfCPUs() {
return zx_system_get_num_cpus();
}
+uptr GetRSS() { UNIMPLEMENTED(); }
+
} // namespace __sanitizer
using namespace __sanitizer; // NOLINT
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 20a5f42e4..710fdf3d6 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -350,6 +350,7 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
}
size_ = size;
name_ = name;
+ (void)os_handle_; // unsupported
return reinterpret_cast<uptr>(base_);
}
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index fab2babea..4f82025ed 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -286,6 +286,7 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
}
size_ = size;
name_ = name;
+ (void)os_handle_; // unsupported
return reinterpret_cast<uptr>(base_);
}