LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - sys_list_mappings.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 86 69 80.2 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2013 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                 :  * NaCl service run-time, list_mappings system call.
       9                 :  */
      10                 : 
      11                 : #include <stdlib.h>
      12                 : 
      13                 : #include "native_client/src/trusted/service_runtime/sys_list_mappings.h"
      14                 : 
      15                 : #include "native_client/src/include/nacl_platform.h"
      16                 : #include "native_client/src/include/portability_string.h"
      17                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      18                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      19                 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
      20                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      21                 : #include "native_client/src/trusted/service_runtime/include/sys/nacl_list_mappings.h"
      22                 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
      23                 : #include "native_client/src/trusted/service_runtime/nacl_copy.h"
      24                 : #include "native_client/src/trusted/service_runtime/nacl_text.h"
      25                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      26                 : 
      27                 : struct NaClSysListMappingsState {
      28                 :   struct NaClApp *nap;
      29                 :   struct NaClMemMappingInfo *regions;
      30                 :   uint32_t count;
      31                 :   uint32_t capacity;
      32                 :   int out_of_memory;
      33                 : };
      34                 : 
      35                 : static const int kStartCapacity = 8;
      36                 : 
      37              21 : static void NaClSysListMappingsAdd(struct NaClSysListMappingsState *state,
      38              21 :                                    uint32_t start,
      39              21 :                                    uint32_t size,
      40              21 :                                    uint32_t prot,
      41              21 :                                    uint32_t max_prot,
      42              21 :                                    uint32_t vmmap_type) {
      43              21 :   struct NaClMemMappingInfo *info;
      44              21 :   uint32_t new_capacity;
      45                 : 
      46              21 :   if (state->out_of_memory) {
      47               0 :     return;
      48                 :   }
      49              21 :   if (state->count == state->capacity) {
      50               3 :     if (state->capacity == 0) {
      51               3 :       new_capacity = kStartCapacity;
      52               3 :     } else {
      53               0 :       new_capacity = state->capacity * 2;
      54               0 :       if (UINT32_MAX / sizeof(*state->regions) < new_capacity) {
      55                 :         /* state->capacity * sizeof(*state->regions) would overflow. */
      56               0 :         state->out_of_memory = 1;
      57               0 :         return;
      58                 :       }
      59                 :     }
      60               3 :     info = (struct NaClMemMappingInfo *) realloc(
      61                 :         state->regions, new_capacity * sizeof(*state->regions));
      62               3 :     if (info == NULL) {
      63               0 :       state->out_of_memory = 1;
      64               0 :       return;
      65                 :     }
      66               3 :     state->capacity = new_capacity;
      67               3 :     state->regions = info;
      68               3 :   }
      69              21 :   info = &state->regions[state->count];
      70              21 :   ++state->count;
      71                 : 
      72              63 :   memset(info, 0, sizeof(*info));
      73              21 :   info->start = start;
      74              21 :   info->size = size;
      75              21 :   info->prot = prot;
      76              21 :   info->max_prot = max_prot;
      77              21 :   info->vmmap_type = vmmap_type;
      78              42 : }
      79                 : 
      80              39 : static int NaClSysListMappingsOrder(const void *a, const void *b) {
      81              39 :   const struct NaClMemMappingInfo *am = (const struct NaClMemMappingInfo *) a;
      82              39 :   const struct NaClMemMappingInfo *bm = (const struct NaClMemMappingInfo *) b;
      83                 : 
      84              66 :   if (am->start < bm->start) return -1;
      85              24 :   if (am->start > bm->start) return 1;
      86               0 :   return 0;
      87              39 : }
      88                 : 
      89              24 : static void NaClSysListMappingsVisit(void *statev,
      90              24 :                                      struct NaClVmmapEntry *vmep) {
      91              24 :   struct NaClSysListMappingsState *state =
      92                 :       (struct NaClSysListMappingsState *) statev;
      93                 : 
      94              24 :   uint32_t start = (uint32_t) (vmep->page_num << NACL_PAGESHIFT);
      95              24 :   uint32_t size = (uint32_t) (vmep->npages << NACL_PAGESHIFT);
      96              24 :   uint32_t max_prot = NaClVmmapEntryMaxProt(vmep);
      97                 :   /* Skip dynamic code region as its parts will be visited separately. */
      98              27 :   if (state->nap->dynamic_text_start == start &&
      99                 :       state->nap->dynamic_text_end == start + size) {
     100               3 :     return;
     101                 :   }
     102              21 :   NaClSysListMappingsAdd(
     103                 :       state,
     104                 :       /* start= */ start,
     105                 :       /* size= */ size,
     106                 :       /* prot= */ vmep->prot,
     107                 :       /* max_prot= */ max_prot,
     108                 :       /* vmmap_type= */ vmep->desc != NULL);
     109              45 : }
     110                 : 
     111               0 : static void NaClSysListMappingsDyncodeVisit(void *statev,
     112               0 :                                             struct NaClDynamicRegion *rg) {
     113               0 :   struct NaClSysListMappingsState *state =
     114                 :       (struct NaClSysListMappingsState *) statev;
     115                 : 
     116               0 :   NaClSysListMappingsAdd(
     117                 :       state,
     118               0 :       /* start= */ (uint32_t) NaClSysToUser(state->nap, rg->start),
     119                 :       /* size= */ (uint32_t) rg->size,
     120                 :       /* prot= */ NACL_ABI_PROT_READ | NACL_ABI_PROT_EXEC,
     121                 :       /* max_prot= */ NACL_ABI_PROT_READ | NACL_ABI_PROT_EXEC,
     122                 :       /* vmmap_type= */ 0);
     123               0 : }
     124                 : 
     125               3 : int32_t NaClSysListMappings(struct NaClAppThread *natp,
     126               3 :                             uint32_t regions,
     127               3 :                             uint32_t count) {
     128               3 :   struct NaClApp *nap = natp->nap;
     129               3 :   struct NaClSysListMappingsState state;
     130                 : 
     131               3 :   if (!nap->enable_list_mappings) {
     132               0 :     return -NACL_ABI_ENOSYS;
     133                 :   }
     134                 : 
     135               3 :   state.nap = nap;
     136               3 :   state.count = 0;
     137               3 :   state.capacity = 0;
     138               3 :   state.out_of_memory = 0;
     139               3 :   state.regions = NULL;
     140                 : 
     141               3 :   NaClXMutexLock(&nap->mu);
     142               3 :   NaClVmmapVisit(&nap->mem_map, NaClSysListMappingsVisit, &state);
     143               3 :   NaClDyncodeVisit(nap, NaClSysListMappingsDyncodeVisit, &state);
     144               3 :   NaClXMutexUnlock(&nap->mu);
     145                 : 
     146               3 :   if (state.out_of_memory) {
     147               0 :     NaClLog(3, "Out of memory while gathering memory map\n");
     148               0 :     return -NACL_ABI_ENOMEM;
     149                 :   }
     150                 : 
     151               3 :   qsort(state.regions, state.count, sizeof(*state.regions),
     152                 :         NaClSysListMappingsOrder);
     153                 : 
     154               3 :   if (state.count < count) {
     155               3 :     count = state.count;
     156               3 :   }
     157               3 :   if (!NaClCopyOutToUser(nap, regions, state.regions,
     158                 :                          sizeof(*state.regions) * count)) {
     159               1 :     NaClLog(3, "Illegal address for ListMappings at 0x%08"NACL_PRIxPTR"\n",
     160                 :             (uintptr_t) regions);
     161               1 :     return -NACL_ABI_EFAULT;
     162                 :   }
     163               2 :   free(state.regions);
     164                 : 
     165               2 :   return state.count;
     166               3 : }

Generated by: LCOV version 1.7