1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/trace_event/heap_profiler_allocation_register.h" 6 7 #include <stddef.h> 8 #include <sys/mman.h> 9 #include <unistd.h> 10 11 #include "base/bits.h" 12 #include "base/logging.h" 13 #include "base/process/process_metrics.h" 14 15 #ifndef MAP_ANONYMOUS 16 #define MAP_ANONYMOUS MAP_ANON 17 #endif 18 19 namespace base { 20 namespace trace_event { 21 namespace internal { 22 23 namespace { 24 size_t GetGuardSize() { 25 return GetPageSize(); 26 } 27 } 28 29 void* AllocateGuardedVirtualMemory(size_t size) { 30 size = bits::Align(size, GetPageSize()); 31 32 // Add space for a guard page at the end. 33 size_t map_size = size + GetGuardSize(); 34 35 void* addr = mmap(nullptr, map_size, PROT_READ | PROT_WRITE, 36 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 37 38 PCHECK(addr != MAP_FAILED); 39 40 // Mark the last page of the allocated address space as inaccessible 41 // (PROT_NONE). The read/write accessible space is still at least |min_size| 42 // bytes. 43 void* guard_addr = 44 reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) + size); 45 int result = mprotect(guard_addr, GetGuardSize(), PROT_NONE); 46 PCHECK(result == 0); 47 48 return addr; 49 } 50 51 void FreeGuardedVirtualMemory(void* address, size_t allocated_size) { 52 size_t size = bits::Align(allocated_size, GetPageSize()) + GetGuardSize(); 53 munmap(address, size); 54 } 55 56 } // namespace internal 57 } // namespace trace_event 58 } // namespace base 59