mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-27 01:03:45 +01:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2567 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			667 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			667 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //****************************************************************************
 | |
| //**
 | |
| //**  Copyright  (C) 2006 Intel Corporation. All rights reserved.
 | |
| //**
 | |
| //** The information and source code contained herein is the exclusive
 | |
| //** property of Intel Corporation and may not be disclosed, examined
 | |
| //** or reproduced in whole or in part without explicit written authorization
 | |
| //** from the company.
 | |
| //**
 | |
| //****************************************************************************
 | |
| #include <cstdio>
 | |
| #include <iostream>
 | |
| #include <fstream>
 | |
| #include <iomanip>
 | |
| #include <stdexcept>
 | |
| #include <set>
 | |
| #include <string>
 | |
| #include <sstream>
 | |
| #include <vector>
 | |
| #include <map>
 | |
| #include <algorithm>
 | |
| using namespace std;
 | |
| 
 | |
| #include "ProcessorBind.h"
 | |
| 
 | |
| class putUINT64
 | |
| {
 | |
| public:
 | |
|     putUINT64(UINT64 ullVal) : m_ull(ullVal) {}
 | |
|     putUINT64(const putUINT64& r) : m_ull(r.m_ull) {}
 | |
| 
 | |
|     template <class _E, class _Tr>
 | |
|     friend basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>&, putUINT64);
 | |
| 
 | |
| private:
 | |
|     UINT64 m_ull;
 | |
| };
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>& os, putUINT64 ull)
 | |
| {
 | |
|     static const char cDigits[] = "0123456789abcdef";
 | |
| 
 | |
|     UINT64 base = 10;
 | |
|     if (os.flags() & ios_base::hex)
 | |
|         base = 16;
 | |
|     else if (os.flags() & ios_base::oct)
 | |
|         base = 8;
 | |
| 
 | |
|     ostringstream ostr;
 | |
|     UINT64 ullVal = ull.m_ull;
 | |
|     while (ullVal != 0)
 | |
|     {
 | |
|         ostr << cDigits[ullVal % base];
 | |
|         ullVal /= base;
 | |
|     }
 | |
| 
 | |
|     string s1(ostr.str());
 | |
|     string s2(s1.rbegin(), s1.rend());
 | |
|     return os << s2;
 | |
| }
 | |
| 
 | |
| class getUINT64
 | |
| {
 | |
| public:
 | |
|     getUINT64(UINT64& ullVal) : m_ull(ullVal) {}
 | |
|     getUINT64(const getUINT64& r) : m_ull(r.m_ull) {}
 | |
| 
 | |
|     template <class _E, class _Tr>
 | |
|     friend basic_istream<_E, _Tr>& operator >> (basic_istream<_E, _Tr>&, getUINT64);
 | |
| 
 | |
| private:
 | |
|     UINT64& m_ull;
 | |
| 
 | |
| private:
 | |
|     getUINT64& operator = (const getUINT64&);
 | |
| };
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_istream<_E, _Tr>& operator >> (basic_istream<_E, _Tr>& is, getUINT64 ull)
 | |
| {
 | |
|     string strBuf;
 | |
|     is >> strBuf;
 | |
| 
 | |
|     UINT64 base = 10;
 | |
|     if (is.flags() & ios_base::hex)
 | |
|         base = 16;
 | |
|     else if (is.flags() & ios_base::oct)
 | |
|         base = 8;
 | |
| 
 | |
|     UINT64 ullVal = 0;
 | |
|     for (string::iterator i = strBuf.begin(); i != strBuf.end(); i++)
 | |
|     {
 | |
|         if (*i <= '9' && *i >= '0')
 | |
|             *i -= '0';
 | |
|         else if (*i <= 'F' && *i >= 'A')
 | |
|             *i -= 'A' - '\x0a';
 | |
|         else if (*i <= 'f' && *i >= 'a')
 | |
|             *i -= 'a' - '\x0a';
 | |
|         else throw runtime_error("Invalid number format");
 | |
| 
 | |
|         ullVal = ullVal * base + *i;
 | |
|     }
 | |
|     ull.m_ull = ullVal;
 | |
|     return is;
 | |
| }
 | |
