tools/runonphone/symbianutils/trkutils.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    49 #include <QtCore/QTime>
    49 #include <QtCore/QTime>
    50 
    50 
    51 #define logMessage(s)  do { qDebug() << "TRKCLIENT: " << s; } while (0)
    51 #define logMessage(s)  do { qDebug() << "TRKCLIENT: " << s; } while (0)
    52 
    52 
    53 namespace trk {
    53 namespace trk {
       
    54 
       
    55 Library::Library() : codeseg(0), dataseg(0), pid(0)
       
    56 {
       
    57 }
       
    58 
       
    59 Library::Library(const TrkResult &result) : codeseg(0), dataseg(0), pid(0)
       
    60 {
       
    61     if (result.data.size() < 20) {
       
    62         qWarning("Invalid trk creation notification received.");
       
    63         return;
       
    64     }
       
    65 
       
    66     const char *data = result.data.constData();
       
    67     pid = extractInt(data + 2);
       
    68     codeseg = extractInt(data + 10);
       
    69     dataseg = extractInt(data + 14);
       
    70     const uint len = extractShort(data + 18);
       
    71     name = result.data.mid(20, len);
       
    72 }
    54 
    73 
    55 TrkAppVersion::TrkAppVersion()
    74 TrkAppVersion::TrkAppVersion()
    56 {
    75 {
    57     reset();
    76     reset();
    58 }
    77 }
    75     defaultTypeSize = 0;
    94     defaultTypeSize = 0;
    76     fpTypeSize = 0;
    95     fpTypeSize = 0;
    77     extended1TypeSize = 0;
    96     extended1TypeSize = 0;
    78     extended2TypeSize = 0;
    97     extended2TypeSize = 0;
    79     pid = 0;
    98     pid = 0;
       
    99     mainTid = 0;
    80     tid = 0;
   100     tid = 0;
    81     codeseg = 0;
   101     codeseg = 0;
    82     dataseg = 0;
   102     dataseg = 0;
    83 
   103 
    84     currentThread = 0;
       
    85     libraries.clear();
   104     libraries.clear();
    86     trkAppVersion.reset();
   105     trkAppVersion.reset();
    87 }
   106 }
    88 
   107 
    89 static QString formatCpu(int major, int minor)
   108 static QString formatCpu(int major, int minor)
   141         fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize);
   160         fpTypeSizeStr = QCoreApplication::translate("trk::Session", ", float size: %1").arg(fpTypeSize);
   142     msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr);
   161     msg = msg.arg(defaultTypeSizeStr).arg(fpTypeSizeStr);
   143     return msg.arg(formatTrkVersion(trkAppVersion));
   162     return msg.arg(formatTrkVersion(trkAppVersion));
   144 }
   163 }
   145 
   164 
       
   165 QByteArray Session::gdbLibraryList() const
       
   166 {
       
   167     const int count = libraries.size();
       
   168     QByteArray response = "l<library-list>";
       
   169     for (int i = 0; i != count; ++i) {
       
   170         const trk::Library &lib = libraries.at(i);
       
   171         response += "<library name=\"";
       
   172         response += lib.name;
       
   173         response += "\">";
       
   174         response += "<section address=\"0x";
       
   175         response += trk::hexNumber(lib.codeseg);
       
   176         response += "\"/>";
       
   177         response += "<section address=\"0x";
       
   178         response += trk::hexNumber(lib.dataseg);
       
   179         response += "\"/>";
       
   180         response += "<section address=\"0x";
       
   181         response += trk::hexNumber(lib.dataseg);
       
   182         response += "\"/>";
       
   183         response += "</library>";
       
   184     }
       
   185     response += "</library-list>";
       
   186     return response;
       
   187 }
       
   188 
       
   189 QByteArray Session::gdbQsDllInfo(int start, int count) const
       
   190 {
       
   191     // Happens with  gdb 6.4.50.20060226-cvs / CodeSourcery.
       
   192     // Never made it into FSF gdb that got qXfer:libraries:read instead.
       
   193     // http://sourceware.org/ml/gdb/2007-05/msg00038.html
       
   194     // Name=hexname,TextSeg=textaddr[,DataSeg=dataaddr]
       
   195     const int libraryCount = libraries.size();
       
   196     const int end = count < 0 ? libraryCount : qMin(libraryCount, start + count);
       
   197     QByteArray response(1, end == libraryCount ? 'l' : 'm');
       
   198     for (int i = start; i < end; ++i) {
       
   199         if (i != start)
       
   200             response += ';';
       
   201         const Library &lib = libraries.at(i);
       
   202         response += "Name=";
       
   203         response += lib.name.toHex();
       
   204         response += ",TextSeg=";
       
   205         response += hexNumber(lib.codeseg);
       
   206         response += ",DataSeg=";
       
   207         response += hexNumber(lib.dataseg);
       
   208     }
       
   209     return response;
       
   210 }
       
   211 
       
   212 QString Session::toString() const
       
   213 {
       
   214     QString rc;
       
   215     QTextStream str(&rc);
       
   216     str << "Session: " << deviceDescription(false) << '\n'
       
   217             << "pid: " << pid <<  "main thread: " << mainTid
       
   218             << " current thread: " << tid << ' ';
       
   219     str.setIntegerBase(16);
       
   220     str << " code: 0x" << codeseg << " data: 0x" << dataseg << '\n';
       
   221     if (const int libCount = libraries.size()) {
       
   222         str << "Libraries:\n";
       
   223         for (int i = 0; i < libCount; i++)
       
   224             str << " #" << i << ' ' << libraries.at(i).name
       
   225                 << " code: 0x" << libraries.at(i).codeseg
       
   226                 << " data: 0x" << libraries.at(i).dataseg << '\n';
       
   227     }
       
   228     if (const int moduleCount = modules.size()) {
       
   229         str << "Modules:\n";
       
   230         for (int i = 0; i < moduleCount; i++)
       
   231             str << " #" << i << ' ' << modules.at(i) << '\n';
       
   232     }
       
   233     str.setIntegerBase(10);
       
   234     if (!addressToBP.isEmpty()) {
       
   235         typedef QHash<uint, uint>::const_iterator BP_ConstIterator;
       
   236         str << "Breakpoints:\n";
       
   237         const BP_ConstIterator cend = addressToBP.constEnd();
       
   238         for (BP_ConstIterator it = addressToBP.constBegin(); it != cend; ++it) {
       
   239             str.setIntegerBase(16);
       
   240             str << "  0x" << it.key();
       
   241             str.setIntegerBase(10);
       
   242             str << ' ' << it.value() << '\n';
       
   243         }
       
   244     }
       
   245 
       
   246     return rc;
       
   247 }
       
   248 
   146 // --------------
   249 // --------------
   147 
   250 
   148 QByteArray decode7d(const QByteArray &ba)
   251 QByteArray decode7d(const QByteArray &ba)
   149 {
   252 {
   150     QByteArray res;
   253     QByteArray res;
   186 {
   289 {
   187     QString str;
   290     QString str;
   188     QString ascii;
   291     QString ascii;
   189     const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen);
   292     const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen);
   190     for (int i = 0; i < size; ++i) {
   293     for (int i = 0; i < size; ++i) {
   191         //if (i == 5 || i == ba.size() - 2)
   294         const int c = byte(ba.at(i));
   192         //    str += "  ";
   295         str += QString::fromAscii("%1 ").arg(c, 2, 16, QChar('0'));
   193         int c = byte(ba.at(i));
   296         ascii += QChar(c).isPrint() ? QChar(c) : QChar('.');
   194         str += QString("%1 ").arg(c, 2, 16, QChar('0'));
       
   195         if (i >= 8 && i < ba.size() - 2)
       
   196             ascii += QChar(c).isPrint() ? QChar(c) : QChar('.');
       
   197     }
   297     }
   198     if (size != ba.size()) {
   298     if (size != ba.size()) {
   199         str += "...";
   299         str += QLatin1String("...");
   200         ascii += "...";
   300         ascii += QLatin1String("...");
   201     }
   301     }
   202     return str + "  " + ascii;
   302     return str + QLatin1String("  ") + ascii;
   203 }
   303 }
   204 
   304 
   205 SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits)
   305 SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits)
   206 {
   306 {
   207     QByteArray ba = QByteArray::number(n, 16);
   307     QByteArray ba = QByteArray::number(n, 16);
   297     }
   397     }
   298     // Some ASCII log message up to first delimiter or all
   398     // Some ASCII log message up to first delimiter or all
   299     return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size();
   399     return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size();
   300 }
   400 }
   301 
   401 
   302 bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByteArray *rawData)
   402 bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, bool &linkEstablishmentMode, QByteArray *rawData)
   303 {
   403 {
   304     result->clear();
   404     result->clear();
   305     if(rawData)
   405     if(rawData)
   306         rawData->clear();
   406         rawData->clear();
   307     const ushort len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
   407     ushort len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
       
   408     // handle receiving application output, which is not a regular command
       
   409     const int delimiterPos = serialFrame ? 4 : 0;
       
   410     if (linkEstablishmentMode) {
       
   411         //when "hot connecting" a device, we can receive partial frames.
       
   412         //this code resyncs by discarding data until a TRK frame is found
       
   413         while (buffer->length() > delimiterPos
       
   414                && result->multiplex != MuxTextTrace
       
   415                && !(result->multiplex == MuxTrk && buffer->at(delimiterPos) == 0x7e)) {
       
   416             buffer->remove(0,1);
       
   417             len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
       
   418         }
       
   419     }
   308     if (!len)
   420     if (!len)
   309         return false;
   421         return false;
   310     // handle receiving application output, which is not a regular command
       
   311     const int delimiterPos = serialFrame ? 4 : 0;
       
   312     if (buffer->at(delimiterPos) != 0x7e) {
   422     if (buffer->at(delimiterPos) != 0x7e) {
   313         result->isDebugOutput = true;
   423         result->isDebugOutput = true;
   314         result->data = buffer->mid(delimiterPos, len);
   424         result->data = buffer->mid(delimiterPos, len);
   315         *buffer->remove(0, delimiterPos + len);
   425         buffer->remove(0, delimiterPos + len);
   316         return true;
   426         return true;
   317     }
   427     }
   318     // FIXME: what happens if the length contains 0xfe?
   428     // FIXME: what happens if the length contains 0xfe?
   319     // Assume for now that it passes unencoded!
   429     // Assume for now that it passes unencoded!
   320     const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2));
   430     const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2));
   321     if(rawData)
   431     if(rawData)
   322         *rawData = data;
   432         *rawData = data;
   323     *buffer->remove(0, delimiterPos + len);
   433     buffer->remove(0, delimiterPos + len);
   324 
   434 
   325     byte sum = 0;
   435     byte sum = 0;
   326     for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum
   436     for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum
   327         sum += byte(data.at(i));
   437         sum += byte(data.at(i));
   328     if (sum != 0xff)
   438     if (sum != 0xff)
   333     result->data = data.mid(2, data.size() - 3);
   443     result->data = data.mid(2, data.size() - 3);
   334     //logMessage("   REST BUF: " << stringFromArray(*buffer));
   444     //logMessage("   REST BUF: " << stringFromArray(*buffer));
   335     //logMessage("   CURR DATA: " << stringFromArray(data));
   445     //logMessage("   CURR DATA: " << stringFromArray(data));
   336     //QByteArray prefix = "READ BUF:                                       ";
   446     //QByteArray prefix = "READ BUF:                                       ";
   337     //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data());
   447     //logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data());
       
   448     linkEstablishmentMode = false; //have received a good TRK packet, therefore in sync
   338     return true;
   449     return true;
   339 }
   450 }
   340 
   451 
   341 SYMBIANUTILS_EXPORT ushort extractShort(const char *data)
   452 SYMBIANUTILS_EXPORT ushort extractShort(const char *data)
   342 {
   453 {