dp_codinfo.cc

Go to the documentation of this file.
00001 /**
00002  * @file dp_codinfo.cc
00003  * @author Nicolas VIVIEN
00004  * @date 2009-08-01
00005  *
00006  * @note CopyRight Nicolas VIVIEN
00007  *
00008  * @brief COD debug file parser
00009  *   RIM's JDE generates several files when you build a COD application.
00010  *   Indeed, with the COD files for the device, we have a ".debug" file.
00011  *   This file is usefull to debug an application from JVM.
00012  *   This tool is a parser to understand these ".debug" files.
00013  *
00014  * @par Modifications
00015  *   - 2009/08/01 : N. VIVIEN
00016  *     - First release
00017  *
00018  * @par Licences
00019  *   Copyright (C) 2009-2010, Nicolas VIVIEN
00020  *
00021  *   This program is free software; you can redistribute it and/or modify
00022  *   it under the terms of the GNU General Public License as published by
00023  *   the Free Software Foundation; either version 2 of the License, or
00024  *   (at your option) any later version.
00025  *
00026  *   This program is distributed in the hope that it will be useful,
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00029  *
00030  *   See the GNU General Public License in the COPYING file at the
00031  *   root directory of this project for more details.
00032  */
00033 
00034 
00035 #include <fstream>
00036 #include <iomanip>
00037 
00038 #include <sys/types.h>
00039 #include <dirent.h>
00040 #include <string.h>
00041 
00042 #include "dp_parser.h"
00043 #include "dp_codinfo.h"
00044 #include "debug.h"
00045 
00046 
00047 #define COD_DEBUG_APPNAME_HEADERFIELD           0x0
00048 #define COD_DEBUG_UNIQUEID_HEADERFIELD          0x8
00049 
00050 #define COD_DEBUG_NONE_FIELD                    0x0
00051 #define COD_DEBUG_BOOLEAN_FIELD                 0x1
00052 #define COD_DEBUG_BYTE_FIELD                    0x2
00053 #define COD_DEBUG_CHAR_FIELD                    0x3
00054 #define COD_DEBUG_SHORT_FIELD                   0x4
00055 #define COD_DEBUG_INT_FIELD                     0x5
00056 #define COD_DEBUG_LONG_FIELD                    0x6
00057 #define COD_DEBUG_CLASS_FIELD                   0x7
00058 #define COD_DEBUG_ARRAY_FIELD                   0x8
00059 #define COD_DEBUG_VOID_FIELD                    0xA
00060 #define COD_DEBUG_DOUBLE_FIELD                  0xC
00061 
00062 
00063 using namespace std;
00064 
00065 
00066 namespace Barry {
00067 
00068 namespace JDG {
00069 
00070 
00071 // Public API
00072 //------------
00073 
00074 #define DEBUG_FILE_EXT          ".debug"
00075 
00076 
00077 void SearchDebugFile(DebugFileList &list)
00078 {
00079         DIR *path;
00080         struct dirent *entry;
00081 
00082         path = opendir(".");
00083 
00084         while( (entry = readdir(path)) ) {
00085                 int offset;
00086 
00087                 if (strlen(entry->d_name) < strlen(DEBUG_FILE_EXT))
00088                         continue;
00089 
00090                 offset = strlen(entry->d_name) - strlen(DEBUG_FILE_EXT);
00091 
00092                 if (!strcmp(entry->d_name + offset, DEBUG_FILE_EXT)) {
00093                         ifstream file(entry->d_name);
00094 
00095                         CodInfo info;
00096 
00097                         // Parse header section
00098                         info.ParseHeaderSection(file);
00099 
00100                         // Add element to list
00101                         list.AddElement(info.GetUniqueId(), info.GetAppName(), entry->d_name);
00102                 }
00103         }
00104 
00105         closedir(path);
00106 }
00107 
00108 
00109 bool LoadDebugInfo(const DebugFileList &list, const char *filename, CodInfo &info)
00110 {
00111         if (filename == NULL)
00112                 return false;
00113 
00114         DebugFileList::const_iterator b = list.begin();
00115 
00116         for( ; b != list.end(); b++ ) {
00117                 const DebugFileEntry &entry = (*b);
00118 
00119                 if( entry.fileName == filename ) {
00120                         info.LoadDebugFile(filename);
00121                         return true;
00122                 }
00123         }
00124 
00125         return false;
00126 }
00127 
00128 
00129 bool LoadDebugInfo(const DebugFileList &list, const uint32_t uniqueId, const std::string module, CodInfo &info)
00130 {
00131         DebugFileList::const_iterator b = list.begin();
00132 
00133         for( ; b != list.end(); b++ ) {
00134                 const DebugFileEntry &entry = (*b);
00135 
00136                 if ((entry.uniqueId == uniqueId) && (entry.appName == module)) {
00137                         info.LoadDebugFile(entry.fileName.c_str());
00138                         return true;
00139                 }
00140         }
00141 
00142         return false;
00143 }
00144 
00145 
00146 // DebugFileList class
00147 //------------------------
00148 
00149 void DebugFileList::AddElement(uint32_t uniqueid,
00150                                 const std::string &appname,
00151                                 const std::string &filename)
00152 {
00153         DebugFileEntry entry;
00154 
00155         entry.uniqueId = uniqueid;
00156         entry.appName = appname;
00157         entry.fileName = filename;
00158 
00159         push_back(entry);
00160 }
00161 
00162 
00163 void DebugFileList::Dump(std::ostream &os) const
00164 {
00165         const_iterator i = begin(), e = end();
00166 
00167         os << "  UniqueID  " << "|";
00168         os << "        Module Name       " << "|";
00169         os << "         File Name        " << endl;
00170 
00171         os << "------------+";
00172         os << "--------------------------+";
00173         os << "--------------------------";
00174         os << endl;
00175 
00176         for( ; i != e; ++i ) {
00177                 (*i).Dump(os);
00178         }
00179 }
00180 
00181 
00182 void DebugFileEntry::Dump(std::ostream &os) const
00183 {
00184         os << " 0x" << setfill('0') << setw(8) << hex << uniqueId << " |";
00185         os << " " << appName << setfill(' ') << setw(24) << " |";
00186         os << " " << fileName << endl;
00187 }
00188 
00189 
00190 // ClassList class
00191 //---------------------------
00192 
00193 
00194 void ClassList::CreateDefaultEntries()
00195 {
00196         ClassEntry entry;
00197 
00198         // 1
00199         entry.classPath = "com.rim.resources";
00200         entry.className = "net_rim_rimsecuridlibRIMResources";
00201         push_back(entry);
00202 
00203         // 2
00204         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00205         entry.className = "RimSecurIDLib";
00206         push_back(entry);
00207 
00208         // 3
00209         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00210         entry.className = "RimDatabaseFullException";
00211         push_back(entry);
00212 
00213         // 4
00214         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00215         entry.className = "RimDecryptFailException";
00216         push_back(entry);
00217 
00218         // 5
00219         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00220         entry.className = "RimDuplicateNameException";
00221         push_back(entry);
00222 
00223         // 6
00224         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00225         entry.className = "RimDuplicateTokenException";
00226         push_back(entry);
00227 
00228         // 7
00229         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00230         entry.className = "RimInvalidParamException";
00231         push_back(entry);
00232 
00233         // 8
00234         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00235         entry.className = "RimSecurIDLib";
00236         push_back(entry);
00237 
00238         // 9
00239         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00240         entry.className = "RimWrongDeviceIDException";
00241         push_back(entry);
00242 
00243         // 10
00244         entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
00245         entry.className = "RimWrongFormFactorException";
00246         push_back(entry);
00247 }
00248 
00249 
00250 // CodInfo class
00251 //------------------------
00252 
00253 bool CodInfo::LoadDebugFile(const char *filename)
00254 {
00255         uint32_t field;
00256 
00257         if (filename == NULL)
00258                 return false;
00259 
00260         ifstream file(filename);
00261 
00262         // Parse header file
00263         ParseHeaderSection(file);
00264 
00265         // Parse type area zone
00266         ParseTypeSection(file);
00267 
00268         // FIXME : ???
00269         field = ParseInteger(file); // Read 0x0
00270         field = ParseInteger(file); // Read 0x1
00271 
00272         // FIXME : ???
00273         field = ParseInteger(file); // Read 0x0
00274         field = ParseInteger(file); // Read 0x0 or 0xA
00275 
00276         if (field == 0xA) {
00277                 // Parse ressource area zone
00278                 ParseResourceSection(file);
00279         }
00280 
00281         return true;
00282 }
00283 
00284 
00285 uint32_t CodInfo::GetUniqueId()
00286 {
00287         return uniqueId;
00288 }
00289 
00290 
00291 string CodInfo::GetAppName()
00292 {
00293         return appName;
00294 }
00295 
00296 
00297 // Private API - Section parsing
00298 //-------------------------------
00299 
00300 void CodInfo::ParseHeaderSection(istream &input)
00301 {
00302         uint32_t type;
00303 
00304         type = ParseNextHeaderField(input);
00305 
00306         if (type != COD_DEBUG_UNIQUEID_HEADERFIELD)
00307                 return;
00308 
00309         type = ParseNextHeaderField(input);
00310 
00311         if (type != COD_DEBUG_APPNAME_HEADERFIELD)
00312                 return;
00313 }
00314 
00315 
00316 void CodInfo::ParseTypeSection(istream &input)
00317 {
00318         uint32_t type;
00319         uint32_t count;
00320         uint32_t nbr, check;
00321 
00322         // Read number of declared type content into this section
00323         nbr = ParseInteger(input);
00324 
00325         // Read each object
00326         count = 0;
00327 
00328         while (!input.eof()) {
00329                 type = ParseNextTypeField(input);
00330 
00331                 if (type == COD_DEBUG_NONE_FIELD)
00332                         break;
00333 
00334                 count++;
00335         }
00336 
00337         // Read again number of declared type content into this section
00338         // We have to find the same value
00339         check = ParseInteger(input);
00340 
00341         // Checking...
00342         dout("Nbr = " << dec << nbr << " / Count = " << dec << count << " / check = " << check);
00343 }
00344 
00345 
00346 void CodInfo::ParseResourceSection(istream &input)
00347 {
00348         uint32_t len;
00349         uint32_t type;
00350         uint32_t unknown01;
00351         uint32_t unknown02;
00352         uint32_t unknown03;
00353         uint32_t unknown04;
00354         uint32_t unknown05;
00355         uint32_t unknown06;
00356         uint32_t unknown07;
00357 
00358         string name;
00359 
00360         // type = 1
00361         for (int i=0; i<10; i++) {
00362                 type = ParseInteger(input);
00363 
00364                 len = ParseInteger(input);
00365                 name = ParseString(input, len);
00366 
00367                 unknown01 = ParseInteger(input);
00368                 unknown02 = ParseInteger(input);
00369                 unknown03 = ParseInteger(input);
00370 
00371                 dout("JDGCodInfo::parseRessource"
00372                         << "\n  Name : " << name
00373                         << "\n  unknown01 : " << hex << unknown01
00374                         << "\n  unknown02 : " << hex << unknown02
00375                         << "\n  unknown03 : " << hex << unknown03);
00376         }
00377 
00378         // type = 2
00379         type = ParseInteger(input);
00380 
00381         len = ParseInteger(input);
00382         name = ParseString(input, len);
00383 
00384         unknown01 = ParseInteger(input);
00385         unknown02 = ParseInteger(input);
00386         unknown03 = ParseInteger(input);
00387         unknown04 = ParseInteger(input);
00388         unknown05 = ParseInteger(input);
00389         unknown06 = ParseInteger(input);
00390         unknown07 = ParseInteger(input);
00391 
00392         dout("JDGCodInfo::parseRessource"
00393                 << "\n  Name : " << name
00394                 << "\n  unknown01 : " << hex << unknown01
00395                 << "\n  unknown02 : " << hex << unknown02
00396                 << "\n  unknown03 : " << hex << unknown03
00397                 << "\n  unknown04 : " << hex << unknown04
00398                 << "\n  unknown05 : " << hex << unknown05
00399                 << "\n  unknown06 : " << hex << unknown06
00400                 << "\n  unknown07 : " << hex << unknown07);
00401 
00402         // type = 1
00403         type = ParseInteger(input);
00404 
00405         len = ParseInteger(input);
00406         name = ParseString(input, len);
00407 
00408         unknown01 = ParseInteger(input);
00409         unknown02 = ParseInteger(input);
00410         unknown03 = ParseInteger(input);
00411         unknown04 = ParseInteger(input);
00412 
00413         dout("JDGCodInfo::parseRessource"
00414                 << "\n  Name : " << name
00415                 << "\n  unknown01 : " << hex << unknown01
00416                 << "\n  unknown02 : " << hex << unknown02
00417                 << "\n  unknown03 : " << hex << unknown03
00418                 << "\n  unknown04 : " << hex << unknown04);
00419 
00420         // type = 0
00421         type = ParseInteger(input);
00422 
00423         len = ParseInteger(input);
00424         name = ParseString(input, len);
00425 
00426         unknown01 = ParseInteger(input);
00427         unknown02 = ParseInteger(input);
00428         unknown03 = ParseInteger(input);
00429         unknown04 = ParseInteger(input);
00430         unknown05 = ParseInteger(input);
00431 
00432         dout("JDGCodInfo::parseRessource"
00433                 << "\n  Name : " << name
00434                 << "\n  unknown01 : " << hex << unknown01
00435                 << "\n  unknown02 : " << hex << unknown02
00436                 << "\n  unknown03 : " << hex << unknown03
00437                 << "\n  unknown04 : " << hex << unknown04
00438                 << "\n  unknown05 : " << hex << unknown05);
00439 }
00440 
00441 
00442 
00443 // Private API - Field parsing
00444 //-------------------------------
00445 
00446 
00447 uint32_t CodInfo::ParseNextHeaderField(istream &input)
00448 {
00449         uint32_t type = ParseInteger(input);
00450 
00451         switch (type) {
00452         case COD_DEBUG_UNIQUEID_HEADERFIELD:
00453                 ParseUniqueId(input);
00454                 break;
00455 
00456         case COD_DEBUG_APPNAME_HEADERFIELD:
00457                 ParseAppName(input);
00458                 break;
00459 
00460         default:
00461                 type = 0xFFFFFFFF;
00462         }
00463 
00464         return type;
00465 }
00466 
00467 
00468 uint32_t CodInfo::ParseNextTypeField(istream &input)
00469 {
00470         uint32_t type = ParseInteger(input);
00471 
00472         switch (type) {
00473         case COD_DEBUG_NONE_FIELD:
00474                 break;
00475 
00476         case COD_DEBUG_BOOLEAN_FIELD:
00477                 ParseBoolean(input);
00478                 break;
00479 
00480         case COD_DEBUG_BYTE_FIELD:
00481                 ParseByte(input);
00482                 break;
00483 
00484         case COD_DEBUG_CHAR_FIELD:
00485                 ParseChar(input);
00486                 break;
00487 
00488         case COD_DEBUG_SHORT_FIELD:
00489                 ParseShort(input);
00490                 break;
00491 
00492         case COD_DEBUG_INT_FIELD:
00493                 ParseInt(input);
00494                 break;
00495 
00496         case COD_DEBUG_LONG_FIELD:
00497                 ParseLong(input);
00498                 break;
00499 
00500         case COD_DEBUG_CLASS_FIELD:
00501                 ParseClass(input);
00502                 break;
00503 
00504         case COD_DEBUG_ARRAY_FIELD:
00505                 ParseArray(input);
00506                 break;
00507 
00508         case COD_DEBUG_VOID_FIELD:
00509                 ParseVoid(input);
00510                 break;
00511 
00512         case COD_DEBUG_DOUBLE_FIELD:
00513                 ParseDouble(input);
00514                 break;
00515 
00516         default:
00517                 dout("Type unknown ! " << hex << type);
00518                 type = 0xFFFFFFFF;
00519         }
00520 
00521         return type;
00522 }
00523 
00524 
00525 void CodInfo::ParseUniqueId(istream &input)
00526 {
00527         uniqueId = ParseInteger(input);
00528 }
00529 
00530 
00531 void CodInfo::ParseAppName(istream &input)
00532 {
00533         uint32_t len = ParseInteger(input);
00534 
00535         appName = ParseString(input, len);
00536 }
00537 
00538 
00539 void CodInfo::ParseBoolean(istream &input)
00540 {
00541         uint32_t len  = ParseInteger(input);
00542 
00543         string str = ParseString(input, len);
00544 
00545         dout("JDG::CodInfo::ParseBoolean\n  name : " << str);
00546 }
00547 
00548 
00549 void CodInfo::ParseByte(istream &input)
00550 {
00551         uint32_t len  = ParseInteger(input);
00552 
00553         string str = ParseString(input, len);
00554 
00555         dout("JDG::CodInfo::ParseByte\n  name : " << str);
00556 }
00557 
00558 
00559 void CodInfo::ParseChar(istream &input)
00560 {
00561         uint32_t len  = ParseInteger(input);
00562 
00563         string str = ParseString(input, len);
00564 
00565         dout("JDG::CodInfo::ParseChar\n  name : " << str);
00566 }
00567 
00568 
00569 void CodInfo::ParseShort(istream &input)
00570 {
00571         uint32_t len  = ParseInteger(input);
00572 
00573         string str = ParseString(input, len);
00574 
00575         dout("JDG::CodInfo::ParseShort\n  name : " << str);
00576 }
00577 
00578 
00579 void CodInfo::ParseInt(istream &input)
00580 {
00581         uint32_t len  = ParseInteger(input);
00582 
00583         string str = ParseString(input, len);
00584 
00585         dout("JDG::CodInfo::ParseInt\n  name : " << str);
00586 }
00587 
00588 
00589 void CodInfo::ParseLong(istream &input)
00590 {
00591         uint32_t len  = ParseInteger(input);
00592 
00593         string str = ParseString(input, len);
00594 
00595         dout("JDG::CodInfo::ParseLong\n  name : " << str);
00596 }
00597 
00598 
00599 void CodInfo::ParseClass(istream &input)
00600 {
00601         uint32_t len;
00602 
00603         ClassEntry object;
00604 
00605         dout("JDG::CodInfo::ParseClass");
00606 
00607         len  = ParseInteger(input);
00608 
00609         object.className = ParseString(input, len);
00610 
00611         object.type = ParseInteger(input);
00612         object.unknown02 = ParseInteger(input);
00613         object.unknown03 = ParseInteger(input);
00614         object.id = ParseInteger(input);
00615 
00616         len  = ParseInteger(input);
00617 
00618         if (len == 0)
00619                 object.classPath = "com.barry." + appName;
00620         else if (len != 0xFFFFFF)
00621                 object.classPath = ParseString(input, len);
00622 
00623         len  = ParseInteger(input);
00624 
00625         object.sourceFile = ParseString(input, len);
00626 
00627         object.unknown05 = ParseInteger(input);
00628         object.unknown06 = ParseInteger(input);
00629         object.unknown07 = ParseInteger(input);
00630         object.unknown08 = ParseInteger(input);
00631 
00632         classList.push_back(object);
00633 
00634         dout("\n  name : " << object.className
00635                 << "\n  path : " << object.classPath
00636                 << "\n  type : " << hex << object.type
00637                 << "\n  unknown02 : " << hex << object.unknown02
00638                 << "\n  unknown03 : " << hex << object.unknown03
00639                 << "\n  id : " << hex << object.id
00640                 << "\n  source file : " << object.sourceFile
00641                 << "\n  unknown05 : " << hex << object.unknown05
00642                 << "\n  unknown06 : " << hex << object.unknown06
00643                 << "\n  unknown07 : " << hex << object.unknown07
00644                 << "\n  unknown08 : " << hex << object.unknown08);
00645 }
00646 
00647 
00648 void CodInfo::ParseArray(istream &input)
00649 {
00650         uint32_t len  = ParseInteger(input);
00651 
00652         string str = ParseString(input, len);
00653 
00654         dout("JDG::CodInfo::ParseArray\n  name : " << str);
00655 }
00656 
00657 
00658 void CodInfo::ParseVoid(istream &input)
00659 {
00660         uint32_t len  = ParseInteger(input);
00661 
00662         string str = ParseString(input, len);
00663 
00664         dout("JDG::CodInfo::ParseVoid\n  name : " << str);
00665 }
00666 
00667 
00668 void CodInfo::ParseDouble(istream &input)
00669 {
00670         uint32_t len  = ParseInteger(input);
00671 
00672         string str = ParseString(input, len);
00673 
00674         dout("JDG::CodInfo::ParseDouble\n  name : " << str);
00675 }
00676 
00677 /*
00678 void CodInfo::ParseType2(istream &input) {
00679         uint32_t value;
00680         uint32_t len  = ParseInteger(input);
00681 
00682         string str = ParseString(input, len);
00683 
00684         dout("Type2 : " << str);
00685 
00686         value = ParseInteger(input);
00687         value = ParseInteger(input);
00688         value = ParseInteger(input);
00689         value = ParseInteger(input);
00690         value = ParseInteger(input);
00691         value = ParseInteger(input);
00692 }
00693 */
00694 } // namespace JDG
00695 
00696 } // namespace Barry
00697 

Generated on Tue Mar 1 17:50:15 2011 for Barry by  doxygen 1.5.6