LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - thread_common.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 50 50 100.0 %
Date: 2014-07-02 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 <map>
       8                 : #include <string.h>
       9                 : 
      10                 : #include "native_client/src/shared/platform/nacl_check.h"
      11                 : #include "native_client/src/shared/platform/nacl_log.h"
      12                 : #include "native_client/src/trusted/debug_stub/abi.h"
      13                 : #include "native_client/src/trusted/debug_stub/mutex.h"
      14                 : #include "native_client/src/trusted/debug_stub/thread.h"
      15                 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
      16                 : #include "native_client/src/trusted/service_runtime/nacl_signal.h"
      17                 : #include "native_client/src/trusted/service_runtime/thread_suspension.h"
      18                 : 
      19                 : namespace {
      20                 : 
      21                 : const int kX86TrapFlag = 1 << 8;
      22                 : 
      23                 : }  // namespace
      24                 : 
      25                 : namespace port {
      26                 : 
      27                 : // TODO(mseaborn): Merge Thread and IThread into a single class,
      28                 : // because there is only one implementation of IThread and the methods
      29                 : // do not need to be virtual.
      30                 : 
      31                 : class Thread : public IThread {
      32                 :  public:
      33              22 :   Thread(uint32_t id, struct NaClAppThread *natp)
      34              22 :       : id_(id), natp_(natp), fault_signal_(0) {}
      35               6 :   ~Thread() {}
      36                 : 
      37              73 :   uint32_t GetId() {
      38              73 :     return id_;
      39                 :   }
      40                 : 
      41             119 :   virtual bool SetStep(bool on) {
      42                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
      43             119 :     if (on) {
      44              35 :       context_.flags |= kX86TrapFlag;
      45                 :     } else {
      46              84 :       context_.flags &= ~kX86TrapFlag;
      47                 :     }
      48             119 :     return true;
      49                 : #else
      50                 :     // TODO(mseaborn): Implement for ARM.
      51                 :     UNREFERENCED_PARAMETER(on);
      52                 :     return false;
      53                 : #endif
      54                 :   }
      55                 : 
      56            1584 :   virtual bool GetRegister(uint32_t index, void *dst, uint32_t len) {
      57            1584 :     const gdb_rsp::Abi *abi = gdb_rsp::Abi::Get();
      58            1584 :     const gdb_rsp::Abi::RegDef *reg = abi->GetRegisterDef(index);
      59            1584 :     memcpy(dst, (char *) &context_ + reg->offset_, len);
      60            1584 :     return false;
      61                 :   }
      62                 : 
      63             208 :   virtual bool SetRegister(uint32_t index, void* src, uint32_t len) {
      64             208 :     const gdb_rsp::Abi *abi = gdb_rsp::Abi::Get();
      65             208 :     const gdb_rsp::Abi::RegDef *reg = abi->GetRegisterDef(index);
      66             208 :     if (reg->type_ == gdb_rsp::Abi::READ_ONLY) {
      67                 :       // Do not change read-only registers.
      68                 :       // TODO(eaeltsin): it is an error if new value is not equal to old value.
      69                 :       // Suppress it for now as this is used in G packet that writes all
      70                 :       // registers at once, and its failure might confuse GDB.
      71                 :       // We can start actually reporting the error when we support P packet
      72                 :       // that writes registers one at a time, as failure to write a single
      73                 :       // register should be much less confusing.
      74                 :     } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 &&
      75                 :                NACL_BUILD_SUBARCH == 64 &&
      76                 :                reg->type_ == gdb_rsp::Abi::X86_64_TRUSTED_PTR) {
      77                 :       // Do not change high 32 bits.
      78                 :       // GDB should work with untrusted addresses, thus high 32 bits of new
      79                 :       // value should be 0.
      80                 :       // TODO(eaeltsin): this is not fully implemented yet, and high 32 bits
      81                 :       // of new value may also be equal to high 32 bits of old value.
      82                 :       // Other cases are definitely bogus.
      83                 :       CHECK(len == 8);
      84                 :       memcpy((char *) &context_ + reg->offset_, src, 4);
      85                 :     } else {
      86             130 :       memcpy((char *) &context_ + reg->offset_, src, len);
      87                 :     }
      88             208 :     return false;
      89                 :   }
      90                 : 
      91              93 :   virtual void CopyRegistersFromAppThread() {
      92              93 :     NaClAppThreadGetSuspendedRegisters(natp_, &context_);
      93              93 :   }
      94                 : 
      95              74 :   virtual void CopyRegistersToAppThread() {
      96              74 :     NaClAppThreadSetSuspendedRegisters(natp_, &context_);
      97              74 :   }
      98                 : 
      99              11 :   virtual void SuspendThread() {
     100              11 :     NaClUntrustedThreadSuspend(natp_, /* save_registers= */ 1);
     101              11 :     CopyRegistersFromAppThread();
     102              11 :   }
     103                 : 
     104              11 :   virtual void ResumeThread() {
     105              11 :     CopyRegistersToAppThread();
     106              11 :     NaClUntrustedThreadResume(natp_);
     107              11 :   }
     108                 : 
     109                 :   // HasThreadFaulted() returns whether the given thread has been
     110                 :   // blocked as a result of faulting.  The thread does not need to be
     111                 :   // currently suspended.
     112           10361 :   virtual bool HasThreadFaulted() {
     113           10361 :     return natp_->fault_signal != 0;
     114                 :   }
     115                 : 
     116                 :   // UnqueueFaultedThread() takes a thread that has been blocked as a
     117                 :   // result of faulting and unblocks it.  As a precondition, the
     118                 :   // thread must be currently suspended.
     119              84 :   virtual void UnqueueFaultedThread() {
     120                 :     int exception_code;
     121              84 :     CHECK(NaClAppThreadUnblockIfFaulted(natp_, &exception_code));
     122              84 :     fault_signal_ = 0;
     123              84 :   }
     124                 : 
     125             257 :   virtual int GetFaultSignal() {
     126             257 :     return fault_signal_;
     127                 :   }
     128                 : 
     129              84 :   virtual void SetFaultSignal(int signal) {
     130              84 :     fault_signal_ = signal;
     131              84 :   }
     132                 : 
     133              49 :   virtual struct NaClSignalContext *GetContext() { return &context_; }
     134              84 :   virtual struct NaClAppThread *GetAppThread() { return natp_; }
     135                 : 
     136                 :  private:
     137                 :   uint32_t id_;
     138                 :   struct NaClAppThread *natp_;
     139                 :   struct NaClSignalContext context_;
     140                 :   int fault_signal_;
     141                 : };
     142                 : 
     143              22 : IThread *IThread::Create(uint32_t id, struct NaClAppThread *natp) {
     144              22 :   return new Thread(id, natp);
     145                 : }
     146                 : 
     147                 : }  // namespace port

Generated by: LCOV version 1.7