| 
 | |
| class EMemoryLeak : public logic_error
 | |
| {
 | |
| public:
 | |
|     EMemoryLeak() : logic_error("Memory leak detected") {}
 | |
| };
 | |
| 
 | |
| class EInvalidGuidString : public invalid_argument
 | |
| {
 | |
| public:
 | |
|     EInvalidGuidString() : invalid_argument("Unexpected format of GUID string") {}
 | |
| };
 | |
| 
 | |
| class ELogFileError : public logic_error
 | |
| {
 | |
| public:
 | |
|     ELogFileError(const string& strMsg) : logic_error(strMsg) {}
 | |
| };
 | |
| 
 | |
| class EDuplicatedFfsFile : public ELogFileError
 | |
| {
 | |
| public:
 | |
|     EDuplicatedFfsFile() : ELogFileError("Duplicated FFS found in LOG file") {}
 | |
| };
 | |
| 
 | |
| class EUnexpectedLogFileToken : public ELogFileError
 | |
| {
 | |
| public:
 | |
|     EUnexpectedLogFileToken() : ELogFileError("Unexpected LOG file token") {}
 | |
| };
 | |
| 
 | |
| class EFileNotFound : public invalid_argument
 | |
| {
 | |
| public:
 | |
|     EFileNotFound(const string& strFName) : invalid_argument("File not found - " + strFName) {}
 | |
| };
 | |
| 
 | |
| class EUnexpectedMapFile : public logic_error
 | |
| {
 | |
| public:
 | |
|     EUnexpectedMapFile(const string& strKeyWord) : logic_error("Unexpected map file format - " + strKeyWord) {}
 | |
| };
 | |
| 
 | |
| class EUsage : public invalid_argument
 | |
