3 * @author Nicolas VIVIEN
6 * @note CopyRight Nicolas VIVIEN
8 * @brief COD debug file parser
9 * RIM's JDE generates several files when you build a COD application.
10 * Indeed, with the COD files for the device, we have a ".debug" file.
11 * This file is usefull to debug an application from JVM.
12 * This tool is a parser to understand these ".debug" files.
15 * - 2009/08/01 : N. VIVIEN
19 * Copyright (C) 2009-2010, Nicolas VIVIEN
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30 * See the GNU General Public License in the COPYING file at the
31 * root directory of this project for more details.
39 #include <sys/types.h>
58 #define DEBUG_FILE_EXT ".debug"
61 void searchDebugFile(JDGDebugFileList
&list
)
68 while (entry
= readdir(path
)) {
71 if (strlen(entry
->d_name
) < strlen(DEBUG_FILE_EXT
))
74 offset
= strlen(entry
->d_name
) - strlen(DEBUG_FILE_EXT
);
76 if (!strcmp(entry
->d_name
+ offset
, DEBUG_FILE_EXT
)) {
77 ifstream
file(entry
->d_name
);
81 // Parse header section
82 info
.parseHeaderSection(file
);
84 // Add element to list
85 list
.AddElement(info
.getUniqueId(), info
.getAppName(), entry
->d_name
);
93 bool loadDebugInfo(JDGDebugFileList
&list
, const char *filename
, JDGCodInfo
&info
)
98 vector
<JDGDebugFileEntry
>::iterator b
= list
.begin();
100 for( ; b
!= list
.end(); b
++ ) {
101 JDGDebugFileEntry entry
= (*b
);
103 if (entry
.fileName
== string(filename
)) {
104 info
.loadDebugFile(filename
);
113 bool loadDebugInfo(JDGDebugFileList
&list
, const uint32_t uniqueId
, const std::string module
, JDGCodInfo
&info
)
115 vector
<JDGDebugFileEntry
>::iterator b
= list
.begin();
117 for( ; b
!= list
.end(); b
++ ) {
118 JDGDebugFileEntry entry
= (*b
);
120 if ((entry
.uniqueId
== uniqueId
) && (entry
.appName
== module
)) {
121 info
.loadDebugFile(entry
.fileName
.c_str());
130 // JDGDebugFileList class
131 //------------------------
133 void JDGDebugFileList::AddElement(uint32_t uniqueid
, std::string appname
, std::string filename
)
135 JDGDebugFileEntry entry
;
137 entry
.uniqueId
= uniqueid
;
138 entry
.appName
= appname
;
139 entry
.fileName
= filename
;
145 void JDGDebugFileList::Dump(std::ostream
&os
) const
147 const_iterator i
= begin(), e
= end();
149 os
<< " UniqueID " << "|";
150 os
<< " Module Name " << "|";
151 os
<< " File Name " << endl
;
153 os
<< "------------+";
154 os
<< "--------------------------+";
155 os
<< "--------------------------";
158 for( ; i
!= e
; ++i
) {
164 void JDGDebugFileEntry::Dump(std::ostream
&os
) const
166 os
<< " 0x" << setfill('0') << setw(8) << hex
<< uniqueId
<< " |";
167 os
<< " " << appName
<< setfill(' ') << setw(24) << " |";
168 os
<< " " << fileName
<< endl
;
172 // JDGClassList class
173 //---------------------------
176 void JDGClassList::createDefaultEntries() {
180 entry
.classPath
= "com.rim.resources";
181 entry
.className
= "net_rim_rimsecuridlibRIMResources";
185 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
186 entry
.className
= "RimSecurIDLib";
190 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
191 entry
.className
= "RimDatabaseFullException";
195 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
196 entry
.className
= "RimDecryptFailException";
200 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
201 entry
.className
= "RimDuplicateNameException";
205 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
206 entry
.className
= "RimDuplicateTokenException";
210 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
211 entry
.className
= "RimInvalidParamException";
215 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
216 entry
.className
= "RimSecurIDLib";
220 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
221 entry
.className
= "RimWrongDeviceIDException";
225 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
226 entry
.className
= "RimWrongFormFactorException";
232 //------------------------
234 bool JDGCodInfo::loadDebugFile(const char *filename
)
236 if (filename
== NULL
)
239 ifstream
file(filename
);
242 parseHeaderSection(file
);
244 // Parse type area zone
245 parseTypeSection(file
);
251 uint32_t JDGCodInfo::getUniqueId()
257 string
JDGCodInfo::getAppName()
263 // Private API - Section parsing
264 //-------------------------------
266 void JDGCodInfo::parseHeaderSection(ifstream
&input
)
270 type
= parseNextHeaderField(input
);
272 if (type
!= COD_DEBUG_UNIQUEID_HEADERFIELD
)
275 type
= parseNextHeaderField(input
);
277 if (type
!= COD_DEBUG_APPNAME_HEADERFIELD
)
282 void JDGCodInfo::parseTypeSection(ifstream
&input
)
288 // Read number of declared type content into this section
289 nbr
= ParseInteger(input
);
294 while (!input
.eof()) {
295 type
= parseNextTypeField(input
);
297 if (type
== COD_DEBUG_NONE_FIELD
)
303 // Read again number of declared type content into this section
304 // We have to find the same value
305 check
= ParseInteger(input
);
308 cout
<< "Nbr = " << dec
<< nbr
<< " / Count = " << dec
<< count
<< " / check = " << check
<< endl
;
312 uint32_t JDGCodInfo::parseNextHeaderField(ifstream
&input
)
314 uint32_t type
= ParseInteger(input
);
317 case COD_DEBUG_UNIQUEID_HEADERFIELD
:
318 parseUniqueId(input
);
321 case COD_DEBUG_APPNAME_HEADERFIELD
:
333 uint32_t JDGCodInfo::parseNextTypeField(ifstream
&input
)
335 uint32_t type
= ParseInteger(input
);
338 case COD_DEBUG_NONE_FIELD
:
341 case COD_DEBUG_BOOLEAN_FIELD
:
345 case COD_DEBUG_BYTE_FIELD
:
349 case COD_DEBUG_CHAR_FIELD
:
353 case COD_DEBUG_SHORT_FIELD
:
357 case COD_DEBUG_INT_FIELD
:
361 case COD_DEBUG_LONG_FIELD
:
365 case COD_DEBUG_CLASS_FIELD
:
369 case COD_DEBUG_ARRAY_FIELD
:
373 case COD_DEBUG_VOID_FIELD
:
377 case COD_DEBUG_DOUBLE_FIELD
:
382 cout
<< "Type unknown ! " << hex
<< type
<< endl
;
390 void JDGCodInfo::parseUniqueId(ifstream
&input
)
392 uniqueId
= ParseInteger(input
);
396 void JDGCodInfo::parseAppName(ifstream
&input
)
398 uint32_t len
= ParseInteger(input
);
400 appName
= ParseString(input
, len
);
404 void JDGCodInfo::parseBoolean(ifstream
&input
)
406 uint32_t len
= ParseInteger(input
);
408 string str
= ParseString(input
, len
);
410 cout
<< "JDGCodInfo::parseBoolean" << endl
;
411 cout
<< " name : " << str
<< endl
;
415 void JDGCodInfo::parseByte(ifstream
&input
)
417 uint32_t len
= ParseInteger(input
);
419 string str
= ParseString(input
, len
);
421 cout
<< "JDGCodInfo::parseByte" << endl
;
422 cout
<< " name : " << str
<< endl
;
426 void JDGCodInfo::parseChar(ifstream
&input
)
428 uint32_t len
= ParseInteger(input
);
430 string str
= ParseString(input
, len
);
432 cout
<< "JDGCodInfo::parseChar" << endl
;
433 cout
<< " name : " << str
<< endl
;
437 void JDGCodInfo::parseShort(ifstream
&input
)
439 uint32_t len
= ParseInteger(input
);
441 string str
= ParseString(input
, len
);
443 cout
<< "JDGCodInfo::parseShort" << endl
;
444 cout
<< " name : " << str
<< endl
;
448 void JDGCodInfo::parseInt(ifstream
&input
)
450 uint32_t len
= ParseInteger(input
);
452 string str
= ParseString(input
, len
);
454 cout
<< "JDGCodInfo::parseInt" << endl
;
455 cout
<< " name : " << str
<< endl
;
459 void JDGCodInfo::parseLong(ifstream
&input
)
461 uint32_t len
= ParseInteger(input
);
463 string str
= ParseString(input
, len
);
465 cout
<< "JDGCodInfo::parseLong" << endl
;
466 cout
<< " name : " << str
<< endl
;
470 void JDGCodInfo::parseClass(ifstream
&input
)
474 JDGClassEntry object
;
476 cout
<< "JDGCodInfo::parseClass" << endl
;
478 len
= ParseInteger(input
);
480 object
.className
= ParseString(input
, len
);
482 object
.type
= ParseInteger(input
);
483 object
.unknown02
= ParseInteger(input
);
484 object
.unknown03
= ParseInteger(input
);
485 object
.id
= ParseInteger(input
);
487 len
= ParseInteger(input
);
490 object
.classPath
= "com.barry." + appName
;
491 else if (len
!= 0xFFFFFF)
492 object
.classPath
= ParseString(input
, len
);
494 len
= ParseInteger(input
);
496 object
.sourceFile
= ParseString(input
, len
);
498 object
.unknown05
= ParseInteger(input
);
499 object
.unknown06
= ParseInteger(input
);
500 object
.unknown07
= ParseInteger(input
);
501 object
.unknown08
= ParseInteger(input
);
503 classList
.push_back(object
);
505 cout
<< " name : " << object
.className
<< endl
;
506 cout
<< " path : " << object
.classPath
<< endl
;
507 cout
<< " type : " << hex
<< object
.type
<< endl
;
508 cout
<< " unknown02 : " << hex
<< object
.unknown02
<< endl
;
509 cout
<< " unknown03 : " << hex
<< object
.unknown03
<< endl
;
510 cout
<< " id : " << hex
<< object
.id
<< endl
;
511 cout
<< " source file : " << object
.sourceFile
<< endl
;
512 cout
<< " unknown05 : " << hex
<< object
.unknown05
<< endl
;
513 cout
<< " unknown06 : " << hex
<< object
.unknown06
<< endl
;
514 cout
<< " unknown07 : " << hex
<< object
.unknown07
<< endl
;
515 cout
<< " unknown08 : " << hex
<< object
.unknown08
<< endl
;
519 void JDGCodInfo::parseArray(ifstream
&input
)
521 uint32_t len
= ParseInteger(input
);
523 string str
= ParseString(input
, len
);
525 cout
<< "JDGCodInfo::parseArray" << endl
;
526 cout
<< " name : " << str
<< endl
;
530 void JDGCodInfo::parseVoid(ifstream
&input
)
532 uint32_t len
= ParseInteger(input
);
534 string str
= ParseString(input
, len
);
536 cout
<< "JDGCodInfo::parseVoid" << endl
;
537 cout
<< " name : " << str
<< endl
;
541 void JDGCodInfo::parseDouble(ifstream
&input
)
543 uint32_t len
= ParseInteger(input
);
545 string str
= ParseString(input
, len
);
547 cout
<< "JDGCodInfo::parseDouble" << endl
;
548 cout
<< " name : " << str
<< endl
;
552 void JDGCodInfo::parseType2(ifstream &input) {
554 uint32_t len = ParseInteger(input);
556 string str = ParseString(input, len);
558 cout << "Type2 : " << str << endl;
560 value = ParseInteger(input);
561 value = ParseInteger(input);
562 value = ParseInteger(input);
563 value = ParseInteger(input);
564 value = ParseInteger(input);
565 value = ParseInteger(input);