LCOV - code coverage report
Current view: directory - src/trusted/gdb_rsp - session_mock.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 88 82 93.2 %
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 <assert.h>
       8                 : #include <string.h>
       9                 : #include <stdio.h>
      10                 : #include <stdlib.h>
      11                 : 
      12                 : #include <string>
      13                 : #include <sstream>
      14                 : 
      15                 : #include "native_client/src/trusted/gdb_rsp/abi.h"
      16                 : #include "native_client/src/trusted/gdb_rsp/session.h"
      17                 : #include "native_client/src/trusted/gdb_rsp/session_mock.h"
      18                 : #include "native_client/src/trusted/port/platform.h"
      19                 : #include "native_client/src/trusted/port/thread.h"
      20                 : #include "native_client/src/trusted/port/transport.h"
      21                 : 
      22                 : #ifdef WIN32
      23                 : #define snprintf _snprintf
      24                 : #endif
      25                 : 
      26                 : namespace gdb_rsp {
      27                 : 
      28               2 : SessionMock::SessionMock(bool target) : Session() {
      29               2 :   target_ = target;
      30               2 :   cur_ = 0;
      31                 : 
      32               4 :   Session::Init(new TransportMock);
      33               2 :   SetFlags(IGNORE_ACK);
      34               2 : }
      35                 : 
      36               2 : SessionMock::~SessionMock() {
      37              44 :   for (size_t a = 0; a < actions_.size(); a++)
      38              42 :     delete actions_[a];
      39                 : 
      40               2 :   delete static_cast<TransportMock*>(io_);
      41               2 : }
      42                 : 
      43              20 : bool SessionMock::SendPacketOnly(gdb_rsp::Packet *packet) {
      44              20 :   if (PeekAction() == SEND) {
      45              20 :     Action *pact = GetAction();
      46              20 :     const char *str = packet->GetPayload();
      47                 : 
      48              20 :     if (GetFlags() & DEBUG_SEND) port::IPlatform::LogInfo("TX %s\n", str);
      49                 : 
      50                 :     // Check if we match
      51              20 :     if (pact->str_ == str) return true;
      52                 : 
      53                 :     port::IPlatform::LogInfo("Mismatch:\n\tSENDING: %s\n\tEXPECT: %s\n",
      54               0 :                               str, pact->str_.data());
      55                 :   }
      56               0 :   return false;
      57                 : }
      58                 : 
      59              22 : bool SessionMock::GetPacket(gdb_rsp::Packet *packet) {
      60              22 :   if (PeekAction() == RECV) {
      61              20 :     Action *pact = GetAction();
      62              20 :     packet->Clear();
      63              20 :     packet->AddString(pact->str_.data());
      64              20 :     if (GetFlags() & DEBUG_RECV) {
      65               0 :       port::IPlatform::LogInfo("RX %s\n", pact->str_.data());
      66                 :     }
      67              20 :     return true;
      68                 :   }
      69               2 :   return false;
      70                 : }
      71                 : 
      72               0 : bool SessionMock::DataAvailable() {
      73               0 :   return PeekAction() == RECV;
      74                 : }
      75                 : 
      76              44 : SessionMock::ActionType SessionMock::PeekAction() {
      77              44 :   if (cur_ < actions_.size()) {
      78              43 :     Action* pact = actions_[cur_];
      79              43 :     ActionType at = pact->type_;
      80              43 :     if (DISCONNECT == at) {
      81               3 :       connected_ = false;
      82                 :     }
      83              43 :     return at;
      84                 :   }
      85               1 :   return TIMEOUT;
      86                 : }
      87                 : 
      88              41 : SessionMock::Action* SessionMock::GetAction() {
      89              41 :   if (cur_ < actions_.size()) return actions_[cur_++];
      90               0 :   return NULL;
      91                 : }
      92                 : 
      93              42 : void SessionMock::AddAction(ActionType act, const char *str) {
      94              42 :   Action *pact = new Action;
      95                 : 
      96              42 :   pact->type_ = act;
      97              42 :   pact->str_ = str;
      98              42 :   actions_.push_back(pact);
      99              42 : }
     100                 : 
     101              19 : void SessionMock::AddTransaction(const char *snd, const char *rcv) {
     102              19 :   if (target_) {
     103                 :     // If we are a target, we get a command, then respond
     104               7 :     AddAction(RECV, snd);
     105               7 :     AddAction(SEND, rcv);
     106                 :   } else {
     107                 :     // If we are a host, we send a command, and expect a reply
     108              12 :     AddAction(SEND, snd);
     109              12 :     AddAction(RECV, rcv);
     110                 :   }
     111              19 : }
     112                 : 
     113               2 : void AddMockInit(SessionMock* ses) {
     114               2 :   const gdb_rsp::Abi* abi = gdb_rsp::Abi::Get();
     115                 : 
     116                 :   // Setup supported query
     117                 :   ses->AddTransaction(
     118                 :     "qSupported",
     119               2 :     "PacketSize=7cf;qXfer:libraries:read+;qXfer:features:read+");
     120                 : 
     121                 :   // Setup arch query
     122               2 :   std::string str = "l<target><architecture>";
     123               4 :   str += abi->GetName();
     124               2 :   str += "</architecture></target>";
     125                 :   ses->AddTransaction(
     126                 :     "qXfer:features:read:target.xml:0,7cf",
     127               2 :     str.data());
     128               2 : }
     129                 : 
     130               3 : void AddMockUpdate(SessionMock* ses, uint8_t sig) {
     131               3 :   const gdb_rsp::Abi* abi = gdb_rsp::Abi::Get();
     132                 : 
     133                 :   // Setup thread query
     134                 :   ses->AddTransaction(
     135                 :     "qfThreadInfo",
     136               3 :     "m1234");
     137                 :   ses->AddTransaction(
     138                 :     "qsThreadInfo",
     139               3 :     "l");
     140                 :   ses->AddTransaction(
     141                 :     "Hg1234",
     142               3 :     "OK");
     143                 : 
     144                 :   // Setup Register Query
     145               3 :   std::string str = "";
     146               6 :   port::IThread *thread = port::IThread::Acquire(0x1234, true);
     147              51 :   for (uint32_t a = 0; a < abi->GetRegisterCount(); a++) {
     148                 :     char tmp[8];
     149              48 :     const Abi::RegDef* def = abi->GetRegisterDef(a);
     150              48 :     uint64_t val = static_cast<uint64_t>(a);
     151              48 :     uint8_t *pval = reinterpret_cast<uint8_t*>(&val);
     152                 : 
     153                 :     // Create a hex version of the register number of
     154                 :     // the specified zero padded to the correct size
     155             240 :     for (uint32_t b = 0; b < def->bytes_; b++) {
     156             192 :       snprintf(tmp, sizeof(tmp), "%02x", pval[b]);
     157             192 :       str += tmp;
     158                 :     }
     159                 : 
     160              48 :     thread->SetRegister(a, &val, def->bytes_);
     161                 :   }
     162               3 :   ses->AddTransaction("g", str.data());
     163                 : 
     164                 :   char tmp[8];
     165               3 :   snprintf(tmp, sizeof(tmp), "S%02x", sig);
     166               3 :   ses->AddTransaction("?", tmp);
     167               3 : }
     168                 : 
     169                 : // GetGoldenSessionMock
     170                 : //
     171                 : // The function bellow generates a mock session and preloads it
     172                 : // with expected inputs and outputs for a common connection case.
     173                 : // For GDB, that's:
     174                 : //  1) qSupported - Querry for supported features
     175                 : //  2) qXfer:features:read:target.xml:0,7cf - Query for target arch.
     176                 : //  3) qfThreadInfo/qsThreadInfo - Query for active threads
     177                 : //  4) Hg1234 - Set current register context to retreived thread id
     178                 : //  5) g - Get current thread registers
     179                 : //  6) disconnect
     180               2 : SessionMock *GetGoldenSessionMock(bool target, bool debug) {
     181               2 :   SessionMock   *ses = new SessionMock(target);
     182                 : 
     183               2 :   if (debug) ses->SetFlags(Session::DEBUG_RECV | Session::DEBUG_SEND);
     184                 : 
     185               2 :   AddMockInit(ses);
     186               2 :   AddMockUpdate(ses, 5);
     187                 : 
     188               2 :   ses->AddAction(SessionMock::DISCONNECT, "");
     189               2 :   return ses;
     190                 : }
     191                 : 
     192                 : }  // namespace gdb_rsp

Generated by: LCOV version 1.7