LCOV - code coverage report
Current view: directory - src/trusted/service_runtime/osx - mmap_test_check.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 50 48 96.0 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : #include "native_client/src/trusted/service_runtime/mmap_test_check.h"
       8                 : 
       9                 : #include <mach/mach.h>
      10                 : #include <mach/mach_vm.h>
      11                 : #include <stdio.h>
      12                 : 
      13                 : #include "native_client/src/include/nacl_assert.h"
      14                 : 
      15                 : 
      16                 : namespace {
      17                 : 
      18                 : // Returns information about one or more VM region located at or above
      19                 : // |address| by calling |mach_vm_region| repeatedly to determine the size of a
      20                 : // contiguous region composed of multiple smaller regions that have the same
      21                 : // protection and sharing flags set. Returns the number of smaller regions
      22                 : // that were coalesced, which may be 0, in which case the out parameters are
      23                 : // not valid. |region_address|, |region_size|, |region_protection|, and
      24                 : // |region_share_mode| are set according to the characteristics of the large
      25                 : // region.
      26                 : //
      27                 : // This is necessary because a single anonymous mmap() for a large region will
      28                 : // be broken up into 128MB chunks in the kernel's VM map when allocated - see
      29                 : // ANON_CHUNK_SIZE in 10.8.2 xnu-2050.18.24/osfmk/vm/vm_map.c vm_map_enter.
      30              14 : size_t CoalescedVMRegionInfo(mach_vm_address_t address,
      31              14 :                              mach_vm_address_t *region_address,
      32              14 :                              mach_vm_size_t *region_size,
      33              14 :                              vm_prot_t *region_protection,
      34              14 :                              unsigned char *region_share_mode) {
      35              14 :   mach_port_t self_task = mach_task_self();
      36                 : 
      37              14 :   mach_vm_address_t this_region_address = address;
      38              14 :   mach_vm_size_t this_region_size;
      39              14 :   vm_region_extended_info_data_t info;
      40              14 :   mach_msg_type_number_t info_count = VM_REGION_EXTENDED_INFO_COUNT;
      41              14 :   mach_port_t object;
      42              14 :   kern_return_t kr = mach_vm_region(self_task,
      43                 :                                     &this_region_address,
      44                 :                                     &this_region_size,
      45                 :                                     VM_REGION_EXTENDED_INFO,
      46                 :                                     reinterpret_cast<vm_region_info_t>(&info),
      47                 :                                     &info_count,
      48                 :                                     &object);
      49              14 :   if (kr != KERN_SUCCESS) {
      50               0 :     return 0;
      51                 :   }
      52                 : 
      53              14 :   kr = mach_port_deallocate(self_task, object);
      54              42 :   ASSERT_EQ(kr, KERN_SUCCESS);
      55                 : 
      56              14 :   size_t regions = 1;
      57              14 :   *region_address = this_region_address;
      58              14 :   *region_size = this_region_size;
      59              14 :   *region_protection = info.protection;
      60              14 :   *region_share_mode = info.share_mode;
      61                 : 
      62              14 :   while (true) {
      63             659 :     this_region_address += this_region_size;
      64             659 :     mach_vm_address_t probe_address = this_region_address;
      65                 : 
      66             659 :     kr = mach_vm_region(self_task,
      67                 :                         &this_region_address,
      68                 :                         &this_region_size,
      69                 :                         VM_REGION_EXTENDED_INFO,
      70                 :                         reinterpret_cast<vm_region_info_t>(&info),
      71                 :                         &info_count,
      72                 :                         &object);
      73             659 :     if (kr != KERN_SUCCESS) {
      74               0 :       break;
      75                 :     }
      76                 : 
      77             659 :     kr = mach_port_deallocate(self_task, object);
      78            1977 :     ASSERT_EQ(kr, KERN_SUCCESS);
      79                 : 
      80            1964 :     if (this_region_address != probe_address ||
      81                 :         *region_protection != info.protection ||
      82                 :         *region_share_mode != info.share_mode) {
      83              14 :       break;
      84                 :     }
      85                 : 
      86             645 :     *region_size += this_region_size;
      87             645 :     ++regions;
      88             645 :   }
      89                 : 
      90              14 :   return regions;
      91              14 : }
      92                 : 
      93                 : }  // namespace
      94                 : 
      95              14 : void CheckMapping(uintptr_t addr, size_t size, int protect, int map_type) {
      96              14 :   uintptr_t end = addr + size - 1;
      97                 : 
      98              14 :   mach_vm_address_t r_start;
      99              14 :   mach_vm_size_t r_size;
     100              14 :   vm_prot_t r_protection;
     101              14 :   unsigned char r_share_mode;
     102              14 :   size_t regions = CoalescedVMRegionInfo(addr,
     103                 :                                          &r_start,
     104                 :                                          &r_size,
     105                 :                                          &r_protection,
     106                 :                                          &r_share_mode);
     107              42 :   ASSERT_GT(regions, 0);
     108                 : 
     109              14 :   mach_vm_address_t r_end = r_start + r_size - 1;
     110                 : 
     111              42 :   ASSERT_LE(r_start, addr);
     112              42 :   ASSERT_GE(r_end, end);
     113              42 :   ASSERT_EQ(r_protection, protect);
     114                 :   // TODO(phosek): not sure whether this check is correct
     115              42 :   ASSERT_EQ(r_share_mode, map_type);
     116              14 : }

Generated by: LCOV version 1.7