LCOV - code coverage report
Current view: directory - src/trusted/debug_stub/posix - platform_impl.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 51 0 0.0 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright 2010 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can
       4                 :  * be 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/shared/platform/nacl_check.h"
      19                 : #include "native_client/src/shared/platform/nacl_log.h"
      20                 : #include "native_client/src/trusted/gdb_rsp/abi.h"
      21                 : #include "native_client/src/trusted/gdb_rsp/util.h"
      22                 : #include "native_client/src/trusted/port/event.h"
      23                 : #include "native_client/src/trusted/port/platform.h"
      24                 : 
      25                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      26                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      27                 : #include "native_client/src/trusted/service_runtime/sel_rt.h"
      28                 : 
      29                 : 
      30                 : /*
      31                 :  * Define the OS specific portions of gdb_utils IPlatform interface.
      32                 :  */
      33                 : 
      34                 : 
      35               0 : static port::IEvent* GetLaunchEvent() {
      36               0 :   static port::IEvent* event_ = port::IEvent::Allocate();
      37               0 :   return event_;
      38                 : }
      39                 : 
      40                 : namespace port {
      41                 : 
      42                 : struct StartInfo_t {
      43                 :   port::IPlatform::ThreadFunc_t func_;
      44                 :   void *cookie_;
      45                 :   volatile uint32_t id_;
      46                 : };
      47                 : 
      48                 : // Get the OS id of this thread
      49               0 : uint32_t IPlatform::GetCurrentThread() {
      50               0 :   return static_cast<uint32_t>(syscall(SYS_gettid));
      51                 : }
      52                 : 
      53                 : // Use start stub, to record thread id, and signal launcher
      54               0 : static void *StartFunc(void* cookie) {
      55               0 :   StartInfo_t* info = reinterpret_cast<StartInfo_t*>(cookie);
      56               0 :   info->id_ = (uint32_t) syscall(SYS_gettid);
      57                 : 
      58               0 :   printf("Started thread...\n");
      59               0 :   GetLaunchEvent()->Signal();
      60               0 :   info->func_(info->cookie_);
      61                 : 
      62               0 :   return NULL;
      63                 : }
      64                 : 
      65               0 : uint32_t IPlatform::CreateThread(ThreadFunc_t func, void* cookie) {
      66                 :   pthread_t thread;
      67                 :   StartInfo_t info;
      68                 : 
      69                 :   // Setup the thread information
      70               0 :   info.func_ = func;
      71               0 :   info.cookie_ = cookie;
      72                 : 
      73               0 :   printf("Creating thread...\n");
      74                 : 
      75                 :   // Redirect to stub and wait for signal before continuing
      76               0 :   if (pthread_create(&thread, NULL, StartFunc, &info) == 0) {
      77               0 :     GetLaunchEvent()->Wait();
      78               0 :     printf("Found thread...\n");
      79               0 :     return info.id_;
      80                 :   }
      81                 : 
      82               0 :   return 0;
      83                 : }
      84                 : 
      85               0 : void IPlatform::Relinquish(uint32_t msec) {
      86               0 :   usleep(msec * 1000);
      87               0 : }
      88                 : 
      89                 : // In order to read from a pointer that might not be valid, we use the
      90                 : // trick of getting the kernel to do it on our behalf.
      91               0 : static bool SafeMemoryCopy(void *dest, void *src, size_t len) {
      92                 :   // The trick only works if we are copying less than the buffer size
      93                 :   // of a pipe.  For now, return an error on larger sizes.
      94                 :   // TODO(mseaborn): If we need to copy more, we would have to break
      95                 :   // it up into smaller parts.
      96               0 :   const size_t kPipeBufferBound = 0x1000;
      97               0 :   if (len > kPipeBufferBound)
      98               0 :     return false;
      99                 : 
     100               0 :   bool success = false;
     101                 :   int pipe_fds[2];
     102               0 :   if (pipe(pipe_fds) != 0)
     103               0 :     return false;
     104               0 :   ssize_t sent = write(pipe_fds[1], src, len);
     105               0 :   if (sent == static_cast<ssize_t>(len)) {
     106               0 :     ssize_t got = read(pipe_fds[0], dest, len);
     107               0 :     if (got == static_cast<ssize_t>(len))
     108               0 :       success = true;
     109                 :   }
     110               0 :   CHECK(close(pipe_fds[0]) == 0);
     111               0 :   CHECK(close(pipe_fds[1]) == 0);
     112               0 :   return success;
     113                 : }
     114                 : 
     115               0 : bool IPlatform::GetMemory(uint64_t virt, uint32_t len, void *dst) {
     116               0 :   return SafeMemoryCopy(dst, reinterpret_cast<void*>(virt), len);
     117                 : }
     118                 : 
     119               0 : bool IPlatform::SetMemory(uint64_t virt, uint32_t len, void *src) {
     120               0 :   uintptr_t page_mask = NACL_PAGESIZE - 1;
     121               0 :   uintptr_t page = virt & ~page_mask;
     122               0 :   uintptr_t mapping_size = ((virt + len + page_mask) & ~page_mask) - page;
     123               0 :   if (mprotect(reinterpret_cast<void*>(page), mapping_size,
     124                 :                PROT_READ | PROT_WRITE) != 0) {
     125               0 :     return false;
     126                 :   }
     127               0 :   bool succeeded = SafeMemoryCopy(reinterpret_cast<void*>(virt), src, len);
     128                 :   // TODO(mseaborn): We assume here that SetMemory() is being used to
     129                 :   // set or remove a breakpoint in the code area, so that PROT_READ |
     130                 :   // PROT_EXEC are the correct flags to restore the mapping to.
     131                 :   // The earlier mprotect() does not tell us what the original flags
     132                 :   // were.  To find this out we could either:
     133                 :   //  * read /proc/self/maps (not available inside outer sandbox); or
     134                 :   //  * use service_runtime's own mapping tables.
     135                 :   // Alternatively, we could modify code the same way nacl_text.c does.
     136               0 :   if (mprotect(reinterpret_cast<void*>(page), mapping_size,
     137                 :                PROT_READ | PROT_EXEC) != 0) {
     138               0 :     return false;
     139                 :   }
     140               0 :   return succeeded;
     141                 : }
     142                 : 
     143                 : }  // End of port namespace
     144                 : 

Generated by: LCOV version 1.7