194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez// Copyright 2015 The Chromium Authors. All rights reserved.
294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez// found in the LICENSE file.
494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include "base/trace_event/heap_profiler_allocation_register.h"
694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <stddef.h>
894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <sys/mman.h>
994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include <unistd.h>
1094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
1194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include "base/bits.h"
1294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include "base/logging.h"
1394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include "base/process/process_metrics.h"
1494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
1594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#ifndef MAP_ANONYMOUS
1694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#define MAP_ANONYMOUS MAP_ANON
1794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#endif
1894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
1994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chaveznamespace base {
2094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chaveznamespace trace_event {
210c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chaveznamespace internal {
2294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
2394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chaveznamespace {
2494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavezsize_t GetGuardSize() {
2594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  return GetPageSize();
2694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}
2794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}
2894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
290c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavezvoid* AllocateGuardedVirtualMemory(size_t size) {
3094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  size = bits::Align(size, GetPageSize());
3194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
3294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // Add space for a guard page at the end.
3394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  size_t map_size = size + GetGuardSize();
3494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
3594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  void* addr = mmap(nullptr, map_size, PROT_READ | PROT_WRITE,
3694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
3794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
3894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  PCHECK(addr != MAP_FAILED);
3994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
4094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // Mark the last page of the allocated address space as inaccessible
4194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // (PROT_NONE). The read/write accessible space is still at least |min_size|
4294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  // bytes.
4394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  void* guard_addr =
4494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez      reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) + size);
4594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  int result = mprotect(guard_addr, GetGuardSize(), PROT_NONE);
4694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  PCHECK(result == 0);
4794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
4894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  return addr;
4994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}
5094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
510c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavezvoid FreeGuardedVirtualMemory(void* address, size_t allocated_size) {
5294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  size_t size = bits::Align(allocated_size, GetPageSize()) + GetGuardSize();
5394ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez  munmap(address, size);
5494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}
5594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez
560c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez}  // namespace internal
5794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}  // namespace trace_event
5894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez}  // namespace base
59