1. Added a new tool GenFvMap, which is able to generate FV map files upon LOG files generated by PeiRebase.

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
This commit is contained in:
bxing
2006-12-30 09:17:16 +00:00
parent 242c77a085
commit 8733430b83
6 changed files with 973 additions and 303 deletions

View File

@ -0,0 +1,507 @@
//****************************************************************************
//**
//** 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 <stdexcept>
#include <list>
#include <map>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
#include <algorithm>
#include <functional>
using namespace std;
typedef unsigned __int64 ulonglong_t;
template <class T>
class CMemoryLeakChecker : public list<T*>
{
public:
static CMemoryLeakChecker<T>& GetInstance(void);
private:
CMemoryLeakChecker(void)
{
}
~CMemoryLeakChecker(void);
};
template <class T>
CMemoryLeakChecker<T>& CMemoryLeakChecker<T>::GetInstance(void)
{
static CMemoryLeakChecker<T> s_memLeakChecker;
return s_memLeakChecker;
}
template <class T>
CMemoryLeakChecker<T>::~CMemoryLeakChecker(void)
{
if (!list<T*>::empty())
throw logic_error(__FUNCTION__ ": Memory leak detected!");
}
class CObjRoot
{
protected:
CObjRoot(void);
virtual ~CObjRoot(void);
};
CObjRoot::CObjRoot(void)
{
CMemoryLeakChecker<CObjRoot>::GetInstance().push_back(this);
}
CObjRoot::~CObjRoot(void)
{
CMemoryLeakChecker<CObjRoot>::GetInstance().remove(this);
}
class CIdentity : public CObjRoot
{
public:
CIdentity(void);
CIdentity(const string&);
CIdentity(const CIdentity&);
bool operator < (const CIdentity&) const;
friend istream& operator >> (istream&, CIdentity&);
static const string::size_type s_nIdStrLen;
protected:
ulonglong_t m_ullId[2];
};
const string::size_type CIdentity::s_nIdStrLen = 36;
CIdentity::CIdentity(void)
{
memset(m_ullId, 0, sizeof(m_ullId));
}
CIdentity::CIdentity(const string& strId)
{
if (strId.length() != CIdentity::s_nIdStrLen ||
strId[8] != '-' ||
strId[13] != '-' ||
strId[18] != '-' ||
strId[23] != '-')
throw runtime_error(
__FUNCTION__ ": Error GUID format " + strId);
string strIdCopy(strId);
strIdCopy.erase(23, 1);
strIdCopy[18] = ' ';
strIdCopy.erase(13, 1);
strIdCopy.erase(8, 1);
istringstream is(strIdCopy);
is >> hex >> m_ullId[0] >> m_ullId[1];
if (!is)
throw runtime_error(
__FUNCTION__ ": GUID contains invalid characters" + strId);
}
CIdentity::CIdentity(const CIdentity& idRight)
{
memmove(m_ullId, idRight.m_ullId, sizeof(m_ullId));
}
bool CIdentity::operator < (const CIdentity& idRight) const
{
return memcmp(m_ullId, idRight.m_ullId, sizeof(m_ullId)) < 0;
}
istream& operator >> (istream& is, CIdentity& idRight)
{
string strId;
is >> strId;
if (!!is)
idRight = CIdentity(strId);
return is;
}
class CInputFile : public CObjRoot
{
protected:
CInputFile(const string&);
CInputFile(istream&);
istream& GetLine(string&);
private:
CInputFile(const CInputFile&);
CInputFile& operator = (const CInputFile&);
private:
auto_ptr<istream> m_pIs;
protected:
istream& m_is;
};
CInputFile::CInputFile(const string& strFName)
: m_pIs(new ifstream(strFName.c_str()))
, m_is(*m_pIs)
{
if (!m_is)
throw runtime_error(__FUNCTION__ ": Error opening input file " + strFName);
}
CInputFile::CInputFile(istream& is)
: m_is(is)
{
if (!m_is)
throw runtime_error(__FUNCTION__ ": Error opening input stream");
}
istream& CInputFile::GetLine(string& strALine)
{
if (!!m_is)
while (!!getline(m_is, strALine))
{
string::size_type pos = strALine.find_last_not_of(' ');
if (pos != string::npos)
{
strALine.erase(pos + 1);
strALine.erase(0, strALine.find_first_not_of(' '));
break;
}
}
return m_is;
}
class CIdAddressMap : public CInputFile, public map<CIdentity, ulonglong_t>
{
public:
CIdAddressMap(istream&);
};
CIdAddressMap::CIdAddressMap(istream& is)
: CInputFile(is)
{
CIdentity id;
ulonglong_t ullBase;
while (!!(m_is >> hex >> id >> ullBase))
if (!insert(value_type(id, ullBase)).second)
throw runtime_error(__FUNCTION__ ": Duplicated files");
}
class CIdPathMap : public CInputFile, public map<CIdentity, string>
{
public:
CIdPathMap(istream&);
};
CIdPathMap::CIdPathMap(istream& is)
: CInputFile(is)
{
static const char cszFileSec[] = "[files]";
static const char cszFfsFile[] = "EFI_FILE_NAME";
string strALine;
// Find the [files] section
while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszFileSec) - 1, cszFileSec));
// m_is error means no FFS files listed in this INF file
if (!m_is)
return;
// Parse FFS files one by one
while (!!GetLine(strALine))
{
// Test if this begins a new section
if (strALine[0] == '[')
break;
// Is it a line of FFS file?
if (strALine.compare(0, sizeof(cszFfsFile) - 1, cszFfsFile))
continue;
string::size_type pos = strALine.find_first_not_of(' ', sizeof(cszFfsFile) - 1);
if (pos == string::npos || strALine[pos] != '=')
throw runtime_error(__FUNCTION__ ": Invalid FV INF format");
pos = strALine.find_first_not_of(' ', pos + 1);
if (pos == string::npos)
throw runtime_error(__FUNCTION__ ": Incomplete line");
strALine.erase(0, pos);
pos = strALine.rfind('\\');
if (pos == string::npos)
pos = 0;
else pos++;
CIdentity id(strALine.substr(pos, CIdentity::s_nIdStrLen));
if (!insert(value_type(id, strALine)).second)
throw runtime_error(__FUNCTION__ ": Duplicated FFS files");
}
}
class CSymbol : public CObjRoot
{
public:
string m_strAddress;
string m_strName;
ulonglong_t m_ullRva;
string m_strFrom;
bool m_bStatic;
bool m_bFunction;
CSymbol()
{
}
CSymbol(const string&, bool = false);
friend ostream& operator << (ostream&, const CSymbol&);
};
CSymbol::CSymbol(const string& strALine, bool bStatic)
: m_bStatic(bStatic)
{
istringstream is(strALine);
is >> m_strAddress >> m_strName >> hex >> m_ullRva >> m_strFrom;
if (m_strFrom == "F" || m_strFrom == "f")
{
m_bFunction = true;
is >> m_strFrom;
} else m_bFunction = false;
}
ostream& operator << (ostream& os, const CSymbol& symbol)
{
os << hex << setw(16) << setfill('0') << symbol.m_ullRva << setw(0);
os << ' ' << (symbol.m_bFunction ? 'F' : ' ')
<< (symbol.m_bStatic ? 'S' : ' ') << ' ';
return os << symbol.m_strName << endl;
}
class CMapFile : public CInputFile, public list<CSymbol>
{
public:
CMapFile(const string&);
void SetLoadAddress(ulonglong_t);
friend ostream& operator << (ostream&, const CMapFile&);
string m_strModuleName;
ulonglong_t m_ullLoadAddr;
string m_strEntryPoint;
};
CMapFile::CMapFile(const string& strFName)
: CInputFile(strFName)
{
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";
string strALine;
GetLine(m_strModuleName);
while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszLoadAddr) - 1, cszLoadAddr));
if (!m_is)
throw runtime_error(__FUNCTION__ ": Load Address not listed in map file");
istringstream is(strALine.substr(sizeof(cszLoadAddr) - 1));
if (!(is >> hex >> m_ullLoadAddr))
throw runtime_error(__FUNCTION__ ": Unexpected Load Address format");
while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszGlobal) - 1, cszGlobal));
if (!m_is)
throw runtime_error(__FUNCTION__ ": Global symbols not found in map file");
while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszEntryPoint) - 1, cszEntryPoint))
push_back(CSymbol(strALine));
if (!m_is)
throw runtime_error(__FUNCTION__ ": Entry Point not listed in map file");
is.str(strALine.substr(strALine.find_first_not_of(' ', sizeof(cszEntryPoint) - 1)));
is.clear();
if (!getline(is, m_strEntryPoint))
throw runtime_error(__FUNCTION__ ": Unexpected Entry Point format");
while (!!GetLine(strALine) && strALine.compare(0, sizeof(cszStatic) - 1, cszStatic));
while (!!GetLine(strALine))
push_back(CSymbol(strALine, true));
}
void CMapFile::SetLoadAddress(ulonglong_t ullLoadAddr)
{
for (iterator i = begin(); i != end(); i++)
if (i->m_ullRva != 0)
i->m_ullRva += ullLoadAddr - m_ullLoadAddr;
m_ullLoadAddr = ullLoadAddr;
}
ostream& operator << (ostream& os, const CMapFile& mapFile)
{
CMapFile::const_iterator i = mapFile.begin();
while (i != mapFile.end() && i->m_strAddress != mapFile.m_strEntryPoint)
i++;
if (i == mapFile.end())
throw runtime_error(
__FUNCTION__ ": Entry point not found for module " +
mapFile.m_strModuleName);
os << endl << hex
<< mapFile.m_strModuleName << " (EP=" << i->m_ullRva
<< ", BA=" << mapFile.m_ullLoadAddr << ')' << endl
<< endl;
for (i = mapFile.begin(); i != mapFile.end(); i++)
os << " " << *i;
return os << endl;
}
class COutputFile : public CObjRoot
{
protected:
COutputFile(ostream&);
ostream& m_os;
private:
COutputFile(const COutputFile&);
COutputFile& operator = (const COutputFile&);
};
class CFvMapFile : public CObjRoot, public map<CIdentity, CMapFile*>
{
public:
CFvMapFile(const CIdAddressMap&, const CIdPathMap&);
~CFvMapFile(void);
friend ostream& operator << (ostream&, const CFvMapFile&);
private:
void Cleanup(void);
};
CFvMapFile::CFvMapFile(const CIdAddressMap& idAddr, const CIdPathMap& idPath)
{
for (CIdAddressMap::const_iterator i = idAddr.begin(); i != idAddr.end(); i++)
{
CIdPathMap::const_iterator j = idPath.find(i->first);
if (j == idPath.end())
throw runtime_error(__FUNCTION__ ": Map file not found");
try
{
pair<iterator, bool> k = insert(value_type(i->first,
new CMapFile(j->second.substr(0, j->second.rfind('.')) + ".map")));
if (!k.second)
throw logic_error(__FUNCTION__ ": Duplicated file found in rebase log");
k.first->second->SetLoadAddress(i->second);
}
catch (const runtime_error& e)
{
cerr << e.what() << endl;
}
}
}
void CFvMapFile::Cleanup(void)
{
for (iterator i = begin(); i != end(); i++)
delete i->second;
}
ostream& operator << (ostream& os, const CFvMapFile& fvMap)
{
for (CFvMapFile::const_iterator i = fvMap.begin(); !!os && i != fvMap.end(); i++)
os << *i->second;
return os;
}
CFvMapFile::~CFvMapFile(void)
{
Cleanup();
}
class CGenFvMapUsage : public invalid_argument
{
public:
CGenFvMapUsage(void) : invalid_argument(s_szUsage)
{
}
private:
static const char s_szUsage[];
};
const char CGenFvMapUsage::s_szUsage[] = "Usage: GenFvMap <LOG> <INF> <MAP>";
class CGenFvMapApp : public CObjRoot
{
public:
CGenFvMapApp(int, char *[]);
~CGenFvMapApp(void);
int Run(void);
private:
int m_cArgc;
char **m_ppszArgv;
};
CGenFvMapApp::CGenFvMapApp(int cArgc, char *ppszArgv[])
: m_cArgc(cArgc)
, m_ppszArgv(ppszArgv)
{
if (cArgc != 4)
throw CGenFvMapUsage();
}
CGenFvMapApp::~CGenFvMapApp(void)
{
}
int CGenFvMapApp::Run(void)
{
ifstream isLog(m_ppszArgv[1]);
ifstream isInf(m_ppszArgv[2]);
CIdAddressMap idAddress(isLog);
CIdPathMap idPath(isInf);
CFvMapFile fvMap(idAddress, idPath);
ofstream osMap(m_ppszArgv[3], ios_base::out | ios_base::trunc);
osMap << fvMap;
if (!osMap)
throw runtime_error(__FUNCTION__ ": Error writing output file");
return 0;
}
int main(int argc, char *argv[])
{
try
{
CGenFvMapApp app(argc, argv);
return app.Run();
}
catch (const exception& e)
{
cerr << e.what() << endl;
return -1;
}
}

