]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Added a new tool GenFvMap, which is able to generate FV map files upon LOG files...
authorbxing <bxing@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Dec 2006 09:17:16 +0000 (09:17 +0000)
committerbxing <bxing@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Dec 2006 09:17:16 +0000 (09:17 +0000)
2. Updated PeiRebase to generate LOG files while processing FV images. The original MAP feature and its corresponding option '-M' are dropped, however, they are superceded by the FV map file.
3. The FV map file are not generated yet. My next check-in will update FPD files to generate FV map files.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2157 6f19259b-4bc3-4df7-8a09-765794883524

Tools/CCode/Source/GenFvMap/GenFvMap.cpp [new file with mode: 0644]
Tools/CCode/Source/GenFvMap/build.xml [new file with mode: 0644]
Tools/CCode/Source/PeiRebase/PeiRebaseExe.c
Tools/CCode/Source/PeiRebase/PeiRebaseExe.h
Tools/CCode/Source/TianoTools.msa
Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/PeiReBaseTask.java

diff --git a/Tools/CCode/Source/GenFvMap/GenFvMap.cpp b/Tools/CCode/Source/GenFvMap/GenFvMap.cpp
new file mode 100644 (file)
index 0000000..4a8c726
--- /dev/null
@@ -0,0 +1,507 @@
+//****************************************************************************\r
+//**\r
+//**  Copyright  (C) 2006 Intel Corporation. All rights reserved. \r
+//**\r
+//** The information and source code contained herein is the exclusive \r
+//** property of Intel Corporation and may not be disclosed, examined\r
+//** or reproduced in whole or in part without explicit written authorization \r
+//** from the company.\r
+//**\r
+//****************************************************************************\r
+\r
+#include <stdexcept>\r
+#include <list>\r
+#include <map>\r
+#include <iostream>\r
+#include <iomanip>\r
+#include <fstream>\r
+#include <sstream>\r
+#include <string>\r
+#include <utility>\r
+#include <algorithm>\r
+#include <functional>\r
+using namespace std;\r
+\r
+typedef unsigned __int64 ulonglong_t;\r
+\r
+template <class T>\r
+class CMemoryLeakChecker : public list<T*>\r
+{\r
+public:\r
+    static CMemoryLeakChecker<T>& GetInstance(void);\r
+\r
+private:\r
+    CMemoryLeakChecker(void)\r
+    {\r
+    }\r
+\r
+    ~CMemoryLeakChecker(void);\r
+};\r
+\r
+template <class T>\r
+CMemoryLeakChecker<T>& CMemoryLeakChecker<T>::GetInstance(void)\r
+{\r
+    static CMemoryLeakChecker<T> s_memLeakChecker;\r
+    return s_memLeakChecker;\r
+}\r
+\r
+template <class T>\r
+CMemoryLeakChecker<T>::~CMemoryLeakChecker(void)\r
+{\r
+    if (!list<T*>::empty())\r
+        throw logic_error(__FUNCTION__ ": Memory leak detected!");\r
+}\r
+\r
+class CObjRoot\r
+{\r
+protected:\r
+    CObjRoot(void);\r
+    virtual ~CObjRoot(void);\r
+};\r
+\r
+CObjRoot::CObjRoot(void)\r
+{\r
+    CMemoryLeakChecker<CObjRoot>::GetInstance().push_back(this);\r
+}\r
+\r
+CObjRoot::~CObjRoot(void)\r
+{\r
+    CMemoryLeakChecker<CObjRoot>::GetInstance().remove(this);\r
+}\r
+\r
+class CIdentity : public CObjRoot\r
+{\r
+public:\r
+    CIdentity(void);\r
+    CIdentity(const string&);\r
+    CIdentity(const CIdentity&);\r
+\r
+    bool operator < (const CIdentity&) const;\r
+    friend istream& operator >> (istream&, CIdentity&);\r
+\r
+    static const string::size_type s_nIdStrLen;\r
+\r
+protected:\r
+    ulonglong_t m_ullId[2];\r
+};\r
+\r
+const string::size_type CIdentity::s_nIdStrLen = 36;\r
+\r
+CIdentity::CIdentity(void)\r
+{\r
+    memset(m_ullId, 0, sizeof(m_ullId));\r
+}\r
+\r
+CIdentity::CIdentity(const string& strId)\r
+{\r
+    if (strId.length() != CIdentity::s_nIdStrLen ||\r
+        strId[8] != '-' ||\r
+        strId[13] != '-' ||\r
+        strId[18] != '-' ||\r
+        strId[23] != '-')\r
+        throw runtime_error(\r
+            __FUNCTION__ ": Error GUID format " + strId);\r
+\r
+    string strIdCopy(strId);\r
+    strIdCopy.erase(23, 1);\r
+    strIdCopy[18] = ' ';\r
+    strIdCopy.erase(13, 1);\r
+    strIdCopy.erase(8, 1);\r
+\r
+    istringstream is(strIdCopy);\r
+    is >> hex >> m_ullId[0] >> m_ullId[1];\r
+    if (!is)\r
+        throw runtime_error(\r
+            __FUNCTION__ ": GUID contains invalid characters" + strId);\r
+}\r
+\r
+CIdentity::CIdentity(const CIdentity& idRight)\r
+{\r
+    memmove(m_ullId, idRight.m_ullId, sizeof(m_ullId));\r
+}\r
+\r
+bool CIdentity::operator < (const CIdentity& idRight) const\r
+{\r
+    return memcmp(m_ullId, idRight.m_ullId, sizeof(m_ullId)) < 0;\r
+}\r
+\r
+istream& operator >> (istream& is, CIdentity& idRight)\r
+{\r
+    string strId;\r
+    is >> strId;\r
+    if (!!is)\r
+        idRight = CIdentity(strId);\r
+    return is;\r
+}\r
+\r
+class CInputFile : public CObjRoot\r
+{\r
+protected:\r
+    CInputFile(const string&);\r
+    CInputFile(istream&);\r
+    istream& GetLine(string&);\r
+\r
+private:\r
+    CInputFile(const CInputFile&);\r
+    CInputFile& operator = (const CInputFile&);\r
+\r
+private:\r
+    auto_ptr<istream> m_pIs;\r
+\r
+protected:\r
+    istream& m_is;\r
+};\r
+\r
+CInputFile::CInputFile(const string& strFName)\r
+: m_pIs(new ifstream(strFName.c_str()))\r
+, m_is(*m_pIs)\r
+{\r
+    if (!m_is)\r
+        throw runtime_error(__FUNCTION__ ": Error opening input file " + strFName);\r
+}\r
+\r
+CInputFile::CInputFile(istream& is)\r
+: m_is(is)\r
+{\r
+    if (!m_is)\r
+        throw runtime_error(__FUNCTION__ ": Error opening input stream");\r
+}\r
+\r
+istream& CInputFile::GetLine(string& strALine)\r
+{\r
+    if (!!m_is)\r
+        while (!!getline(m_is, strALine))\r
+        {\r
+            string::size_type pos = strALine.find_last_not_of(' ');\r
+            if (pos != string::npos)\r
+            {\r
+                strALine.erase(pos + 1);\r
+                strALine.erase(0, strALine.find_first_not_of(' '));\r
+                break;\r
+            }\r
+        }\r
+    return m_is;\r
+}\r
+\r
+class CIdAddressMap : public CInputFile, public map<CIdentity, ulonglong_t>\r
+{\r
+public:\r
+    CIdAddressMap(istream&);\r
+};\r
+\r
+CIdAddressMap::CIdAddressMap(istream& is)\r
+: CInputFile(is)\r
+{\r
+    CIdentity id;\r
+    ulonglong_t ullBase;\r
+\r
+    while (!!(m_is >> hex >> id >> ullBase))\r
+        if (!insert(value_type(id, ullBase)).second)\r
+            throw runtime_error(__FUNCTION__ ": Duplicated files");\r
+}\r
+\r
+class CIdPathMap : public CInputFile, public map<CIdentity, string>\r
+{\r
+public:\r
+    CIdPathMap(istream&);\r
+};\r
+\r
+CIdPathMap::CIdPathMap(istream& is)\r
+: CInputFile(is)\r
+{\r
+    static const char cszFileSec[] = "[files]";\r
+    static const char cszFfsFile[] = "EFI_FILE_NAME";\r
+\r
+    string strALine;\r
+\r
+    // Find the [files] section\r
+    while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszFileSec) - 1, cszFileSec));\r
+\r
+    // m_is error means no FFS files listed in this INF file\r
+    if (!m_is)\r
+        return;\r
+\r
+    // Parse FFS files one by one\r
+    while (!!GetLine(strALine))\r
+    {\r
+        // Test if this begins a new section\r
+        if (strALine[0] == '[')\r
+            break;\r
+\r
+        // Is it a line of FFS file?\r
+        if (strALine.compare(0, sizeof(cszFfsFile) - 1, cszFfsFile))\r
+            continue;\r
+\r
+        string::size_type pos = strALine.find_first_not_of(' ', sizeof(cszFfsFile) - 1);\r
+        if (pos == string::npos || strALine[pos] != '=')\r
+            throw runtime_error(__FUNCTION__ ": Invalid FV INF format");\r
+        pos = strALine.find_first_not_of(' ', pos + 1);\r
+        if (pos == string::npos)\r
+            throw runtime_error(__FUNCTION__ ": Incomplete line");\r
+\r
+        strALine.erase(0, pos);\r
+        pos = strALine.rfind('\\');\r
+        if (pos == string::npos)\r
+            pos = 0;\r
+        else pos++;\r
+\r
+        CIdentity id(strALine.substr(pos, CIdentity::s_nIdStrLen));\r
+        if (!insert(value_type(id, strALine)).second)\r
+            throw runtime_error(__FUNCTION__ ": Duplicated FFS files");\r
+    }\r
+}\r
+\r
+class CSymbol : public CObjRoot\r
+{\r
+public:\r
+    string m_strAddress;\r
+    string m_strName;\r
+    ulonglong_t m_ullRva;\r
+    string m_strFrom;\r
+    bool m_bStatic;\r
+    bool m_bFunction;\r
+\r
+    CSymbol()\r
+    {\r
+    }\r
+    CSymbol(const string&, bool = false);\r
+    friend ostream& operator << (ostream&, const CSymbol&);\r
+};\r
+\r
+CSymbol::CSymbol(const string& strALine, bool bStatic)\r
+: m_bStatic(bStatic)\r
+{\r
+    istringstream is(strALine);\r
+\r
+    is >> m_strAddress >> m_strName >> hex >> m_ullRva >> m_strFrom;\r
+    if (m_strFrom == "F" || m_strFrom == "f")\r
+    {\r
+        m_bFunction = true;\r
+        is >> m_strFrom;\r
+    } else m_bFunction = false;\r
+}\r
+\r
+ostream& operator << (ostream& os, const CSymbol& symbol)\r
+{\r
+    os << hex << setw(16) << setfill('0') << symbol.m_ullRva << setw(0);\r
+    os << ' ' << (symbol.m_bFunction ? 'F' : ' ')\r
+        << (symbol.m_bStatic ? 'S' : ' ') << ' ';\r
+    return os << symbol.m_strName << endl;\r
+}\r
+\r
+class CMapFile : public CInputFile, public list<CSymbol>\r
+{\r
+public:\r
+    CMapFile(const string&);\r
+\r
+    void SetLoadAddress(ulonglong_t);\r
+    friend ostream& operator << (ostream&, const CMapFile&);\r
+\r
+    string m_strModuleName;\r
+    ulonglong_t m_ullLoadAddr;\r
+    string m_strEntryPoint;\r
+};\r
+\r
+CMapFile::CMapFile(const string& strFName)\r
+: CInputFile(strFName)\r
+{\r
+    static const char cszLoadAddr[] = "Preferred load address is";\r
+    static const char cszGlobal[] = "Address";\r
+    static const char cszEntryPoint[] = "entry point at";\r
+    static const char cszStatic[] = "Static symbols";\r
+\r
+    string strALine;\r
+\r
+    GetLine(m_strModuleName);\r
+\r
+    while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszLoadAddr) - 1, cszLoadAddr));\r
+    if (!m_is)\r
+        throw runtime_error(__FUNCTION__ ": Load Address not listed in map file");\r
+\r
+    istringstream is(strALine.substr(sizeof(cszLoadAddr) - 1));\r
+    if (!(is >> hex >> m_ullLoadAddr))\r
+        throw runtime_error(__FUNCTION__ ": Unexpected Load Address format");\r
+\r
+    while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszGlobal) - 1, cszGlobal));\r
+    if (!m_is)\r
+        throw runtime_error(__FUNCTION__ ": Global symbols not found in map file");\r
+\r
+    while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszEntryPoint) - 1, cszEntryPoint))\r
+        push_back(CSymbol(strALine));\r
+    if (!m_is)\r
+        throw runtime_error(__FUNCTION__ ": Entry Point not listed in map file");\r
+\r
+    is.str(strALine.substr(strALine.find_first_not_of(' ', sizeof(cszEntryPoint) - 1)));\r
+    is.clear();\r
+    if (!getline(is, m_strEntryPoint))\r
+        throw runtime_error(__FUNCTION__ ": Unexpected Entry Point format");\r
+\r
+    while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszStatic) - 1, cszStatic));\r
+    while (!!GetLine(strALine))\r
+        push_back(CSymbol(strALine, true));\r
+}\r
+\r
+void CMapFile::SetLoadAddress(ulonglong_t ullLoadAddr)\r
+{\r
+    for (iterator i = begin(); i != end(); i++)\r
+        if (i->m_ullRva != 0)\r
+            i->m_ullRva += ullLoadAddr - m_ullLoadAddr;\r
+    m_ullLoadAddr = ullLoadAddr;\r
+}\r
+\r
+ostream& operator << (ostream& os, const CMapFile& mapFile)\r
+{\r
+    CMapFile::const_iterator i = mapFile.begin();\r
+    while (i != mapFile.end() && i->m_strAddress != mapFile.m_strEntryPoint)\r
+        i++;\r
+    if (i == mapFile.end())\r
+        throw runtime_error(\r
+            __FUNCTION__ ": Entry point not found for module " +\r
+            mapFile.m_strModuleName);\r
+\r
+    os << endl << hex\r
+        << mapFile.m_strModuleName << " (EP=" << i->m_ullRva\r
+        << ", BA=" << mapFile.m_ullLoadAddr << ')' << endl\r
+        << endl;\r
+\r
+    for (i = mapFile.begin(); i != mapFile.end(); i++)\r
+        os << "  " << *i;\r
+\r
+    return os << endl;\r
+}\r
+\r
+class COutputFile : public CObjRoot\r
+{\r
+protected:\r
+    COutputFile(ostream&);\r
+    ostream& m_os;\r
+\r
+private:\r
+    COutputFile(const COutputFile&);\r
+    COutputFile& operator = (const COutputFile&);\r
+};\r
+\r
+class CFvMapFile : public CObjRoot, public map<CIdentity, CMapFile*>\r
+{\r
+public:\r
+    CFvMapFile(const CIdAddressMap&, const CIdPathMap&);\r
+    ~CFvMapFile(void);\r
+\r
+    friend ostream& operator << (ostream&, const CFvMapFile&);\r
+\r
+private:\r
+    void Cleanup(void);\r
+};\r
+\r
+CFvMapFile::CFvMapFile(const CIdAddressMap& idAddr, const CIdPathMap& idPath)\r
+{\r
+    for (CIdAddressMap::const_iterator i = idAddr.begin(); i != idAddr.end(); i++)\r
+    {\r
+        CIdPathMap::const_iterator j = idPath.find(i->first);\r
+        if (j == idPath.end())\r
+            throw runtime_error(__FUNCTION__ ": Map file not found");\r
+\r
+        try\r
+        {\r
+            pair<iterator, bool> k = insert(value_type(i->first,\r
+                new CMapFile(j->second.substr(0, j->second.rfind('.')) + ".map")));\r
+            if (!k.second)\r
+                throw logic_error(__FUNCTION__ ": Duplicated file found in rebase log");\r
+\r
+            k.first->second->SetLoadAddress(i->second);\r
+        }\r
+        catch (const runtime_error& e)\r
+        {\r
+            cerr << e.what() << endl;\r
+        }\r
+    }\r
+}\r
+\r
+void CFvMapFile::Cleanup(void)\r
+{\r
+    for (iterator i = begin(); i != end(); i++)\r
+        delete i->second;\r
+}\r
+\r
+ostream& operator << (ostream& os, const CFvMapFile& fvMap)\r
+{\r
+    for (CFvMapFile::const_iterator i = fvMap.begin(); !!os && i != fvMap.end(); i++)\r
+        os << *i->second;\r
+    return os;\r
+}\r
+\r
+CFvMapFile::~CFvMapFile(void)\r
+{\r
+    Cleanup();\r
+}\r
+\r
+class CGenFvMapUsage : public invalid_argument\r
+{\r
+public:\r
+    CGenFvMapUsage(void) : invalid_argument(s_szUsage)\r
+    {\r
+    }\r
+\r
+private:\r
+    static const char s_szUsage[];\r
+};\r
+\r
+const char CGenFvMapUsage::s_szUsage[] = "Usage: GenFvMap <LOG> <INF> <MAP>";\r
+\r
+class CGenFvMapApp : public CObjRoot\r
+{\r
+public:\r
+    CGenFvMapApp(int, char *[]);\r
+    ~CGenFvMapApp(void);\r
+\r
+    int Run(void);\r
+\r
+private:\r
+    int m_cArgc;\r
+    char **m_ppszArgv;\r
+};\r
+\r
+CGenFvMapApp::CGenFvMapApp(int cArgc, char *ppszArgv[])\r
+: m_cArgc(cArgc)\r
+, m_ppszArgv(ppszArgv)\r
+{\r
+    if (cArgc != 4)\r
+        throw CGenFvMapUsage();\r
+}\r
+\r
+CGenFvMapApp::~CGenFvMapApp(void)\r
+{\r
+}\r
+\r
+int CGenFvMapApp::Run(void)\r
+{\r
+    ifstream isLog(m_ppszArgv[1]);\r
+    ifstream isInf(m_ppszArgv[2]);\r
+\r
+    CIdAddressMap idAddress(isLog);\r
+    CIdPathMap idPath(isInf);\r
+\r
+    CFvMapFile fvMap(idAddress, idPath);\r
+\r
+    ofstream osMap(m_ppszArgv[3], ios_base::out | ios_base::trunc);\r
+    osMap << fvMap;\r
+\r
+    if (!osMap)\r
+        throw runtime_error(__FUNCTION__ ": Error writing output file");\r
+\r
+    return 0;\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+    try\r
+    {\r
+        CGenFvMapApp app(argc, argv);\r
+        return app.Run();\r
+    }\r
+    catch (const exception& e)\r
+    {\r
+        cerr << e.what() << endl;\r
+        return -1;\r
+    }\r
+}\r
diff --git a/Tools/CCode/Source/GenFvMap/build.xml b/Tools/CCode/Source/GenFvMap/build.xml
new file mode 100644 (file)
index 0000000..6c236bf
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" ?>\r
+<!--\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+-->\r
+<project default="GenTool" basedir=".">\r
+<!--\r
+    EDK GenTEImage Tool\r
+  Copyright (c) 2006, Intel Corporation\r
+-->\r
+  <property name="ToolName" value="GenFvMap"/>\r
+  <property name="FileSet" value="*.cpp"/>\r
+\r
+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>\r
+\r
+\r
+  <property name="LINK_OUTPUT_TYPE" value="static"/>\r
+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>\r
+\r
+  <target name="GenTool" depends="init, Tool">\r
+    <echo message="The EDK Tool: ${ToolName} build has completed!"/>\r
+  </target>\r
+\r
+  <target name="init">\r
+    <echo message="Building the EDK Tool: ${ToolName}"/>\r
+    <mkdir dir="${BUILD_DIR}"/>\r
+  </target>\r
+\r
+  <target name="Tool" depends="init">\r
+    <cc name="${ToolChain}" objdir="${BUILD_DIR}"\r
+        outfile="${BIN_DIR}/${ToolName}"\r
+        outtype="executable"\r
+        debug="true"\r
+        optimize="speed">\r
+      <compilerarg value="${ExtraArgus}" if="ExtraArgus" />\r
+      <compilerarg value="/EHsc" unless="GCC"/>\r
+\r
+      <fileset dir="${basedir}/${ToolName}"\r
+        includes="${FileSet}"\r
+        defaultexcludes="TRUE"\r
+        excludes="*.xml *.inf"/>\r
+\r
+      <includepath path="${PACKAGE_DIR}/Include"/>\r
+      <includepath path="${PACKAGE_DIR}/Include/${HostArch}"/>\r
+      <includepath path="${PACKAGE_DIR}/Common"/>\r
+      <libset dir="${LIB_DIR}" libs="CommonTools"/>\r
+    </cc>\r
+  </target>\r
+\r
+  <target name="clean">\r
+    <echo message="Removing Intermediate Files Only"/>\r
+    <delete>\r
+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>\r
+    </delete>\r
+  </target>\r
+\r
+  <target name="cleanall">\r
+    <echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>\r
+    <delete failonerror="false" quiet="true" includeEmptyDirs="true">\r
+      <fileset dir="${BUILD_DIR}"/>\r
+      <fileset file="${BIN_DIR}/${ToolName}${ext_exe}"/>\r
+      <fileset file="${BIN_DIR}/${ToolName}.pdb"/>\r
+    </delete>\r
+  </target>\r
+\r
+</project>\r
index 2d28a83066d7fc84b1b557d8e218a05ade7717a4..11192c428b3feae44e654149c580a938d8d342b1 100644 (file)
@@ -1,8 +1,8 @@
 /*++\r
 \r
 Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
 /*++\r
 \r
 Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available \r
-under the terms and conditions of the BSD License which accompanies this \r
+This program and the accompanying materials are licensed and made available\r
+under the terms and conditions of the BSD License which accompanies this\r
 distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
 distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
@@ -59,23 +59,21 @@ Arguments:
 \r
   argc          - Number of command line arguments\r
   argv[]:\r
 \r
   argc          - Number of command line arguments\r
   argv[]:\r
-  BaseAddress     The base address to use for rebasing the FV.  The correct \r
+  BaseAddress     The base address to use for rebasing the FV.  The correct\r
                   format is a hex number preceded by 0x.\r
   InputFileName   The name of the input FV file.\r
   OutputFileName  The name of the output FV file.\r
                   format is a hex number preceded by 0x.\r
   InputFileName   The name of the input FV file.\r
   OutputFileName  The name of the output FV file.\r
-  MapFileName     The name of the map file of relocation info.\r
 \r
   Arguments come in pair in any order.\r
 \r
   Arguments come in pair in any order.\r
-    -I InputFileName \r
+    -I InputFileName\r
     -O OutputFileName\r
     -O OutputFileName\r
-    -B BaseAddress \r
-    -M MapFileName \r
+    -B BaseAddress\r
 \r
 Returns:\r
 \r
   0   No error conditions detected.\r
   1   One or more of the input parameters is invalid.\r
 \r
 Returns:\r
 \r
   0   No error conditions detected.\r
   1   One or more of the input parameters is invalid.\r
-  2   A resource required by the utility was unavailable.  \r
+  2   A resource required by the utility was unavailable.\r
       Most commonly this will be memory allocation or file creation.\r
   3   PeiRebase.dll could not be loaded.\r
   4   Error executing the PEI rebase.\r
       Most commonly this will be memory allocation or file creation.\r
   3   PeiRebase.dll could not be loaded.\r
   4   Error executing the PEI rebase.\r
@@ -84,14 +82,13 @@ Returns:
 {\r
   UINT8                       Index;\r
   CHAR8                       InputFileName[_MAX_PATH];\r
 {\r
   UINT8                       Index;\r
   CHAR8                       InputFileName[_MAX_PATH];\r
-  CHAR8                       OutputFileName[_MAX_PATH];\r
-  CHAR8                       MapFileName[_MAX_PATH];\r
-  EFI_PHYSICAL_ADDRESS        BaseAddress;\r
-  BOOLEAN                     BaseAddressSet;\r
+  CHAR8                       *OutputFileName;\r
+  EFI_PHYSICAL_ADDRESS        XipBase, BsBase, RtBase;\r
+  UINT32                      BaseTypes;\r
   EFI_STATUS                  Status;\r
   FILE                        *InputFile;\r
   FILE                        *OutputFile;\r
   EFI_STATUS                  Status;\r
   FILE                        *InputFile;\r
   FILE                        *OutputFile;\r
-  FILE                        *MapFile;\r
+  FILE                        *LogFile;\r
   UINT64                      FvOffset;\r
   UINT32                      FileCount;\r
   int                         BytesRead;\r
   UINT64                      FvOffset;\r
   UINT32                      FileCount;\r
   int                         BytesRead;\r
@@ -99,11 +96,8 @@ Returns:
   UINT32                      FvSize;\r
   EFI_FFS_FILE_HEADER         *CurrentFile;\r
   BOOLEAN                     ErasePolarity;\r
   UINT32                      FvSize;\r
   EFI_FFS_FILE_HEADER         *CurrentFile;\r
   BOOLEAN                     ErasePolarity;\r
-  EFI_PHYSICAL_ADDRESS        CurrentFileBaseAddress;\r
-  CHAR8                       InfFileName[_MAX_PATH];\r
-  CHAR8                       *InfFileImage;\r
-  UINTN                       InfFileSize;\r
   MEMORY_FILE                 InfMemoryFile;\r
   MEMORY_FILE                 InfMemoryFile;\r
+  CHAR8                       StringBuffer[0x100];\r
 \r
   ErasePolarity = FALSE;\r
   //\r
 \r
   ErasePolarity = FALSE;\r
   //\r
@@ -121,21 +115,17 @@ Returns:
   //\r
   // Initialize variables\r
   //\r
   //\r
   // Initialize variables\r
   //\r
-  InputFileName[0]  = 0;\r
-  OutputFileName[0] = 0;\r
-  MapFileName[0]    = 0;\r
-  BaseAddress       = 0;\r
-  BaseAddressSet    = FALSE;\r
+  InputFileName[0]  = '\0';\r
+  OutputFileName    = NULL;\r
+  XipBase = BsBase = RtBase = 0;\r
+  BaseTypes         = 0;\r
   FvOffset          = 0;\r
   FileCount         = 0;\r
   ErasePolarity     = FALSE;\r
   InputFile         = NULL;\r
   OutputFile        = NULL;\r
   FvOffset          = 0;\r
   FileCount         = 0;\r
   ErasePolarity     = FALSE;\r
   InputFile         = NULL;\r
   OutputFile        = NULL;\r
-  MapFile           = NULL;\r
+  LogFile           = NULL;\r
   FvImage           = NULL;\r
   FvImage           = NULL;\r
-  InfFileImage      = NULL;\r
-  InfFileSize       = 0;\r
-  strcpy (InfFileName, "");\r
 \r
   //\r
   // Parse the command line arguments\r
 \r
   //\r
   // Parse the command line arguments\r
@@ -156,7 +146,7 @@ Returns:
       PrintUsage ();\r
       Error (NULL, 0, 0, argv[Index], "unrecognized option");\r
       return STATUS_ERROR;\r
       PrintUsage ();\r
       Error (NULL, 0, 0, argv[Index], "unrecognized option");\r
       return STATUS_ERROR;\r
-    }    \r
+    }\r
     //\r
     // Determine argument to read\r
     //\r
     //\r
     // Determine argument to read\r
     //\r
@@ -174,8 +164,8 @@ Returns:
 \r
     case 'O':\r
     case 'o':\r
 \r
     case 'O':\r
     case 'o':\r
-      if (strlen (OutputFileName) == 0) {\r
-        strcpy (OutputFileName, argv[Index + 1]);\r
+      if (OutputFileName == NULL) {\r
+        OutputFileName = argv[Index + 1];\r
       } else {\r
         PrintUsage ();\r
         Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");\r
       } else {\r
         PrintUsage ();\r
         Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");\r
@@ -183,79 +173,86 @@ Returns:
       }\r
       break;\r
 \r
       }\r
       break;\r
 \r
+    case 'F':\r
+    case 'f':\r
+      //\r
+      // Load INF file into memory & initialize MEMORY_FILE structure\r
+      //\r
+      Status = GetFileImage (argv[Index + 1], &InfMemoryFile.FileImage, (UINT32*)&InfMemoryFile.Eof);\r
+      InfMemoryFile.Eof = InfMemoryFile.FileImage + (UINT32)(UINTN)InfMemoryFile.Eof;\r
+      InfMemoryFile.CurrentFilePointer = InfMemoryFile.FileImage;\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 0, argv[Index + 1], "Error opening FvInfFile");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      //\r
+      // Read BaseAddress from fv.inf file\r
+      //\r
+      FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, StringBuffer);\r
+\r
+      //\r
+      // Free INF file image\r
+      //\r
+      free (InfMemoryFile.FileImage);\r
+\r
+      //\r
+      // Point argv[Index + 1] to StringBuffer so that it could be processed as "-b"\r
+      //\r
+      argv[Index + 1] = StringBuffer;\r
+\r
     case 'B':\r
     case 'b':\r
     case 'B':\r
     case 'b':\r
-      if (!BaseAddressSet) {\r
-        Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);\r
-        if (EFI_ERROR (Status)) {\r
-          PrintUsage ();\r
-          Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");\r
-          return STATUS_ERROR;\r
-        }\r
+      if (BaseTypes & 1) {\r
+        PrintUsage ();\r
+        Error (NULL, 0, 0, argv[Index + 1], "XipBaseAddress may be specified only once by either -b or -f");\r
+        return STATUS_ERROR;\r
+      }\r
 \r
 \r
-        BaseAddressSet = TRUE;\r
-      } else {\r
+      Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &XipBase);\r
+      if (EFI_ERROR (Status)) {\r
         PrintUsage ();\r
         PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");\r
+        Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for XIP base address");\r
         return STATUS_ERROR;\r
       }\r
         return STATUS_ERROR;\r
       }\r
+\r
+      BaseTypes |= 1;\r
       break;\r
 \r
       break;\r
 \r
-    case 'F':\r
-    case 'f':\r
-      if (!BaseAddressSet) {\r
-        strcpy (InfFileName, argv[Index + 1]);\r
-        //\r
-        // Read the INF file image\r
-        //\r
-        Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
-        if (EFI_ERROR (Status)) {\r
-          PrintUsage ();\r
-          Error (NULL, 0, 0, argv[Index + 1], "-f FvInfFile can't be opened.");\r
-          return STATUS_ERROR;\r
-        }\r
-        //\r
-        // Initialize file structures\r
-        //\r
-        InfMemoryFile.FileImage           = InfFileImage;\r
-        InfMemoryFile.CurrentFilePointer  = InfFileImage;\r
-        InfMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
-        //\r
-        // Read BaseAddress from fv.inf file.\r
-        //\r
-        FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, InfFileName);\r
-        //\r
-        // free Inf File Image\r
-        //\r
-        free (InfFileImage);\r
-        \r
-        //\r
-        // Convert string to UINT64 base address.\r
-        //\r
-        Status = AsciiStringToUint64 (InfFileName, FALSE, &BaseAddress);\r
-        if (EFI_ERROR (Status)) {\r
-          PrintUsage ();\r
-          Error (NULL, 0, 0, argv[Index + 1], "can't find the base address in the specified fv.inf file.");\r
-          return STATUS_ERROR;\r
-        }\r
+    case 'D':\r
+    case 'd':\r
+      if (BaseTypes & 2) {\r
+        PrintUsage ();\r
+        Error (NULL, 0, 0, argv[Index + 1], "-d BsBaseAddress may be specified only once");\r
+        return STATUS_ERROR;\r
+      }\r
 \r
 \r
-        BaseAddressSet = TRUE;\r
-      } else {\r
+      Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BsBase);\r
+      if (EFI_ERROR (Status)) {\r
         PrintUsage ();\r
         PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "BaseAddress has been got once from fv.inf or the specified base address.");\r
+        Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for BS_DRIVER base address");\r
         return STATUS_ERROR;\r
       }\r
         return STATUS_ERROR;\r
       }\r
+\r
+      BaseTypes |= 2;\r
       break;\r
 \r
       break;\r
 \r
-    case 'M':\r
-    case 'm':\r
-      if (strlen (MapFileName) == 0) {\r
-        strcpy (MapFileName, argv[Index + 1]);\r
-      } else {\r
+    case 'R':\r
+    case 'r':\r
+      if (BaseTypes & 4) {\r
+        PrintUsage ();\r
+        Error (NULL, 0, 0, argv[Index + 1], "-r RtBaseAddress may be specified only once");\r
+        return STATUS_ERROR;\r
+      }\r
+\r
+      Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &RtBase);\r
+      if (EFI_ERROR (Status)) {\r
         PrintUsage ();\r
         PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified");\r
+        Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for RT_DRIVER base address");\r
         return STATUS_ERROR;\r
       }\r
         return STATUS_ERROR;\r
       }\r
+\r
+      BaseTypes |= 4;\r
       break;\r
 \r
     default:\r
       break;\r
 \r
     default:\r
@@ -265,18 +262,6 @@ Returns:
       break;\r
     }\r
   }\r
       break;\r
     }\r
   }\r
-  \r
-  //\r
-  // Create the Map file if we need it\r
-  //\r
-  if (strlen (MapFileName) != 0) {\r
-    MapFile = fopen (MapFileName, "w");\r
-    if (MapFile == NULL) {\r
-      Error (NULL, 0, 0, MapFileName, "failed to open map file");\r
-      goto Finish;\r
-    }\r
-  } \r
-\r
   //\r
   // Open the file containing the FV\r
   //\r
   //\r
   // Open the file containing the FV\r
   //\r
@@ -285,6 +270,16 @@ Returns:
     Error (NULL, 0, 0, InputFileName, "could not open input file for reading");\r
     return STATUS_ERROR;\r
   }\r
     Error (NULL, 0, 0, InputFileName, "could not open input file for reading");\r
     return STATUS_ERROR;\r
   }\r
+\r
+  //\r
+  // Open the log file\r
+  //\r
+  strcat (InputFileName, ".log");\r
+  LogFile = fopen (InputFileName, "a");\r
+  if (LogFile == NULL) {\r
+    Error (NULL, 0, 0, InputFileName, "could not append to log file");\r
+  }\r
+\r
   //\r
   // Determine size of FV\r
   //\r
   //\r
   // Determine size of FV\r
   //\r
@@ -330,8 +325,14 @@ Returns:
     //\r
     // Rebase this file\r
     //\r
     //\r
     // Rebase this file\r
     //\r
-    CurrentFileBaseAddress  = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);\r
-    Status                  = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile);\r
+    FfsRebase (\r
+      CurrentFile,\r
+      BaseTypes,\r
+      XipBase + (UINTN)CurrentFile - (UINTN)FvImage,\r
+      &BsBase,\r
+      &RtBase,\r
+      LogFile\r
+      );\r
 \r
     if (EFI_ERROR (Status)) {\r
       switch (Status) {\r
 \r
     if (EFI_ERROR (Status)) {\r
       switch (Status) {\r
@@ -359,7 +360,6 @@ Returns:
 \r
       goto Finish;\r
     }\r
 \r
       goto Finish;\r
     }\r
-\r
     //\r
     // Get the next file\r
     //\r
     //\r
     // Get the next file\r
     //\r
@@ -399,8 +399,8 @@ Finish:
     fclose (OutputFile);\r
   }\r
 \r
     fclose (OutputFile);\r
   }\r
 \r
-  if (MapFile != NULL) {\r
-    fclose (MapFile);\r
+  if (LogFile != NULL) {\r
+    fclose (LogFile);\r
   }\r
 \r
   if (FvImage != NULL) {\r
   }\r
 \r
   if (FvImage != NULL) {\r
@@ -420,7 +420,7 @@ ReadHeader (
 \r
 Routine Description:\r
 \r
 \r
 Routine Description:\r
 \r
-  This function determines the size of the FV and the erase polarity.  The \r
+  This function determines the size of the FV and the erase polarity.  The\r
   erase polarity is the FALSE value for file state.\r
 \r
 Arguments:\r
   erase polarity is the FALSE value for file state.\r
 \r
 Arguments:\r
@@ -428,9 +428,9 @@ Arguments:
   InputFile       The file that contains the FV image.\r
   FvSize          The size of the FV.\r
   ErasePolarity   The FV erase polarity.\r
   InputFile       The file that contains the FV image.\r
   FvSize          The size of the FV.\r
   ErasePolarity   The FV erase polarity.\r
-    \r
+\r
 Returns:\r
 Returns:\r
\r
+\r
   EFI_SUCCESS             Function completed successfully.\r
   EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.\r
   EFI_ABORTED             The function encountered an error.\r
   EFI_SUCCESS             Function completed successfully.\r
   EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.\r
   EFI_ABORTED             The function encountered an error.\r
@@ -539,38 +539,36 @@ Returns:
 --*/\r
 {\r
   printf (\r
 --*/\r
 {\r
   printf (\r
-    "Usage: %s -I InputFileName -O OutputFileName [-B BaseAddress] -F FvInfFileName -M MapFile\n",\r
+    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",\r
     UTILITY_NAME\r
     );\r
   printf ("  Where:\n");\r
     UTILITY_NAME\r
     );\r
   printf ("  Where:\n");\r
-  printf ("    InputFileName  is the name of the EFI FV file to rebase.\n");\r
+  printf ("    InputFileName is the name of the EFI FV file to rebase.\n");\r
   printf ("    OutputFileName is the desired output file name.\n");\r
   printf ("    OutputFileName is the desired output file name.\n");\r
-  printf ("    BaseAddress    is the FV base address to rebase agains.\n");\r
-  printf ("    FvInfFileName  is the fv.inf to be used to generate this fv image.\n");\r
-  printf ("                   BaseAddress can also be got from the fv.inf file.\n");\r
-  printf ("                   Choose only one method to input BaseAddress.\n");\r
-  printf ("    MapFileName    is an optional map file of the relocations\n");\r
-  printf ("    Argument pair may be in any order.\n\n");\r
+  printf ("    BaseAddress is the FV base address to rebase agains.\n");\r
+  printf ("  Argument pair may be in any order.\n\n");\r
 }\r
 \r
 EFI_STATUS\r
 FfsRebase (\r
 }\r
 \r
 EFI_STATUS\r
 FfsRebase (\r
-  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,\r
-  IN EFI_PHYSICAL_ADDRESS       BaseAddress,\r
-  IN FILE                       *MapFile      OPTIONAL\r
+  IN OUT  EFI_FFS_FILE_HEADER       *FfsFile,\r
+  IN      UINT32                    Flags,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      XipBase,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      *BsBase,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      *RtBase,\r
+  OUT     FILE                      *LogFile\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  This function determines if a file is XIP and should be rebased.  It will \r
+  This function determines if a file is XIP and should be rebased.  It will\r
   rebase any PE32 sections found in the file using the base address.\r
   rebase any PE32 sections found in the file using the base address.\r
-  \r
+\r
 Arguments:\r
 \r
   FfsFile           A pointer to Ffs file image.\r
   BaseAddress       The base address to use for rebasing the file image.\r
 Arguments:\r
 \r
   FfsFile           A pointer to Ffs file image.\r
   BaseAddress       The base address to use for rebasing the file image.\r
-  MapFile           Optional file to dump relocation information into\r
 \r
 Returns:\r
 \r
 \r
 Returns:\r
 \r
@@ -590,20 +588,21 @@ Returns:
   UINT64                                ImageSize;\r
   EFI_PHYSICAL_ADDRESS                  EntryPoint;\r
   UINT32                                Pe32ImageSize;\r
   UINT64                                ImageSize;\r
   EFI_PHYSICAL_ADDRESS                  EntryPoint;\r
   UINT32                                Pe32ImageSize;\r
-  UINT32                                NewPe32BaseAddress;\r
+  EFI_PHYSICAL_ADDRESS                  NewPe32BaseAddress;\r
   UINTN                                 Index;\r
   EFI_FILE_SECTION_POINTER              CurrentPe32Section;\r
   EFI_FFS_FILE_STATE                    SavedState;\r
   UINTN                                 Index;\r
   EFI_FILE_SECTION_POINTER              CurrentPe32Section;\r
   EFI_FFS_FILE_STATE                    SavedState;\r
-  EFI_IMAGE_NT_HEADERS                  *PeHdr;\r
+  EFI_IMAGE_NT_HEADERS32                *PeHdr;\r
+  EFI_IMAGE_NT_HEADERS64                *PePlusHdr;\r
   UINT32                                *PeHdrSizeOfImage;\r
   UINT32                                *PeHdrChecksum;\r
   UINT32                                *PeHdrSizeOfImage;\r
   UINT32                                *PeHdrChecksum;\r
-  UINT32                                FoundCount;\r
   EFI_TE_IMAGE_HEADER                   *TEImageHeader;\r
   UINT8                                 *TEBuffer;\r
   EFI_IMAGE_DOS_HEADER                  *DosHeader;\r
   UINT8                                 FileGuidString[80];\r
   UINT32                                TailSize;\r
   EFI_FFS_FILE_TAIL                     TailValue;\r
   EFI_TE_IMAGE_HEADER                   *TEImageHeader;\r
   UINT8                                 *TEBuffer;\r
   EFI_IMAGE_DOS_HEADER                  *DosHeader;\r
   UINT8                                 FileGuidString[80];\r
   UINT32                                TailSize;\r
   EFI_FFS_FILE_TAIL                     TailValue;\r
+  EFI_PHYSICAL_ADDRESS                  *BaseToUpdate;\r
 \r
   //\r
   // Verify input parameters\r
 \r
   //\r
   // Verify input parameters\r
@@ -611,7 +610,6 @@ Returns:
   if (FfsFile == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (FfsFile == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
   //\r
   // Convert the GUID to a string so we can at least report which file\r
   // if we find an error.\r
   //\r
   // Convert the GUID to a string so we can at least report which file\r
   // if we find an error.\r
@@ -622,7 +620,6 @@ Returns:
   } else {\r
     TailSize = 0;\r
   }\r
   } else {\r
     TailSize = 0;\r
   }\r
-  \r
   //\r
   // Do some cursory checks on the FFS file contents\r
   //\r
   //\r
   // Do some cursory checks on the FFS file contents\r
   //\r
@@ -632,36 +629,31 @@ Returns:
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  memset (&ImageContext, 0, sizeof (ImageContext));\r
-\r
   //\r
   //\r
-  // Check if XIP file type. If not XIP, don't rebase.\r
+  // We only process files potentially containing PE32 sections.\r
   //\r
   //\r
-  if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
-      ) {\r
-    return EFI_SUCCESS;\r
+  switch (FfsFile->Type) {\r
+    case EFI_FV_FILETYPE_SECURITY_CORE:\r
+    case EFI_FV_FILETYPE_PEI_CORE:\r
+    case EFI_FV_FILETYPE_PEIM:\r
+    case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
+    case EFI_FV_FILETYPE_DRIVER:\r
+    case EFI_FV_FILETYPE_DXE_CORE:\r
+      break;\r
+    default:\r
+      return EFI_SUCCESS;\r
   }\r
 \r
   //\r
   // Rebase each PE32 section\r
   //\r
   Status      = EFI_SUCCESS;\r
   }\r
 \r
   //\r
   // Rebase each PE32 section\r
   //\r
   Status      = EFI_SUCCESS;\r
-  FoundCount  = 0;\r
   for (Index = 1;; Index++) {\r
     Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
 \r
   for (Index = 1;; Index++) {\r
     Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
 \r
-    FoundCount++;\r
-\r
-    //\r
-    // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section\r
-    //\r
-    NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);\r
 \r
     //\r
     // Initialize context\r
 \r
     //\r
     // Initialize context\r
@@ -669,25 +661,102 @@ Returns:
     memset (&ImageContext, 0, sizeof (ImageContext));\r
     ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));\r
     ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
     memset (&ImageContext, 0, sizeof (ImageContext));\r
     ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));\r
     ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
