Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -142,6 +142,7 @@ void* base_; uptr size_; const char* name_; + unsigned int address_space_handle; }; typedef void (*fill_profile_f)(uptr start, uptr rss, bool file, Index: lib/sanitizer_common/sanitizer_fuchsia.cc =================================================================== --- lib/sanitizer_common/sanitizer_fuchsia.cc +++ lib/sanitizer_common/sanitizer_fuchsia.cc @@ -242,106 +242,78 @@ uptr ReservedAddressRange::Init(uptr init_size, const char* name, uptr fixed_addr) { - base_ = MmapNoAccess(init_size); - size_ = init_size; - name_ = name; - return reinterpret_cast(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(MmapFixedOrDieOnFatalError(fixed_addr, - map_size)); -} - -uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) { - return reinterpret_cast(MmapFixedOrDie(fixed_addr, map_size)); -} - -void ReservedAddressRange::Unmap(uptr addr, uptr size) { - void* addr_as_void = reinterpret_cast(addr); - uptr base_as_uptr = reinterpret_cast(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(addr), size); - if (addr_as_void == base_) { - base_ = reinterpret_cast(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(address_space_handle, ZX_HANDLE_INVALID); uintptr_t base; - zx_status_t status = - _zx_vmar_allocate(_zx_vmar_root_self(), 0, size, - ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE | - ZX_VM_FLAG_CAN_MAP_SPECIFIC, - &allocator_vmar, &base); + zx_handle_t usable_address_space_handle = static_cast(address_space_handle); + zx_status_t status = _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, &usable_address_space_handle, &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(base); + size_ = init_size; + name_ = name; + address_space_handle = static_cast(usable_address_space_handle); - allocator_vmar_base = base; - allocator_vmar_size = size; - return reinterpret_cast(base); + return reinterpret_cast(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(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 reinterpret_cast(nullptr); } - _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, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_SPECIFIC, - &addr); + 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 reinterpret_cast(nullptr); } + IncreaseTotalMmap(map_size); + return addr; - IncreaseTotalMmap(size); +} - return reinterpret_cast(addr); +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) { + return DoMmapFixedOrDie(address_space_handle, fixed_addr, map_size, base_, name_, false); } -void *MmapFixedOrDie(uptr fixed_addr, uptr size) { - return DoMmapFixedOrDie(fixed_addr, size, true); +uptr ReservedAddressRange::MapOrDie(uptr offset, uptr map_size) { + return DoMmapFixedOrDie(address_space_handle, fixed_addr, map_size, base_, name_, true) } -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(base_); + uptr addr = reinterpret_cast(base_) + offset; + void* addr_as_void = reinterpret_cast(addr); + uptr base_as_uptr = reinterpret_cast(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(addr), size, static_cast(address_space_handle)); + if (addr_as_void == base_) { + base_ = reinterpret_cast(addr + size); + } + size_ = size_ - size; } // This should never be called. @@ -412,11 +384,11 @@ return reinterpret_cast(addr); } -void UnmapOrDie(void *addr, uptr size) { +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(_zx_vmar_root_self(), + zx_status_t status = _zx_vmar_unmap(target_vmar, reinterpret_cast(addr), size); if (status != ZX_OK) { Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n", @@ -427,12 +399,17 @@ DecreaseTotalMmap(size); } +void UnmapOrDie(void *addr, uptr size) { + UnmapOrDieVmar(addr, size, _zx_vmar_root_self()); +} + // This is used on the shadow mapping, which cannot be changed. // Zircon doesn't have anything like MADV_DONTNEED. void ReleaseMemoryPagesToOS(uptr beg, uptr end) {} void DumpProcessMap() { - UNIMPLEMENTED(); // TODO(mcgrathr): write it + // TODO(mcgrathr): write it + return; } bool IsAccessibleMemoryRange(uptr beg, uptr size) { @@ -528,6 +505,10 @@ return true; } +uptr GetRSS() { + UNIMPLEMENTED(); +} + } // namespace __sanitizer using namespace __sanitizer; // NOLINT