LCOV - code coverage report
Current view: directory - src/trusted/debug_stub/posix - platform_impl.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 38 34 89.5 %
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 <stdio.h>
       8                 : #include <stdlib.h>
       9                 : #include <unistd.h>
      10                 : #include <sys/mman.h>
      11                 : #include <sys/types.h>
      12                 : #include <sys/syscall.h>
      13                 : #include <pthread.h>
      14                 : 
      15                 : #include <map>
      16                 : #include <vector>
      17                 : 
      18                 : #include "native_client/src/include/concurrency_ops.h"
      19                 : #include "native_client/src/shared/platform/nacl_check.h"
      20                 : #include "native_client/src/shared/platform/nacl_log.h"
      21                 : #include "native_client/src/trusted/debug_stub/abi.h"
      22                 : #include "native_client/src/trusted/debug_stub/util.h"
      23                 : #include "native_client/src/trusted/debug_stub/platform.h"
      24                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      25                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      26                 : #include "native_client/src/trusted/service_runtime/sel_rt.h"
      27                 : 
      28                 : 
      29                 : /*
      30                 :  * Define the OS specific portions of IPlatform interface.
      31                 :  */
      32                 : 
      33                 : 
      34                 : namespace port {
      35                 : 
      36                 : // In order to read from a pointer that might not be valid, we use the
      37                 : // trick of getting the kernel to do it on our behalf.
      38             674 : static bool SafeMemoryCopy(void *dest, void *src, size_t len) {
      39                 :   // The trick only works if we are copying less than the buffer size
      40                 :   // of a pipe.  For now, return an error on larger sizes.
      41                 :   // TODO(mseaborn): If we need to copy more, we would have to break
      42                 :   // it up into smaller parts.
      43             674 :   const size_t kPipeBufferBound = 0x1000;
      44             674 :   if (len > kPipeBufferBound)
      45               0 :     return false;
      46                 : 
      47             674 :   bool success = false;
      48             674 :   int pipe_fds[2];
      49             674 :   if (pipe(pipe_fds) != 0)
      50               0 :     return false;
      51             674 :   ssize_t sent = write(pipe_fds[1], src, len);
      52             674 :   if (sent == static_cast<ssize_t>(len)) {
      53             670 :     ssize_t got = read(pipe_fds[0], dest, len);
      54             670 :     if (got == static_cast<ssize_t>(len))
      55             670 :       success = true;
      56             670 :   }
      57            2022 :   CHECK(close(pipe_fds[0]) == 0);
      58            2022 :   CHECK(close(pipe_fds[1]) == 0);
      59             674 :   return success;
      60             674 : }
      61                 : 
      62             534 : bool IPlatform::GetMemory(uint64_t virt, uint32_t len, void *dst) {
      63             534 :   return SafeMemoryCopy(dst, reinterpret_cast<void*>(virt), len);
      64                 : }
      65                 : 
      66             140 : bool IPlatform::SetMemory(struct NaClApp *nap, uint64_t virt, uint32_t len,
      67             140 :                           void *src) {
      68             140 :   uintptr_t page_mask = NACL_PAGESIZE - 1;
      69             140 :   uintptr_t page = virt & ~page_mask;
      70             140 :   uintptr_t mapping_size = ((virt + len + page_mask) & ~page_mask) - page;
      71             140 :   bool is_code = virt + len <= nap->mem_start + nap->dynamic_text_end;
      72             140 :   if (is_code) {
      73             136 :     if (mprotect(reinterpret_cast<void*>(page), mapping_size,
      74                 :                  PROT_READ | PROT_WRITE) != 0) {
      75               0 :       return false;
      76                 :     }
      77             136 :   }
      78             140 :   bool succeeded = SafeMemoryCopy(reinterpret_cast<void*>(virt), src, len);
      79                 :   // We use mprotect() only to modify code area, so PROT_READ | PROT_EXEC are
      80                 :   // the correct flags to restore the mapping to in most cases. However, this
      81                 :   // does not behave correctly for non-allocated pages in code area (where
      82                 :   // we will make zeroed bytes executable) and zero page (where we additionally
      83                 :   // prevent some null pointer exceptions).
      84                 :   //
      85                 :   // TODO(mseaborn): Handle those cases correctly. We might do that by modifying
      86                 :   // code via the dynamic code area the same way nacl_text.c does.
      87             140 :   if (is_code) {
      88             136 :     if (mprotect(reinterpret_cast<void*>(page), mapping_size,
      89                 :                  PROT_READ | PROT_EXEC) != 0) {
      90               0 :       return false;
      91                 :     }
      92             136 :   }
      93                 :   // Flush the instruction cache in case we just modified code to add
      94                 :   // or remove a breakpoint, otherwise breakpoints will not behave
      95                 :   // reliably on ARM.
      96             140 :   NaClFlushCacheForDoublyMappedCode((uint8_t *) virt, (uint8_t *) virt, len);
      97             140 :   return succeeded;
      98             140 : }
      99                 : 
     100                 : }  // End of port namespace
     101                 : 

Generated by: LCOV version 1.7