-\r
     Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
     Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
     if (EFI_ERROR (Status)) {\r
       Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);\r
       return Status;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);\r
       return Status;\r
     }\r
+\r
+    //\r
+    // Calculate the PE32 base address, based on file type\r
+    //\r
+    switch (FfsFile->Type) {\r
+      case EFI_FV_FILETYPE_SECURITY_CORE:\r
+      case EFI_FV_FILETYPE_PEI_CORE:\r
+      case EFI_FV_FILETYPE_PEIM:\r
+      case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:\r
+        if ((Flags & 1) == 0) {\r
+          //\r
+          // We aren't relocating XIP code, so skip it.\r
+          //\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+        NewPe32BaseAddress =\r
+          XipBase +\r
+          (UINTN)CurrentPe32Section.Pe32Section +\r
+          sizeof (EFI_COMMON_SECTION_HEADER) -\r
+          (UINTN)FfsFile;\r
+        BaseToUpdate = &XipBase;\r
+        break;\r
+\r
+      case EFI_FV_FILETYPE_DRIVER:\r
+        PeHdr = (EFI_IMAGE_NT_HEADERS32*)(\r
+          (UINTN)CurrentPe32Section.Pe32Section +\r
+          sizeof (EFI_COMMON_SECTION_HEADER) +\r
+          ImageContext.PeCoffHeaderOffset\r
+          );\r
+        switch (PeHdr->OptionalHeader.Subsystem) {\r
+          case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
+            if ((Flags & 4) == 0) {\r
+              //\r
+              // RT drivers aren't supposed to be relocated\r
+              //\r
+              continue;\r
+            }\r
+\r
+            NewPe32BaseAddress = *RtBase;\r
+            BaseToUpdate = RtBase;\r
+            break;\r
+\r
+          default:\r
+            //\r
+            // We treat all other subsystems the same as BS_DRIVER\r
+            //\r
+            if ((Flags & 2) == 0) {\r
+              //\r
+              // Skip all BS_DRIVER's\r
+              //\r
+              continue;\r
+            }\r
+\r
+            NewPe32BaseAddress = *BsBase;\r
+            BaseToUpdate = BsBase;\r
+            break;\r
+        }\r
+        break;\r
+\r
+      case EFI_FV_FILETYPE_DXE_CORE:\r
+        if ((Flags & 2) == 0) {\r
+          //\r
+          // Skip DXE core\r
+          //\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+        NewPe32BaseAddress = *BsBase;\r
+        BaseToUpdate = BsBase;\r
+        break;\r
+\r
+      default:\r
+        //\r
+        // Not supported file type\r
+        //\r
+        return EFI_SUCCESS;\r
+    }\r
+\r
     //\r
     // Allocate a buffer for the image to be loaded into.\r
     //\r
     Pe32ImageSize       = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);\r
     //\r
     // Allocate a buffer for the image to be loaded into.\r
     //\r
     Pe32ImageSize       = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);\r