| {
 | |
| public:
 | |
|     EUsage() : invalid_argument("Usage: GenFvMap <FV.LOG> <FV.INF> <FV.MAP>") {}
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class CMemoryLeakChecker : public set<T*>
 | |
| {
 | |
| protected:
 | |
|     CMemoryLeakChecker()
 | |
|     {
 | |
|     }
 | |
| 
 | |
| public:
 | |
|     virtual ~CMemoryLeakChecker();
 | |
|     static CMemoryLeakChecker<T>& GetInstance();
 | |
| 
 | |
| private:
 | |
|     CMemoryLeakChecker(const CMemoryLeakChecker<T>&);
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| CMemoryLeakChecker<T>::~CMemoryLeakChecker()
 | |
| {
 | |
|     if (!CMemoryLeakChecker<T>::empty())
 | |
|         throw EMemoryLeak();
 | |
| }
 | |
| 
 | |
| template <class T>
 | |
| CMemoryLeakChecker<T>& CMemoryLeakChecker<T>::GetInstance()
 | |
| {
 | |
|     static CMemoryLeakChecker<T> s_instance;
 | |
|     return s_instance;
 | |
| }
 | |
| 
 | |
| class CObjRoot
 | |
| {
 | |
| protected:
 | |
|     CObjRoot()
 | |
|     {
 | |
| #ifdef _CHK_MEM_LEAK
 | |
|         CMemoryLeakChecker<CObjRoot>::GetInstance().insert(this);
 | |
| #endif
 | |
|     }
 | |
| 
 | |
| public:
 | |
|     virtual ~CObjRoot()
 | |
|     {
 | |
| #ifdef _CHK_MEM_LEAK
 | |
|         CMemoryLeakChecker<CObjRoot>::GetInstance().erase(this);
 | |
| #endif
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     CObjRoot(const CObjRoot&);
 | |
| };
 | |
| 
 | |
| class CIdentity : public CObjRoot
 | |
| {
 | |
| public:
 | |
|     CIdentity(const string&);
 | |
|     operator string (void) const;
 | |
| 
 | |
|     bool operator < (const CIdentity& id) const
 | |
|     {
 | |
|         return memcmp(this, &id, sizeof(*this)) < 0;
 | |
|     }
 | |
| 
 | |
|     CIdentity() : ulD1(0), wD2(0), wD3(0), wD4(0), ullD5(0)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     CIdentity(const CIdentity& r) : ulD1(r.ulD1), wD2(r.wD2), wD3(r.wD3), wD4(r.wD4), ullD5(r.ullD5)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     template <class _E, class _Tr>
 | |
|     basic_istream<_E, _Tr>& ReadId(basic_istream<_E, _Tr>&);
 | |
|     template <class _E, class _Tr>
 | |
|     basic_ostream<_E, _Tr>& WriteId(basic_ostream<_E, _Tr>&);
 | |
| 
 | |
|     template <class _E, class _Tr>
 | |
|     friend basic_istream<_E, _Tr>& operator >> (basic_istream<_E, _Tr>&, CIdentity&);
 | |
|     template <class _E, class _Tr>
 | |
|     friend basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>&, CIdentity);
 | |
| 
 | |
| private:
 | |
|     UINT32 ulD1;
 | |
|     UINT16 wD2, wD3, wD4;
 | |
|     UINT64 ullD5;
 | |
| };
 | |
| 
 | |
| CIdentity::CIdentity(const string& strGuid)
 | |
| {
 | |
|     try
 | |
|     {
 | |
|         string str(strGuid);
 | |
|         str.erase(0, str.find_first_not_of(" {"));
 | |
|         str.resize(str.find_last_not_of(" }") + 1);
 | |
|         str[str.find('-')] = ' ';
 | |
|         str[str.find('-')] = ' ';
 | |
|         str[str.find('-')] = ' ';
 | |
|         str[str.find('-')] = ' ';
 | |
| 
 | |
|         istringstream is(str);
 | |
|         is >> hex >> ulD1 >> wD2 >> wD3 >> wD4 >> getUINT64(ullD5);
 | |
|     }
 | |
|     catch (const exception&)
 | |
|     {
 | |
|         throw EInvalidGuidString();
 | |
|     }
 | |
| }
 | |
| 
 | |
| CIdentity::operator string(void) const
 | |
| {
 | |
|     ostringstream os;
 | |
|     os << hex << setfill('0')
 | |
|         << setw(8) << ulD1 << '-'
 | |
|         << setw(4) << wD2 << '-'
 | |
|         << setw(4) << wD3 << '-'
 | |
|         << setw(4) << wD4 << '-'
 | |
|         << setw(12) << putUINT64(ullD5);
 | |
|     return os.str();
 | |
| }
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_istream<_E, _Tr>& CIdentity::ReadId(basic_istream<_E, _Tr>& is)
 | |
| {
 | |
|     string str;
 | |
|     if (!!(is >> str))
 | |
|         *this = CIdentity(str);
 | |
|     return is;
 | |
| }
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_ostream<_E, _Tr>& CIdentity::WriteId(basic_ostream<_E, _Tr>& os)
 | |
| {
 | |
|     return os << (string)(*this);
 | |
| }
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_istream<_E, _Tr>& operator >> (basic_istream<_E, _Tr>& is, CIdentity& id)
 | |
| {
 | |
|     return id.ReadId(is);
 | |
| }
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>& os, CIdentity id)
 | |
| {
 | |
|     return id.WriteId(os);
 | |
| }
 | |
| 
 | |
| template <class T>
 | |
| class IVectorContainerByReference : virtual public CObjRoot, public vector<T*>
 | |
| {
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class IMapContainer : virtual public CObjRoot, public map<CIdentity, T>
 | |
| {
 | |
| };
 | |
| 
 | |
| struct ISymbol : virtual public CObjRoot
 | |
| {
 | |
|     string strAddress;
 | |
|     string strName;
 | |
|     string strFrom;
 | |
|     UINT64 ullRva;
 | |
|     bool bStatic;
 | |
|     bool bFunction;
 | |
|     virtual void Relocate(UINT64)=0;
 | |
| };
 | |
| 
 | |
| class IModule : public IVectorContainerByReference<ISymbol>
 | |
| {
 | |
| public:
 | |
|     string strName;
 | |
|     CIdentity id;
 | |
|     virtual UINT64 BaseAddress(void) const=0;
 | |
|     virtual UINT64 BaseAddress(UINT64)=0;
 | |
|     virtual const ISymbol *EntryPoint(void) const=0;
 | |
| };
 | |
| 
 | |
| class IFirmwareVolume : public IVectorContainerByReference<IModule>
 | |
| {
 | |
| };
 | |
| 
 | |
| class IMapFileSet : public IMapContainer<istream*>
 | |
| {
 | |
| };
 | |
| 
 | |
| class IFfsSet : public IMapContainer<UINT64>
 | |
| {
 | |
| };
 | |
| 
 | |
| class CFfsSetFromLogFile : public IFfsSet
 | |
| {
 | |
| public:
 | |
|     CFfsSetFromLogFile(const string&);
 | |
| };
 | |
| 
 | |
| CFfsSetFromLogFile::CFfsSetFromLogFile(const string& strFName)
 | |
| {
 | |
|     ifstream ifs(strFName.c_str());
 | |
|     if (!ifs)
 | |
|         throw EFileNotFound(strFName);
 | |
| 
 | |
|     CIdentity ffsId;
 | |
|     while (!!ffsId.ReadId(ifs))
 | |
|     {
 | |
|         UINT64 ullBase;
 | |
|         if (!(ifs >> hex >> getUINT64(ullBase)))
 | |
|             throw EUnexpectedLogFileToken();
 | |
|         if (!insert(value_type(ffsId, ullBase)).second)
 | |
|             throw EDuplicatedFfsFile();
 | |
|     }
 | |
| }
 | |
| 
 | |
| class CMapFileSetFromInfFile : public IMapFileSet
 | |
| {
 | |
| public:
 | |
|     CMapFileSetFromInfFile(const string&);
 | |
|     ~CMapFileSetFromInfFile();
 | |
| };
 | |
| 
 | |
| CMapFileSetFromInfFile::CMapFileSetFromInfFile(const string& strFName)
 | |
| {
 | |
|     static const char cszEfiFileName[] = "EFI_FILE_NAME";
 | |
| 
 | |
|     ifstream ifs(strFName.c_str());
 | |
|     if (!ifs)
 | |
|         throw EFileNotFound(strFName);
 | |
| 
 | |
|     string strFile;
 | |
|     getline(ifs, strFile, ifstream::traits_type::to_char_type(ifstream::traits_type::eof()));
 | |
|     strFile.erase(0, strFile.find("[files]"));
 | |
| 
 | |
|     istringstream is(strFile);
 | |
|     string strTmp;
 | |
|     while (!!getline(is, strTmp))
 | |
|     {
 | |
|         string::size_type pos = strTmp.find(cszEfiFileName);
 | |
|         if (pos == string::npos)
 | |
|             continue;
 | |
| 
 | |
|         strTmp.erase(0, strTmp.find_first_not_of(" =", pos + sizeof(cszEfiFileName) - 1));
 | |
|         pos = strTmp.find_last_of("\\/");
 | |
|         string strId(
 | |
|             strTmp.begin() + pos + 1,
 | |
|             strTmp.begin() + strTmp.find('-', strTmp.find('-', strTmp.find('-', strTmp.find('-', strTmp.find('-') + 1) + 1) + 1) + 1)
 | |
|             );
 | |
|         strTmp.erase(pos + 1, strId.length() + 1);
 | |
|         strTmp.replace(strTmp.rfind('.'), string::npos, ".map");
 | |
| 
 | |
|         istream *ifmaps = new ifstream(strTmp.c_str());
 | |
|         if (ifmaps && !!*ifmaps &&
 | |
|             !insert(value_type(CIdentity(strId), ifmaps)).second)
 | |
|                 throw EDuplicatedFfsFile();
 | |
|     }
 | |
| }
 | |
| 
 | |
| CMapFileSetFromInfFile::~CMapFileSetFromInfFile()
 | |
| {
 | |
|     for (iterator i = begin(); i != end(); i++)
 | |
|         delete i->second;
 | |
| }
 | |
| 
 | |
| class CSymbolFromString : public ISymbol
 | |
| {
 | |
| public:
 | |
|     CSymbolFromString(const string&, bool = false);
 | |
|     void Relocate(UINT64);
 | |
| };
 | |
| 
 | |
| CSymbolFromString::CSymbolFromString(const string& strSymbol, bool b)
 | |
| {
 | |
|     bStatic = b;
 | |
| 
 | |
|     istringstream is(strSymbol);
 | |
|     is >> strAddress >> strName >> hex >> getUINT64(ullRva) >> strFrom;
 | |
|     if (strFrom == "f")
 | |
|     {
 | |
|         bFunction = true;
 | |
|         is >> strFrom;
 | |
|     }
 | |
|     else bFunction = false;
 | |
|     if (!is)
 | |
|         throw EUnexpectedMapFile("Symbol line format");
 | |
| }
 | |
| 
 | |
| void CSymbolFromString::Relocate(UINT64 ullDelta)
 | |
| {
 | |
|     if (ullRva > 0)
 | |
|         ullRva += ullDelta;
 | |
| }
 | |
| 
 | |
| class CModuleFromMap : public IModule
 | |
| {
 | |
| public:
 | |
|     CModuleFromMap(istream&);
 | |
|     ~CModuleFromMap();
 | |
| 
 | |
|     UINT64 BaseAddress() const;
 | |
|     UINT64 BaseAddress(UINT64);
 | |
|     const ISymbol *EntryPoint() const;
 | |
| 
 | |
| private:
 | |
|     UINT64 m_ullLoadAddress;
 | |
|     iterator m_iEntryPoint;
 | |
| 
 | |
|     static pair<string, string::size_type> FindToken(istream&, const string&);
 | |
| };
 | |
| 
 | |
| pair<string, string::size_type> CModuleFromMap::FindToken(istream& is, const string& strToken)
 | |
| {
 | |
|     for (string strTmp; !!getline(is, strTmp);)
 | |
|     {
 | |
|         string::size_type pos = strTmp.find(strToken);
 | |
|         if (pos != string::npos)
 | |
|             return pair<string, string::size_type>(strTmp, pos);
 | |
|     }
 | |
|     throw EUnexpectedMapFile(strToken);
 | |
| }
 | |
| 
 | |
| CModuleFromMap::CModuleFromMap(istream& imaps)
 | |
| {
 | |
|     static const char cszLoadAddr[] = "Preferred load address is";
 | |
|     static const char cszGlobal[] = "Address";
 | |
|     static const char cszEntryPoint[] = "entry point at";
 | |
|     static const char cszStatic[] = "Static symbols";
 | |
| 
 | |
|     pair<string, string::size_type> pairTmp;
 | |
|     istringstream iss;
 | |
| 
 | |
|     getline(imaps, strName);
 | |
|     strName.erase(0, strName.find_first_not_of(' '));
 | |
| 
 | |
|     pairTmp = FindToken(imaps, cszLoadAddr);
 | |
|     iss.str(pairTmp.first.substr(pairTmp.second + sizeof(cszLoadAddr) - 1));
 | |
|     iss >> getUINT64(m_ullLoadAddress);
 | |
| 
 | |
|     pairTmp = FindToken(imaps, cszGlobal);
 | |
|     while (!!getline(imaps, pairTmp.first) &&
 | |
|             pairTmp.first.find(cszEntryPoint) == string::npos)
 | |
|         if (pairTmp.first.find_first_not_of(' ') != string::npos)
 | |
|             push_back(new CSymbolFromString(pairTmp.first));
 | |
| 
 | |
|     iss.str(pairTmp.first.substr(pairTmp.first.find(cszEntryPoint) + sizeof(cszEntryPoint) - 1));
 | |
|     iss.clear();
 | |
|     string strEntryPoint;
 | |
|     iss >> strEntryPoint;
 | |
| 
 | |
|     pairTmp = FindToken(imaps, cszStatic);
 | |
|     if (pairTmp.second)
 | |
|         while (!!getline(imaps, pairTmp.first))
 | |
|             if (pairTmp.first.find_first_not_of(' ') != string::npos)
 | |
|                 push_back(new CSymbolFromString(pairTmp.first, true));
 | |
| 
 | |
|     for (m_iEntryPoint = begin();
 | |
|          m_iEntryPoint != end() && (*m_iEntryPoint)->strAddress != strEntryPoint;
 | |
|          m_iEntryPoint++);
 | |
|     if (m_iEntryPoint == end())
 | |
|         throw EUnexpectedMapFile("Entry point not found");
 | |
| }
 | |
| 
 | |
| CModuleFromMap::~CModuleFromMap()
 | |
| {
 | |
|     for (iterator i = begin(); i != end(); i++)
 | |
|         delete *i;
 | |
| }
 | |
| 
 | |
| UINT64 CModuleFromMap::BaseAddress(void) const
 | |
| {
 | |
|     return m_ullLoadAddress;
 | |
| }
 | |
| 
 | |
| UINT64 CModuleFromMap::BaseAddress(UINT64 ullNewBase)
 | |
| {
 | |
|     ullNewBase -= m_ullLoadAddress;
 | |
|     for (iterator i = begin(); i != end(); i++)
 | |
|         (*i)->Relocate(ullNewBase);
 | |
|     m_ullLoadAddress += ullNewBase;
 | |
|     return m_ullLoadAddress - ullNewBase;
 | |
| }
 | |
| 
 | |
| const ISymbol *CModuleFromMap::EntryPoint(void) const
 | |
| {
 | |
|     return *m_iEntryPoint;
 | |
| }
 | |
| 
 | |
| class CFvMap : public IFirmwareVolume
 | |
| {
 | |
| public:
 | |
|     CFvMap(IFfsSet*, IMapFileSet*);
 | |
|     ~CFvMap();
 | |
| 
 | |
| private:
 | |
|     CFvMap(const CFvMap&);
 | |
| };
 | |
| 
 | |
| CFvMap::CFvMap(IFfsSet *pFfsSet, IMapFileSet *pMapSet)
 | |
| {
 | |
|     for (IFfsSet::iterator i = pFfsSet->begin(); i != pFfsSet->end(); i++)
 | |
|     {
 | |
|         IMapFileSet::iterator j = pMapSet->find(i->first);
 | |
|         if (j != pMapSet->end())
 | |
|         {
 | |
|             IModule *pModule = new CModuleFromMap(*j->second);
 | |
|             pModule->id = i->first;
 | |
|             pModule->BaseAddress(i->second);
 | |
|             push_back(pModule);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| CFvMap::~CFvMap()
 | |
| {
 | |
|     for (iterator i = begin(); i != end(); i++)
 | |
|         delete *i;
 | |
| }
 | |
| 
 | |
| class CFvMapGenerator : public CObjRoot
 | |
| {
 | |
| public:
 | |
|     CFvMapGenerator(const IFirmwareVolume *pFv) : m_pFv(pFv) {}
 | |
|     CFvMapGenerator(const CFvMapGenerator& r) : m_pFv(r.m_pFv) {}
 | |
| 
 | |
|     template <class _E, class _Tr>
 | |
|     friend basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>&, CFvMapGenerator);
 | |
| 
 | |
| private:
 | |
|     static bool Less(const IModule*, const IModule*);
 | |
| 
 | |
| private:
 | |
|     const IFirmwareVolume *m_pFv;
 | |
| };
 | |
| 
 | |
| template <class _E, class _Tr>
 | |
| basic_ostream<_E, _Tr>& operator << (basic_ostream<_E, _Tr>& os, CFvMapGenerator fvMapFmt)
 | |
| {
 | |
|     vector<IModule*> rgMods(fvMapFmt.m_pFv->begin(), fvMapFmt.m_pFv->end());
 | |
|     sort(rgMods.begin(), rgMods.end(), CFvMapGenerator::Less);
 | |
|     for (vector<IModule*>::iterator i = rgMods.begin(); i != rgMods.end(); i++)
 | |
|     {
 | |
|         os << (*i)->strName << hex << " (BaseAddress=" << putUINT64((*i)->BaseAddress());
 | |
|         os << ", EntryPoint=" << hex << putUINT64((*i)->EntryPoint()->ullRva);
 | |
|         os << ", GUID=";
 | |
|         (*i)->id.WriteId(os);
 | |
|         os << ")" << endl << endl;
 | |
| 
 | |
|         for (IModule::iterator j = (*i)->begin(); j != (*i)->end(); j++)
 | |
|         {
 | |
|             os << hex << "  " << setw(16) << setfill('0') << putUINT64((*j)->ullRva);
 | |
|             os << ((*j)->bFunction ? " F" : "  ")
 | |
|                 << ((*j)->bStatic ? "S " : "  ")
 | |
|                 << (*j)->strName << endl;
 | |
|         }
 | |
| 
 | |
|         os << endl << endl;
 | |
|     }
 | |
|     return os;
 | |
| }
 | |
| 
 | |
| bool CFvMapGenerator::Less(const IModule *pModL, const IModule *pModR)
 | |
| {
 | |
|     return pModL->BaseAddress() < pModR->BaseAddress();
 | |
| }
 | |
| 
 | |
| class CApplication : public CObjRoot
 | |
| {
 | |
| public:
 | |
|     CApplication(int, char**);
 | |
|     int Run(void);
 | |
| 
 | |
| private:
 | |
|     char **m_ppszArg;
 | |
| private:
 | |
|     CApplication(const CApplication&);
 | |
| };
 | |
| 
 | |
| CApplication::CApplication(int cArg, char *ppszArg[])
 | |
| : m_ppszArg(ppszArg)
 | |
| {
 | |
|     if (cArg != 4)
 | |
|         throw EUsage();
 | |
| }
 | |
| 
 | |
| int CApplication::Run(void)
 | |
| {
 | |
|     CFfsSetFromLogFile ffsSet(m_ppszArg[1]);
 | |
|     CMapFileSetFromInfFile mapSet(m_ppszArg[2]);
 | |
|     ofstream ofs(m_ppszArg[3]);
 | |
|     CFvMap fvMap(&ffsSet, &mapSet);
 | |
|     ofs << CFvMapGenerator(&fvMap);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int main(int argc, char *argv[])
 | |
| {
 | |
|     try
 | |
|     {
 | |
|         CApplication app(argc, argv);
 | |
|         return app.Run();
 | |
|     }
 | |
|     catch (const exception& e)
 | |
|     {
 | |
|         cerr << e.what() << endl;
 | |
|         return -1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #ifdef _DDK3790x1830_WORKAROUND
 | |
| extern "C" void __fastcall __security_check_cookie(int)
 | |
| {
 | |
| }
 | |
| #endif
 |