LCOV - code coverage report
Current view: directory - src/shared/platform/win - nacl_find_addrsp.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 28 21 75.0 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2010 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                 : 
       8                 : #include <windows.h>
       9                 : 
      10                 : #include "native_client/src/shared/platform/nacl_find_addrsp.h"
      11                 : 
      12                 : #include "native_client/src/include/nacl_base.h"
      13                 : #include "native_client/src/include/portability.h"
      14                 : #include "native_client/src/shared/platform/nacl_check.h"
      15                 : #include "native_client/src/shared/platform/nacl_global_secure_random.h"
      16                 : #include "native_client/src/shared/platform/nacl_log.h"
      17                 : 
      18                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
      19                 : /*
      20                 :  * The x86-64 (currently) permits only a 48 bit virtual address space
      21                 :  * (and requires that the upper 64-48=16 bits is sign extended from
      22                 :  * bit 47).  Additionally, (empirically) Windows 8 disallows addresses
      23                 :  * with bits 44 and above set for user-space code.  So instead of 48,
      24                 :  * we get a maximum of 43 usable bits of virtual address.
      25                 :  */
      26                 : # define NUM_USER_ADDRESS_BITS 43
      27                 : /*
      28                 :  * Windows is P64 and not LP64
      29                 :  */
      30                 : # define NACL_POINTER_SIZE 64
      31                 : #else
      32                 : # define NUM_USER_ADDRESS_BITS 31
      33                 : # define NACL_POINTER_SIZE 32
      34                 : #endif
      35                 : 
      36                 : 
      37                 : /* bool */
      38                 : int NaClFindAddressSpaceRandomized(uintptr_t *addr, size_t memory_size,
      39               3 :                                    int max_tries) {
      40                 :   void *map_addr;
      41                 :   int tries_remaining;
      42                 :   /*
      43                 :    * Mask for keeping the low order NUM_USER_ADDRESS_BITS of a randomly
      44                 :    * generated address.  VirtualAlloc will drop the low 16 bits for
      45                 :    * MEM_RESERVE, so we do not need to mask those off.
      46                 :    */
      47                 :   uintptr_t addr_mask;
      48                 :   uintptr_t suggested_addr;
      49                 : 
      50               3 :   CHECK(max_tries >= 0);
      51                 :   NaClLog(4,
      52                 :           "NaClFindAddressSpaceRandomized: looking for %"NACL_PRIxS" bytes\n",
      53               3 :           memory_size);
      54                 : 
      55                 :   /* 64kB allocation size */
      56               3 :   addr_mask = ~(uintptr_t) 0;
      57                 : #if NACL_POINTER_SIZE > NUM_USER_ADDRESS_BITS
      58               3 :   addr_mask &= (((uintptr_t) 1 << NUM_USER_ADDRESS_BITS) - 1);
      59                 : #endif
      60                 : 
      61               3 :   for (tries_remaining = max_tries; tries_remaining >= 0; --tries_remaining) {
      62               3 :     if (tries_remaining > 0) {
      63                 :       /* Pick a random address for the first max_tries */
      64                 : #if NACL_POINTER_SIZE > 32
      65                 :       suggested_addr = (((uintptr_t) NaClGlobalSecureRngUint32() << 32) |
      66                 :                         (uintptr_t) NaClGlobalSecureRngUint32());
      67                 : #else
      68               0 :       suggested_addr = ((uintptr_t) NaClGlobalSecureRngUint32());
      69                 : #endif
      70               0 :       suggested_addr &= addr_mask;
      71               0 :     } else {
      72                 :       /* Give up picking randomly -- now just let the system pick */
      73               3 :       suggested_addr = 0;
      74                 :     }
      75                 : 
      76                 :     NaClLog(4,
      77                 :             ("NaClFindAddressSpaceRandomized: try %d: starting addr hint %"
      78                 :              NACL_PRIxPTR"\n"),
      79                 :             max_tries - tries_remaining,
      80               3 :             suggested_addr);
      81                 :     map_addr = VirtualAlloc((void *) suggested_addr,
      82               3 :                             memory_size, MEM_RESERVE, PAGE_READWRITE);
      83               3 :     if (NULL != map_addr) {
      84                 :       /* success */
      85               3 :       break;
      86                 :     }
      87               0 :   }
      88               3 :   if (NULL == map_addr) {
      89                 :     NaClLog(LOG_ERROR,
      90                 :             ("NaClFindAddressSpaceRandomized: VirtualAlloc failed looking for"
      91                 :              " 0x%"NACL_PRIxS" bytes\n"),
      92               0 :             memory_size);
      93               0 :     return 0;
      94                 :   }
      95               3 :   if (!VirtualFree(map_addr, 0, MEM_RELEASE)) {
      96                 :     NaClLog(LOG_FATAL,
      97                 :             ("NaClFindAddressSpaceRandomized: VirtualFree of VirtualAlloc"
      98                 :              " result (0x%"NACL_PRIxPTR"failed, GetLastError %d.\n"),
      99                 :             (uintptr_t) map_addr,
     100               0 :             GetLastError());
     101                 :   }
     102                 :   NaClLog(4,
     103                 :           "NaClFindAddressSpaceRandomized: got addr %"NACL_PRIxPTR"\n",
     104               3 :           (uintptr_t) map_addr);
     105               3 :   *addr = (uintptr_t) map_addr;
     106               3 :   return 1;
     107               3 : }
     108                 : 
     109               3 : int NaClFindAddressSpace(uintptr_t *addr, size_t memory_size) {
     110               3 :   return NaClFindAddressSpaceRandomized(addr, memory_size, 0);
     111               3 : }

Generated by: LCOV version 1.7