lib: Moving default Barry::Data size into constants.
[barry.git] / src / dp_codinfo.cc
blob53e9a164faddc160f2b7c197235d93b007cd22ae
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 "ios_state.h"
45 #include "debug.h"
48 #define COD_DEBUG_APPNAME_HEADERFIELD 0x0
49 #define COD_DEBUG_UNIQUEID_HEADERFIELD 0x8
51 #define COD_DEBUG_NONE_FIELD 0x0
52 #define COD_DEBUG_BOOLEAN_FIELD 0x1
53 #define COD_DEBUG_BYTE_FIELD 0x2
54 #define COD_DEBUG_CHAR_FIELD 0x3
55 #define COD_DEBUG_SHORT_FIELD 0x4
56 #define COD_DEBUG_INT_FIELD 0x5
57 #define COD_DEBUG_LONG_FIELD 0x6
58 #define COD_DEBUG_CLASS_FIELD 0x7
59 #define COD_DEBUG_ARRAY_FIELD 0x8
60 #define COD_DEBUG_VOID_FIELD 0xA
61 #define COD_DEBUG_DOUBLE_FIELD 0xC
64 using namespace std;
67 namespace Barry {
69 namespace JDG {
72 // Public API
73 //------------
75 #define DEBUG_FILE_EXT ".debug"
78 void SearchDebugFile(DebugFileList &list)
80 DIR *path;
81 struct dirent *entry;
83 path = opendir(".");
85 while( (entry = readdir(path)) ) {
86 int offset;
88 if (strlen(entry->d_name) < strlen(DEBUG_FILE_EXT))
89 continue;
91 offset = strlen(entry->d_name) - strlen(DEBUG_FILE_EXT);
93 if (!strcmp(entry->d_name + offset, DEBUG_FILE_EXT)) {
94 ifstream file(entry->d_name);
96 CodInfo info;
98 // Parse header section
99 info.ParseHeaderSection(file);
101 // Add element to list
102 list.AddElement(info.GetUniqueId(), info.GetAppName(), entry->d_name);
106 closedir(path);
110 bool LoadDebugInfo(const DebugFileList &list, const char *filename, CodInfo &info)
112 if (filename == NULL)
113 return false;
115 DebugFileList::const_iterator b = list.begin();
117 for( ; b != list.end(); b++ ) {
118 const DebugFileEntry &entry = (*b);
120 if( entry.fileName == filename ) {
121 info.LoadDebugFile(filename);
122 return true;
126 return false;
130 bool LoadDebugInfo(const DebugFileList &list, const uint32_t uniqueId, const std::string module, CodInfo &info)
132 DebugFileList::const_iterator b = list.begin();
134 for( ; b != list.end(); b++ ) {
135 const DebugFileEntry &entry = (*b);
137 if ((entry.uniqueId == uniqueId) && (entry.appName == module)) {
138 info.LoadDebugFile(entry.fileName.c_str());
139 return true;
143 return false;
147 // DebugFileList class
148 //------------------------
150 void DebugFileList::AddElement(uint32_t uniqueid,
151 const std::string &appname,
152 const std::string &filename)
154 DebugFileEntry entry;
156 entry.uniqueId = uniqueid;
157 entry.appName = appname;
158 entry.fileName = filename;
160 push_back(entry);
164 void DebugFileList::Dump(std::ostream &os) const
166 ios_format_state state(os);
168 const_iterator i = begin(), e = end();
170 os << " UniqueID " << "|";
171 os << " Module Name " << "|";
172 os << " File Name " << endl;
174 os << "------------+";
175 os << "--------------------------+";
176 os << "--------------------------";
177 os << endl;
179 for( ; i != e; ++i ) {
180 (*i).Dump(os);
185 void DebugFileEntry::Dump(std::ostream &os) const
187 ios_format_state state(os);
189 os << " 0x" << setfill('0') << setw(8) << hex << uniqueId << " |";
190 os << " " << appName << setfill(' ') << setw(24) << " |";
191 os << " " << fileName << endl;
195 // ClassList class
196 //---------------------------
199 void ClassList::CreateDefaultEntries()
201 ClassEntry entry;
203 // 1
204 entry.classPath = "com.rim.resources";
205 entry.className = "net_rim_rimsecuridlibRIMResources";
206 push_back(entry);
208 // 2
209 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
210 entry.className = "RimSecurIDLib";
211 push_back(entry);
213 // 3
214 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
215 entry.className = "RimDatabaseFullException";
216 push_back(entry);
218 // 4
219 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
220 entry.className = "RimDecryptFailException";
221 push_back(entry);
223 // 5
224 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
225 entry.className = "RimDuplicateNameException";
226 push_back(entry);
228 // 6
229 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
230 entry.className = "RimDuplicateTokenException";
231 push_back(entry);
233 // 7
234 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
235 entry.className = "RimInvalidParamException";
236 push_back(entry);
238 // 8
239 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
240 entry.className = "RimSecurIDLib";
241 push_back(entry);
243 // 9
244 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
245 entry.className = "RimWrongDeviceIDException";
246 push_back(entry);
248 // 10
249 entry.classPath = "net.rim.device.cldc.impl.softtoken.rimsecuridlib";
250 entry.className = "RimWrongFormFactorException";
251 push_back(entry);
255 // CodInfo class
256 //------------------------
258 bool CodInfo::LoadDebugFile(const char *filename)
260 uint32_t field;
262 if (filename == NULL)
263 return false;
265 ifstream file(filename);
267 // Parse header file
268 ParseHeaderSection(file);
270 // Parse type area zone
271 ParseTypeSection(file);
273 // FIXME : ???
274 field = ParseInteger(file); // Read 0x0
275 field = ParseInteger(file); // Read 0x1
277 // FIXME : ???
278 field = ParseInteger(file); // Read 0x0
279 field = ParseInteger(file); // Read 0x0 or 0xA
281 if (field == 0xA) {
282 // Parse ressource area zone
283 ParseResourceSection(file);
286 return true;
290 uint32_t CodInfo::GetUniqueId()
292 return uniqueId;
296 string CodInfo::GetAppName()
298 return appName;
302 // Private API - Section parsing
303 //-------------------------------
305 void CodInfo::ParseHeaderSection(istream &input)
307 uint32_t type;
309 type = ParseNextHeaderField(input);
311 if (type != COD_DEBUG_UNIQUEID_HEADERFIELD)
312 return;
314 type = ParseNextHeaderField(input);
316 if (type != COD_DEBUG_APPNAME_HEADERFIELD)
317 return;
321 void CodInfo::ParseTypeSection(istream &input)
323 uint32_t type;
324 uint32_t count;
325 uint32_t nbr, check;
327 // Read number of declared type content into this section
328 nbr = ParseInteger(input);
330 // Read each object
331 count = 0;
333 while (!input.eof()) {
334 type = ParseNextTypeField(input);
336 if (type == COD_DEBUG_NONE_FIELD)
337 break;
339 count++;
342 // Read again number of declared type content into this section
343 // We have to find the same value
344 check = ParseInteger(input);
346 // Checking... this code only exists in __DEBUG_MODE__ only, so
347 // make sure unused variables are always "used"
348 (void)nbr;
349 (void)check;
350 dout("Nbr = " << dec << nbr << " / Count = " << dec << count << " / check = " << check);
354 void CodInfo::ParseResourceSection(istream &input)
356 uint32_t len;
357 uint32_t type;
358 uint32_t unknown01;
359 uint32_t unknown02;
360 uint32_t unknown03;
361 uint32_t unknown04;
362 uint32_t unknown05;
363 uint32_t unknown06;
364 uint32_t unknown07;
366 string name;
368 // type = 1
369 for (int i=0; i<10; i++) {
370 type = ParseInteger(input);
372 len = ParseInteger(input);
373 name = ParseString(input, len);
375 unknown01 = ParseInteger(input);
376 unknown02 = ParseInteger(input);
377 unknown03 = ParseInteger(input);
379 dout("JDGCodInfo::parseRessource"
380 << "\n Name : " << name
381 << "\n unknown01 : " << hex << unknown01
382 << "\n unknown02 : " << hex << unknown02
383 << "\n unknown03 : " << hex << unknown03);
386 // type = 2
387 type = ParseInteger(input);
389 len = ParseInteger(input);
390 name = ParseString(input, len);
392 unknown01 = ParseInteger(input);
393 unknown02 = ParseInteger(input);
394 unknown03 = ParseInteger(input);
395 unknown04 = ParseInteger(input);
396 unknown05 = ParseInteger(input);
397 unknown06 = ParseInteger(input);
398 unknown07 = ParseInteger(input);
400 dout("JDGCodInfo::parseRessource"
401 << "\n Name : " << name
402 << "\n unknown01 : " << hex << unknown01
403 << "\n unknown02 : " << hex << unknown02
404 << "\n unknown03 : " << hex << unknown03
405 << "\n unknown04 : " << hex << unknown04
406 << "\n unknown05 : " << hex << unknown05
407 << "\n unknown06 : " << hex << unknown06
408 << "\n unknown07 : " << hex << unknown07);
410 // type = 1
411 type = ParseInteger(input);
413 len = ParseInteger(input);
414 name = ParseString(input, len);
416 unknown01 = ParseInteger(input);
417 unknown02 = ParseInteger(input);
418 unknown03 = ParseInteger(input);
419 unknown04 = ParseInteger(input);
421 dout("JDGCodInfo::parseRessource"
422 << "\n Name : " << name
423 << "\n unknown01 : " << hex << unknown01
424 << "\n unknown02 : " << hex << unknown02
425 << "\n unknown03 : " << hex << unknown03
426 << "\n unknown04 : " << hex << unknown04);
428 // type = 0
429 type = ParseInteger(input);
431 len = ParseInteger(input);
432 name = ParseString(input, len);
434 unknown01 = ParseInteger(input);
435 unknown02 = ParseInteger(input);
436 unknown03 = ParseInteger(input);
437 unknown04 = ParseInteger(input);
438 unknown05 = ParseInteger(input);
440 dout("JDGCodInfo::parseRessource"
441 << "\n Name : " << name
442 << "\n unknown01 : " << hex << unknown01
443 << "\n unknown02 : " << hex << unknown02
444 << "\n unknown03 : " << hex << unknown03
445 << "\n unknown04 : " << hex << unknown04
446 << "\n unknown05 : " << hex << unknown05);
448 // make sure that unused variables are always "used" when
449 // not in __DEBUG_MODE__
450 (void)type;
451 (void)unknown01;
452 (void)unknown02;
453 (void)unknown03;
454 (void)unknown04;
455 (void)unknown05;
456 (void)unknown06;
457 (void)unknown07;
462 // Private API - Field parsing
463 //-------------------------------
466 uint32_t CodInfo::ParseNextHeaderField(istream &input)
468 uint32_t type = ParseInteger(input);
470 switch (type) {
471 case COD_DEBUG_UNIQUEID_HEADERFIELD:
472 ParseUniqueId(input);
473 break;
475 case COD_DEBUG_APPNAME_HEADERFIELD:
476 ParseAppName(input);
477 break;
479 default:
480 type = 0xFFFFFFFF;
483 return type;
487 uint32_t CodInfo::ParseNextTypeField(istream &input)
489 uint32_t type = ParseInteger(input);
491 switch (type) {
492 case COD_DEBUG_NONE_FIELD:
493 break;
495 case COD_DEBUG_BOOLEAN_FIELD:
496 ParseBoolean(input);
497 break;
499 case COD_DEBUG_BYTE_FIELD:
500 ParseByte(input);
501 break;
503 case COD_DEBUG_CHAR_FIELD:
504 ParseChar(input);
505 break;
507 case COD_DEBUG_SHORT_FIELD:
508 ParseShort(input);
509 break;
511 case COD_DEBUG_INT_FIELD:
512 ParseInt(input);
513 break;
515 case COD_DEBUG_LONG_FIELD:
516 ParseLong(input);
517 break;
519 case COD_DEBUG_CLASS_FIELD:
520 ParseClass(input);
521 break;
523 case COD_DEBUG_ARRAY_FIELD:
524 ParseArray(input);
525 break;
527 case COD_DEBUG_VOID_FIELD:
528 ParseVoid(input);
529 break;
531 case COD_DEBUG_DOUBLE_FIELD:
532 ParseDouble(input);
533 break;
535 default:
536 dout("Type unknown ! " << hex << type);
537 type = 0xFFFFFFFF;
540 return type;
544 void CodInfo::ParseUniqueId(istream &input)
546 uniqueId = ParseInteger(input);
550 void CodInfo::ParseAppName(istream &input)
552 uint32_t len = ParseInteger(input);
554 appName = ParseString(input, len);
558 void CodInfo::ParseBoolean(istream &input)
560 uint32_t len = ParseInteger(input);
562 string str = ParseString(input, len);
564 dout("JDG::CodInfo::ParseBoolean\n name : " << str);
568 void CodInfo::ParseByte(istream &input)
570 uint32_t len = ParseInteger(input);
572 string str = ParseString(input, len);
574 dout("JDG::CodInfo::ParseByte\n name : " << str);
578 void CodInfo::ParseChar(istream &input)
580 uint32_t len = ParseInteger(input);
582 string str = ParseString(input, len);
584 dout("JDG::CodInfo::ParseChar\n name : " << str);
588 void CodInfo::ParseShort(istream &input)
590 uint32_t len = ParseInteger(input);
592 string str = ParseString(input, len);
594 dout("JDG::CodInfo::ParseShort\n name : " << str);
598 void CodInfo::ParseInt(istream &input)
600 uint32_t len = ParseInteger(input);
602 string str = ParseString(input, len);
604 dout("JDG::CodInfo::ParseInt\n name : " << str);
608 void CodInfo::ParseLong(istream &input)
610 uint32_t len = ParseInteger(input);
612 string str = ParseString(input, len);
614 dout("JDG::CodInfo::ParseLong\n name : " << str);
618 void CodInfo::ParseClass(istream &input)
620 uint32_t len;
622 ClassEntry object;
624 dout("JDG::CodInfo::ParseClass");
626 len = ParseInteger(input);
628 object.className = ParseString(input, len);
630 object.type = ParseInteger(input);
631 object.unknown02 = ParseInteger(input);
632 object.unknown03 = ParseInteger(input);
633 object.id = ParseInteger(input);
635 len = ParseInteger(input);
637 if (len == 0)
638 object.classPath = "com.barry." + appName;
639 else if (len != 0xFFFFFF)
640 object.classPath = ParseString(input, len);
642 len = ParseInteger(input);
644 object.sourceFile = ParseString(input, len);
646 object.unknown05 = ParseInteger(input);
647 object.unknown06 = ParseInteger(input);
648 object.unknown07 = ParseInteger(input);
649 object.unknown08 = ParseInteger(input);
651 classList.push_back(object);
653 dout("\n name : " << object.className
654 << "\n path : " << object.classPath
655 << "\n type : " << hex << object.type
656 << "\n unknown02 : " << hex << object.unknown02
657 << "\n unknown03 : " << hex << object.unknown03
658 << "\n id : " << hex << object.id
659 << "\n source file : " << object.sourceFile
660 << "\n unknown05 : " << hex << object.unknown05
661 << "\n unknown06 : " << hex << object.unknown06
662 << "\n unknown07 : " << hex << object.unknown07
663 << "\n unknown08 : " << hex << object.unknown08);
667 void CodInfo::ParseArray(istream &input)
669 uint32_t len = ParseInteger(input);
671 string str = ParseString(input, len);
673 dout("JDG::CodInfo::ParseArray\n name : " << str);
677 void CodInfo::ParseVoid(istream &input)
679 uint32_t len = ParseInteger(input);
681 string str = ParseString(input, len);
683 dout("JDG::CodInfo::ParseVoid\n name : " << str);
687 void CodInfo::ParseDouble(istream &input)
689 uint32_t len = ParseInteger(input);
691 string str = ParseString(input, len);
693 dout("JDG::CodInfo::ParseDouble\n name : " << str);
697 void CodInfo::ParseType2(istream &input) {
698 uint32_t value;
699 uint32_t len = ParseInteger(input);
701 string str = ParseString(input, len);
703 dout("Type2 : " << str);
705 value = ParseInteger(input);
706 value = ParseInteger(input);
707 value = ParseInteger(input);
708 value = ParseInteger(input);
709 value = ParseInteger(input);
710 value = ParseInteger(input);
713 } // namespace JDG
715 } // namespace Barry