View File

@ -0,0 +1,72 @@
<?xml version="1.0" ?>
<!--
Copyright (c) 2006, Intel Corporation
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 license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-->
<project default="GenTool" basedir=".">
<!--
EDK GenTEImage Tool
Copyright (c) 2006, Intel Corporation
-->
<property name="ToolName" value="GenFvMap"/>
<property name="FileSet" value="*.cpp"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property name="LINK_OUTPUT_TYPE" value="static"/>
<property name="BUILD_DIR" value="${PACKAGE_DIR}/${ToolName}/tmp"/>
<target name="GenTool" depends="init, Tool">
<echo message="The EDK Tool: ${ToolName} build has completed!"/>
</target>
<target name="init">
<echo message="Building the EDK Tool: ${ToolName}"/>
<mkdir dir="${BUILD_DIR}"/>
</target>
<target name="Tool" depends="init">
<cc name="${ToolChain}" objdir="${BUILD_DIR}"
outfile="${BIN_DIR}/${ToolName}"
outtype="executable"
debug="true"
optimize="speed">
<compilerarg value="${ExtraArgus}" if="ExtraArgus" />
<compilerarg value="/EHsc" unless="GCC"/>
<fileset dir="${basedir}/${ToolName}"
includes="${FileSet}"
defaultexcludes="TRUE"
excludes="*.xml *.inf"/>
<includepath path="${PACKAGE_DIR}/Include"/>
<includepath path="${PACKAGE_DIR}/Include/${HostArch}"/>
<includepath path="${PACKAGE_DIR}/Common"/>
<libset dir="${LIB_DIR}" libs="CommonTools"/>
</cc>
</target>
<target name="clean">
<echo message="Removing Intermediate Files Only"/>
<delete>
<fileset dir="${BUILD_DIR}" includes="*.obj"/>
</delete>
</target>
<target name="cleanall">
<echo message="Removing Object Files and the Executable: ${ToolName}${ext_exe}"/>
<delete failonerror="false" quiet="true" includeEmptyDirs="true">
<fileset dir="${BUILD_DIR}"/>
<fileset file="${BIN_DIR}/${ToolName}${ext_exe}"/>
<fileset file="${BIN_DIR}/${ToolName}.pdb"/>
</delete>
</target>
</project>