-    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x10000));\r
+    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation failure", NULL);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation failure", NULL);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\r
-    \r
+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
+    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
+\r
 \r
     ImageContext.ImageAddress = MemoryImagePointerAligned;\r
 \r
 \r
     ImageContext.ImageAddress = MemoryImagePointerAligned;\r
 \r
@@ -697,24 +766,6 @@ Returns:
       free ((VOID *) MemoryImagePointer);\r
       return Status;\r
     }\r
       free ((VOID *) MemoryImagePointer);\r
       return Status;\r
     }\r
-    \r
-    //\r
-    // Check if section-alignment and file-alignment match or not\r
-    //\r
-    if (!(ImageContext.IsTeImage)) {\r
-      PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + \r
-                                              ImageContext.PeCoffHeaderOffset);\r
-      if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {\r
-        Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-    else {\r
-      //\r
-      // BUGBUG: TE Image Header lack section-alignment and file-alignment info\r
-      //\r
-    }\r
 \r
     ImageContext.DestinationAddress = NewPe32BaseAddress;\r
     Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
 \r
     ImageContext.DestinationAddress = NewPe32BaseAddress;\r
     Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
@@ -742,21 +793,34 @@ Returns:
       free ((VOID *) MemoryImagePointer);\r
       return EFI_ABORTED;\r
     }\r
       free ((VOID *) MemoryImagePointer);\r
       return EFI_ABORTED;\r
     }\r
