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 //****************************************************************************
11 #include "ProcessorBind.h"
25 typedef UINT64 ulonglong_t
;
28 #if __STDC_VERSION__ < 199901L
29 #define __FUNCTION__ __FILE__
34 class CMemoryLeakChecker
: public list
<T
*>
37 static CMemoryLeakChecker
<T
>& GetInstance(void);
40 CMemoryLeakChecker(void)
44 ~CMemoryLeakChecker(void);
48 CMemoryLeakChecker
<T
>& CMemoryLeakChecker
<T
>::GetInstance(void)
50 static CMemoryLeakChecker
<T
> s_memLeakChecker
;
51 return s_memLeakChecker
;
55 CMemoryLeakChecker
<T
>::~CMemoryLeakChecker(void)
57 if (!list
<T
*>::empty())
58 throw logic_error(__FUNCTION__
": Memory leak detected!");
65 virtual ~CObjRoot(void);
68 CObjRoot::CObjRoot(void)
70 CMemoryLeakChecker
<CObjRoot
>::GetInstance().push_back(this);
73 CObjRoot::~CObjRoot(void)
75 CMemoryLeakChecker
<CObjRoot
>::GetInstance().remove(this);
78 class CIdentity
: public CObjRoot
82 CIdentity(const string
&);
83 CIdentity(const CIdentity
&);
85 bool operator < (const CIdentity
&) const;
86 friend istream
& operator >> (istream
&, CIdentity
&);
87 friend ostream
& operator << (ostream
&, const CIdentity
&);
89 static const string::size_type s_nIdStrLen
;
92 ulonglong_t m_ullId
[2];
95 const string::size_type
CIdentity::s_nIdStrLen
= 36;
97 CIdentity::CIdentity(void)
99 memset(m_ullId
, 0, sizeof(m_ullId
));
102 CIdentity::CIdentity(const string
& strId
)
104 if (strId
.length() != CIdentity::s_nIdStrLen
||
110 __FUNCTION__
": Error GUID format " + strId
);
112 string
strIdCopy(strId
);
113 strIdCopy
.erase(23, 1);
115 strIdCopy
.erase(13, 1);
116 strIdCopy
.erase(8, 1);
118 istringstream
is(strIdCopy
);
119 is
>> hex
>> m_ullId
[0] >> m_ullId
[1];
122 __FUNCTION__
": GUID contains invalid characters" + strId
);
125 CIdentity::CIdentity(const CIdentity
& idRight
)
127 memmove(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
));
130 bool CIdentity::operator < (const CIdentity
& idRight
) const
132 return memcmp(m_ullId
, idRight
.m_ullId
, sizeof(m_ullId
)) < 0;
135 istream
& operator >> (istream
& is
, CIdentity
& idRight
)
140 idRight
= CIdentity(strId
);
144 ostream
& operator << (ostream
& os
, const CIdentity
& idRight
)
146 return os
<< hex
<< setfill('0')
147 << setw(8) << (unsigned long)(idRight
.m_ullId
[0] >> 32) << '-'
148 << setw(4) << (unsigned short)(idRight
.m_ullId
[0] >> 16) << '-'
149 << setw(4) << (unsigned short)idRight
.m_ullId
[0] << '-'
150 << setw(4) << (unsigned short)(idRight
.m_ullId
[1] >> 48) << '-'
151 << setw(12) << (idRight
.m_ullId
[1] & 0xffffffffffffULL
);
154 class CInputFile
: public CObjRoot
157 CInputFile(const string
&);
158 CInputFile(istream
&);
159 istream
& GetLine(string
&);
162 CInputFile(const CInputFile
&);
163 CInputFile
& operator = (const CInputFile
&);
166 auto_ptr
<istream
> m_pIs
;
172 CInputFile::CInputFile(const string
& strFName
)
173 : m_pIs(new ifstream(strFName
.c_str()))
177 throw runtime_error(__FUNCTION__
": Error opening input file " + strFName
);
180 CInputFile::CInputFile(istream
& is
)
184 throw runtime_error(__FUNCTION__
": Error opening input stream");
187 istream
& CInputFile::GetLine(string
& strALine
)
190 while (!!getline(m_is
, strALine
))
192 string::size_type pos
= strALine
.find_last_not_of(' ');
193 if (pos
!= string::npos
)
195 strALine
.erase(pos
+ 1);
196 strALine
.erase(0, strALine
.find_first_not_of(' '));
203 class CIdAddressPathMap
: public CInputFile
, public map
<CIdentity
, pair
<ulonglong_t
, string
> >
206 CIdAddressPathMap(istream
&);
209 CIdAddressPathMap::CIdAddressPathMap(istream
& is
)
214 while (!!(m_is
>> hex
>> k
>> m
.first
) && !!GetLine(m
.second
))
215 if (!insert(value_type(k
, m
)).second
)
216 throw runtime_error(__FUNCTION__
": Duplicated files");
219 class CSymbol
: public CObjRoot
224 ulonglong_t m_ullRva
;
232 CSymbol(const string
&, bool = false);
233 friend ostream
& operator << (ostream
&, const CSymbol
&);
236 CSymbol::CSymbol(const string
& strALine
, bool bStatic
)
239 istringstream
is(strALine
);
241 is
>> m_strAddress
>> m_strName
>> hex
>> m_ullRva
>> m_strFrom
;
242 if (m_strFrom
== "F" || m_strFrom
== "f")
246 } else m_bFunction
= false;
249 ostream
& operator << (ostream
& os
, const CSymbol
& symbol
)
251 os
<< hex
<< setw(16) << setfill('0') << symbol
.m_ullRva
<< setw(0);
252 os
<< ' ' << (symbol
.m_bFunction
? 'F' : ' ')
253 << (symbol
.m_bStatic
? 'S' : ' ') << ' ';
254 return os
<< symbol
.m_strName
;
257 class CMapFile
: public CInputFile
, public list
<CSymbol
>
260 CMapFile(const string
&);
262 void SetLoadAddress(ulonglong_t
);
264 string m_strModuleName
;
265 ulonglong_t m_ullLoadAddr
;
266 string m_strEntryPoint
;
269 CMapFile::CMapFile(const string
& strFName
)
270 : CInputFile(strFName
)
272 static const char cszLoadAddr
[] = "Preferred load address is";
273 static const char cszGlobal
[] = "Address";
274 static const char cszEntryPoint
[] = "entry point at";
275 static const char cszStatic
[] = "Static symbols";
279 GetLine(m_strModuleName
);
281 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszLoadAddr
) - 1, cszLoadAddr
));
283 throw runtime_error(__FUNCTION__
": Load Address not listed in map file");
285 istringstream
is(strALine
.substr(sizeof(cszLoadAddr
) - 1));
286 if (!(is
>> hex
>> m_ullLoadAddr
))
287 throw runtime_error(__FUNCTION__
": Unexpected Load Address format");
289 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszGlobal
) - 1, cszGlobal
));
291 throw runtime_error(__FUNCTION__
": Global symbols not found in map file");
293 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszEntryPoint
) - 1, cszEntryPoint
))
294 push_back(CSymbol(strALine
));
296 throw runtime_error(__FUNCTION__
": Entry Point not listed in map file");
298 is
.str(strALine
.substr(strALine
.find_first_not_of(' ', sizeof(cszEntryPoint
) - 1)));
300 if (!getline(is
, m_strEntryPoint
))
301 throw runtime_error(__FUNCTION__
": Unexpected Entry Point format");
303 while (!!GetLine(strALine
) && strALine
.compare(0, sizeof(cszStatic
) - 1, cszStatic
));
304 while (!!GetLine(strALine
))
305 push_back(CSymbol(strALine
, true));
308 void CMapFile::SetLoadAddress(ulonglong_t ullLoadAddr
)
310 for (iterator i
= begin(); i
!= end(); i
++)
311 if (i
->m_ullRva
>= m_ullLoadAddr
)
312 i
->m_ullRva
+= ullLoadAddr
- m_ullLoadAddr
;
313 m_ullLoadAddr
= ullLoadAddr
;
316 class COutputFile
: public CObjRoot
319 COutputFile(ostream
&);
323 COutputFile(const COutputFile
&);
324 COutputFile
& operator = (const COutputFile
&);
327 class CFvMapFile
: public CObjRoot
, public map
<CIdentity
, CMapFile
*>
330 CFvMapFile(const CIdAddressPathMap
&);
333 friend ostream
& operator << (ostream
&, const CFvMapFile
&);
339 CFvMapFile::CFvMapFile(const CIdAddressPathMap
& idAddrPath
)
341 for (CIdAddressPathMap::const_iterator i
= idAddrPath
.begin(); i
!= idAddrPath
.end(); i
++)
343 if (i
->second
.second
== "*")
346 pair
<iterator
, bool> r
= insert(value_type(i
->first
,
347 new CMapFile(i
->second
.second
.substr(0, i
->second
.second
.rfind('.')) + ".map")));
348 r
.first
->second
->SetLoadAddress(i
->second
.first
);
352 void CFvMapFile::Cleanup(void)
354 for (iterator i
= begin(); i
!= end(); i
++)
358 ostream
& operator << (ostream
& os
, const CFvMapFile
& fvMap
)
360 for (CFvMapFile::const_iterator i
= fvMap
.begin(); !!os
&& i
!= fvMap
.end(); i
++)
362 CMapFile::const_iterator j
= i
->second
->begin();
363 while (j
!= i
->second
->end() && j
->m_strAddress
!= i
->second
->m_strEntryPoint
) j
++;
364 if (j
== i
->second
->end())
366 __FUNCTION__
":Entry point not found for module " +
367 i
->second
->m_strModuleName
);
370 << i
->second
->m_strModuleName
371 << " (EP=" << j
->m_ullRva
372 << ", BA=" << i
->second
->m_ullLoadAddr
373 << ", GUID=" << i
->first
374 << ")" << endl
<< endl
;
376 for (j
= i
->second
->begin(); j
!= i
->second
->end(); j
++)
377 os
<< " " << *j
<< endl
;
385 CFvMapFile::~CFvMapFile(void)
390 class CGenFvMapUsage
: public invalid_argument
393 CGenFvMapUsage(void) : invalid_argument(s_szUsage
)
398 static const char s_szUsage
[];
401 const char CGenFvMapUsage::s_szUsage
[] = "Usage: GenFvMap <LOG> <MAP>";
403 class CGenFvMapApp
: public CObjRoot
406 CGenFvMapApp(int, char *[]);
416 CGenFvMapApp::CGenFvMapApp(int cArgc
, char *ppszArgv
[])
418 , m_ppszArgv(ppszArgv
)
421 throw CGenFvMapUsage();
424 CGenFvMapApp::~CGenFvMapApp(void)
428 int CGenFvMapApp::Run(void)
430 ifstream
isLog(m_ppszArgv
[1]);
431 CIdAddressPathMap
idAddrPath(isLog
);
432 CFvMapFile
fvMap(idAddrPath
);
434 ofstream
osMap(m_ppszArgv
[2], ios_base::out
| ios_base::trunc
);
438 throw runtime_error(__FUNCTION__
": Error writing output file");
443 int main(int argc
, char *argv
[])
447 CGenFvMapApp
app(argc
, argv
);
450 catch (const exception
& e
)
452 cerr
<< e
.what() << endl
;