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 //****************************************************************************
25 typedef unsigned __int64 ulonglong_t
;
28 class CMemoryLeakChecker
: public list
<T
*>
31 static CMemoryLeakChecker
<T
>& GetInstance(void);
34 CMemoryLeakChecker(void)
38 ~CMemoryLeakChecker(void);
42 CMemoryLeakChecker
<T
>& CMemoryLeakChecker
<T
>::GetInstance(void)
44 static CMemoryLeakChecker
<T
> s_memLeakChecker
;
45 return s_memLeakChecker
;
49 CMemoryLeakChecker
<T
>::~CMemoryLeakChecker(void)
51 if (!list
<T
*>::empty())
52 throw logic_error(__FUNCTION__
": Memory leak detected!");
59 virtual ~CObjRoot(void);
62 CObjRoot::CObjRoot(void)
64 CMemoryLeakChecker
<CObjRoot
>::GetInstance().push_back(this);
67 CObjRoot::~CObjRoot(void)
69 CMemoryLeakChecker
<CObjRoot
>::GetInstance().remove(this);
72 class CIdentity
: public CObjRoot
76 CIdentity(const string
&);
77 CIdentity(const CIdentity
&);
79 bool operator < (const CIdentity
&) const;
80 friend istream
& operator >> (istream
&, CIdentity
&);
82 static const string::size_type s_nIdStrLen
;
85 ulonglong_t m_ullId
[2];
88 const string::size_type
CIdentity::s_nIdStrLen
= 36;
90 CIdentity::CIdentity(void)
92 memset(m_ullId
, 0, sizeof(m_ullId
));
95 CIdentity::CIdentity(const string
& strId
)
97 if (strId
.length() != CIdentity::s_nIdStrLen
||
103 __FUNCTION__
": Error GUID format " + strId
);
105 string
strIdCopy(strId
);
106 strIdCopy
.erase(23, 1);
108 strIdCopy
.erase(13, 1);
109 strIdCopy
.erase(8, 1);
111 istringstream
is(strIdCopy
);
112 is
>> hex
>> m_ullId
[0] >> m_ullId
[1];
115 __FUNCTION__
": GUID contains invalid characters" + strId
);
118 CIdentity::CIdentity(const CIdentity
& idRight
)
120 memmove(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
));
123 bool CIdentity::operator < (const CIdentity
& idRight
) const
125 return memcmp(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
)) < 0;
128 istream
& operator >> (istream
& is
, CIdentity
& idRight
)
133 idRight
= CIdentity(strId
);
137 class CInputFile
: public CObjRoot
140 CInputFile(const string
&);
141 CInputFile(istream
&);
142 istream
& GetLine(string
&);
145 CInputFile(const CInputFile
&);
146 CInputFile
& operator = (const CInputFile
&);
149 auto_ptr
<istream
> m_pIs
;
155 CInputFile::CInputFile(const string
& strFName
)
156 : m_pIs(new ifstream(strFName
.c_str()))
160 throw runtime_error(__FUNCTION__
": Error opening input file " + strFName
);
163 CInputFile::CInputFile(istream
& is
)
167 throw runtime_error(__FUNCTION__
": Error opening input stream");
170 istream
& CInputFile::GetLine(string
& strALine
)
173 while (!!getline(m_is
, strALine
))
175 string::size_type pos
= strALine
.find_last_not_of(' ');
176 if (pos
!= string::npos
)
178 strALine
.erase(pos
+ 1);
179 strALine
.erase(0, strALine
.find_first_not_of(' '));
186 class CIdAddressMap
: public CInputFile
, public map
<CIdentity
, ulonglong_t
>
189 CIdAddressMap(istream
&);
192 CIdAddressMap::CIdAddressMap(istream
& is
)
198 while (!!(m_is
>> hex
>> id
>> ullBase
))
199 if (!insert(value_type(id
, ullBase
)).second
)
200 throw runtime_error(__FUNCTION__
": Duplicated files");
203 class CIdPathMap
: public CInputFile
, public map
<CIdentity
, string
>
206 CIdPathMap(istream
&);
209 CIdPathMap::CIdPathMap(istream
& is
)
212 static const char cszFileSec
[] = "[files]";
213 static const char cszFfsFile
[] = "EFI_FILE_NAME";
217 // Find the [files] section
218 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszFileSec
) - 1, cszFileSec
));
220 // m_is error means no FFS files listed in this INF file
224 // Parse FFS files one by one
225 while (!!GetLine(strALine
))
227 // Test if this begins a new section
228 if (strALine
[0] == '[')
231 // Is it a line of FFS file?
232 if (strALine
.compare(0, sizeof(cszFfsFile
) - 1, cszFfsFile
))
235 string::size_type pos
= strALine
.find_first_not_of(' ', sizeof(cszFfsFile
) - 1);
236 if (pos
== string::npos
|| strALine
[pos
] != '=')
237 throw runtime_error(__FUNCTION__
": Invalid FV INF format");
238 pos
= strALine
.find_first_not_of(' ', pos
+ 1);
239 if (pos
== string::npos
)
240 throw runtime_error(__FUNCTION__
": Incomplete line");
242 strALine
.erase(0, pos
);
243 pos
= strALine
.rfind('\\');
244 if (pos
== string::npos
)
248 CIdentity
id(strALine
.substr(pos
, CIdentity::s_nIdStrLen
));
249 if (!insert(value_type(id
, strALine
)).second
)
250 throw runtime_error(__FUNCTION__
": Duplicated FFS files");
254 class CSymbol
: public CObjRoot
259 ulonglong_t m_ullRva
;
267 CSymbol(const string
&, bool = false);
268 friend ostream
& operator << (ostream
&, const CSymbol
&);
271 CSymbol::CSymbol(const string
& strALine
, bool bStatic
)
274 istringstream
is(strALine
);
276 is
>> m_strAddress
>> m_strName
>> hex
>> m_ullRva
>> m_strFrom
;
277 if (m_strFrom
== "F" || m_strFrom
== "f")
281 } else m_bFunction
= false;
284 ostream
& operator << (ostream
& os
, const CSymbol
& symbol
)
286 os
<< hex
<< setw(16) << setfill('0') << symbol
.m_ullRva
<< setw(0);
287 os
<< ' ' << (symbol
.m_bFunction
? 'F' : ' ')
288 << (symbol
.m_bStatic
? 'S' : ' ') << ' ';
289 return os
<< symbol
.m_strName
<< endl
;
292 class CMapFile
: public CInputFile
, public list
<CSymbol
>
295 CMapFile(const string
&);
297 void SetLoadAddress(ulonglong_t
);
298 friend ostream
& operator << (ostream
&, const CMapFile
&);
300 string m_strModuleName
;
301 ulonglong_t m_ullLoadAddr
;
302 string m_strEntryPoint
;
305 CMapFile::CMapFile(const string
& strFName
)
306 : CInputFile(strFName
)
308 static const char cszLoadAddr
[] = "Preferred load address is";
309 static const char cszGlobal
[] = "Address";
310 static const char cszEntryPoint
[] = "entry point at";
311 static const char cszStatic
[] = "Static symbols";
315 GetLine(m_strModuleName
);
317 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszLoadAddr
) - 1, cszLoadAddr
));
319 throw runtime_error(__FUNCTION__
": Load Address not listed in map file");
321 istringstream
is(strALine
.substr(sizeof(cszLoadAddr
) - 1));
322 if (!(is
>> hex
>> m_ullLoadAddr
))
323 throw runtime_error(__FUNCTION__
": Unexpected Load Address format");
325 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszGlobal
) - 1, cszGlobal
));
327 throw runtime_error(__FUNCTION__
": Global symbols not found in map file");
329 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszEntryPoint
) - 1, cszEntryPoint
))
330 push_back(CSymbol(strALine
));
332 throw runtime_error(__FUNCTION__
": Entry Point not listed in map file");
334 is
.str(strALine
.substr(strALine
.find_first_not_of(' ', sizeof(cszEntryPoint
) - 1)));
336 if (!getline(is
, m_strEntryPoint
))
337 throw runtime_error(__FUNCTION__
": Unexpected Entry Point format");
339 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszStatic
) - 1, cszStatic
));
340 while (!!GetLine(strALine
))
341 push_back(CSymbol(strALine
, true));
344 void CMapFile::SetLoadAddress(ulonglong_t ullLoadAddr
)
346 for (iterator i
= begin(); i
!= end(); i
++)
347 if (i
->m_ullRva
!= 0)
348 i
->m_ullRva
+= ullLoadAddr
- m_ullLoadAddr
;
349 m_ullLoadAddr
= ullLoadAddr
;
352 ostream
& operator << (ostream
& os
, const CMapFile
& mapFile
)
354 CMapFile::const_iterator i
= mapFile
.begin();
355 while (i
!= mapFile
.end() && i
->m_strAddress
!= mapFile
.m_strEntryPoint
)
357 if (i
== mapFile
.end())
359 __FUNCTION__
": Entry point not found for module " +
360 mapFile
.m_strModuleName
);
363 << mapFile
.m_strModuleName
<< " (EP=" << i
->m_ullRva
364 << ", BA=" << mapFile
.m_ullLoadAddr
<< ')' << endl
367 for (i
= mapFile
.begin(); i
!= mapFile
.end(); i
++)
373 class COutputFile
: public CObjRoot
376 COutputFile(ostream
&);
380 COutputFile(const COutputFile
&);
381 COutputFile
& operator = (const COutputFile
&);
384 class CFvMapFile
: public CObjRoot
, public map
<CIdentity
, CMapFile
*>
387 CFvMapFile(const CIdAddressMap
&, const CIdPathMap
&);
390 friend ostream
& operator << (ostream
&, const CFvMapFile
&);
396 CFvMapFile::CFvMapFile(const CIdAddressMap
& idAddr
, const CIdPathMap
& idPath
)
398 for (CIdAddressMap::const_iterator i
= idAddr
.begin(); i
!= idAddr
.end(); i
++)
400 CIdPathMap::const_iterator j
= idPath
.find(i
->first
);
401 if (j
== idPath
.end())
402 throw runtime_error(__FUNCTION__
": Map file not found");
406 pair
<iterator
, bool> k
= insert(value_type(i
->first
,
407 new CMapFile(j
->second
.substr(0, j
->second
.rfind('.')) + ".map")));
409 throw logic_error(__FUNCTION__
": Duplicated file found in rebase log");
411 k
.first
->second
->SetLoadAddress(i
->second
);
413 catch (const runtime_error
& e
)
415 cerr
<< e
.what() << endl
;
420 void CFvMapFile::Cleanup(void)
422 for (iterator i
= begin(); i
!= end(); i
++)
426 ostream
& operator << (ostream
& os
, const CFvMapFile
& fvMap
)
428 for (CFvMapFile::const_iterator i
= fvMap
.begin(); !!os
&& i
!= fvMap
.end(); i
++)
433 CFvMapFile::~CFvMapFile(void)
438 class CGenFvMapUsage
: public invalid_argument
441 CGenFvMapUsage(void) : invalid_argument(s_szUsage
)
446 static const char s_szUsage
[];
449 const char CGenFvMapUsage::s_szUsage
[] = "Usage: GenFvMap <LOG> <INF> <MAP>";
451 class CGenFvMapApp
: public CObjRoot
454 CGenFvMapApp(int, char *[]);
464 CGenFvMapApp::CGenFvMapApp(int cArgc
, char *ppszArgv
[])
466 , m_ppszArgv(ppszArgv
)
469 throw CGenFvMapUsage();
472 CGenFvMapApp::~CGenFvMapApp(void)
476 int CGenFvMapApp::Run(void)
478 ifstream
isLog(m_ppszArgv
[1]);
479 ifstream
isInf(m_ppszArgv
[2]);
481 CIdAddressMap
idAddress(isLog
);
482 CIdPathMap
idPath(isInf
);
484 CFvMapFile
fvMap(idAddress
, idPath
);
486 ofstream
osMap(m_ppszArgv
[3], ios_base::out
| ios_base::trunc
);
490 throw runtime_error(__FUNCTION__
": Error writing output file");
495 int main(int argc
, char *argv
[])
499 CGenFvMapApp
app(argc
, argv
);
502 catch (const exception
& e
)
504 cerr
<< e
.what() << endl
;