1 //****************************************************************************
3 //** Copyright (C) 2006 Intel Corporation. All rights reserved.
5 //** The information and source code contained herein is the exclusive
6 //** property of Intel Corporation and may not be disclosed, examined
7 //** or reproduced in whole or in part without explicit written authorization
10 //****************************************************************************
24 #include "ProcessorBind.h"
29 putUINT64(UINT64 ullVal
) : m_ull(ullVal
) {}
30 putUINT64(const putUINT64
& r
) : m_ull(r
.m_ull
) {}
32 template <class _E
, class _Tr
>
33 friend basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>&, putUINT64
);
39 template <class _E
, class _Tr
>
40 basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>& os
, putUINT64 ull
)
42 static const char cDigits
[] = "0123456789abcdef";
45 if (os
.flags() & ios_base::hex
)
47 else if (os
.flags() & ios_base::oct
)
51 UINT64 ullVal
= ull
.m_ull
;
54 ostr
<< cDigits
[ullVal
% base
];
58 string
s1(ostr
.str());
59 string
s2(s1
.rbegin(), s1
.rend());
66 getUINT64(UINT64
& ullVal
) : m_ull(ullVal
) {}
67 getUINT64(const getUINT64
& r
) : m_ull(r
.m_ull
) {}
69 template <class _E
, class _Tr
>
70 friend basic_istream
<_E
, _Tr
>& operator >> (basic_istream
<_E
, _Tr
>&, getUINT64
);
76 getUINT64
& operator = (const getUINT64
&);
79 template <class _E
, class _Tr
>
80 basic_istream
<_E
, _Tr
>& operator >> (basic_istream
<_E
, _Tr
>& is
, getUINT64 ull
)
86 if (is
.flags() & ios_base::hex
)
88 else if (is
.flags() & ios_base::oct
)
92 for (string::iterator i
= strBuf
.begin(); i
!= strBuf
.end(); i
++)
94 if (*i
<= '9' && *i
>= '0')
96 else if (*i
<= 'F' && *i
>= 'A')
98 else if (*i
<= 'f' && *i
>= 'a')
100 else throw runtime_error("Invalid number format");
102 ullVal
= ullVal
* base
+ *i
;
108 class EMemoryLeak
: public logic_error
111 EMemoryLeak() : logic_error("Memory leak detected") {}
114 class EInvalidGuidString
: public invalid_argument
117 EInvalidGuidString() : invalid_argument("Unexpected format of GUID string") {}
120 class ELogFileError
: public logic_error
123 ELogFileError(const string
& strMsg
) : logic_error(strMsg
) {}
126 class EDuplicatedFfsFile
: public ELogFileError
129 EDuplicatedFfsFile() : ELogFileError("Duplicated FFS found in LOG file") {}
132 class EUnexpectedLogFileToken
: public ELogFileError
135 EUnexpectedLogFileToken() : ELogFileError("Unexpected LOG file token") {}
138 class EFileNotFound
: public invalid_argument
141 EFileNotFound(const string
& strFName
) : invalid_argument("File not found - " + strFName
) {}
144 class EUnexpectedMapFile
: public logic_error
147 EUnexpectedMapFile(const string
& strKeyWord
) : logic_error("Unexpected map file format - " + strKeyWord
) {}
150 class EUsage
: public invalid_argument
153 EUsage() : invalid_argument("Usage: GenFvMap <FV.LOG> <FV.INF> <FV.MAP>") {}
157 class CMemoryLeakChecker
: public set
<T
*>
165 virtual ~CMemoryLeakChecker();
166 static CMemoryLeakChecker
<T
>& GetInstance();
169 CMemoryLeakChecker(const CMemoryLeakChecker
<T
>&);
173 CMemoryLeakChecker
<T
>::~CMemoryLeakChecker()
175 if (!CMemoryLeakChecker
<T
>::empty())
180 CMemoryLeakChecker
<T
>& CMemoryLeakChecker
<T
>::GetInstance()
182 static CMemoryLeakChecker
<T
> s_instance
;
192 CMemoryLeakChecker
<CObjRoot
>::GetInstance().insert(this);
200 CMemoryLeakChecker
<CObjRoot
>::GetInstance().erase(this);
205 CObjRoot(const CObjRoot
&);
208 class CIdentity
: public CObjRoot
211 CIdentity(const string
&);
212 operator string (void) const;
214 bool operator < (const CIdentity
& id
) const
216 return memcmp(this, &id
, sizeof(*this)) < 0;
219 CIdentity() : ulD1(0), wD2(0), wD3(0), wD4(0), ullD5(0)
223 CIdentity(const CIdentity
& r
) : ulD1(r
.ulD1
), wD2(r
.wD2
), wD3(r
.wD3
), wD4(r
.wD4
), ullD5(r
.ullD5
)
227 template <class _E
, class _Tr
>
228 basic_istream
<_E
, _Tr
>& ReadId(basic_istream
<_E
, _Tr
>&);
229 template <class _E
, class _Tr
>
230 basic_ostream
<_E
, _Tr
>& WriteId(basic_ostream
<_E
, _Tr
>&);
232 template <class _E
, class _Tr
>
233 friend basic_istream
<_E
, _Tr
>& operator >> (basic_istream
<_E
, _Tr
>&, CIdentity
&);
234 template <class _E
, class _Tr
>
235 friend basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>&, CIdentity
);
239 UINT16 wD2
, wD3
, wD4
;
243 CIdentity::CIdentity(const string
& strGuid
)
248 str
.erase(0, str
.find_first_not_of(" {"));
249 str
.resize(str
.find_last_not_of(" }") + 1);
250 str
[str
.find('-')] = ' ';
251 str
[str
.find('-')] = ' ';
252 str
[str
.find('-')] = ' ';
253 str
[str
.find('-')] = ' ';
255 istringstream
is(str
);
256 is
>> hex
>> ulD1
>> wD2
>> wD3
>> wD4
>> getUINT64(ullD5
);
258 catch (const exception
&)
260 throw EInvalidGuidString();
264 CIdentity::operator string(void) const
267 os
<< hex
<< setfill('0')
268 << setw(8) << ulD1
<< '-'
269 << setw(4) << wD2
<< '-'
270 << setw(4) << wD3
<< '-'
271 << setw(4) << wD4
<< '-'
272 << setw(12) << putUINT64(ullD5
);
276 template <class _E
, class _Tr
>
277 basic_istream
<_E
, _Tr
>& CIdentity::ReadId(basic_istream
<_E
, _Tr
>& is
)
281 *this = CIdentity(str
);
285 template <class _E
, class _Tr
>
286 basic_ostream
<_E
, _Tr
>& CIdentity::WriteId(basic_ostream
<_E
, _Tr
>& os
)
288 return os
<< (string
)(*this);
291 template <class _E
, class _Tr
>
292 basic_istream
<_E
, _Tr
>& operator >> (basic_istream
<_E
, _Tr
>& is
, CIdentity
& id
)
294 return id
.ReadId(is
);
297 template <class _E
, class _Tr
>
298 basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>& os
, CIdentity id
)
300 return id
.WriteId(os
);
304 class IVectorContainerByReference
: virtual public CObjRoot
, public vector
<T
*>
309 class IMapContainer
: virtual public CObjRoot
, public map
<CIdentity
, T
>
313 struct ISymbol
: virtual public CObjRoot
321 virtual void Relocate(UINT64
)=0;
324 class IModule
: public IVectorContainerByReference
<ISymbol
>
329 virtual UINT64
BaseAddress(void) const=0;
330 virtual UINT64
BaseAddress(UINT64
)=0;
331 virtual const ISymbol
*EntryPoint(void) const=0;
334 class IFirmwareVolume
: public IVectorContainerByReference
<IModule
>
338 class IMapFileSet
: public IMapContainer
<istream
*>
342 class IFfsSet
: public IMapContainer
<UINT64
>
346 class CFfsSetFromLogFile
: public IFfsSet
349 CFfsSetFromLogFile(const string
&);
352 CFfsSetFromLogFile::CFfsSetFromLogFile(const string
& strFName
)
354 ifstream
ifs(strFName
.c_str());
356 throw EFileNotFound(strFName
);
359 while (!!ffsId
.ReadId(ifs
))
362 if (!(ifs
>> hex
>> getUINT64(ullBase
)))
363 throw EUnexpectedLogFileToken();
364 if (!insert(value_type(ffsId
, ullBase
)).second
)
365 throw EDuplicatedFfsFile();
369 class CMapFileSetFromInfFile
: public IMapFileSet
372 CMapFileSetFromInfFile(const string
&);
373 ~CMapFileSetFromInfFile();
376 CMapFileSetFromInfFile::CMapFileSetFromInfFile(const string
& strFName
)
378 static const char cszEfiFileName
[] = "EFI_FILE_NAME";
380 ifstream
ifs(strFName
.c_str());
382 throw EFileNotFound(strFName
);
385 getline(ifs
, strFile
, ifstream::traits_type::to_char_type(ifstream::traits_type::eof()));
386 strFile
.erase(0, strFile
.find("[files]"));
388 istringstream
is(strFile
);
390 while (!!getline(is
, strTmp
))
392 string::size_type pos
= strTmp
.find(cszEfiFileName
);
393 if (pos
== string::npos
)
396 strTmp
.erase(0, strTmp
.find_first_not_of(" =", pos
+ sizeof(cszEfiFileName
) - 1));
397 pos
= strTmp
.find_last_of("\\/");
399 strTmp
.begin() + pos
+ 1,
400 strTmp
.begin() + strTmp
.find('-', strTmp
.find('-', strTmp
.find('-', strTmp
.find('-', strTmp
.find('-') + 1) + 1) + 1) + 1)
402 strTmp
.erase(pos
+ 1, strId
.length() + 1);
403 strTmp
.replace(strTmp
.rfind('.'), string::npos
, ".map");
405 istream
*ifmaps
= new ifstream(strTmp
.c_str());
406 if (ifmaps
&& !!*ifmaps
&&
407 !insert(value_type(CIdentity(strId
), ifmaps
)).second
)
408 throw EDuplicatedFfsFile();
412 CMapFileSetFromInfFile::~CMapFileSetFromInfFile()
414 for (iterator i
= begin(); i
!= end(); i
++)
418 class CSymbolFromString
: public ISymbol
421 CSymbolFromString(const string
&, bool = false);
422 void Relocate(UINT64
);
425 CSymbolFromString::CSymbolFromString(const string
& strSymbol
, bool b
)
429 istringstream
is(strSymbol
);
430 is
>> strAddress
>> strName
>> hex
>> getUINT64(ullRva
) >> strFrom
;
436 else bFunction
= false;
438 throw EUnexpectedMapFile("Symbol line format");
441 void CSymbolFromString::Relocate(UINT64 ullDelta
)
447 class CModuleFromMap
: public IModule
450 CModuleFromMap(istream
&);
453 UINT64
BaseAddress() const;
454 UINT64
BaseAddress(UINT64
);
455 const ISymbol
*EntryPoint() const;
458 UINT64 m_ullLoadAddress
;
459 iterator m_iEntryPoint
;
461 static pair
<string
, string::size_type
> FindToken(istream
&, const string
&);
464 pair
<string
, string::size_type
> CModuleFromMap::FindToken(istream
& is
, const string
& strToken
)
466 for (string strTmp
; !!getline(is
, strTmp
);)
468 string::size_type pos
= strTmp
.find(strToken
);
469 if (pos
!= string::npos
)
470 return pair
<string
, string::size_type
>(strTmp
, pos
);
472 throw EUnexpectedMapFile(strToken
);
475 CModuleFromMap::CModuleFromMap(istream
& imaps
)
477 static const char cszLoadAddr
[] = "Preferred load address is";
478 static const char cszGlobal
[] = "Address";
479 static const char cszEntryPoint
[] = "entry point at";
480 static const char cszStatic
[] = "Static symbols";
482 pair
<string
, string::size_type
> pairTmp
;
485 getline(imaps
, strName
);
486 strName
.erase(0, strName
.find_first_not_of(' '));
488 pairTmp
= FindToken(imaps
, cszLoadAddr
);
489 iss
.str(pairTmp
.first
.substr(pairTmp
.second
+ sizeof(cszLoadAddr
) - 1));
490 iss
>> getUINT64(m_ullLoadAddress
);
492 pairTmp
= FindToken(imaps
, cszGlobal
);
493 while (!!getline(imaps
, pairTmp
.first
) &&
494 pairTmp
.first
.find(cszEntryPoint
) == string::npos
)
495 if (pairTmp
.first
.find_first_not_of(' ') != string::npos
)
496 push_back(new CSymbolFromString(pairTmp
.first
));
498 iss
.str(pairTmp
.first
.substr(pairTmp
.first
.find(cszEntryPoint
) + sizeof(cszEntryPoint
) - 1));
500 string strEntryPoint
;
501 iss
>> strEntryPoint
;
503 pairTmp
= FindToken(imaps
, cszStatic
);
505 while (!!getline(imaps
, pairTmp
.first
))
506 if (pairTmp
.first
.find_first_not_of(' ') != string::npos
)
507 push_back(new CSymbolFromString(pairTmp
.first
, true));
509 for (m_iEntryPoint
= begin();
510 m_iEntryPoint
!= end() && (*m_iEntryPoint
)->strAddress
!= strEntryPoint
;
512 if (m_iEntryPoint
== end())
513 throw EUnexpectedMapFile("Entry point not found");
516 CModuleFromMap::~CModuleFromMap()
518 for (iterator i
= begin(); i
!= end(); i
++)
522 UINT64
CModuleFromMap::BaseAddress(void) const
524 return m_ullLoadAddress
;
527 UINT64
CModuleFromMap::BaseAddress(UINT64 ullNewBase
)
529 ullNewBase
-= m_ullLoadAddress
;
530 for (iterator i
= begin(); i
!= end(); i
++)
531 (*i
)->Relocate(ullNewBase
);
532 m_ullLoadAddress
+= ullNewBase
;
533 return m_ullLoadAddress
- ullNewBase
;
536 const ISymbol
*CModuleFromMap::EntryPoint(void) const
538 return *m_iEntryPoint
;
541 class CFvMap
: public IFirmwareVolume
544 CFvMap(IFfsSet
*, IMapFileSet
*);
548 CFvMap(const CFvMap
&);
551 CFvMap::CFvMap(IFfsSet
*pFfsSet
, IMapFileSet
*pMapSet
)
553 for (IFfsSet::iterator i
= pFfsSet
->begin(); i
!= pFfsSet
->end(); i
++)
555 IMapFileSet::iterator j
= pMapSet
->find(i
->first
);
556 if (j
!= pMapSet
->end())
558 IModule
*pModule
= new CModuleFromMap(*j
->second
);
559 pModule
->id
= i
->first
;
560 pModule
->BaseAddress(i
->second
);
568 for (iterator i
= begin(); i
!= end(); i
++)
572 class CFvMapGenerator
: public CObjRoot
575 CFvMapGenerator(const IFirmwareVolume
*pFv
) : m_pFv(pFv
) {}
576 CFvMapGenerator(const CFvMapGenerator
& r
) : m_pFv(r
.m_pFv
) {}
578 template <class _E
, class _Tr
>
579 friend basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>&, CFvMapGenerator
);
582 static bool Less(const IModule
*, const IModule
*);
585 const IFirmwareVolume
*m_pFv
;
588 template <class _E
, class _Tr
>
589 basic_ostream
<_E
, _Tr
>& operator << (basic_ostream
<_E
, _Tr
>& os
, CFvMapGenerator fvMapFmt
)
591 vector
<IModule
*> rgMods(fvMapFmt
.m_pFv
->begin(), fvMapFmt
.m_pFv
->end());
592 sort(rgMods
.begin(), rgMods
.end(), CFvMapGenerator::Less
);
593 for (vector
<IModule
*>::iterator i
= rgMods
.begin(); i
!= rgMods
.end(); i
++)
595 os
<< (*i
)->strName
<< hex
<< " (BaseAddress=" << putUINT64((*i
)->BaseAddress());
596 os
<< ", EntryPoint=" << hex
<< putUINT64((*i
)->EntryPoint()->ullRva
);
598 (*i
)->id
.WriteId(os
);
599 os
<< ")" << endl
<< endl
;
601 for (IModule::iterator j
= (*i
)->begin(); j
!= (*i
)->end(); j
++)
603 os
<< hex
<< " " << setw(16) << setfill('0') << putUINT64((*j
)->ullRva
);
604 os
<< ((*j
)->bFunction
? " F" : " ")
605 << ((*j
)->bStatic
? "S " : " ")
606 << (*j
)->strName
<< endl
;
614 bool CFvMapGenerator::Less(const IModule
*pModL
, const IModule
*pModR
)
616 return pModL
->BaseAddress() < pModR
->BaseAddress();
619 class CApplication
: public CObjRoot
622 CApplication(int, char**);
628 CApplication(const CApplication
&);
631 CApplication::CApplication(int cArg
, char *ppszArg
[])
638 int CApplication::Run(void)
640 CFfsSetFromLogFile
ffsSet(m_ppszArg
[1]);
641 CMapFileSetFromInfFile
mapSet(m_ppszArg
[2]);
642 ofstream
ofs(m_ppszArg
[3]);
643 CFvMap
fvMap(&ffsSet
, &mapSet
);
644 ofs
<< CFvMapGenerator(&fvMap
);
648 int main(int argc
, char *argv
[])
652 CApplication
app(argc
, argv
);
655 catch (const exception
& e
)
657 cerr
<< e
.what() << endl
;
662 #ifdef _DDK3790x1830_WORKAROUND
663 extern "C" void __fastcall
__security_check_cookie(int)