|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 /** |
|
20 @file |
|
21 @internalComponent |
|
22 @released |
|
23 */ |
|
24 |
|
25 #include "romreader.h" |
|
26 #include "romfsentry.h" |
|
27 #include "romimageheader.h" |
|
28 #include <e32rom.h> |
|
29 #include <e32ldr.h> |
|
30 #include <iostream> |
|
31 #include <algorithm> |
|
32 #include <functional> |
|
33 |
|
34 void InflateUnCompress(unsigned char* source, int sourcesize, unsigned char* dest, int destsize); |
|
35 |
|
36 /** |
|
37 Static variable to mark whether TRomLoaderHeader is present in the ROM image or not. |
|
38 |
|
39 @internalComponent |
|
40 @released |
|
41 */ |
|
42 bool RomReader::iNoRomLoaderHeader = false; |
|
43 |
|
44 /** |
|
45 Constructor intializes the class pointer members and member variables. |
|
46 |
|
47 @internalComponent |
|
48 @released |
|
49 |
|
50 @param aFile - image file name |
|
51 @param aImageType - image type |
|
52 */ |
|
53 RomReader::RomReader(const char* aFile, EImageType aImgType) |
|
54 : ImageReader(aFile), iImageHeader(0), iData(0), iImgType(aImgType) |
|
55 { |
|
56 iRomImageRootDirEntry = new RomImageDirEntry(""); |
|
57 } |
|
58 |
|
59 /** |
|
60 Destructor deletes the class pointer members. |
|
61 |
|
62 @internalComponent |
|
63 @released |
|
64 */ |
|
65 RomReader::~RomReader() |
|
66 { |
|
67 delete [] iData; |
|
68 iRomImageRootDirEntry->Destroy(); |
|
69 iRomImageRootDirEntry = 0; |
|
70 DELETE(iImageHeader); |
|
71 iRootDirList = 0; |
|
72 iExeVsRomFsEntryMap.clear(); |
|
73 } |
|
74 |
|
75 /** |
|
76 Function responsible to read the whole image and assign it to an member |
|
77 |
|
78 @internalComponent |
|
79 @released |
|
80 */ |
|
81 void RomReader::ReadImage() |
|
82 { |
|
83 iInputStream.open(iImgFileName.c_str(), Ios::binary | Ios::in); |
|
84 if(!iInputStream.is_open()) |
|
85 { |
|
86 cout << "Error: " << "Can not open file: " << ImageName().c_str() << endl; |
|
87 exit(EXIT_FAILURE); |
|
88 } |
|
89 iInputStream.seekg(0, Ios::end); |
|
90 iImageSize = iInputStream.tellg(); |
|
91 iData = new unsigned char[iImageSize]; |
|
92 memset(iData, 0, iImageSize); |
|
93 iInputStream.seekg(0, Ios::beg); |
|
94 iInputStream.read((char*)iData, iImageSize); |
|
95 iInputStream.close(); |
|
96 } |
|
97 |
|
98 |
|
99 /** |
|
100 Function responsible to return the compression type |
|
101 Can handle ROM and Extension ROM images. |
|
102 |
|
103 @internalComponent |
|
104 @released |
|
105 |
|
106 @return - returns the compression type |
|
107 */ |
|
108 const unsigned long int RomReader::ImageCompressionType() const |
|
109 { |
|
110 if(iImageHeader->iRomHdr) |
|
111 return iImageHeader->iRomHdr->iCompressionType; |
|
112 else |
|
113 return iImageHeader->iExtRomHdr->iCompressionType; |
|
114 } |
|
115 |
|
116 |
|
117 /** |
|
118 Function responsible to return the Rom header pointer address |
|
119 Can handle ROM and Extension ROM images. |
|
120 |
|
121 @internalComponent |
|
122 @released |
|
123 |
|
124 @return - returns the Rom header pointer address |
|
125 */ |
|
126 const char* RomReader::RomHdrPtr() const |
|
127 { |
|
128 if(iImageHeader->iRomHdr) |
|
129 return (char*)(iImageHeader->iRomHdr); |
|
130 else |
|
131 return (char*)(iImageHeader->iExtRomHdr); |
|
132 } |
|
133 |
|
134 |
|
135 /** |
|
136 Function responsible to return the Rom base address in the image |
|
137 Can handle ROM and Extension ROM images. |
|
138 |
|
139 @internalComponent |
|
140 @released |
|
141 |
|
142 @return - returns the Rom base address |
|
143 */ |
|
144 const unsigned long int RomReader::RomBase() const |
|
145 { |
|
146 if(iImageHeader->iRomHdr) |
|
147 return iImageHeader->iRomHdr->iRomBase ; |
|
148 else |
|
149 return iImageHeader->iExtRomHdr->iRomBase; |
|
150 } |
|
151 |
|
152 |
|
153 /** |
|
154 Function responsible to return the Rom root directory list |
|
155 Can handle ROM and Extension ROM images. |
|
156 |
|
157 @internalComponent |
|
158 @released |
|
159 |
|
160 @return - returns the Rom root directory list |
|
161 */ |
|
162 const unsigned long int RomReader::RootDirList() const |
|
163 { |
|
164 if(iImageHeader->iRomHdr) |
|
165 return iImageHeader->iRomHdr->iRomRootDirectoryList; |
|
166 else |
|
167 return iImageHeader->iExtRomHdr->iRomRootDirectoryList; |
|
168 } |
|
169 |
|
170 |
|
171 /** |
|
172 Function responsible to return the Rom header size |
|
173 Can handle ROM and Extension ROM images. |
|
174 |
|
175 @internalComponent |
|
176 @released |
|
177 |
|
178 @return - returns the Rom header size |
|
179 */ |
|
180 const unsigned int RomReader::HdrSize() const |
|
181 { |
|
182 if(iImageHeader->iRomHdr) |
|
183 return (sizeof(TRomLoaderHeader) + sizeof(TRomHeader)); |
|
184 else |
|
185 return sizeof(TExtensionRomHeader); |
|
186 } |
|
187 |
|
188 /** |
|
189 Function responsible to return the Rom image size |
|
190 Can handle ROM and Extension ROM images. |
|
191 |
|
192 @internalComponent |
|
193 @released |
|
194 |
|
195 @return - returns the Rom Image size |
|
196 */ |
|
197 const unsigned int RomReader::ImgSize() const |
|
198 { |
|
199 if(ImageCompressionType() == KUidCompressionDeflate) |
|
200 return iImageHeader->iRomHdr->iUncompressedSize; |
|
201 else |
|
202 return iImageSize; |
|
203 } |
|
204 |
|
205 /** |
|
206 Function responsible to process the ROM image |
|
207 1. Read the header. |
|
208 2. Identify the compression type. |
|
209 3. If the image is compressed then uncompress and update the image content buffer iData. |
|
210 4. Build the directory tree by reading all the Rood and subdirectory elements. |
|
211 |
|
212 @internalComponent |
|
213 @released |
|
214 */ |
|
215 void RomReader::ProcessImage() |
|
216 { |
|
217 if(iImageSize > sizeof(TRomLoaderHeader) || iImageSize > sizeof(TExtensionRomHeader)) |
|
218 { |
|
219 iImageHeader = new RomImageHeader((char*)iData, iImgType, iNoRomLoaderHeader); |
|
220 |
|
221 if(ImageCompressionType() == KUidCompressionDeflate) |
|
222 { |
|
223 unsigned int aDataStart = HdrSize(); |
|
224 unsigned char* aData = new unsigned char[iImageHeader->iRomHdr->iUncompressedSize + aDataStart]; |
|
225 InflateUnCompress((iData + aDataStart), iImageHeader->iRomHdr->iCompressedSize, (aData + aDataStart), iImageHeader->iRomHdr->iUncompressedSize); |
|
226 memcpy(aData, iData, aDataStart); |
|
227 delete [] iData; |
|
228 |
|
229 iData = aData; |
|
230 //update the header fields... |
|
231 if(iImgType == ERomImage) |
|
232 { |
|
233 iImageHeader->iLoaderHdr = (TRomLoaderHeader*)iData; |
|
234 iImageHeader->iRomHdr = (TRomHeader*)(iData + sizeof(TRomLoaderHeader)); |
|
235 } |
|
236 } |
|
237 else if(ImageCompressionType() != 0) |
|
238 { |
|
239 std::cout << "Error: Invalid image: " << ImageName() << std::endl; |
|
240 exit(EXIT_FAILURE); |
|
241 } |
|
242 else if (iImageHeader->iRomHdr && iImageHeader->iRomHdr->iRomPageIndex) // paged ROM |
|
243 { |
|
244 const int KPageSize = 0x1000; |
|
245 TRomHeader *pRomHdr = iImageHeader->iRomHdr; |
|
246 unsigned int headerSize = HdrSize(); |
|
247 |
|
248 TInt numPages = (pRomHdr->iPageableRomStart + pRomHdr->iPageableRomSize+KPageSize-1)/KPageSize; |
|
249 unsigned char* aData = new unsigned char[pRomHdr->iUncompressedSize + headerSize]; |
|
250 unsigned char* dest = aData + sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart; |
|
251 SRomPageInfo* pi = (SRomPageInfo*)((unsigned char*)pRomHdr + pRomHdr->iRomPageIndex); |
|
252 CBytePair bpe(EFalse); |
|
253 |
|
254 for(int i = 0; i < numPages; i++, pi++) |
|
255 { |
|
256 if (pi->iPagingAttributes != SRomPageInfo::EPageable) // skip uncompressed part at the beginning of ROM image |
|
257 continue; |
|
258 |
|
259 switch(pi->iCompressionType) |
|
260 { |
|
261 case SRomPageInfo::ENoCompression: |
|
262 memcpy(dest, (unsigned char*)pRomHdr + pi->iDataStart, pi->iDataSize); |
|
263 dest += pi->iDataSize; |
|
264 break; |
|
265 |
|
266 case SRomPageInfo::EBytePair: |
|
267 { |
|
268 unsigned char* srcNext = 0; |
|
269 int unpacked = bpe.Decompress(dest, KPageSize, (unsigned char*)pRomHdr + pi->iDataStart, pi->iDataSize, srcNext); |
|
270 if (unpacked < 0) |
|
271 { |
|
272 delete [] aData; |
|
273 std::cout << "Error:" << "Corrupted BytePair compressed ROM image" << std::endl; |
|
274 exit(EXIT_FAILURE); |
|
275 } |
|
276 |
|
277 dest += unpacked; |
|
278 break; |
|
279 } |
|
280 |
|
281 default: |
|
282 delete [] aData; |
|
283 std::cout << "Error:" << "Undefined compression type" << std::endl; |
|
284 exit(EXIT_FAILURE); |
|
285 } |
|
286 } |
|
287 |
|
288 memcpy(aData, iData, sizeof(TRomLoaderHeader) + pRomHdr->iPageableRomStart); |
|
289 delete [] iData; |
|
290 |
|
291 iData = aData; |
|
292 |
|
293 //update the header fields... |
|
294 if(iImgType == ERomImage) |
|
295 { |
|
296 iImageHeader->iLoaderHdr = (TRomLoaderHeader*)iData; |
|
297 iImageHeader->iRomHdr = (TRomHeader*)(iData + sizeof(TRomLoaderHeader)); |
|
298 } |
|
299 } |
|
300 |
|
301 unsigned long int aOff = RootDirList() - RomBase(); |
|
302 iRootDirList = (TRomRootDirectoryList*)(RomHdrPtr() + aOff); |
|
303 int aDirs = 0; |
|
304 TRomDir *aRomDir; |
|
305 while(aDirs < iRootDirList->iNumRootDirs) |
|
306 { |
|
307 aOff = iRootDirList->iRootDir[aDirs].iAddressLin - RomBase(); |
|
308 aRomDir = (TRomDir*)(RomHdrPtr() + aOff); |
|
309 |
|
310 BuildDir(aRomDir, iRomImageRootDirEntry); |
|
311 aDirs++; |
|
312 } |
|
313 } |
|
314 else |
|
315 { |
|
316 std::cout << "Error: " << "Invalid image: " << iImgFileName.c_str() << std::endl; |
|
317 exit(EXIT_FAILURE); |
|
318 } |
|
319 } |
|
320 |
|
321 |
|
322 /** |
|
323 Function responsible to Get Rom directory table |
|
324 |
|
325 @internalComponent |
|
326 @released |
|
327 |
|
328 @param aBase - base poniter |
|
329 @param aCount - No of entries in the table |
|
330 @param aRomDir - Current Rom directory. |
|
331 */ |
|
332 void RomReader::GetRomDirTbl(short int** aBase, short int& aCount, TRomDir *aRomDir) |
|
333 { |
|
334 short int *aSubDirCnt = 0; |
|
335 short int *aFileCnt = 0; |
|
336 |
|
337 //Sub directories in this directories |
|
338 aSubDirCnt = (short int*)((char*)aRomDir + aRomDir->iSize + sizeof(aRomDir->iSize)); |
|
339 //Files within this directory |
|
340 aFileCnt = aSubDirCnt+1; |
|
341 aCount = (*aFileCnt + *aSubDirCnt); |
|
342 *aBase = aFileCnt+1; |
|
343 } |
|
344 |
|
345 |
|
346 /** |
|
347 Function responsible to Build directory tree. |
|
348 |
|
349 @internalComponent |
|
350 @released |
|
351 |
|
352 @param aDir - directory |
|
353 @param aPaFSEntry - Parent RomImageFSEntry |
|
354 */ |
|
355 void RomReader::BuildDir(TRomDir* aDir, RomImageFSEntry* aPaFSEntry) |
|
356 { |
|
357 |
|
358 short int *aBase, aCount; |
|
359 |
|
360 GetRomDirTbl(&aBase, aCount, aDir); |
|
361 /**Images built using option -no-sorted-romfs are compatible with Symbian OS v6.1. |
|
362 But imgcheck tool supports only Symbian OS v9.1 to Future versions. |
|
363 */ |
|
364 if(aCount <= 0) |
|
365 { |
|
366 cerr << "Error: Invalid Image " << iImgFileName.c_str() << endl; |
|
367 exit(EXIT_FAILURE); |
|
368 } |
|
369 BuildDir(aBase, aCount, aDir, aPaFSEntry); |
|
370 } |
|
371 |
|
372 |
|
373 /** |
|
374 Function responsible to add the read directory or file into tree. |
|
375 |
|
376 @internalComponent |
|
377 @released |
|
378 |
|
379 @param aOffsetTbl - Table offset |
|
380 @param aOffsetTblCount - No of entries in the table |
|
381 @param aPaRomDir - Parent TRomDir |
|
382 @param aPaFSEntry - Parent RomImageFSEntry |
|
383 */ |
|
384 void RomReader::BuildDir(short int *aOffsetTbl, short int aOffsetTblCount, |
|
385 TRomDir *aPaRomDir, RomImageFSEntry* aPaFSEntry) |
|
386 { |
|
387 RomImageFSEntry *aNewFSEntry; |
|
388 TRomDir *aNewDir; |
|
389 TRomEntry *aRomEntry; |
|
390 unsigned long int aOffsetFromBase; |
|
391 unsigned int aOffset; |
|
392 String aName; |
|
393 char *aPtr; |
|
394 |
|
395 while(aOffsetTblCount--) |
|
396 { |
|
397 aOffsetFromBase = *aOffsetTbl; |
|
398 aOffsetFromBase <<= 2; |
|
399 aRomEntry = (TRomEntry*)((char*)aPaRomDir + sizeof(int) + aOffsetFromBase); |
|
400 aPtr = (char*)aRomEntry->iName; |
|
401 Name(aName, aPtr, aRomEntry->iNameLength); |
|
402 |
|
403 if(aRomEntry->iAtt & 0x10)//KEntryAttDir |
|
404 { |
|
405 aNewFSEntry = new RomImageDirEntry((char*)aName.data()); |
|
406 AddChild(aPaFSEntry, aNewFSEntry, KNull); |
|
407 |
|
408 aOffset = aRomEntry->iAddressLin - RomBase(); |
|
409 aNewDir = (TRomDir*)(RomHdrPtr() + aOffset); |
|
410 BuildDir(aNewDir, aNewFSEntry); |
|
411 } |
|
412 else |
|
413 { |
|
414 aNewFSEntry = new RomImageFileEntry((char*)aName.data()); |
|
415 AddChild(aPaFSEntry, aNewFSEntry, aRomEntry); |
|
416 } |
|
417 aOffsetTbl++; |
|
418 } |
|
419 } |
|
420 |
|
421 |
|
422 /** |
|
423 Function responsible to add current entry as child to aPa. |
|
424 |
|
425 @internalComponent |
|
426 @released |
|
427 |
|
428 @param aPa - Parent RomImageFSEntry. |
|
429 @param aChild - child RomImageFSEntry. |
|
430 @param aRomEntry - Current entry. |
|
431 */ |
|
432 void RomReader::AddChild(RomImageFSEntry *aPa, RomImageFSEntry *aChild, TRomEntry* aRomEntry) |
|
433 { |
|
434 if(!aPa->iChildren) |
|
435 { |
|
436 aPa->iChildren = aChild; |
|
437 } |
|
438 else |
|
439 { |
|
440 RomImageFSEntry *aLast = aPa->iChildren; |
|
441 while(aLast->iSibling) |
|
442 aLast = aLast->iSibling; |
|
443 |
|
444 aLast->iSibling = aChild; |
|
445 } |
|
446 |
|
447 if(!aChild->IsDirectory()) |
|
448 { |
|
449 TRomImageHeader* aImgHdr; |
|
450 unsigned long int aOff; |
|
451 RomImageFileEntry* entry = (RomImageFileEntry*)aChild; |
|
452 entry->iTRomEntryPtr = aRomEntry; |
|
453 if(aRomEntry->iAddressLin > RomBase()) |
|
454 { |
|
455 aOff = aRomEntry->iAddressLin - RomBase(); |
|
456 aImgHdr = (TRomImageHeader*)(RomHdrPtr() + aOff); |
|
457 entry->ImagePtr.iRomFileEntry = aImgHdr; |
|
458 unsigned char aUid1[4]; |
|
459 memcpy(aUid1, &((RomImageFileEntry*)aChild)->ImagePtr.iRomFileEntry->iUid1, 4); |
|
460 |
|
461 //Skip the E32 executables included as a DATA files in ROM image. |
|
462 if(ReaderUtil::IsExecutable(aUid1) && aImgHdr->iCodeAddress > RomBase() && |
|
463 aImgHdr->iCodeAddress < (RomBase() + ImgSize())) |
|
464 { |
|
465 iExeAvailable = true; |
|
466 entry->iExecutable = true; |
|
467 iExeVsRomFsEntryMap.insert(std::make_pair(entry->iName, aChild)); |
|
468 } |
|
469 else |
|
470 { |
|
471 entry->iExecutable = false; |
|
472 entry->ImagePtr.iDataFileAddr = aRomEntry->iAddressLin; |
|
473 } |
|
474 } |
|
475 else |
|
476 { |
|
477 entry->ImagePtr.iRomFileEntry = KNull; |
|
478 } |
|
479 } |
|
480 if(aPa != iRomImageRootDirEntry) |
|
481 { |
|
482 aChild->iPath = aPa->iPath; |
|
483 aChild->iPath += KDirSeperaor; |
|
484 aChild->iPath += aPa->iName.data(); |
|
485 } |
|
486 } |
|
487 |
|
488 |
|
489 /** |
|
490 Function responsible to return the complete name by taking its unicode and length. |
|
491 |
|
492 @internalComponent |
|
493 @released |
|
494 |
|
495 @param aName - Name to be returned |
|
496 @param aUnicodeName - Unicode name |
|
497 @param aLen - Length of the name |
|
498 */ |
|
499 void RomReader::Name(String& aName, const char * aUnicodeName, const int aLen) |
|
500 { |
|
501 int aPos = 0; |
|
502 int uncodeLen = aLen << 1; |
|
503 aName = (""); |
|
504 while(aPos < uncodeLen) |
|
505 { |
|
506 if(aUnicodeName[aPos]) |
|
507 aName += aUnicodeName[aPos]; |
|
508 aPos++; |
|
509 } |
|
510 } |
|
511 |
|
512 /** |
|
513 Function responsible to prepare Executable List by traversing through iExeVsRomFsEntryMap |
|
514 |
|
515 @internalComponent |
|
516 @released |
|
517 */ |
|
518 void RomReader::PrepareExecutableList() |
|
519 { |
|
520 ExeVsRomFsEntryMap::iterator exeBegin = iExeVsRomFsEntryMap.begin(); |
|
521 ExeVsRomFsEntryMap::iterator exeEnd = iExeVsRomFsEntryMap.end(); |
|
522 while(exeBegin != exeEnd) |
|
523 { |
|
524 String str = exeBegin->first; |
|
525 iExecutableList.push_back(ReaderUtil::ToLower(str)); |
|
526 ++exeBegin; |
|
527 } |
|
528 } |
|
529 |
|
530 /** |
|
531 Function responsible to create address vs executable map. |
|
532 Later this address is used as a key to get executable name |
|
533 |
|
534 @internalComponent |
|
535 @released |
|
536 */ |
|
537 void RomReader::PrepareAddVsExeMap() |
|
538 { |
|
539 ExeVsRomFsEntryMap::iterator exeBegin = iExeVsRomFsEntryMap.begin(); |
|
540 ExeVsRomFsEntryMap::iterator exeEnd = iExeVsRomFsEntryMap.end(); |
|
541 while(exeBegin != exeEnd) |
|
542 { |
|
543 UintVsString sizeVsExeName; |
|
544 unsigned int address; |
|
545 RomImageFileEntry* fileEntry = (RomImageFileEntry*)exeBegin->second; |
|
546 TRomImageHeader *aRomImgEntry = fileEntry->ImagePtr.iRomFileEntry; |
|
547 if(aRomImgEntry != KNull) |
|
548 { |
|
549 address = aRomImgEntry->iCodeAddress; |
|
550 sizeVsExeName[aRomImgEntry->iCodeSize] = ReaderUtil::ToLower(exeBegin->second->iName); |
|
551 } |
|
552 else |
|
553 { |
|
554 address = fileEntry->iTRomEntryPtr->iAddressLin; |
|
555 sizeVsExeName[fileEntry->iTRomEntryPtr->iSize] = ReaderUtil::ToLower(exeBegin->second->iName); |
|
556 } |
|
557 iAddVsExeMap.insert(std::make_pair(address, sizeVsExeName)); |
|
558 iImageAddress.push_back(address); |
|
559 ++exeBegin; |
|
560 } |
|
561 std::sort(iImageAddress.begin(), iImageAddress.end(), std::greater < unsigned int>()); |
|
562 } |
|
563 |
|
564 /** |
|
565 Function responsible to say whether it is an ROM image or not. |
|
566 |
|
567 @internalComponent |
|
568 @released |
|
569 |
|
570 @param aWord - which has the identifier string |
|
571 @return - returns true or false. |
|
572 */ |
|
573 bool RomReader::IsRomImage(const String& aWord) |
|
574 { |
|
575 //Epoc Identifier should start at 0th location, Rom Identifier should start at 8th location |
|
576 if((aWord.find(KEpocIdentifier) == 0) && (aWord.find(KRomImageIdentifier) == 8)) |
|
577 { |
|
578 return true; |
|
579 } |
|
580 else |
|
581 { |
|
582 iNoRomLoaderHeader = true; |
|
583 //TRomLoaderHeader is not present |
|
584 TRomHeader *romHdr = (TRomHeader*)aWord.c_str(); |
|
585 /**If the ROM image is built without TRomLoaderHeaderi, ROM specific identifier will not be available |
|
586 hence these two header variables used.*/ |
|
587 if((romHdr->iRomBase >= KRomBase) && (romHdr->iRomRootDirectoryList > KRomBase) |
|
588 && (romHdr->iRomBase < KRomBaseMaxLimit) && (romHdr->iRomRootDirectoryList < KRomBaseMaxLimit)) |
|
589 { |
|
590 return true; |
|
591 } |
|
592 } |
|
593 return false; |
|
594 } |
|
595 |
|
596 /** |
|
597 Function responsible to say whether it is an ROM extension image or not. |
|
598 |
|
599 @internalComponent |
|
600 @released |
|
601 |
|
602 @param aWord - which has the identifier string |
|
603 @return - retruns true or false. |
|
604 */ |
|
605 bool RomReader::IsRomExtImage(const String& aWord) |
|
606 { |
|
607 if(aWord.at(0) == KNull && aWord.at(1) == KNull && |
|
608 aWord.at(2) == KNull && aWord.at(3) == KNull && |
|
609 aWord.at(4) == KNull && aWord.at(5) == KNull) |
|
610 { |
|
611 //Since no specific identifier is present in the ROM Extension image these two header variables used. |
|
612 TExtensionRomHeader* romHdr = (TExtensionRomHeader*)aWord.c_str(); |
|
613 if((romHdr->iRomBase > KRomBase) && (romHdr->iRomRootDirectoryList > KRomBase) |
|
614 && (romHdr->iRomBase < KRomBaseMaxLimit) && (romHdr->iRomRootDirectoryList < KRomBaseMaxLimit)) |
|
615 { |
|
616 return true; |
|
617 } |
|
618 } |
|
619 return false; |
|
620 } |
|
621 |
|
622 /** |
|
623 Function responsible to gather dependencies for all the executables. |
|
624 |
|
625 @internalComponent |
|
626 @released |
|
627 |
|
628 @return iImageVsDepList - returns all executable's dependencies |
|
629 */ |
|
630 ExeNamesVsDepListMap& RomReader::GatherDependencies() |
|
631 { |
|
632 PrepareAddVsExeMap(); |
|
633 ExeVsRomFsEntryMap::iterator exeBegin = iExeVsRomFsEntryMap.begin(); |
|
634 ExeVsRomFsEntryMap::iterator exeEnd = iExeVsRomFsEntryMap.end(); |
|
635 while(exeBegin != exeEnd) |
|
636 { |
|
637 if(((RomImageFileEntry*)exeBegin->second)->iTRomEntryPtr->iAddressLin > RomBase()) |
|
638 { |
|
639 StringList importExecutableNameList; |
|
640 CollectImportExecutableNames(exeBegin->second, importExecutableNameList); |
|
641 iImageVsDepList.insert(std::make_pair(exeBegin->second->iName, importExecutableNameList)); |
|
642 } |
|
643 ++exeBegin; |
|
644 } |
|
645 return iImageVsDepList; |
|
646 } |
|
647 |
|
648 /** |
|
649 Function responsible to read the dependency names. |
|
650 |
|
651 @internalComponent |
|
652 @released |
|
653 |
|
654 @param aRomReader - ROM reader pointer |
|
655 @param aEntry - Current RomImageFSEntry |
|
656 @param aImportExecutableNameList - Executable list.(output) |
|
657 */ |
|
658 void RomReader::CollectImportExecutableNames(const RomImageFSEntry* aEntry, StringList& aImportExecutableNameList) |
|
659 { |
|
660 unsigned int sectionOffset = 0; |
|
661 unsigned int codeSize = 0; |
|
662 unsigned int dependencyAddress = 0; |
|
663 unsigned int* codeSection = 0; |
|
664 bool patternFound = false; |
|
665 |
|
666 RomImageFileEntry* fileEntry = (RomImageFileEntry*)aEntry; |
|
667 TRomImageHeader *romImgEntry = fileEntry->ImagePtr.iRomFileEntry; |
|
668 sectionOffset = romImgEntry->iCodeAddress - RomBase(); |
|
669 codeSection = (unsigned int*)((char*)RomHdrPtr() + sectionOffset); |
|
670 codeSize = romImgEntry->iCodeSize; |
|
671 |
|
672 UintVsString* CodeSizeVsExeNameAddress = 0; |
|
673 RomAddrVsExeName::iterator addVsSizeExeName; |
|
674 UintVsString::iterator CodeSizeVsExeName; |
|
675 // Checking for LDR Instruction in PLT section(Inside Code section) |
|
676 // to get the import address. |
|
677 while(codeSize > 0) |
|
678 { |
|
679 if(*codeSection++ == KLdrOpcode) |
|
680 { |
|
681 patternFound = true; |
|
682 dependencyAddress = *codeSection++; |
|
683 addVsSizeExeName = iAddVsExeMap.find(CodeSectionAddress(dependencyAddress)); |
|
684 CodeSizeVsExeNameAddress = &addVsSizeExeName->second; |
|
685 CodeSizeVsExeName = CodeSizeVsExeNameAddress->begin(); |
|
686 if(!(dependencyAddress < (addVsSizeExeName->first + CodeSizeVsExeName->first))) |
|
687 { |
|
688 aImportExecutableNameList.push_back(KUnknownDependency); |
|
689 } |
|
690 else |
|
691 { |
|
692 aImportExecutableNameList.push_back(CodeSizeVsExeName->second); |
|
693 } |
|
694 } |
|
695 else |
|
696 { |
|
697 if(patternFound == true) |
|
698 { |
|
699 break; |
|
700 } |
|
701 } |
|
702 --codeSize; |
|
703 } |
|
704 aImportExecutableNameList.sort(); |
|
705 aImportExecutableNameList.unique(); |
|
706 } |
|
707 typedef std::iterator_traits<VectorList::iterator>::difference_type Distance; |
|
708 static VectorList::iterator get_lower_bound(VectorList aVec, const unsigned int& aVal){ |
|
709 VectorList::iterator first = aVec.begin(); |
|
710 VectorList::iterator last = aVec.end(); |
|
711 Distance len = std::distance(first, last); |
|
712 Distance half; |
|
713 VectorList::iterator middle; |
|
714 |
|
715 while (len > 0) { |
|
716 half = len >> 1; |
|
717 middle = first; |
|
718 std::advance(middle, half); |
|
719 if (*middle > aVal) { |
|
720 first = middle; |
|
721 ++first; |
|
722 len = len - half - 1; |
|
723 } |
|
724 else |
|
725 len = half; |
|
726 } |
|
727 return first; |
|
728 } |
|
729 |
|
730 |
|
731 /** |
|
732 Function responsible to read the dependency address from the Exe Map container. |
|
733 |
|
734 @internalComponent |
|
735 @released |
|
736 |
|
737 @param aImageAddress - Dependency address (function address) |
|
738 @returns - e32image start address(code section). |
|
739 */ |
|
740 unsigned int RomReader::CodeSectionAddress(unsigned int& aImageAddress) |
|
741 { |
|
742 /* |
|
743 This invocation leads to a warning, due to the stlport implememtation |
|
744 VectorList::iterator lowerAddress = std::lower_bound(iImageAddress.begin(), |
|
745 iImageAddress.end(), aImageAddress, std::greater <unsigned int>()); |
|
746 */ |
|
747 |
|
748 VectorList::iterator lowerAddress = get_lower_bound(iImageAddress,aImageAddress); |
|
749 return *lowerAddress; |
|
750 } |
|
751 |
|
752 /** |
|
753 Function responsible to fill iExeVsIdData and iSidVsExeName containers. |
|
754 |
|
755 @internalComponent |
|
756 @released |
|
757 |
|
758 @param iRomImageRootDirEntry - Root directory entry |
|
759 @param iExeVsIdData - Container |
|
760 @param iSidVsExeName - Container |
|
761 */ |
|
762 void RomReader::PrepareExeVsIdMap() |
|
763 { |
|
764 ExeVsRomFsEntryMap::iterator exeBegin = iExeVsRomFsEntryMap.begin(); |
|
765 ExeVsRomFsEntryMap::iterator exeEnd = iExeVsRomFsEntryMap.end(); |
|
766 IdData* id = KNull; |
|
767 RomImageFileEntry* entry = KNull; |
|
768 if(iExeVsIdData.size() == 0) //Is not already prepared |
|
769 { |
|
770 while(exeBegin != exeEnd) |
|
771 { |
|
772 id = new IdData; |
|
773 entry = (RomImageFileEntry*)exeBegin->second; |
|
774 id->iUid = entry->ImagePtr.iRomFileEntry->iUid1; |
|
775 id->iDbgFlag = (entry->ImagePtr.iRomFileEntry->iFlags & KImageDebuggable) ? true : false; |
|
776 if(entry->iTRomEntryPtr->iAddressLin > RomBase()) |
|
777 { |
|
778 String& exeName = exeBegin->second->iName; |
|
779 //This header contains the SID and VID, so create the instance of IdData. |
|
780 TRomImageHeader *aRomImgEntry = entry->ImagePtr.iRomFileEntry; |
|
781 |
|
782 id->iSid = aRomImgEntry->iS.iSecureId; |
|
783 id->iVid = aRomImgEntry->iS.iVendorId; |
|
784 id->iFileOffset = aRomImgEntry->iEntryPoint; |
|
785 iExeVsIdData[exeName] = id; |
|
786 } |
|
787 ++exeBegin; |
|
788 } |
|
789 } |
|
790 id = KNull; |
|
791 } |
|
792 |
|
793 /** |
|
794 Function responsible to return the Executable versus IdData container. |
|
795 |
|
796 @internalComponent |
|
797 @released |
|
798 |
|
799 @return - returns iExeVsIdData |
|
800 */ |
|
801 const ExeVsIdDataMap& RomReader::GetExeVsIdMap() const |
|
802 { |
|
803 return iExeVsIdData; |
|
804 } |