+\r
+    //\r
+    // Update BASE address\r
+    //\r
+    fprintf (\r
+      LogFile,\r
+      "%s %016I64X\n",\r
+      FileGuidString,\r
+      ImageContext.DestinationAddress\r
+      );\r
+    *BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;\r
+\r
     //\r
     // Since we may have updated the Codeview RVA, we need to insure the PE\r
     // header indicates the image is large enough to contain the Codeview data\r
     // so it will be loaded properly later if the PEIM is reloaded into memory...\r
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
     //\r
     // Since we may have updated the Codeview RVA, we need to insure the PE\r
     // header indicates the image is large enough to contain the Codeview data\r
     // so it will be loaded properly later if the PEIM is reloaded into memory...\r
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
+    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
     } else {\r
       Error (\r
         NULL,\r
     } else {\r
       Error (\r
         NULL,\r
@@ -779,24 +843,6 @@ Returns:
     }\r
 \r
     memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);\r
     }\r
 \r
     memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);\r
-    \r
-    //\r
-    // Get EntryPoint in Flash Region.\r
-    //\r
-    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
-\r
-    //\r
-    // If a map file was selected output mapping information for any file that\r
-    // was rebased.\r
-    //\r
-    if (MapFile != NULL) {\r
-      fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress);\r
-      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
-      if (ImageContext.PdbPointer != NULL) {\r
-        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
-      }\r
-      fprintf (MapFile, "\n");\r
-    }\r
 \r
     free ((VOID *) MemoryImagePointer);\r
 \r
 \r
     free ((VOID *) MemoryImagePointer);\r
 \r