View File

@ -1,8 +1,8 @@
/*++ /*++
Copyright (c) 1999-2006 Intel Corporation. All rights reserved Copyright (c) 1999-2006 Intel Corporation. All rights reserved
This program and the accompanying materials are licensed and made available This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
@ -59,23 +59,21 @@ Arguments:
argc - Number of command line arguments argc - Number of command line arguments
argv[]: argv[]:
BaseAddress The base address to use for rebasing the FV. The correct BaseAddress The base address to use for rebasing the FV. The correct
format is a hex number preceded by 0x. format is a hex number preceded by 0x.
InputFileName The name of the input FV file. InputFileName The name of the input FV file.
OutputFileName The name of the output FV file. OutputFileName The name of the output FV file.
MapFileName The name of the map file of relocation info.
Arguments come in pair in any order. Arguments come in pair in any order.
-I InputFileName -I InputFileName
-O OutputFileName -O OutputFileName
-B BaseAddress -B BaseAddress
-M MapFileName
Returns: Returns:
0 No error conditions detected. 0 No error conditions detected.
1 One or more of the input parameters is invalid. 1 One or more of the input parameters is invalid.
2 A resource required by the utility was unavailable. 2 A resource required by the utility was unavailable.
Most commonly this will be memory allocation or file creation. Most commonly this will be memory allocation or file creation.
3 PeiRebase.dll could not be loaded. 3 PeiRebase.dll could not be loaded.
4 Error executing the PEI rebase. 4 Error executing the PEI rebase.
@ -84,14 +82,13 @@ Returns:
{ {
UINT8 Index; UINT8 Index;
CHAR8 InputFileName[_MAX_PATH]; CHAR8 InputFileName[_MAX_PATH];
CHAR8 OutputFileName[_MAX_PATH]; CHAR8 *OutputFileName;
CHAR8 MapFileName[_MAX_PATH]; EFI_PHYSICAL_ADDRESS XipBase, BsBase, RtBase;
EFI_PHYSICAL_ADDRESS BaseAddress; UINT32 BaseTypes;
BOOLEAN BaseAddressSet;
EFI_STATUS Status; EFI_STATUS Status;
FILE *InputFile; FILE *InputFile;
FILE *OutputFile; FILE *OutputFile;
FILE *MapFile; FILE *LogFile;
UINT64 FvOffset; UINT64 FvOffset;
UINT32 FileCount; UINT32 FileCount;
int BytesRead; int BytesRead;
@ -99,11 +96,8 @@ Returns:
UINT32 FvSize; UINT32 FvSize;
EFI_FFS_FILE_HEADER *CurrentFile; EFI_FFS_FILE_HEADER *CurrentFile;
BOOLEAN ErasePolarity; BOOLEAN ErasePolarity;
EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress;
CHAR8 InfFileName[_MAX_PATH];
CHAR8 *InfFileImage;
UINTN InfFileSize;
MEMORY_FILE InfMemoryFile; MEMORY_FILE InfMemoryFile;
CHAR8 StringBuffer[0x100];
ErasePolarity = FALSE; ErasePolarity = FALSE;
// //
@ -121,21 +115,17 @@ Returns:
// //
// Initialize variables // Initialize variables
// //
InputFileName[0] = 0; InputFileName[0] = '\0';
OutputFileName[0] = 0; OutputFileName = NULL;
MapFileName[0] = 0; XipBase = BsBase = RtBase = 0;
BaseAddress = 0; BaseTypes = 0;
BaseAddressSet = FALSE;
FvOffset = 0; FvOffset = 0;
FileCount = 0; FileCount = 0;
ErasePolarity = FALSE; ErasePolarity = FALSE;
InputFile = NULL; InputFile = NULL;
OutputFile = NULL; OutputFile = NULL;
MapFile = NULL; LogFile = NULL;
FvImage = NULL; FvImage = NULL;
InfFileImage = NULL;
InfFileSize = 0;
strcpy (InfFileName, "");
// //
// Parse the command line arguments // Parse the command line arguments
@ -156,7 +146,7 @@ Returns:
PrintUsage (); PrintUsage ();
Error (NULL, 0, 0, argv[Index], "unrecognized option"); Error (NULL, 0, 0, argv[Index], "unrecognized option");
return STATUS_ERROR; return STATUS_ERROR;
} }
// //
// Determine argument to read // Determine argument to read
// //
@ -174,8 +164,8 @@ Returns:
case 'O': case 'O':
case 'o': case 'o':
if (strlen (OutputFileName) == 0) { if (OutputFileName == NULL) {
strcpy (OutputFileName, argv[Index + 1]); OutputFileName = argv[Index + 1];
} else { } else {
PrintUsage (); PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified"); Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");
@ -183,79 +173,86 @@ Returns:
} }
break; break;
case 'B':
case 'b':
if (!BaseAddressSet) {
Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);
if (EFI_ERROR (Status)) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");
return STATUS_ERROR;
}
BaseAddressSet = TRUE;
} else {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");
return STATUS_ERROR;
}
break;
case 'F': case 'F':
case 'f': case 'f':
if (!BaseAddressSet) { //
strcpy (InfFileName, argv[Index + 1]); // Load INF file into memory & initialize MEMORY_FILE structure
// //
// Read the INF file image Status = GetFileImage (argv[Index + 1], &InfMemoryFile.FileImage, (UINT32*)&InfMemoryFile.Eof);
// InfMemoryFile.Eof = InfMemoryFile.FileImage + (UINT32)(UINTN)InfMemoryFile.Eof;
Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize); InfMemoryFile.CurrentFilePointer = InfMemoryFile.FileImage;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
PrintUsage (); Error (NULL, 0, 0, argv[Index + 1], "Error opening FvInfFile");
Error (NULL, 0, 0, argv[Index + 1], "-f FvInfFile can't be opened.");
return STATUS_ERROR;
}
//
// Initialize file structures
//
InfMemoryFile.FileImage = InfFileImage;
InfMemoryFile.CurrentFilePointer = InfFileImage;
InfMemoryFile.Eof = InfFileImage + InfFileSize;
//
// Read BaseAddress from fv.inf file.
//
FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, InfFileName);
//
// free Inf File Image
//
free (InfFileImage);
//
// Convert string to UINT64 base address.
//
Status = AsciiStringToUint64 (InfFileName, FALSE, &BaseAddress);
if (EFI_ERROR (Status)) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "can't find the base address in the specified fv.inf file.");
return STATUS_ERROR;
}
BaseAddressSet = TRUE;
} else {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "BaseAddress has been got once from fv.inf or the specified base address.");
return STATUS_ERROR; return STATUS_ERROR;
} }
//
// Read BaseAddress from fv.inf file
//
FindToken (&InfMemoryFile, "[options]", "EFI_BASE_ADDRESS", 0, StringBuffer);
//
// Free INF file image
//
free (InfMemoryFile.FileImage);
//
// Point argv[Index + 1] to StringBuffer so that it could be processed as "-b"
//
argv[Index + 1] = StringBuffer;
case 'B':
case 'b':
if (BaseTypes & 1) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "XipBaseAddress may be specified only once by either -b or -f");
return STATUS_ERROR;
}
Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &XipBase);
if (EFI_ERROR (Status)) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for XIP base address");
return STATUS_ERROR;
}
BaseTypes |= 1;
break; break;
case 'M': case 'D':
case 'm': case 'd':
if (strlen (MapFileName) == 0) { if (BaseTypes & 2) {
strcpy (MapFileName, argv[Index + 1]);
} else {
PrintUsage (); PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified"); Error (NULL, 0, 0, argv[Index + 1], "-d BsBaseAddress may be specified only once");
return STATUS_ERROR; return STATUS_ERROR;
} }
Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BsBase);
if (EFI_ERROR (Status)) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for BS_DRIVER base address");
return STATUS_ERROR;
}
BaseTypes |= 2;
break;
case 'R':
case 'r':
if (BaseTypes & 4) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "-r RtBaseAddress may be specified only once");
return STATUS_ERROR;
}
Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &RtBase);
if (EFI_ERROR (Status)) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for RT_DRIVER base address");
return STATUS_ERROR;
}
BaseTypes |= 4;
break; break;
default: default:
@ -265,18 +262,6 @@ Returns:
break; break;
} }
} }
//
// Create the Map file if we need it
//
if (strlen (MapFileName) != 0) {
MapFile = fopen (MapFileName, "w");
if (MapFile == NULL) {
Error (NULL, 0, 0, MapFileName, "failed to open map file");
goto Finish;
}
}
// //
// Open the file containing the FV // Open the file containing the FV
// //
@ -285,6 +270,16 @@ Returns:
Error (NULL, 0, 0, InputFileName, "could not open input file for reading"); Error (NULL, 0, 0, InputFileName, "could not open input file for reading");
return STATUS_ERROR; return STATUS_ERROR;
} }
//
// Open the log file
//
strcat (InputFileName, ".log");
LogFile = fopen (InputFileName, "a");
if (LogFile == NULL) {
Error (NULL, 0, 0, InputFileName, "could not append to log file");
}
// //
// Determine size of FV // Determine size of FV
// //
@ -330,8 +325,14 @@ Returns:
// //
// Rebase this file // Rebase this file
// //
CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage); FfsRebase (
Status = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile); CurrentFile,
BaseTypes,
XipBase + (UINTN)CurrentFile - (UINTN)FvImage,
&BsBase,
&RtBase,
LogFile
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
switch (Status) { switch (Status) {
@ -359,7 +360,6 @@ Returns:
goto Finish; goto Finish;
} }
// //
// Get the next file // Get the next file
// //
@ -399,8 +399,8 @@ Finish:
fclose (OutputFile); fclose (OutputFile);
} }
if (MapFile != NULL) { if (LogFile != NULL) {
fclose (MapFile); fclose (LogFile);
} }
if (FvImage != NULL) { if (FvImage != NULL) {
@ -420,7 +420,7 @@ ReadHeader (
Routine Description: Routine Description:
This function determines the size of the FV and the erase polarity. The This function determines the size of the FV and the erase polarity. The
erase polarity is the FALSE value for file state. erase polarity is the FALSE value for file state.
Arguments: Arguments:
@ -428,9 +428,9 @@ Arguments:
InputFile The file that contains the FV image. InputFile The file that contains the FV image.
FvSize The size of the FV. FvSize The size of the FV.
ErasePolarity The FV erase polarity. ErasePolarity The FV erase polarity.
Returns: Returns:
EFI_SUCCESS Function completed successfully. EFI_SUCCESS Function completed successfully.
EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
EFI_ABORTED The function encountered an error. EFI_ABORTED The function encountered an error.
@ -539,38 +539,36 @@ Returns:
--*/ --*/
{ {
printf ( printf (
"Usage: %s -I InputFileName -O OutputFileName [-B BaseAddress] -F FvInfFileName -M MapFile\n", "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
UTILITY_NAME UTILITY_NAME
); );
printf (" Where:\n"); printf (" Where:\n");
printf (" InputFileName is the name of the EFI FV file to rebase.\n"); printf (" InputFileName is the name of the EFI FV file to rebase.\n");
printf (" OutputFileName is the desired output file name.\n"); printf (" OutputFileName is the desired output file name.\n");
printf (" BaseAddress is the FV base address to rebase agains.\n"); printf (" BaseAddress is the FV base address to rebase agains.\n");
printf (" FvInfFileName is the fv.inf to be used to generate this fv image.\n"); printf (" Argument pair may be in any order.\n\n");
printf (" BaseAddress can also be got from the fv.inf file.\n");
printf (" Choose only one method to input BaseAddress.\n");
printf (" MapFileName is an optional map file of the relocations\n");
printf (" Argument pair may be in any order.\n\n");
} }
EFI_STATUS EFI_STATUS
FfsRebase ( FfsRebase (
IN OUT EFI_FFS_FILE_HEADER *FfsFile, IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT32 Flags,
IN FILE *MapFile OPTIONAL IN OUT EFI_PHYSICAL_ADDRESS XipBase,
IN OUT EFI_PHYSICAL_ADDRESS *BsBase,
IN OUT EFI_PHYSICAL_ADDRESS *RtBase,
OUT FILE *LogFile
) )
/*++ /*++
Routine Description: Routine Description:
This function determines if a file is XIP and should be rebased. It will This function determines if a file is XIP and should be rebased. It will
rebase any PE32 sections found in the file using the base address. rebase any PE32 sections found in the file using the base address.
Arguments: Arguments:
FfsFile A pointer to Ffs file image. FfsFile A pointer to Ffs file image.
BaseAddress The base address to use for rebasing the file image. BaseAddress The base address to use for rebasing the file image.
MapFile Optional file to dump relocation information into
Returns: Returns:
@ -590,20 +588,21 @@ Returns:
UINT64 ImageSize; UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS EntryPoint; EFI_PHYSICAL_ADDRESS EntryPoint;
UINT32 Pe32ImageSize; UINT32 Pe32ImageSize;
UINT32 NewPe32BaseAddress; EFI_PHYSICAL_ADDRESS NewPe32BaseAddress;
UINTN Index; UINTN Index;
EFI_FILE_SECTION_POINTER CurrentPe32Section; EFI_FILE_SECTION_POINTER CurrentPe32Section;
EFI_FFS_FILE_STATE SavedState; EFI_FFS_FILE_STATE SavedState;
EFI_IMAGE_NT_HEADERS *PeHdr; EFI_IMAGE_NT_HEADERS32 *PeHdr;
EFI_IMAGE_NT_HEADERS64 *PePlusHdr;
UINT32 *PeHdrSizeOfImage; UINT32 *PeHdrSizeOfImage;
UINT32 *PeHdrChecksum; UINT32 *PeHdrChecksum;
UINT32 FoundCount;
EFI_TE_IMAGE_HEADER *TEImageHeader; EFI_TE_IMAGE_HEADER *TEImageHeader;
UINT8 *TEBuffer; UINT8 *TEBuffer;
EFI_IMAGE_DOS_HEADER *DosHeader; EFI_IMAGE_DOS_HEADER *DosHeader;
UINT8 FileGuidString[80]; UINT8 FileGuidString[80];
UINT32 TailSize; UINT32 TailSize;
EFI_FFS_FILE_TAIL TailValue; EFI_FFS_FILE_TAIL TailValue;
EFI_PHYSICAL_ADDRESS *BaseToUpdate;
// //
// Verify input parameters // Verify input parameters
@ -611,7 +610,6 @@ Returns:
if (FfsFile == NULL) { if (FfsFile == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
// //
// Convert the GUID to a string so we can at least report which file // Convert the GUID to a string so we can at least report which file
// if we find an error. // if we find an error.
@ -622,7 +620,6 @@ Returns:
} else { } else {
TailSize = 0; TailSize = 0;
} }
// //
// Do some cursory checks on the FFS file contents // Do some cursory checks on the FFS file contents
// //
@ -632,36 +629,31 @@ Returns:
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
memset (&ImageContext, 0, sizeof (ImageContext));
// //
// Check if XIP file type. If not XIP, don't rebase. // We only process files potentially containing PE32 sections.
// //
if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && switch (FfsFile->Type) {
FfsFile->Type != EFI_FV_FILETYPE_PEIM && case EFI_FV_FILETYPE_SECURITY_CORE:
FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && case EFI_FV_FILETYPE_PEI_CORE:
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER case EFI_FV_FILETYPE_PEIM:
) { case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
return EFI_SUCCESS; case EFI_FV_FILETYPE_DRIVER:
case EFI_FV_FILETYPE_DXE_CORE:
break;
default:
return EFI_SUCCESS;
} }
// //
// Rebase each PE32 section // Rebase each PE32 section
// //
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
FoundCount = 0;
for (Index = 1;; Index++) { for (Index = 1;; Index++) {
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
break; break;
} }
FoundCount++;
//
// Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section
//
NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);
// //
// Initialize context // Initialize context
@ -669,25 +661,102 @@ Returns:
memset (&ImageContext, 0, sizeof (ImageContext)); memset (&ImageContext, 0, sizeof (ImageContext));
ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION)); ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext); Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString); Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);
return Status; return Status;
} }
//
// Calculate the PE32 base address, based on file type
//
switch (FfsFile->Type) {
case EFI_FV_FILETYPE_SECURITY_CORE:
case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM:
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
if ((Flags & 1) == 0) {
//
// We aren't relocating XIP code, so skip it.
//
return EFI_SUCCESS;
}
NewPe32BaseAddress =
XipBase +
(UINTN)CurrentPe32Section.Pe32Section +
sizeof (EFI_COMMON_SECTION_HEADER) -
(UINTN)FfsFile;
BaseToUpdate = &XipBase;
break;
case EFI_FV_FILETYPE_DRIVER:
PeHdr = (EFI_IMAGE_NT_HEADERS32*)(
(UINTN)CurrentPe32Section.Pe32Section +
sizeof (EFI_COMMON_SECTION_HEADER) +
ImageContext.PeCoffHeaderOffset
);
switch (PeHdr->OptionalHeader.Subsystem) {
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
if ((Flags & 4) == 0) {
//
// RT drivers aren't supposed to be relocated
//
continue;
}
NewPe32BaseAddress = *RtBase;
BaseToUpdate = RtBase;
break;
default:
//
// We treat all other subsystems the same as BS_DRIVER
//
if ((Flags & 2) == 0) {
//
// Skip all BS_DRIVER's
//
continue;
}
NewPe32BaseAddress = *BsBase;
BaseToUpdate = BsBase;
break;
}
break;
case EFI_FV_FILETYPE_DXE_CORE:
if ((Flags & 2) == 0) {
//
// Skip DXE core
//
return EFI_SUCCESS;
}
NewPe32BaseAddress = *BsBase;
BaseToUpdate = BsBase;
break;
default:
//
// Not supported file type
//
return EFI_SUCCESS;
}
// //
// Allocate a buffer for the image to be loaded into. // Allocate a buffer for the image to be loaded into.
// //
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION); Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x10000)); MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) { if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation failure", NULL); Error (NULL, 0, 0, "memory allocation failure", NULL);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000); memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16); MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
ImageContext.ImageAddress = MemoryImagePointerAligned; ImageContext.ImageAddress = MemoryImagePointerAligned;
@ -697,24 +766,6 @@ Returns:
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
return Status; return Status;
} }
//
// Check if section-alignment and file-alignment match or not
//
if (!(ImageContext.IsTeImage)) {
PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress +
ImageContext.PeCoffHeaderOffset);
if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {
Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);
free ((VOID *) MemoryImagePointer);
return EFI_ABORTED;
}
}
else {
//
// BUGBUG: TE Image Header lack section-alignment and file-alignment info
//
}
ImageContext.DestinationAddress = NewPe32BaseAddress; ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext); Status = PeCoffLoaderRelocateImage (&ImageContext);
@ -742,21 +793,34 @@ Returns:
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
return EFI_ABORTED; return EFI_ABORTED;
} }
//
// Update BASE address
//
fprintf (
LogFile,
"%s %016I64X\n",
FileGuidString,
ImageContext.DestinationAddress
);
*BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;
// //
// Since we may have updated the Codeview RVA, we need to insure the PE // Since we may have updated the Codeview RVA, we need to insure the PE
// header indicates the image is large enough to contain the Codeview data // header indicates the image is large enough to contain the Codeview data
// so it will be loaded properly later if the PEIM is reloaded into memory... // so it will be loaded properly later if the PEIM is reloaded into memory...
// //
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) { } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else { } else {
Error ( Error (
NULL, NULL,
@ -779,24 +843,6 @@ Returns:
} }
memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize); memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);
//
// Get EntryPoint in Flash Region.
//
EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;
//
// If a map file was selected output mapping information for any file that
// was rebased.
//
if (MapFile != NULL) {
fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress);
fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);
if (ImageContext.PdbPointer != NULL) {
fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);
}
fprintf (MapFile, "\n");
}
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
@ -832,6 +878,20 @@ Returns:
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
} }
} }
if ((Flags & 1) == 0 || (
FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
)) {
//
// Only XIP code may have a TE section
//
return EFI_SUCCESS;
}
// //
// Now process TE sections // Now process TE sections
// //
@ -841,15 +901,13 @@ Returns:
break; break;
} }
FoundCount++;
// //
// Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
// by GenTEImage // by GenTEImage
// //
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER)); TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
NewPe32BaseAddress = ((UINT32) BaseAddress) + NewPe32BaseAddress = ((UINT32) XipBase) +
( (
(UINTN) CurrentPe32Section.Pe32Section + (UINTN) CurrentPe32Section.Pe32Section +
sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER) +
@ -880,6 +938,7 @@ Returns:
DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE; DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;
*(UINT32 *) (TEBuffer + 0x3C) = 0x40; *(UINT32 *) (TEBuffer + 0x3C) = 0x40;
PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40); PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE; PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
PeHdr->FileHeader.Machine = TEImageHeader->Machine; PeHdr->FileHeader.Machine = TEImageHeader->Machine;
PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections; PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;
@ -889,39 +948,89 @@ Returns:
// the 0x40 bytes for our DOS header. // the 0x40 bytes for our DOS header.
// //
PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER)); PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));
PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER)); if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {
PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint; PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
PeHdr->OptionalHeader.BaseOfCode = TEImageHeader->BaseOfCode; } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem; } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections * } else {
sizeof (EFI_IMAGE_SECTION_HEADER) - 12; Error (
NULL,
// 0,
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image 0,
// "unknown machine type in TE image",
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) || "machine type=0x%X, file=%s",
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) (UINT32) TEImageHeader->Machine,
) { FileGuidString
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1; );
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; free (TEBuffer);
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; return EFI_ABORTED;
} }
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) || if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
) { PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) { sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
//
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
//
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
) {
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
} }
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
) {
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
}
}
//
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
//
PeHdr->OptionalHeader.SectionAlignment = 0x10;
} else {
PePlusHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
PePlusHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
PePlusHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
PePlusHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
//
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
//
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
) {
PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
) {
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
}
}
//
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
//
PePlusHdr->OptionalHeader.SectionAlignment = 0x10;
} }
//
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
//
PeHdr->OptionalHeader.SectionAlignment = 0x10;
// //
// Copy the rest of the image to its original offset // Copy the rest of the image to its original offset
@ -950,15 +1059,15 @@ Returns:
// //
// Allocate a buffer for the image to be loaded into. // Allocate a buffer for the image to be loaded into.
// //
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x10000)); MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) { if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString); Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);
free (TEBuffer); free (TEBuffer);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x10000); memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16); MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
ImageContext.ImageAddress = MemoryImagePointerAligned; ImageContext.ImageAddress = MemoryImagePointerAligned;
Status = PeCoffLoaderLoadImage (&ImageContext); Status = PeCoffLoaderLoadImage (&ImageContext);
@ -968,11 +1077,6 @@ Returns:
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
return Status; return Status;
} }
//
// Check if section-alignment and file-alignment match or not
// BUGBUG: TE Image Header lack section-alignment and file-alignment info
//
ImageContext.DestinationAddress = NewPe32BaseAddress; ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext); Status = PeCoffLoaderRelocateImage (&ImageContext);
@ -993,12 +1097,16 @@ Returns:
// so it will be loaded properly later if the PEIM is reloaded into memory... // so it will be loaded properly later if the PEIM is reloaded into memory...
// //
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); PeHdrSizeOfImage = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); PeHdrChecksum = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
PeHdrSizeOfImage = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);
} else { } else {
Error ( Error (
NULL, NULL,
@ -1028,25 +1136,6 @@ Returns:
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
sizeof (EFI_TE_IMAGE_HEADER) sizeof (EFI_TE_IMAGE_HEADER)
); );
//
// Get EntryPoint in Flash Region.
//
EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;
//
// If a map file was selected output mapping information for any file that
// was rebased.
//
if (MapFile != NULL) {
fprintf (MapFile, "TE File: %s Base:%08lx", FileGuidString, BaseAddress);
fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);
if (ImageContext.PdbPointer != NULL) {
fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);
}
fprintf (MapFile, "\n");
}
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
free (TEBuffer); free (TEBuffer);
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
@ -1079,18 +1168,15 @@ Returns:
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference)); TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
} }
fprintf (
LogFile,
"%s %016I64X\n",
FileGuidString,
ImageContext.DestinationAddress
);
} }
//
// If we found no files, then emit an error if no compressed sections either
//
if (FoundCount == 0) {
Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);
return EFI_NOT_FOUND;
}
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -1,8 +1,8 @@
/*++ /*++
Copyright (c) 1999-2006 Intel Corporation. All rights reserved Copyright (c) 1999-2006 Intel Corporation. All rights reserved
This program and the accompanying materials are licensed and made available This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
@ -11,7 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name: Module Name:
PeiRebaseExe.h PeiRebaseExe.h
Abstract: Abstract:
@ -43,7 +43,7 @@ Abstract:
// //
// The maximum number of arguments accepted from the command line. // The maximum number of arguments accepted from the command line.
// //
#define MAX_ARGS 9 #define MAX_ARGS 7
// //
// The file copy buffer size // The file copy buffer size
@ -130,9 +130,12 @@ Returns:
EFI_STATUS EFI_STATUS
FfsRebase ( FfsRebase (
IN OUT EFI_FFS_FILE_HEADER *FfsFile, IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT32 Flags,
IN FILE *MapFile OPTIONAL IN OUT EFI_PHYSICAL_ADDRESS XipBase,
IN OUT EFI_PHYSICAL_ADDRESS *BsBase,
IN OUT EFI_PHYSICAL_ADDRESS *RtBase,
OUT FILE *LogFile
) )
/*++ /*++

View File

@ -13,8 +13,8 @@
updates either the OS or the HOST tool chain, these tools should be rebuilt.</Description> updates either the OS or the HOST tool chain, these tools should be rebuilt.</Description>
<Copyright>Copyright 2006, Intel Corporation</Copyright> <Copyright>Copyright 2006, Intel Corporation</Copyright>
<License URL="http://opensource.org/licenses/bsd-license.php">All rights reserved. This program and the accompanying materials <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 are licensed and made available under the terms and conditions of the
BSD License which accompanies this distribution. The full text of the BSD License which accompanies this distribution. The full text of the
license may be found at license may be found at
http://opensource.org/licenses/bsd-license.php 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> <Filename>GenFvImage/GenFvImageLib.c</Filename>
<Filename>GenFvImage/GenFvImageLib.h</Filename> <Filename>GenFvImage/GenFvImageLib.h</Filename>
<Filename>GenFvImage/GenFvImageLibInternal.h</Filename> <Filename>GenFvImage/GenFvImageLibInternal.h</Filename>
<Filename>GenFvMap/build.xml</Filename>
<Filename>GenFvMap/GenFvMap.cpp</Filename>
<Filename>GenSection/build.xml</Filename> <Filename>GenSection/build.xml</Filename>
<Filename>GenSection/GenSection.c</Filename> <Filename>GenSection/GenSection.c</Filename>
<Filename>GenSection/GenSection.h</Filename> <Filename>GenSection/GenSection.h</Filename>

View File

@ -51,11 +51,11 @@ public class PeiReBaseTask extends Task implements EfiDefine {
private ToolArg baseAddr = new ToolArg(); private ToolArg baseAddr = new ToolArg();
// //
// Fv.inf file // Fv.inf file
// //
private FileArg fvinfFile = new FileArg(); private FileArg fvinfFile = new FileArg();
// //
// map file // map file
// //
private FileArg mapFile = new FileArg(); private FileArg mapFile = new FileArg();
// //
// Architecture // Architecture
@ -64,10 +64,10 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
execute execute
PeiReBaseTask execute function is to assemble tool command line & execute PeiReBaseTask execute function is to assemble tool command line & execute
tool command line tool command line
@throws BuidException @throws BuidException
**/ **/
public void execute() throws BuildException { public void execute() throws BuildException {
@ -103,7 +103,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
if (mapFile.getValue().length() == 0) { if (mapFile.getValue().length() == 0) {
mapFile.setArg(" -M ", outputFile.getValue() + ".map"); mapFile.setArg(" -M ", outputFile.getValue() + ".map");
} }
argument = "" + inputFile + outputFile + baseAddr + fvinfFile + mapFile; argument = "" + inputFile + outputFile + baseAddr + fvinfFile;
// //
// return value of fwimage execution // return value of fwimage execution
@ -125,7 +125,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
// Set debug log information. // Set debug log information.
// //
EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline())); EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline()));
EdkLog.log(this, EdkLog.EDK_INFO, inputFile.toFileList() + " => " EdkLog.log(this, EdkLog.EDK_INFO, inputFile.toFileList() + " => "
+ outputFile.toFileList() + outputFile.toFileList()
+ mapFile.toFileList()); + mapFile.toFileList());
@ -150,9 +150,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
getInputFile getInputFile
This function is to get class member "inputFile". This function is to get class member "inputFile".
@return string of input file name. @return string of input file name.
**/ **/
public String getInputFile() { public String getInputFile() {
@ -161,9 +161,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
setComponentType setComponentType
This function is to set class member "inputFile". This function is to set class member "inputFile".
@param inputFile @param inputFile
string of input file name. string of input file name.
**/ **/
@ -173,9 +173,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
getOutputFile getOutputFile
This function is to get class member "outputFile" This function is to get class member "outputFile"
@return outputFile string of output file name. @return outputFile string of output file name.
**/ **/
public String getOutputFile() { public String getOutputFile() {
@ -184,9 +184,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
setOutputFile setOutputFile
This function is to set class member "outputFile" This function is to set class member "outputFile"
@param outputFile @param outputFile
string of output file name. string of output file name.
**/ **/
@ -196,9 +196,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
getBaseAddr getBaseAddr
This function is to get class member "baseAddr" This function is to get class member "baseAddr"
@return baseAddr string of base address. @return baseAddr string of base address.
**/ **/
public String getBaseAddr() { public String getBaseAddr() {
@ -207,9 +207,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
setBaseAddr setBaseAddr
This function is to set class member "baseAddr" This function is to set class member "baseAddr"
@param baseAddr string of base address @param baseAddr string of base address
**/ **/
public void setBaseAddr(String baseAddr) { public void setBaseAddr(String baseAddr) {
@ -218,9 +218,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
getArch getArch
This function is to get class member "arch". This function is to get class member "arch".
@return arch Architecture @return arch Architecture
**/ **/
public String getArch() { public String getArch() {
@ -229,9 +229,9 @@ public class PeiReBaseTask extends Task implements EfiDefine {
/** /**
setArch setArch
This function is to set class member "arch" This function is to set class member "arch"
@param arch Architecture @param arch Architecture
**/ **/
public void setArch(String arch) { public void setArch(String arch) {
@ -276,7 +276,7 @@ public class PeiReBaseTask extends Task implements EfiDefine {
// //
// Dependency check // Dependency check
// //
private boolean isUptodate() { private boolean isUptodate() {
File srcFile = new File(inputFile.getValue()); File srcFile = new File(inputFile.getValue());
File dstFile = new File(outputFile.getValue()); File dstFile = new File(outputFile.getValue());