Home | History | Annotate | Download | only in handler
      1 // Copyright (c) 2006, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 //
     30 // ProtectedMemoryAllocator
     31 //
     32 // See the header file for documentation
     33 
     34 #include "protected_memory_allocator.h"
     35 #include <assert.h>
     36 
     37 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     38 ProtectedMemoryAllocator::ProtectedMemoryAllocator(vm_size_t pool_size)
     39   : pool_size_(pool_size),
     40     next_alloc_offset_(0),
     41     valid_(false) {
     42 
     43   kern_return_t result = vm_allocate(mach_task_self(),
     44                                      &base_address_,
     45                                      pool_size,
     46                                      TRUE
     47                                      );
     48 
     49   valid_ = (result == KERN_SUCCESS);
     50   assert(valid_);
     51 }
     52 
     53 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     54 ProtectedMemoryAllocator::~ProtectedMemoryAllocator() {
     55   vm_deallocate(mach_task_self(),
     56                 base_address_,
     57                 pool_size_
     58                 );
     59 }
     60 
     61 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     62 char *ProtectedMemoryAllocator::Allocate(vm_size_t bytes) {
     63   if (valid_ && next_alloc_offset_ + bytes <= pool_size_) {
     64     char *p = (char*)base_address_ + next_alloc_offset_;
     65     next_alloc_offset_ += bytes;
     66     return p;
     67   }
     68 
     69   return NULL;  // ran out of memory in our allocation block
     70 }
     71 
     72 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     73 kern_return_t  ProtectedMemoryAllocator::Protect() {
     74   kern_return_t result = vm_protect(mach_task_self(),
     75                                     base_address_,
     76                                     pool_size_,
     77                                     FALSE,
     78                                     VM_PROT_READ);
     79 
     80   return result;
     81 }
     82 
     83 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     84 kern_return_t  ProtectedMemoryAllocator::Unprotect() {
     85   kern_return_t result = vm_protect(mach_task_self(),
     86                                     base_address_,
     87                                     pool_size_,
     88                                     FALSE,
     89                                     VM_PROT_READ | VM_PROT_WRITE);
     90 
     91   return result;
     92 }
     93