lib: show offset and rectype in HexDumpParser
[barry.git] / src / dp_codinfo.cc
blob3e7f7745e7d8c630cdca8f6a0530f2b9755aac38
1 /**
2 * @file dp_codinfo.cc
3 * @author Nicolas VIVIEN
4 * @date 2009-08-01
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.
14 * @par Modifications
15 * - 2009/08/01 : N. VIVIEN
16 * - First release
18 * @par Licences
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.
35 #include <fstream>
36 #include <iomanip>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <string.h>
42 #include "dp_parser.h"
43 #include "dp_codinfo.h"
44 #include "debug.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
63 using namespace std;
66 namespace Barry {
68 namespace JDG {
71 // Public API
72 //------------
74 #define DEBUG_FILE_EXT ".debug"
77 void SearchDebugFile(DebugFileList &list)
79 DIR *path;
80 struct dirent *entry;
82 path = opendir(".");
84 while( (entry = readdir(path)) ) {
85 int offset;
87 if (strlen(entry->d_name) < strlen(DEBUG_FILE_EXT))
88 continue;
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);
95 CodInfo info;
97 // Parse header section
98 info.ParseHeaderSection(file);
100 // Add element to list
101 list.AddElement(info.GetUniqueId(), info.GetAppName(), entry->d_name);
105 closedir(path);
109 bool LoadDebugInfo(const DebugFileList &list, const char *filename, CodInfo &info)
111 if (filename == NULL)
112 return false;
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);
121 return true;
125 return false;
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());
138 return true;
142 return false;
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;
159 push_back(entry);
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 << "--------------------------";
174 os << endl;
176 for( ; i != e; ++i ) {
177 (*i).Dump(os);
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;
190 // ClassList class
191 //---------------------------
194 void ClassList::CreateDefaultEntries()
196 ClassEntry entry;
198 // 1
199 entry.classPath = "com.rim.resources";
200 entry.className = "net_rim_rimsecuridlibRIMResources";
201 push_back(entry);
203 // 2
204 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
205 entry.className = "RimSecurIDLib";
206 push_back(entry);
208 // 3
209 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
210 entry.className = "RimDatabaseFullException";
211 push_back(entry);
213 // 4
214 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
215 entry.className = "RimDecryptFailException";
216 push_back(entry);
218 // 5
219 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
220 entry.className = "RimDuplicateNameException";
221 push_back(entry);
223 // 6
224 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
225 entry.className = "RimDuplicateTokenException";
226 push_back(entry);
228 // 7
229 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
230 entry.className = "RimInvalidParamException";
231 push_back(entry);
233 // 8
234 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
235 entry.className = "RimSecurIDLib";
236 push_back(entry);
238 // 9
239 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
240 entry.className = "RimWrongDeviceIDException";
241 push_back(entry);
243 // 10
244 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
245 entry.className = "RimWrongFormFactorException";
246 push_back(entry);
250 // CodInfo class
251 //------------------------
253 bool CodInfo::LoadDebugFile(const char *filename)
255 uint32_t field;
257 if (filename == NULL)
258 return false;
260 ifstream file(filename);
262 // Parse header file
263 ParseHeaderSection(file);
265 // Parse type area zone
266 ParseTypeSection(file);
268 // FIXME : ???
269 field = ParseInteger(file); // Read 0x0
270 field = ParseInteger(file); // Read 0x1
272 // FIXME : ???
273 field = ParseInteger(file); // Read 0x0
274 field = ParseInteger(file); // Read 0x0 or 0xA
276 if (field == 0xA) {
277 // Parse ressource area zone
278 ParseResourceSection(file);
281 return true;
285 uint32_t CodInfo::GetUniqueId()
287 return uniqueId;
291 string CodInfo::GetAppName()
293 return appName;
297 // Private API - Section parsing
298 //-------------------------------
300 void CodInfo::ParseHeaderSection(istream &input)
302 uint32_t type;
304 type = ParseNextHeaderField(input);
306 if (type != COD_DEBUG_UNIQUEID_HEADERFIELD)
307 return;
309 type = ParseNextHeaderField(input);
311 if (type != COD_DEBUG_APPNAME_HEADERFIELD)
312 return;
316 void CodInfo::ParseTypeSection(istream &input)
318 uint32_t type;
319 uint32_t count;
320 uint32_t nbr, check;
322 // Read number of declared type content into this section
323 nbr = ParseInteger(input);
325 // Read each object
326 count = 0;
328 while (!input.eof()) {
329 type = ParseNextTypeField(input);
331 if (type == COD_DEBUG_NONE_FIELD)
332 break;
334 count++;
337 // Read again number of declared type content into this section
338 // We have to find the same value
339 check = ParseInteger(input);
341 // Checking...
342 dout("Nbr = " << dec << nbr << " / Count = " << dec << count << " / check = " << check);
346 void CodInfo::ParseResourceSection(istream &input)
348 uint32_t len;
349 uint32_t type;
350 uint32_t unknown01;
351 uint32_t unknown02;
352 uint32_t unknown03;
353 uint32_t unknown04;
354 uint32_t unknown05;
355 uint32_t unknown06;
356 uint32_t unknown07;
358 string name;
360 // type = 1
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);
378 // type = 2
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);
402 // type = 1
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);
420 // type = 0
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);
451 switch (type) {
452 case COD_DEBUG_UNIQUEID_HEADERFIELD:
453 ParseUniqueId(input);
454 break;
456 case COD_DEBUG_APPNAME_HEADERFIELD:
457 ParseAppName(input);
458 break;
460 default:
461 type = 0xFFFFFFFF;
464 return type;
468 uint32_t CodInfo::ParseNextTypeField(istream &input)
470 uint32_t type = ParseInteger(input);
472 switch (type) {
473 case COD_DEBUG_NONE_FIELD:
474 break;
476 case COD_DEBUG_BOOLEAN_FIELD:
477 ParseBoolean(input);
478 break;
480 case COD_DEBUG_BYTE_FIELD:
481 ParseByte(input);
482 break;
484 case COD_DEBUG_CHAR_FIELD:
485 ParseChar(input);
486 break;
488 case COD_DEBUG_SHORT_FIELD:
489 ParseShort(input);
490 break;
492 case COD_DEBUG_INT_FIELD:
493 ParseInt(input);
494 break;
496 case COD_DEBUG_LONG_FIELD:
497 ParseLong(input);
498 break;
500 case COD_DEBUG_CLASS_FIELD:
501 ParseClass(input);
502 break;
504 case COD_DEBUG_ARRAY_FIELD:
505 ParseArray(input);
506 break;
508 case COD_DEBUG_VOID_FIELD:
509 ParseVoid(input);
510 break;
512 case COD_DEBUG_DOUBLE_FIELD:
513 ParseDouble(input);
514 break;
516 default:
517 dout("Type unknown ! " << hex << type);
518 type = 0xFFFFFFFF;
521 return 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)
601 uint32_t len;
603 ClassEntry object;
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);
618 if (len == 0)
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) {
679 uint32_t value;
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);
694 } // namespace JDG
696 } // namespace Barry