@@ -832,6 +878,20 @@ Returns:
       *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
     }\r
   }\r
       *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
     }\r
   }\r
+\r
+  if ((Flags & 1) == 0 || (\r
+      FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
+      FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
+\r
+      FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
+      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
+      )) {\r
+    //\r
+    // Only XIP code may have a TE section\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   // Now process TE sections\r
   //\r
   //\r
   // Now process TE sections\r
   //\r
@@ -841,15 +901,13 @@ Returns:
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
-    FoundCount++;\r
-\r
     //\r
     // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off\r
     // by GenTEImage\r
     //\r
     TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
 \r
     //\r
     // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off\r
     // by GenTEImage\r
     //\r
     TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
 \r
-    NewPe32BaseAddress = ((UINT32) BaseAddress) +\r
+    NewPe32BaseAddress = ((UINT32) XipBase) +\r
       (\r
         (UINTN) CurrentPe32Section.Pe32Section +\r
         sizeof (EFI_COMMON_SECTION_HEADER) +\r
       (\r
         (UINTN) CurrentPe32Section.Pe32Section +\r
         sizeof (EFI_COMMON_SECTION_HEADER) +\r
@@ -880,6 +938,7 @@ Returns:
     DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
     *(UINT32 *) (TEBuffer + 0x3C) = 0x40;\r
     PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);\r
     DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
     *(UINT32 *) (TEBuffer + 0x3C) = 0x40;\r
     PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);\r
+    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
     PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;\r
     PeHdr->FileHeader.Machine = TEImageHeader->Machine;\r
     PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;\r
     PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;\r
     PeHdr->FileHeader.Machine = TEImageHeader->Machine;\r
     PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;\r
@@ -889,39 +948,89 @@ Returns:
     // the 0x40 bytes for our DOS header.\r
     //\r
     PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));\r
     // the 0x40 bytes for our DOS header.\r
     //\r
     PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));\r
