LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - session.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 113 93 82.3 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2010 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 <assert.h>
       8                 : #include <string.h>
       9                 : #include <stdlib.h>
      10                 : 
      11                 : #include <string>
      12                 : #include <sstream>
      13                 : 
      14                 : #include "native_client/src/shared/platform/nacl_log.h"
      15                 : #include "native_client/src/trusted/debug_stub/packet.h"
      16                 : #include "native_client/src/trusted/debug_stub/platform.h"
      17                 : #include "native_client/src/trusted/debug_stub/session.h"
      18                 : #include "native_client/src/trusted/debug_stub/transport.h"
      19                 : #include "native_client/src/trusted/debug_stub/util.h"
      20                 : 
      21                 : using port::IPlatform;
      22                 : using port::ITransport;
      23                 : 
      24                 : namespace gdb_rsp {
      25                 : 
      26              66 : Session::Session(ITransport *transport)
      27                 :   : io_(transport),
      28                 :     flags_(0),
      29                 :     seq_(0),
      30              33 :     connected_(true) {
      31              66 : }
      32                 : 
      33              18 : Session::~Session() {
      34              36 : }
      35                 : 
      36              30 : void Session::SetFlags(uint32_t flags) {
      37              30 :   flags_ |= flags;
      38              30 : }
      39                 : 
      40               2 : void Session::ClearFlags(uint32_t flags) {
      41               2 :   flags_ &= ~flags;
      42               2 : }
      43                 : 
      44                 : uint32_t Session::GetFlags() {
      45            5814 :   return flags_;
      46                 : }
      47                 : 
      48                 : bool Session::IsDataAvailable() {
      49               1 :   return io_->IsDataAvailable();
      50                 : }
      51                 : 
      52                 : bool Session::Connected() {
      53            1333 :   return connected_;
      54                 : }
      55                 : 
      56                 : void Session::Disconnect() {
      57              33 :   io_->Disconnect();
      58              33 :   connected_ = false;
      59              33 : }
      60                 : 
      61           23784 : bool Session::GetChar(char *ch) {
      62           23784 :   if (!io_->Read(ch, 1)) {
      63              32 :     Disconnect();
      64              32 :     return false;
      65                 :   }
      66                 : 
      67           23752 :   return true;
      68           23784 : }
      69                 : 
      70                 : 
      71            1108 : bool Session::SendPacket(Packet *pkt) {
      72            1108 :   char ch;
      73                 : 
      74            1108 :   do {
      75            1108 :     if (!SendPacketOnly(pkt)) return false;
      76                 : 
      77                 :     // If ACKs are off, we are done.
      78            1108 :     if (GetFlags() & IGNORE_ACK) break;
      79                 : 
      80                 :     // Otherwise, poll for '+'
      81            1124 :     if (!GetChar(&ch)) return false;
      82                 : 
      83                 :     // Retry if we didn't get a '+'
      84            2184 :   } while (ch != '+');
      85                 : 
      86            1092 :   return true;
      87            1108 : }
      88                 : 
      89                 : 
      90            1177 : bool Session::SendPacketOnly(Packet *pkt) {
      91            1177 :   const char *ptr;
      92            1177 :   char ch;
      93            1177 :   std::stringstream outstr;
      94                 : 
      95            1177 :   char run_xsum = 0;
      96            1177 :   int32_t seq;
      97                 : 
      98            2354 :   ptr = pkt->GetPayload();
      99            2354 :   size_t size = pkt->GetPayloadSize();
     100                 : 
     101            4708 :   if (!pkt->GetSequence(&seq) && (GetFlags() & USE_SEQ)) {
     102               0 :     pkt->SetSequence(seq_++);
     103               0 :   }
     104                 : 
     105                 :   // Signal start of response
     106            1177 :   outstr << '$';
     107                 : 
     108                 :   // If there is a sequence, send as two nibble 8bit value + ':'
     109            2354 :   if (pkt->GetSequence(&seq)) {
     110               0 :     IntToNibble((seq & 0xFF) >> 4, &ch);
     111               0 :     outstr << ch;
     112               0 :     run_xsum += ch;
     113                 : 
     114               0 :     IntToNibble(seq & 0xF, &ch);
     115               0 :     outstr << ch;
     116               0 :     run_xsum += ch;
     117                 : 
     118               0 :     ch = ':';
     119               0 :     outstr << ch;
     120               0 :     run_xsum += ch;
     121               0 :   }
     122                 : 
     123                 :   // Send the main payload
     124          619694 :   for (size_t offs = 0; offs < size; ++offs) {
     125          308670 :     ch = ptr[offs];
     126          308670 :     outstr << ch;
     127          308670 :     run_xsum += ch;
     128          308670 :   }
     129                 : 
     130            2354 :   if (GetFlags() & DEBUG_SEND) {
     131            4700 :     NaClLog(1, "TX %s\n", outstr.str().c_str());
     132            1175 :   }
     133                 : 
     134                 :   // Send XSUM as two nible 8bit value preceeded by '#'
     135            1177 :   outstr << '#';
     136            1177 :   IntToNibble((run_xsum >> 4) & 0xF, &ch);
     137            1177 :   outstr << ch;
     138            1177 :   IntToNibble(run_xsum & 0xF, &ch);
     139            1177 :   outstr << ch;
     140                 : 
     141            5885 :   return io_->Write(outstr.str().data(),
     142            3531 :                     static_cast<int32_t>(outstr.str().length()));
     143            1177 : }
     144                 : 
     145                 : // Attempt to receive a packet
     146            1191 : bool Session::GetPacket(Packet *pkt) {
     147            1191 :   char run_xsum, fin_xsum, ch;
     148            1191 :   std::string in;
     149                 : 
     150                 :   // Toss characters until we see a start of command
     151            1191 :   do {
     152            2591 :     if (!GetChar(&ch)) return false;
     153            1273 :     in += ch;
     154            3722 :   } while (ch != '$');
     155                 : 
     156                 :  retry:
     157                 :   // Clear the stream
     158            1176 :   pkt->Clear();
     159                 : 
     160                 :   // Prepare XSUM calc
     161            1176 :   run_xsum = 0;
     162            1176 :   fin_xsum = 0;
     163                 : 
     164                 :   // Stream in the characters
     165           20212 :   while (1) {
     166           38072 :     if (!GetChar(&ch)) return false;
     167                 : 
     168                 :     // If we see a '#' we must be done with the data
     169           20212 :     if (ch == '#') break;
     170                 : 
     171           17860 :     in += ch;
     172                 : 
     173                 :     // If we see a '$' we must have missed the last cmd
     174           17860 :     if (ch == '$') {
     175               0 :       NaClLog(LOG_INFO, "RX Missing $, retry.\n");
     176               0 :       goto retry;
     177                 :     }
     178                 :     // Keep a running XSUM
     179           17860 :     run_xsum += ch;
     180           17860 :     pkt->AddRawChar(ch);
     181           17860 :   }
     182                 : 
     183                 : 
     184                 :   // Get two Nibble XSUM
     185            2352 :   if (!GetChar(&ch)) return false;
     186                 : 
     187            1176 :   int val;
     188            1176 :   NibbleToInt(ch, & val);
     189            1176 :   fin_xsum = val << 4;
     190                 : 
     191            2353 :   if (!GetChar(&ch)) return false;
     192            1175 :   NibbleToInt(ch, &val);
     193            1175 :   fin_xsum |= val;
     194                 : 
     195            5872 :   if (GetFlags() & DEBUG_RECV) NaClLog(1, "RX %s\n", in.c_str());
     196                 : 
     197            1175 :   pkt->ParseSequence();
     198                 : 
     199                 :   // If ACKs are off, we are done.
     200            2350 :   if (GetFlags() & IGNORE_ACK) return true;
     201                 : 
     202                 :   // If the XSUMs don't match, signal bad packet
     203            1175 :   if (fin_xsum == run_xsum) {
     204            1175 :     char out[3] = { '+', 0, 0 };
     205            1175 :     int32_t seq;
     206                 : 
     207                 :     // If we have a sequence number
     208            2350 :     if (pkt->GetSequence(&seq)) {
     209                 :       // Respond with Sequence number
     210               0 :       IntToNibble(seq >> 4, &out[1]);
     211               0 :       IntToNibble(seq & 0xF, &out[2]);
     212               0 :       return io_->Write(out, 3);
     213                 :     }
     214            2350 :     return io_->Write(out, 1);
     215                 :   } else {
     216                 :     // Resend a bad XSUM and look for retransmit
     217               0 :     io_->Write("-", 1);
     218                 : 
     219               0 :     NaClLog(LOG_INFO, "RX Bad XSUM, retry\n");
     220               0 :     goto retry;
     221                 :   }
     222                 : 
     223                 :   return true;
     224            1191 : }
     225                 : 
     226                 : }  // End of namespace gdb_rsp
     227                 : 

Generated by: LCOV version 1.7