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
&);
81 friend ostream
& operator << (ostream
&, const CIdentity
&);
83 static const string::size_type s_nIdStrLen
;
86 ulonglong_t m_ullId
[2];
89 const string::size_type
CIdentity::s_nIdStrLen
= 36;
91 CIdentity::CIdentity(void)
93 memset(m_ullId
, 0, sizeof(m_ullId
));
96 CIdentity::CIdentity(const string
& strId
)
98 if (strId
.length() != CIdentity::s_nIdStrLen
||
104 __FUNCTION__
": Error GUID format " + strId
);
106 string
strIdCopy(strId
);
107 strIdCopy
.erase(23, 1);
109 strIdCopy
.erase(13, 1);
110 strIdCopy
.erase(8, 1);
112 istringstream
is(strIdCopy
);
113 is
>> hex
>> m_ullId
[0] >> m_ullId
[1];
116 __FUNCTION__
": GUID contains invalid characters" + strId
);
119 CIdentity::CIdentity(const CIdentity
& idRight
)
121 memmove(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
));
124 bool CIdentity::operator < (const CIdentity
& idRight
) const
126 return memcmp(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
)) < 0;
129 istream
& operator >> (istream
& is
, CIdentity
& idRight
)
134 idRight
= CIdentity(strId
);
138 ostream
& operator << (ostream
& os
, const CIdentity
& idRight
)
140 return os
<< hex
<< setfill('0')
141 << setw(8) << (unsigned long)(idRight
.m_ullId
[0] >> 32) << '-'
142 << setw(4) << (unsigned short)(idRight
.m_ullId
[0] >> 16) << '-'
143 << setw(4) << (unsigned short)idRight
.m_ullId
[0] << '-'
144 << setw(4) << (unsigned short)(idRight
.m_ullId
[1] >> 48) << '-'
145 << setw(12) << (idRight
.m_ullId
[1] & 0xffffffffffff);
148 class CInputFile
: public CObjRoot
151 CInputFile(const string
&);
152 CInputFile(istream
&);
153 istream
& GetLine(string
&);
156 CInputFile(const CInputFile
&);
157 CInputFile
& operator = (const CInputFile
&);
160 auto_ptr
<istream
> m_pIs
;
166 CInputFile::CInputFile(const string
& strFName
)
167 : m_pIs(new ifstream(strFName
.c_str()))
171 throw runtime_error(__FUNCTION__
": Error opening input file " + strFName
);
174 CInputFile::CInputFile(istream
& is
)
178 throw runtime_error(__FUNCTION__
": Error opening input stream");
181 istream
& CInputFile::GetLine(string
& strALine
)
184 while (!!getline(m_is
, strALine
))
186 string::size_type pos
= strALine
.find_last_not_of(' ');
187 if (pos
!= string::npos
)
189 strALine
.erase(pos
+ 1);
190 strALine
.erase(0, strALine
.find_first_not_of(' '));
197 class CIdAddressPathMap
: public CInputFile
, public map
<CIdentity
, pair
<ulonglong_t
, string
> >
200 CIdAddressPathMap(istream
&);
203 CIdAddressPathMap::CIdAddressPathMap(istream
& is
)
208 while (!!(m_is
>> hex
>> k
>> m
.first
) && !!GetLine(m
.second
))
209 if (!insert(value_type(k
, m
)).second
)
210 throw runtime_error(__FUNCTION__
": Duplicated files");
213 class CSymbol
: public CObjRoot
218 ulonglong_t m_ullRva
;
226 CSymbol(const string
&, bool = false);
227 friend ostream
& operator << (ostream
&, const CSymbol
&);
230 CSymbol::CSymbol(const string
& strALine
, bool bStatic
)
233 istringstream
is(strALine
);
235 is
>> m_strAddress
>> m_strName
>> hex
>> m_ullRva
>> m_strFrom
;
236 if (m_strFrom
== "F" || m_strFrom
== "f")
240 } else m_bFunction
= false;
243 ostream
& operator << (ostream
& os
, const CSymbol
& symbol
)
245 os
<< hex
<< setw(16) << setfill('0') << symbol
.m_ullRva
<< setw(0);
246 os
<< ' ' << (symbol
.m_bFunction
? 'F' : ' ')
247 << (symbol
.m_bStatic
? 'S' : ' ') << ' ';
248 return os
<< symbol
.m_strName
;
251 class CMapFile
: public CInputFile
, public list
<CSymbol
>
254 CMapFile(const string
&);
256 void SetLoadAddress(ulonglong_t
);
258 string m_strModuleName
;
259 ulonglong_t m_ullLoadAddr
;
260 string m_strEntryPoint
;
263 CMapFile::CMapFile(const string
& strFName
)
264 : CInputFile(strFName
)
266 static const char cszLoadAddr
[] = "Preferred load address is";
267 static const char cszGlobal
[] = "Address";
268 static const char cszEntryPoint
[] = "entry point at";
269 static const char cszStatic
[] = "Static symbols";
273 GetLine(m_strModuleName
);
275 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszLoadAddr
) - 1, cszLoadAddr
));
277 throw runtime_error(__FUNCTION__
": Load Address not listed in map file");
279 istringstream
is(strALine
.substr(sizeof(cszLoadAddr
) - 1));
280 if (!(is
>> hex
>> m_ullLoadAddr
))
281 throw runtime_error(__FUNCTION__
": Unexpected Load Address format");
283 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszGlobal
) - 1, cszGlobal
));
285 throw runtime_error(__FUNCTION__
": Global symbols not found in map file");
287 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszEntryPoint
) - 1, cszEntryPoint
))
288 push_back(CSymbol(strALine
));
290 throw runtime_error(__FUNCTION__
": Entry Point not listed in map file");
292 is
.str(strALine
.substr(strALine
.find_first_not_of(' ', sizeof(cszEntryPoint
) - 1)));
294 if (!getline(is
, m_strEntryPoint
))
295 throw runtime_error(__FUNCTION__
": Unexpected Entry Point format");
297 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszStatic
) - 1, cszStatic
));
298 while (!!GetLine(strALine
))
299 push_back(CSymbol(strALine
, true));
302 void CMapFile::SetLoadAddress(ulonglong_t ullLoadAddr
)
304 for (iterator i
= begin(); i
!= end(); i
++)
305 if (i
->m_ullRva
>= m_ullLoadAddr
)
306 i
->m_ullRva
+= ullLoadAddr
- m_ullLoadAddr
;
307 m_ullLoadAddr
= ullLoadAddr
;
310 class COutputFile
: public CObjRoot
313 COutputFile(ostream
&);
317 COutputFile(const COutputFile
&);
318 COutputFile
& operator = (const COutputFile
&);
321 class CFvMapFile
: public CObjRoot
, public map
<CIdentity
, CMapFile
*>
324 CFvMapFile(const CIdAddressPathMap
&);
327 friend ostream
& operator << (ostream
&, const CFvMapFile
&);
333 CFvMapFile::CFvMapFile(const CIdAddressPathMap
& idAddrPath
)
335 for (CIdAddressPathMap::const_iterator i
= idAddrPath
.begin(); i
!= idAddrPath
.end(); i
++)
337 if (i
->second
.second
== "*")
340 pair
<iterator
, bool> r
= insert(value_type(i
->first
,
341 new CMapFile(i
->second
.second
.substr(0, i
->second
.second
.rfind('.')) + ".map")));
342 r
.first
->second
->SetLoadAddress(i
->second
.first
);
346 void CFvMapFile::Cleanup(void)
348 for (iterator i
= begin(); i
!= end(); i
++)
352 ostream
& operator << (ostream
& os
, const CFvMapFile
& fvMap
)
354 for (CFvMapFile::const_iterator i
= fvMap
.begin(); !!os
&& i
!= fvMap
.end(); i
++)
356 CMapFile::const_iterator j
= i
->second
->begin();
357 while (j
!= i
->second
->end() && j
->m_strAddress
!= i
->second
->m_strEntryPoint
) j
++;
358 if (j
== i
->second
->end())
360 __FUNCTION__
":Entry point not found for module " +
361 i
->second
->m_strModuleName
);
364 << i
->second
->m_strModuleName
365 << " (EP=" << j
->m_ullRva
366 << ", BA=" << i
->second
->m_ullLoadAddr
367 << ", GUID=" << i
->first
368 << ")" << endl
<< endl
;
370 for (j
= i
->second
->begin(); j
!= i
->second
->end(); j
++)
371 os
<< " " << *j
<< endl
;
379 CFvMapFile::~CFvMapFile(void)
384 class CGenFvMapUsage
: public invalid_argument
387 CGenFvMapUsage(void) : invalid_argument(s_szUsage
)
392 static const char s_szUsage
[];
395 const char CGenFvMapUsage::s_szUsage
[] = "Usage: GenFvMap <LOG> <MAP>";
397 class CGenFvMapApp
: public CObjRoot
400 CGenFvMapApp(int, char *[]);
410 CGenFvMapApp::CGenFvMapApp(int cArgc
, char *ppszArgv
[])
412 , m_ppszArgv(ppszArgv
)
415 throw CGenFvMapUsage();
418 CGenFvMapApp::~CGenFvMapApp(void)
422 int CGenFvMapApp::Run(void)
424 ifstream
isLog(m_ppszArgv
[1]);
425 CIdAddressPathMap
idAddrPath(isLog
);
426 CFvMapFile
fvMap(idAddrPath
);
428 ofstream
osMap(m_ppszArgv
[2], ios_base::out
| ios_base::trunc
);
432 throw runtime_error(__FUNCTION__
": Error writing output file");
437 int main(int argc
, char *argv
[])
441 CGenFvMapApp
app(argc
, argv
);
444 catch (const exception
& e
)
446 cerr
<< e
.what() << endl
;