-    PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
-    PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;\r
-    PeHdr->OptionalHeader.BaseOfCode  = TEImageHeader->BaseOfCode;\r
-    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
-    PeHdr->OptionalHeader.Subsystem   = TEImageHeader->Subsystem;\r
-    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
-    PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
-    sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
-\r
-    //\r
-    // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
-    //\r
-    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
-        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
-        ) {\r
-      PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
+    if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
+    } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {\r
+      PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+    } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {\r
+      PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+    } else {\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        "unknown machine type in TE image",\r
+        "machine type=0x%X, file=%s",\r
+        (UINT32) TEImageHeader->Machine,\r
+        FileGuidString\r
+        );\r
+      free (TEBuffer);\r
+      return EFI_ABORTED;\r
     }\r
 \r
     }\r
 \r
-    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
-        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
-        ) {\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
-      if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
-        PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
+    if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      PeHdr->OptionalHeader.ImageBase     = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
+      PeHdr->OptionalHeader.SizeOfImage   = Pe32ImageSize;\r
+      PeHdr->OptionalHeader.Subsystem     = TEImageHeader->Subsystem;\r
+      PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
+                                            sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
+\r
+      //\r
+      // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
+      //\r
+      if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
+          (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
+          ) {\r
+        PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
+        PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
+        PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
+      }\r
+\r
+      if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
+          (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
+          ) {\r
+        PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+        PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
+        if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
+          PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
+        }\r
+      }\r
+      //\r
+      // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
+      //\r
+      PeHdr->OptionalHeader.SectionAlignment = 0x10;\r
+    } else {\r
+      PePlusHdr->OptionalHeader.ImageBase     = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
+      PePlusHdr->OptionalHeader.SizeOfImage   = Pe32ImageSize;\r
+      PePlusHdr->OptionalHeader.Subsystem     = TEImageHeader->Subsystem;\r
+      PePlusHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
+                                                sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
+\r
+      //\r
+      // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
+      //\r
+      if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
+          (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
+          ) {\r
+        PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
+        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
+        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
       }\r
       }\r
