LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - thread_common.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 49 48 98.0 %
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 <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              40 :   Thread(uint32_t id, struct NaClAppThread *natp)
      34              40 :       : id_(id), natp_(natp), fault_signal_(0) {}
      35              12 :   ~Thread() {}
      36                 : 
      37                 :   uint32_t GetId() {
      38              73 :     return id_;
      39                 :   }
      40                 : 
      41             120 :   virtual bool SetStep(bool on) {
      42                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
      43             120 :     if (on) {
      44              36 :       context_.flags |= kX86TrapFlag;
      45              36 :     } else {
      46              84 :       context_.flags &= ~kX86TrapFlag;
      47                 :     }
      48             120 :     return true;
      49                 : #else
      50                 :     // TODO(mseaborn): Implement for ARM.
      51                 :     UNREFERENCED_PARAMETER(on);
      52                 :     return false;
      53                 : #endif
      54                 :   }
      55                 : 
      56            2400 :   virtual bool GetRegister(uint32_t index, void *dst, uint32_t len) {
      57            2400 :     const gdb_rsp::Abi *abi = gdb_rsp::Abi::Get();
      58            2400 :     const gdb_rsp::Abi::RegDef *reg = abi->GetRegisterDef(index);
      59            2400 :     memcpy(dst, (char *) &context_ + reg->offset_, len);
      60            2400 :     return false;
      61                 :   }
      62                 : 
      63             384 :   virtual bool SetRegister(uint32_t index, void* src, uint32_t len) {
      64             384 :     const gdb_rsp::Abi *abi = gdb_rsp::Abi::Get();
      65             384 :     const gdb_rsp::Abi::RegDef *reg = abi->GetRegisterDef(index);
      66             384 :     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             384 :     } 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             144 :       CHECK(len == 8);
      84              48 :       memcpy((char *) &context_ + reg->offset_, src, 4);
      85              48 :     } else {
      86             224 :       memcpy((char *) &context_ + reg->offset_, src, len);
      87                 :     }
      88             384 :     return false;
      89                 :   }
      90                 : 
      91                 :   virtual void CopyRegistersFromAppThread() {
      92              92 :     NaClAppThreadGetSuspendedRegisters(natp_, &context_);
      93              92 :   }
      94                 : 
      95                 :   virtual void CopyRegistersToAppThread() {
      96              75 :     NaClAppThreadSetSuspendedRegisters(natp_, &context_);
      97              75 :   }
      98                 : 
      99                 :   virtual void SuspendThread() {
     100              11 :     NaClUntrustedThreadSuspend(natp_, /* save_registers= */ 1);
     101              11 :     CopyRegistersFromAppThread();
     102              11 :   }
     103                 : 
     104                 :   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                 :   virtual bool HasThreadFaulted() {
     113             164 :     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                 :   virtual void UnqueueFaultedThread() {
     120              84 :     int exception_code;
     121             252 :     CHECK(NaClAppThreadUnblockIfFaulted(natp_, &exception_code));
     122              84 :     fault_signal_ = 0;
     123              84 :   }
     124                 : 
     125                 :   virtual int GetFaultSignal() {
     126             255 :     return fault_signal_;
     127                 :   }
     128                 : 
     129              84 :   virtual void SetFaultSignal(int signal) {
     130              84 :     fault_signal_ = signal;
     131              84 :   }
     132                 : 
     133              48 :   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              20 : IThread *IThread::Create(uint32_t id, struct NaClAppThread *natp) {
     144              40 :   return new Thread(id, natp);
     145               0 : }
     146                 : 
     147                 : }  // namespace port

Generated by: LCOV version 1.7