1 // Copyright (c) 2013 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 #ifndef CRAZY_LINKER_MEMORY_MAPPING_H 6 #define CRAZY_LINKER_MEMORY_MAPPING_H 7 8 #include <errno.h> 9 #include <sys/mman.h> 10 11 #include "crazy_linker_debug.h" 12 #include "crazy_linker_error.h" 13 14 namespace crazy { 15 16 // Helper class for a memory mapping. This is _not_ scoped. 17 class MemoryMapping { 18 public: 19 enum Protection { 20 CAN_READ = PROT_READ, 21 CAN_WRITE = PROT_WRITE, 22 CAN_READ_WRITE = PROT_READ | PROT_WRITE 23 }; MemoryMapping()24 MemoryMapping() : map_(NULL), size_(0) {} ~MemoryMapping()25 ~MemoryMapping() {} 26 27 // Return current mapping address. Get()28 void* Get() { return map_; } GetSize()29 size_t GetSize() const { return size_; } 30 31 // Allocate a new mapping. 32 // |address| is either NULL or a fixed memory address. 33 // |size| is the page-aligned size, must be > 0. 34 // |prot| are the desired protection bit flags. 35 // |fd| is -1 (for anonymous mappings), or a valid file descriptor. 36 // on failure, return false and sets errno. Allocate(void * address,size_t size,Protection prot,int fd)37 bool Allocate(void* address, size_t size, Protection prot, int fd) { 38 int flags = (fd >= 0) ? MAP_SHARED : MAP_ANONYMOUS; 39 if (address) 40 flags |= MAP_FIXED; 41 42 size_ = size; 43 map_ = ::mmap(address, size_, static_cast<int>(prot), flags, fd, 0); 44 if (map_ == MAP_FAILED) { 45 map_ = NULL; 46 return false; 47 } 48 49 return true; 50 } 51 52 // Change the protection flags of the mapping. 53 // On failure, return false and sets errno. SetProtection(Protection prot)54 bool SetProtection(Protection prot) { 55 if (!map_ || ::mprotect(map_, size_, static_cast<int>(prot)) < 0) 56 return false; 57 return true; 58 } 59 60 // Deallocate an existing mapping, if any. Deallocate()61 void Deallocate() { 62 if (map_) { 63 ::munmap(map_, size_); 64 map_ = NULL; 65 } 66 } 67 68 protected: 69 void* map_; 70 size_t size_; 71 }; 72 73 // Helper class for a memory mapping that is automatically 74 // unmapped on scope exit, unless its Release() method is called. 75 class ScopedMemoryMapping : public MemoryMapping { 76 public: Release()77 void* Release() { 78 void* ret = map_; 79 map_ = NULL; 80 return ret; 81 } 82 ~ScopedMemoryMapping()83 ~ScopedMemoryMapping() { Deallocate(); } 84 }; 85 86 } // namespace crazy 87 88 #endif // CRAZY_LINKER_MEMORY_MAPPING_H 89