+\r
+      if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
+          (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
+          ) {\r
+        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
+        if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
+          PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
+        }\r
+      }\r
+      //\r
+      // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
+      //\r
+      PePlusHdr->OptionalHeader.SectionAlignment = 0x10;\r
     }\r
     }\r
-    //\r
-    // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
-    //\r
-    PeHdr->OptionalHeader.SectionAlignment = 0x10;\r
 \r
     //\r
     // Copy the rest of the image to its original offset\r
 \r
     //\r
     // Copy the rest of the image to its original offset\r
@@ -950,15 +1059,15 @@ Returns:
     //\r
     // Allocate a buffer for the image to be loaded into.\r
     //\r
     //\r
     // Allocate a buffer for the image to be loaded into.\r
     //\r
-    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x10000));\r
+    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);\r
       free (TEBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     if (MemoryImagePointer == 0) {\r
       Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);\r
       free (TEBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\r
-    \r
+    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
+    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
+\r
 \r
     ImageContext.ImageAddress = MemoryImagePointerAligned;\r
     Status                    = PeCoffLoaderLoadImage (&ImageContext);\r
 \r
     ImageContext.ImageAddress = MemoryImagePointerAligned;\r
     Status                    = PeCoffLoaderLoadImage (&ImageContext);\r
@@ -968,11 +1077,6 @@ Returns:
       free ((VOID *) MemoryImagePointer);\r
       return Status;\r
     }\r
       free ((VOID *) MemoryImagePointer);\r
       return Status;\r
     }\r
-    \r
-    //\r
-    // Check if section-alignment and file-alignment match or not\r
-       // BUGBUG: TE Image Header lack section-alignment and file-alignment info\r
-    //\r
 \r
     ImageContext.DestinationAddress = NewPe32BaseAddress;\r
     Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
 \r
     ImageContext.DestinationAddress = NewPe32BaseAddress;\r
     Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
@@ -993,12 +1097,16 @@ Returns:
     // so it will be loaded properly later if the PEIM is reloaded into memory...\r
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
     // so it will be loaded properly later if the PEIM is reloaded into memory...\r
     //\r
     PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
+    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
     } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
+    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
+      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
+      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
     } else {\r
       Error (\r
         NULL,\r
     } else {\r
       Error (\r
         NULL,\r
@@ -1028,25 +1136,6 @@ Returns:
       GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
       sizeof (EFI_TE_IMAGE_HEADER)\r
       );\r
       GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
       sizeof (EFI_TE_IMAGE_HEADER)\r
       );\r
-    \r
-    //\r
-    // Get EntryPoint in Flash Region.\r
-    //\r
-    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
-\r
-    //\r
-    // If a map file was selected output mapping information for any file that\r
-    // was rebased.\r
-    //\r
-    if (MapFile != NULL) {\r
-      fprintf (MapFile, "TE   File: %s Base:%08lx", FileGuidString, BaseAddress);\r
-      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
-      if (ImageContext.PdbPointer != NULL) {\r
-        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
-      }\r
-      fprintf (MapFile, "\n");\r
-    }\r
-\r
     free ((VOID *) MemoryImagePointer);\r
     free (TEBuffer);\r
     if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
     free ((VOID *) MemoryImagePointer);\r
     free (TEBuffer);\r
     if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
@@ -1079,18 +1168,15 @@ Returns:
       TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));\r
       *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
     }\r
       TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));\r
       *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
     }\r
+\r
+    fprintf (\r
+      LogFile,\r
+      "%s %016I64X\n",\r
+      FileGuidString,\r
+      ImageContext.DestinationAddress\r
+      );\r
   }\r
   }\r
