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.
38 #include <sys/types.h>
42 #include "dp_parser.h"
43 #include "dp_codinfo.h"
47 #define COD_DEBUG_APPNAME_HEADERFIELD 0x0
48 #define COD_DEBUG_UNIQUEID_HEADERFIELD 0x8
50 #define COD_DEBUG_NONE_FIELD 0x0
51 #define COD_DEBUG_BOOLEAN_FIELD 0x1
52 #define COD_DEBUG_BYTE_FIELD 0x2
53 #define COD_DEBUG_CHAR_FIELD 0x3
54 #define COD_DEBUG_SHORT_FIELD 0x4
55 #define COD_DEBUG_INT_FIELD 0x5
56 #define COD_DEBUG_LONG_FIELD 0x6
57 #define COD_DEBUG_CLASS_FIELD 0x7
58 #define COD_DEBUG_ARRAY_FIELD 0x8
59 #define COD_DEBUG_VOID_FIELD 0xA
60 #define COD_DEBUG_DOUBLE_FIELD 0xC
74 #define DEBUG_FILE_EXT ".debug"
77 void SearchDebugFile(DebugFileList
&list
)
84 while( (entry
= readdir(path
)) ) {
87 if (strlen(entry
->d_name
) < strlen(DEBUG_FILE_EXT
))
90 offset
= strlen(entry
->d_name
) - strlen(DEBUG_FILE_EXT
);
92 if (!strcmp(entry
->d_name
+ offset
, DEBUG_FILE_EXT
)) {
93 ifstream
file(entry
->d_name
);
97 // Parse header section
98 info
.ParseHeaderSection(file
);
100 // Add element to list
101 list
.AddElement(info
.GetUniqueId(), info
.GetAppName(), entry
->d_name
);
109 bool LoadDebugInfo(const DebugFileList
&list
, const char *filename
, CodInfo
&info
)
111 if (filename
== NULL
)
114 DebugFileList::const_iterator b
= list
.begin();
116 for( ; b
!= list
.end(); b
++ ) {
117 const DebugFileEntry
&entry
= (*b
);
119 if( entry
.fileName
== filename
) {
120 info
.LoadDebugFile(filename
);
129 bool LoadDebugInfo(const DebugFileList
&list
, const uint32_t uniqueId
, const std::string module
, CodInfo
&info
)
131 DebugFileList::const_iterator b
= list
.begin();
133 for( ; b
!= list
.end(); b
++ ) {
134 const DebugFileEntry
&entry
= (*b
);
136 if ((entry
.uniqueId
== uniqueId
) && (entry
.appName
== module
)) {
137 info
.LoadDebugFile(entry
.fileName
.c_str());
146 // DebugFileList class
147 //------------------------
149 void DebugFileList::AddElement(uint32_t uniqueid
,
150 const std::string
&appname
,
151 const std::string
&filename
)
153 DebugFileEntry entry
;
155 entry
.uniqueId
= uniqueid
;
156 entry
.appName
= appname
;
157 entry
.fileName
= filename
;
163 void DebugFileList::Dump(std::ostream
&os
) const
165 const_iterator i
= begin(), e
= end();
167 os
<< " UniqueID " << "|";
168 os
<< " Module Name " << "|";
169 os
<< " File Name " << endl
;
171 os
<< "------------+";
172 os
<< "--------------------------+";
173 os
<< "--------------------------";
176 for( ; i
!= e
; ++i
) {
182 void DebugFileEntry::Dump(std::ostream
&os
) const
184 os
<< " 0x" << setfill('0') << setw(8) << hex
<< uniqueId
<< " |";
185 os
<< " " << appName
<< setfill(' ') << setw(24) << " |";
186 os
<< " " << fileName
<< endl
;
191 //---------------------------
194 void ClassList::CreateDefaultEntries()
199 entry
.classPath
= "com.rim.resources";
200 entry
.className
= "net_rim_rimsecuridlibRIMResources";
204 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
205 entry
.className
= "RimSecurIDLib";
209 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
210 entry
.className
= "RimDatabaseFullException";
214 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
215 entry
.className
= "RimDecryptFailException";
219 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
220 entry
.className
= "RimDuplicateNameException";
224 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
225 entry
.className
= "RimDuplicateTokenException";
229 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
230 entry
.className
= "RimInvalidParamException";
234 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
235 entry
.className
= "RimSecurIDLib";
239 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
240 entry
.className
= "RimWrongDeviceIDException";
244 entry
.classPath
= "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
245 entry
.className
= "RimWrongFormFactorException";
251 //------------------------
253 bool CodInfo::LoadDebugFile(const char *filename
)
257 if (filename
== NULL
)
260 ifstream
file(filename
);
263 ParseHeaderSection(file
);
265 // Parse type area zone
266 ParseTypeSection(file
);
269 field
= ParseInteger(file
); // Read 0x0
270 field
= ParseInteger(file
); // Read 0x1
273 field
= ParseInteger(file
); // Read 0x0
274 field
= ParseInteger(file
); // Read 0x0 or 0xA
277 // Parse ressource area zone
278 ParseResourceSection(file
);
285 uint32_t CodInfo::GetUniqueId()
291 string
CodInfo::GetAppName()
297 // Private API - Section parsing
298 //-------------------------------
300 void CodInfo::ParseHeaderSection(istream
&input
)
304 type
= ParseNextHeaderField(input
);
306 if (type
!= COD_DEBUG_UNIQUEID_HEADERFIELD
)
309 type
= ParseNextHeaderField(input
);
311 if (type
!= COD_DEBUG_APPNAME_HEADERFIELD
)
316 void CodInfo::ParseTypeSection(istream
&input
)
322 // Read number of declared type content into this section
323 nbr
= ParseInteger(input
);
328 while (!input
.eof()) {
329 type
= ParseNextTypeField(input
);
331 if (type
== COD_DEBUG_NONE_FIELD
)
337 // Read again number of declared type content into this section
338 // We have to find the same value
339 check
= ParseInteger(input
);
342 dout("Nbr = " << dec
<< nbr
<< " / Count = " << dec
<< count
<< " / check = " << check
);
346 void CodInfo::ParseResourceSection(istream
&input
)
361 for (int i
=0; i
<10; i
++) {
362 type
= ParseInteger(input
);
364 len
= ParseInteger(input
);
365 name
= ParseString(input
, len
);
367 unknown01
= ParseInteger(input
);
368 unknown02
= ParseInteger(input
);
369 unknown03
= ParseInteger(input
);
371 dout("JDGCodInfo::parseRessource"
372 << "\n Name : " << name
373 << "\n unknown01 : " << hex
<< unknown01
374 << "\n unknown02 : " << hex
<< unknown02
375 << "\n unknown03 : " << hex
<< unknown03
);
379 type
= ParseInteger(input
);
381 len
= ParseInteger(input
);
382 name
= ParseString(input
, len
);
384 unknown01
= ParseInteger(input
);
385 unknown02
= ParseInteger(input
);
386 unknown03
= ParseInteger(input
);
387 unknown04
= ParseInteger(input
);
388 unknown05
= ParseInteger(input
);
389 unknown06
= ParseInteger(input
);
390 unknown07
= ParseInteger(input
);
392 dout("JDGCodInfo::parseRessource"
393 << "\n Name : " << name
394 << "\n unknown01 : " << hex
<< unknown01
395 << "\n unknown02 : " << hex
<< unknown02
396 << "\n unknown03 : " << hex
<< unknown03
397 << "\n unknown04 : " << hex
<< unknown04
398 << "\n unknown05 : " << hex
<< unknown05
399 << "\n unknown06 : " << hex
<< unknown06
400 << "\n unknown07 : " << hex
<< unknown07
);
403 type
= ParseInteger(input
);
405 len
= ParseInteger(input
);
406 name
= ParseString(input
, len
);
408 unknown01
= ParseInteger(input
);
409 unknown02
= ParseInteger(input
);
410 unknown03
= ParseInteger(input
);
411 unknown04
= ParseInteger(input
);
413 dout("JDGCodInfo::parseRessource"
414 << "\n Name : " << name
415 << "\n unknown01 : " << hex
<< unknown01
416 << "\n unknown02 : " << hex
<< unknown02
417 << "\n unknown03 : " << hex
<< unknown03
418 << "\n unknown04 : " << hex
<< unknown04
);
421 type
= ParseInteger(input
);
423 len
= ParseInteger(input
);
424 name
= ParseString(input
, len
);
426 unknown01
= ParseInteger(input
);
427 unknown02
= ParseInteger(input
);
428 unknown03
= ParseInteger(input
);
429 unknown04
= ParseInteger(input
);
430 unknown05
= ParseInteger(input
);
432 dout("JDGCodInfo::parseRessource"
433 << "\n Name : " << name
434 << "\n unknown01 : " << hex
<< unknown01
435 << "\n unknown02 : " << hex
<< unknown02
436 << "\n unknown03 : " << hex
<< unknown03
437 << "\n unknown04 : " << hex
<< unknown04
438 << "\n unknown05 : " << hex
<< unknown05
);
443 // Private API - Field parsing
444 //-------------------------------
447 uint32_t CodInfo::ParseNextHeaderField(istream
&input
)
449 uint32_t type
= ParseInteger(input
);
452 case COD_DEBUG_UNIQUEID_HEADERFIELD
:
453 ParseUniqueId(input
);
456 case COD_DEBUG_APPNAME_HEADERFIELD
:
468 uint32_t CodInfo::ParseNextTypeField(istream
&input
)
470 uint32_t type
= ParseInteger(input
);
473 case COD_DEBUG_NONE_FIELD
:
476 case COD_DEBUG_BOOLEAN_FIELD
:
480 case COD_DEBUG_BYTE_FIELD
:
484 case COD_DEBUG_CHAR_FIELD
:
488 case COD_DEBUG_SHORT_FIELD
:
492 case COD_DEBUG_INT_FIELD
:
496 case COD_DEBUG_LONG_FIELD
:
500 case COD_DEBUG_CLASS_FIELD
:
504 case COD_DEBUG_ARRAY_FIELD
:
508 case COD_DEBUG_VOID_FIELD
:
512 case COD_DEBUG_DOUBLE_FIELD
:
517 dout("Type unknown ! " << hex
<< type
);
525 void CodInfo::ParseUniqueId(istream
&input
)
527 uniqueId
= ParseInteger(input
);
531 void CodInfo::ParseAppName(istream
&input
)
533 uint32_t len
= ParseInteger(input
);
535 appName
= ParseString(input
, len
);
539 void CodInfo::ParseBoolean(istream
&input
)
541 uint32_t len
= ParseInteger(input
);
543 string str
= ParseString(input
, len
);
545 dout("JDG::CodInfo::ParseBoolean\n name : " << str
);
549 void CodInfo::ParseByte(istream
&input
)
551 uint32_t len
= ParseInteger(input
);
553 string str
= ParseString(input
, len
);
555 dout("JDG::CodInfo::ParseByte\n name : " << str
);
559 void CodInfo::ParseChar(istream
&input
)
561 uint32_t len
= ParseInteger(input
);
563 string str
= ParseString(input
, len
);
565 dout("JDG::CodInfo::ParseChar\n name : " << str
);
569 void CodInfo::ParseShort(istream
&input
)
571 uint32_t len
= ParseInteger(input
);
573 string str
= ParseString(input
, len
);
575 dout("JDG::CodInfo::ParseShort\n name : " << str
);
579 void CodInfo::ParseInt(istream
&input
)
581 uint32_t len
= ParseInteger(input
);
583 string str
= ParseString(input
, len
);
585 dout("JDG::CodInfo::ParseInt\n name : " << str
);
589 void CodInfo::ParseLong(istream
&input
)
591 uint32_t len
= ParseInteger(input
);
593 string str
= ParseString(input
, len
);
595 dout("JDG::CodInfo::ParseLong\n name : " << str
);
599 void CodInfo::ParseClass(istream
&input
)
605 dout("JDG::CodInfo::ParseClass");
607 len
= ParseInteger(input
);
609 object
.className
= ParseString(input
, len
);
611 object
.type
= ParseInteger(input
);
612 object
.unknown02
= ParseInteger(input
);
613 object
.unknown03
= ParseInteger(input
);
614 object
.id
= ParseInteger(input
);
616 len
= ParseInteger(input
);
619 object
.classPath
= "com.barry." + appName
;
620 else if (len
!= 0xFFFFFF)
621 object
.classPath
= ParseString(input
, len
);
623 len
= ParseInteger(input
);
625 object
.sourceFile
= ParseString(input
, len
);
627 object
.unknown05
= ParseInteger(input
);
628 object
.unknown06
= ParseInteger(input
);
629 object
.unknown07
= ParseInteger(input
);
630 object
.unknown08
= ParseInteger(input
);
632 classList
.push_back(object
);
634 dout("\n name : " << object
.className
635 << "\n path : " << object
.classPath
636 << "\n type : " << hex
<< object
.type
637 << "\n unknown02 : " << hex
<< object
.unknown02
638 << "\n unknown03 : " << hex
<< object
.unknown03
639 << "\n id : " << hex
<< object
.id
640 << "\n source file : " << object
.sourceFile
641 << "\n unknown05 : " << hex
<< object
.unknown05
642 << "\n unknown06 : " << hex
<< object
.unknown06
643 << "\n unknown07 : " << hex
<< object
.unknown07
644 << "\n unknown08 : " << hex
<< object
.unknown08
);
648 void CodInfo::ParseArray(istream
&input
)
650 uint32_t len
= ParseInteger(input
);
652 string str
= ParseString(input
, len
);
654 dout("JDG::CodInfo::ParseArray\n name : " << str
);
658 void CodInfo::ParseVoid(istream
&input
)
660 uint32_t len
= ParseInteger(input
);
662 string str
= ParseString(input
, len
);
664 dout("JDG::CodInfo::ParseVoid\n name : " << str
);
668 void CodInfo::ParseDouble(istream
&input
)
670 uint32_t len
= ParseInteger(input
);
672 string str
= ParseString(input
, len
);
674 dout("JDG::CodInfo::ParseDouble\n name : " << str
);
678 void CodInfo::ParseType2(istream &input) {
680 uint32_t len = ParseInteger(input);
682 string str = ParseString(input, len);
684 dout("Type2 : " << str);
686 value = ParseInteger(input);
687 value = ParseInteger(input);
688 value = ParseInteger(input);
689 value = ParseInteger(input);
690 value = ParseInteger(input);
691 value = ParseInteger(input);