-  //\r
-  // If we found no files, then emit an error if no compressed sections either\r
-  //\r
-  if (FoundCount == 0) {\r
-    Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);\r
-      return EFI_NOT_FOUND;\r
-    }\r
-  }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
index b05baefb59d4fc412946122d7a4d785533e57483..253387e6ab02dd06fa5fae704d605529847ce5d9 100644 (file)
@@ -1,8 +1,8 @@
 /*++\r
 \r
 Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
 /*++\r
 \r
 Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available \r
-under the terms and conditions of the BSD License which accompanies this \r
+This program and the accompanying materials are licensed and made available\r
+under the terms and conditions of the BSD License which accompanies this\r
 distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
 distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
@@ -11,7 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 \r
 Module Name:\r
 \r
 \r
 Module Name:\r
-  \r
+\r
   PeiRebaseExe.h\r
 \r
 Abstract:\r
   PeiRebaseExe.h\r
 \r
 Abstract:\r
@@ -43,7 +43,7 @@ Abstract:
 //\r
 // The maximum number of arguments accepted from the command line.\r
 //\r
 //\r
 // The maximum number of arguments accepted from the command line.\r
 //\r
-#define MAX_ARGS  9\r
+#define MAX_ARGS  7\r
 \r
 //\r
 // The file copy buffer size\r
 \r
 //\r
 // The file copy buffer size\r
@@ -130,9 +130,12 @@ Returns:
 \r
 EFI_STATUS\r
 FfsRebase (\r
 \r
 EFI_STATUS\r
 FfsRebase (\r
-  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,\r
-  IN EFI_PHYSICAL_ADDRESS       BaseAddress,\r
-  IN FILE                       *MapFile      OPTIONAL\r
+  IN OUT  EFI_FFS_FILE_HEADER       *FfsFile,\r
+  IN      UINT32                    Flags,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      XipBase,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      *BsBase,\r
+  IN OUT  EFI_PHYSICAL_ADDRESS      *RtBase,\r
+  OUT     FILE                      *LogFile\r
   )\r
 /*++\r
 \r
   )\r
 /*++\r
 \r
index 2e4b27c19db6d311017baba6872fa7c7018b7c5d..b7101dda185f250fa645a51ceb0a53c677bd91da 100644 (file)
@@ -13,8 +13,8 @@
       updates either the OS or the HOST tool chain, these tools should be rebuilt.</Description>\r
     <Copyright>Copyright 2006, Intel Corporation</Copyright>\r
     <License URL="http://opensource.org/licenses/bsd-license.php">All rights reserved.  This program and the accompanying materials
       updates either the OS or the HOST tool chain, these tools should be rebuilt.</Description>\r
     <Copyright>Copyright 2006, Intel Corporation</Copyright>\r
     <License URL="http://opensource.org/licenses/bsd-license.php">All rights reserved.  This program and the accompanying materials
-are licensed and made available under the terms and conditions of the 
-BSD License which accompanies this distribution.  The full text of the 
+are licensed and made available under the terms and conditions of the
+BSD License which accompanies this distribution.  The full text of the
 license may be found at
 http://opensource.org/licenses/bsd-license.php
 
 license may be found at
 http://opensource.org/licenses/bsd-license.php
 
@@ -96,6 +96,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</L
     <Filename>GenFvImage/GenFvImageLib.c</Filename>\r
     <Filename>GenFvImage/GenFvImageLib.h</Filename>\r
     <Filename>GenFvImage/GenFvImageLibInternal.h</Filename>\r
     <Filename>GenFvImage/GenFvImageLib.c</Filename>\r
     <Filename>GenFvImage/GenFvImageLib.h</Filename>\r
     <Filename>GenFvImage/GenFvImageLibInternal.h</Filename>\r
+    <Filename>GenFvMap/build.xml</Filename>\r
+    <Filename>GenFvMap/GenFvMap.cpp</Filename>\r
     <Filename>GenSection/build.xml</Filename>\r
     <Filename>GenSection/GenSection.c</Filename>\r
     <Filename>GenSection/GenSection.h</Filename>\r
     <Filename>GenSection/build.xml</Filename>\r
     <Filename>GenSection/GenSection.c</Filename>\r
     <Filename>GenSection/GenSection.h</Filename>\r
index 07154921d22564404f9104418ea0242a3e96bad8..ab563823e8abc84dba666c2acd3a5ca520cbc9b6 100644 (file)
@@ -51,11 +51,11 @@ public class PeiReBaseTask extends Task implements EfiDefine {
     private ToolArg baseAddr = new ToolArg();\r
     //\r
     // Fv.inf file\r
     private ToolArg baseAddr = new ToolArg();\r
     //\r
     // Fv.inf file\r
-    // \r
+    //\r
     private FileArg fvinfFile = new FileArg();\r
     //\r
     // map file\r
     private FileArg fvinfFile = new FileArg();\r
     //\r
     // map file\r
-    // \r
+    //\r
     private FileArg mapFile = new FileArg();\r
     //\r
     // Architecture\r
     private FileArg mapFile = new FileArg();\r
     //\r
     // Architecture\r
@@ -64,10 +64,10 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       execute\r
 \r
     /**\r
       execute\r
-     \r
+\r
       PeiReBaseTask execute function is to assemble tool command line & execute\r
       tool command line\r
       PeiReBaseTask execute function is to assemble tool command line & execute\r
       tool command line\r
-     \r
+\r
       @throws BuidException\r
      **/\r
     public void execute() throws BuildException {\r
       @throws BuidException\r
      **/\r
     public void execute() throws BuildException {\r
@@ -103,7 +103,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
         if (mapFile.getValue().length() == 0) {\r
             mapFile.setArg(" -M ", outputFile.getValue() + ".map");\r
         }\r
         if (mapFile.getValue().length() == 0) {\r
             mapFile.setArg(" -M ", outputFile.getValue() + ".map");\r
         }\r
-        argument = "" + inputFile + outputFile + baseAddr + fvinfFile + mapFile;\r
+        argument = "" + inputFile + outputFile + baseAddr + fvinfFile;\r
 \r
         //\r
         // return value of fwimage execution\r
 \r
         //\r
         // return value of fwimage execution\r
@@ -125,7 +125,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
             // Set debug log information.\r
             //\r
             EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline()));\r
             // Set debug log information.\r
             //\r
             EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline()));\r
-            EdkLog.log(this, EdkLog.EDK_INFO, inputFile.toFileList() + " => " \r
+            EdkLog.log(this, EdkLog.EDK_INFO, inputFile.toFileList() + " => "\r
                                               + outputFile.toFileList()\r
                                               + mapFile.toFileList());\r
 \r
                                               + outputFile.toFileList()\r
                                               + mapFile.toFileList());\r
 \r
@@ -150,9 +150,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       getInputFile\r
 \r
     /**\r
       getInputFile\r
-     \r
+\r
       This function is to get class member "inputFile".\r
       This function is to get class member "inputFile".\r
-     \r
+\r
       @return string of input file name.\r
      **/\r
     public String getInputFile() {\r
       @return string of input file name.\r
      **/\r
     public String getInputFile() {\r
@@ -161,9 +161,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       setComponentType\r
 \r
     /**\r
       setComponentType\r
-     \r
+\r
       This function is to set class member "inputFile".\r
       This function is to set class member "inputFile".\r
-     \r
+\r
       @param inputFile\r
                  string of input file name.\r
      **/\r
       @param inputFile\r
                  string of input file name.\r
      **/\r
@@ -173,9 +173,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       getOutputFile\r
 \r
     /**\r
       getOutputFile\r
-     \r
+\r
       This function is to get class member "outputFile"\r
       This function is to get class member "outputFile"\r
-     \r
+\r
       @return outputFile string of output file name.\r
      **/\r
     public String getOutputFile() {\r
       @return outputFile string of output file name.\r
      **/\r
     public String getOutputFile() {\r
@@ -184,9 +184,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       setOutputFile\r
 \r
     /**\r
       setOutputFile\r
-     \r
+\r
       This function is to set class member "outputFile"\r
       This function is to set class member "outputFile"\r
-     \r
+\r
       @param outputFile\r
                  string of output file name.\r
      **/\r
       @param outputFile\r
                  string of output file name.\r
      **/\r
@@ -196,9 +196,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       getBaseAddr\r
 \r
     /**\r
       getBaseAddr\r
-     \r
+\r
       This function is to get class member "baseAddr"\r
       This function is to get class member "baseAddr"\r
-     \r
+\r
       @return baseAddr   string of base address.\r
      **/\r
     public String getBaseAddr() {\r
       @return baseAddr   string of base address.\r
      **/\r
     public String getBaseAddr() {\r
@@ -207,9 +207,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       setBaseAddr\r
 \r
     /**\r
       setBaseAddr\r
-     \r
+\r
       This function is to set class member "baseAddr"\r
       This function is to set class member "baseAddr"\r
-     \r
+\r
       @param baseAddr    string of base address\r
      **/\r
     public void setBaseAddr(String baseAddr) {\r
       @param baseAddr    string of base address\r
      **/\r
     public void setBaseAddr(String baseAddr) {\r
@@ -218,9 +218,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       getArch\r
 \r
     /**\r
       getArch\r
-     \r
+\r
       This function is to get class member "arch".\r
       This function is to get class member "arch".\r
-     \r
+\r
       @return arch       Architecture\r
      **/\r
     public String getArch() {\r
       @return arch       Architecture\r
      **/\r
     public String getArch() {\r
@@ -229,9 +229,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     /**\r
       setArch\r
 \r
     /**\r
       setArch\r
-     \r
+\r
       This function is to set class member "arch"\r
       This function is to set class member "arch"\r
-     \r
+\r
       @param arch         Architecture\r
      **/\r
     public void setArch(String arch) {\r
       @param arch         Architecture\r
      **/\r
     public void setArch(String arch) {\r
@@ -276,7 +276,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
 \r
     //\r
     // Dependency check\r
 \r
     //\r
     // Dependency check\r
-    // \r
+    //\r
     private boolean isUptodate() {\r
         File srcFile = new File(inputFile.getValue());\r
         File dstFile = new File(outputFile.getValue());\r
     private boolean isUptodate() {\r
         File srcFile = new File(inputFile.getValue());\r
         File dstFile = new File(outputFile.getValue());\r