Adding Additional Tools that are needed for Platform Image creation.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@198 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lhauch 2006-05-19 02:38:56 +00:00
parent 291a871a27
commit d25c4bf080
42 changed files with 17050 additions and 0 deletions

View File

@ -0,0 +1,246 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
CreateMtFile.c
Abstract:
Simple utility to create a pad file containing fixed data.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "TianoCommon.h"
#define PROGRAM_NAME "CreateMtFile"
typedef struct {
INT8 *OutFileName;
INT8 ByteValue;
UINT32 FileSize;
} OPTIONS;
static
EFI_STATUS
ProcessArgs (
IN INT32 Argc,
IN INT8 *Argv[],
IN OUT OPTIONS *Options
);
static
void
Usage (
VOID
);
int
main (
IN INT32 Argc,
IN INT8 *Argv[]
)
/*++
Routine Description:
Main entry point for this utility.
Arguments:
Standard C entry point args Argc and Argv
Returns:
EFI_SUCCESS if good to go
--*/
// GC_TODO: ] - add argument and description to function comment
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
{
FILE *OutFptr;
OPTIONS Options;
//
// Process the command-line arguments.
//
if (ProcessArgs (Argc, Argv, &Options) != EFI_SUCCESS) {
return EFI_INVALID_PARAMETER;
}
//
// Open the output file
//
if ((OutFptr = fopen (Options.OutFileName, "wb")) == NULL) {
fprintf (
stdout,
PROGRAM_NAME " ERROR: Could not open output file '%s' for writing\n",
Options.OutFileName
);
return EFI_DEVICE_ERROR;
}
//
// Write the pad bytes. Do it the slow way (one at a time) for now.
//
while (Options.FileSize > 0) {
if (fwrite (&Options.ByteValue, 1, 1, OutFptr) != 1) {
fclose (OutFptr);
fprintf (stdout, PROGRAM_NAME " ERROR: Failed to write to output file\n");
return EFI_DEVICE_ERROR;
}
Options.FileSize--;
}
//
// Close the file
//
fclose (OutFptr);
return EFI_SUCCESS;
}
static
EFI_STATUS
ProcessArgs (
IN INT32 Argc,
IN INT8 *Argv[],
IN OUT OPTIONS *Options
)
/*++
Routine Description:
Process the command line arguments.
Arguments:
Argc - argument count as passed in to the entry point function
Argv - array of arguments as passed in to the entry point function
Options - stucture of where to put the values of the parsed arguments
Returns:
EFI_SUCCESS if everything looks good
EFI_INVALID_PARAMETER otherwise
--*/
// GC_TODO: ] - add argument and description to function comment
{
UINT32 Multiplier;
//
// Clear the options
//
memset ((char *) Options, 0, sizeof (OPTIONS));
//
// Skip program name
//
Argv++;
Argc--;
if (Argc < 2) {
Usage ();
return EFI_INVALID_PARAMETER;
}
//
// If first arg is dash-option, then print usage.
//
if (Argv[0][0] == '-') {
Usage ();
return EFI_INVALID_PARAMETER;
}
//
// First arg is file name
//
Options->OutFileName = Argv[0];
Argc--;
Argv++;
//
// Second arg is file size. Allow 0x1000, 0x100K, 1024, 1K
//
Multiplier = 1;
if ((Argv[0][strlen (Argv[0]) - 1] == 'k') || (Argv[0][strlen (Argv[0]) - 1] == 'K')) {
Multiplier = 1024;
}
//
// Look for 0x prefix on file size
//
if ((Argv[0][0] == '0') && ((Argv[0][1] == 'x') || (Argv[0][1] == 'X'))) {
if (sscanf (Argv[0], "%x", &Options->FileSize) != 1) {
fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);
Usage ();
return EFI_INVALID_PARAMETER;
}
//
// Otherwise must be a decimal number
//
} else {
if (sscanf (Argv[0], "%d", &Options->FileSize) != 1) {
fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);
Usage ();
return EFI_INVALID_PARAMETER;
}
}
Options->FileSize *= Multiplier;
//
// Assume byte value of 0xff
//
Options->ByteValue = (INT8) (UINT8) 0xFF;
return EFI_SUCCESS;
}
//
// Print utility usage info
//
static
void
Usage (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
{
UINT32 Index;
static const INT8 *Text[] = {
" ",
"Usage: "PROGRAM_NAME " OutFileName FileSize",
" where:",
" OutFileName is the name of the output file to generate",
" FileSize is the size of the file to create",
" Examples:",
" "PROGRAM_NAME " OutFile.bin 32K",
" "PROGRAM_NAME " OutFile.bin 0x1000",
" ",
NULL
};
for (Index = 0; Text[Index] != NULL; Index++) {
fprintf (stdout, "%s\n", Text[Index]);
}
}

View File

@ -0,0 +1,67 @@
#/*++
#
# Copyright (c) 1999 - 2001 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
# license, no part of this software or documentation may be
# reproduced, stored in a retrieval system, or transmitted in any
# form or by any means without the express written consent of
# Intel Corporation.
#
#
# Module Name:
#
# Makefile
#
# Abstract:
#
# makefile for building the CreateMtFile utility.
#
# Revision History
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Define the toolchain which is used to set build options and toolchain paths
#
TOOLCHAIN = TOOLCHAIN_MSVC
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = CreateMtFile
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj
#
# Build the EXE by compiling the source files, then linking the resultant
# object files together.
#
$(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj : $(TARGET_SRC_DIR)\CreateMtFile.c
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\CreateMtFile.c /Fo$@
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,163 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
EfiCompressMain.c
Abstract:
The main function for the compression utility.
--*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "TianoCommon.h"
#include "EfiCompress.h"
int
main (
INT32 argc,
CHAR8 *argv[]
)
/*++
Routine Description:
Compresses the input files
Arguments:
argc - number of arguments passed into the command line.
argv[] - files to compress and files to output compressed data to.
Returns:
int: 0 for successful execution of the function.
--*/
{
EFI_STATUS Status;
FILE *infile;
FILE *outfile;
UINT32 SrcSize;
UINT32 DstSize;
UINT8 *SrcBuffer;
UINT8 *DstBuffer;
UINT8 Buffer[8];
//
// Added for makefile debug - KCE
//
INT32 arg_counter;
printf ("\n\n");
for (arg_counter = 0; arg_counter < argc; arg_counter++) {
printf ("%s ", argv[arg_counter]);
}
printf ("\n\n");
SrcBuffer = DstBuffer = NULL;
infile = outfile = NULL;
if (argc != 3) {
printf ("Usage: EFICOMPRESS <infile> <outfile>\n");
goto Done;
}
if ((outfile = fopen (argv[2], "wb")) == NULL) {
printf ("Can't open output file\n");
goto Done;
}
if ((infile = fopen (argv[1], "rb")) == NULL) {
printf ("Can't open input file\n");
goto Done;
}
//
// Get the size of source file
//
SrcSize = 0;
while (fread (Buffer, 1, 1, infile)) {
SrcSize++;
}
//
// Read in the source data
//
if ((SrcBuffer = malloc (SrcSize)) == NULL) {
printf ("Can't allocate memory\n");
goto Done;
}
rewind (infile);
if (fread (SrcBuffer, 1, SrcSize, infile) != SrcSize) {
printf ("Can't read from source\n");
goto Done;
}
//
// Get destination data size and do the compression
//
DstSize = 0;
Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);
if (Status == EFI_BUFFER_TOO_SMALL) {
if ((DstBuffer = malloc (DstSize)) == NULL) {
printf ("Can't allocate memory\n");
goto Done;
}
Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);
}
if (EFI_ERROR (Status)) {
printf ("Compress Error\n");
goto Done;
}
printf ("\nOrig Size = %ld\n", SrcSize);
printf ("Comp Size = %ld\n", DstSize);
if (DstBuffer == NULL) {
printf ("No destination to write to.\n");
goto Done;
}
//
// Write out the result
//
if (fwrite (DstBuffer, 1, DstSize, outfile) != DstSize) {
printf ("Can't write to destination file\n");
}
Done:
if (SrcBuffer) {
free (SrcBuffer);
}
if (DstBuffer) {
free (DstBuffer);
}
if (infile) {
fclose (infile);
}
if (outfile) {
fclose (outfile);
}
return 0;
}

View File

@ -0,0 +1,77 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Define some macros we use here. Should get rid of them someday and
# get rid of the extra level of indirection.
#
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
#
# BUGBUG: Override standard flags, cannot be built without warnings.
#
C_FLAGS=/nologo /W4 /GX /Zi /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /c
#
# Common information
#
INC=$(INC)
#
# Target specific information
#
TARGET_NAME=EfiCompress
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\EfiCompressMain.c"
TARGET_EXE_INCLUDE = "$(COMMON_SOURCE)\EfiCompress.h"
TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib"
#
# Build targets
#
all: $(TARGET_EXE)
#
# Build EXE
#
$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* > NUL

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name:
#
# makefile
#
# Abstract:
#
# makefile for building the EfiRom utility.
#
# Revision History
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Define the toolchain which is used to set build options and toolchain paths
#
TOOLCHAIN = TOOLCHAIN_MSVC
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = EfiRom
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\EfiRom.exe
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\EfiRom.obj \
$(TIANO_TOOLS_OUTPUT)\EfiCompress.obj
#
# Build the EXE by compiling the source files, then linking the resultant
# object files together.
#
$(TIANO_TOOLS_OUTPUT)\EfiRom.obj : $(TARGET_SRC_DIR)\EfiRom.c
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\EfiRom.c /Fo$@
$(TIANO_TOOLS_OUTPUT)\EfiCompress.obj : $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c
$(CC) $(C_FLAGS) $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c /Fo$@
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
/*++
Copyright (c) 2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
FlashDefFile.h
Abstract:
Header file for flash management utility in the Intel Platform
Innovation Framework for EFI build environment.
--*/
#ifndef _FLASH_DEF_FILE_H_
#define _FLASH_DEF_FILE_H_
#ifdef __cplusplus
extern "C"
{
#endif
void
FDFConstructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
void
FDFDestructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFParseFile (
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateCIncludeFile (
char *FlashDeviceName,
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateCFlashMapDataFile (
char *FlashDeviceName,
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateAsmIncludeFile (
char *FlashDeviceName,
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFParseFile (
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateImage (
char *FlashDeviceName,
char *ImageName,
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
ImageName - GC_TODO: add argument description
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateDscFile (
char *FlashDeviceName,
char *FileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
FileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDFCreateSymbols (
char *FlashDeviceName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FlashDeviceName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
FDDiscover (
char *FDFileName,
unsigned int BaseAddr
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FDFileName - GC_TODO: add argument description
BaseAddr - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
#ifdef __cplusplus
}
#endif
#endif // #ifndef _FLASH_DEF_FILE_H_

View File

@ -0,0 +1,745 @@
/*++
Copyright (c) 2004-2005 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
FlashMap.c
Abstract:
Utility for flash management in the Intel Platform Innovation Framework
for EFI build environment.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "Tiano.h"
#ifndef INT8
#define INT8 char
#endif
#include "EfiUtilityMsgs.h"
#include "Microcode.h"
#include "FlashDefFile.h"
#include "Symbols.h"
#define UTILITY_NAME "FlashMap"
typedef struct _STRING_LIST {
struct _STRING_LIST *Next;
char *Str;
} STRING_LIST;
//
// Keep our globals in one of these structures
//
static struct {
char *CIncludeFileName;
char *FlashDevice;
char *FlashDeviceImage;
char *MCIFileName;
char *MCOFileName;
char *ImageOutFileName;
char *DscFileName;
char *AsmIncludeFileName;
char *FlashDefinitionFileName;
char *StringReplaceInFileName;
char *StringReplaceOutFileName;
char *DiscoverFDImageName;
char MicrocodePadByteValue;
unsigned int MicrocodeAlignment;
STRING_LIST *MCIFileNames;
STRING_LIST *LastMCIFileNames;
unsigned int BaseAddress;
} mGlobals;
#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF
#define DEFAULT_MC_ALIGNMENT 16
static
STATUS
ProcessCommandLine (
int argc,
char *argv[]
);
static
STATUS
MergeMicrocodeFiles (
char *OutFileName,
STRING_LIST *FileNames,
unsigned int Alignment,
char PadByteValue
);
static
void
Usage (
VOID
);
int
main (
int argc,
char *argv[]
)
/*++
Routine Description:
Parse the command line arguments and then call worker functions to do the work
Arguments:
argc - number of elements in argv
argv - array of command-line arguments
Returns:
STATUS_SUCCESS - no problems encountered while processing
STATUS_WARNING - warnings, but no errors, were encountered while processing
STATUS_ERROR - errors were encountered while processing
--*/
{
STATUS Status;
SetUtilityName (UTILITY_NAME);
Status = ProcessCommandLine (argc, argv);
if (Status != STATUS_SUCCESS) {
return Status;
}
//
// Check for discovery of an FD (command line option)
//
if (mGlobals.DiscoverFDImageName != NULL) {
Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress);
goto Done;
}
//
// If they're doing microcode file parsing, then do that
//
if (mGlobals.MCIFileName != NULL) {
MicrocodeConstructor ();
MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName);
MicrocodeDestructor ();
}
//
// If they're doing microcode file merging, then do that now
//
if (mGlobals.MCIFileNames != NULL) {
MergeMicrocodeFiles (
mGlobals.MCOFileName,
mGlobals.MCIFileNames,
mGlobals.MicrocodeAlignment,
mGlobals.MicrocodePadByteValue
);
}
//
// If using a flash definition file, then process that and return
//
if (mGlobals.FlashDefinitionFileName != NULL) {
FDFConstructor ();
SymbolsConstructor ();
Status = FDFParseFile (mGlobals.FlashDefinitionFileName);
if (GetUtilityStatus () != STATUS_ERROR) {
//
// If they want us to do a string-replace on a file, then add the symbol definitions to
// the symbol table, and then do the string replace.
//
if (mGlobals.StringReplaceInFileName != NULL) {
Status = FDFCreateSymbols (mGlobals.FlashDevice);
Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName);
}
//
// If they want us to create a .h defines file or .c flashmap data file, then do so now
//
if (mGlobals.CIncludeFileName != NULL) {
Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName);
}
if (mGlobals.AsmIncludeFileName != NULL) {
Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName);
}
//
// If they want us to create an image, do that now
//
if (mGlobals.ImageOutFileName != NULL) {
Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName);
}
//
// If they want to create an output DSC file, do that now
//
if (mGlobals.DscFileName != NULL) {
Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName);
}
}
SymbolsDestructor ();
FDFDestructor ();
}
Done:
//
// Free up memory
//
while (mGlobals.MCIFileNames != NULL) {
mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next;
_free (mGlobals.MCIFileNames);
mGlobals.MCIFileNames = mGlobals.LastMCIFileNames;
}
return GetUtilityStatus ();
}
static
STATUS
MergeMicrocodeFiles (
char *OutFileName,
STRING_LIST *FileNames,
unsigned int Alignment,
char PadByteValue
)
/*++
Routine Description:
Merge binary microcode files into a single file, taking into consideration
the alignment and pad value.
Arguments:
OutFileName - name of the output file to create
FileNames - linked list of input microcode files to merge
Alignment - alignment for each microcode file in the output image
PadByteValue - value to use when padding to meet alignment requirements
Returns:
STATUS_SUCCESS - merge completed successfully or with acceptable warnings
STATUS_ERROR - merge failed, output file not created
--*/
{
long FileSize;
long TotalFileSize;
FILE *InFptr;
FILE *OutFptr;
char *Buffer;
STATUS Status;
//
// Open the output file
//
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
return STATUS_ERROR;
}
//
// Walk the list of files
//
Status = STATUS_ERROR;
Buffer = NULL;
InFptr = NULL;
TotalFileSize = 0;
while (FileNames != NULL) {
//
// Open the file, determine the size, then read it in and write
// it back out.
//
if ((InFptr = fopen (FileNames->Str, "rb")) == NULL) {
Error (NULL, 0, 0, FileNames->Str, "failed to open input file for reading");
goto Done;
}
fseek (InFptr, 0, SEEK_END);
FileSize = ftell (InFptr);
fseek (InFptr, 0, SEEK_SET);
if (FileSize != 0) {
Buffer = (char *) _malloc (FileSize);
if (Buffer == NULL) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
goto Done;
}
if (fread (Buffer, FileSize, 1, InFptr) != 1) {
Error (NULL, 0, 0, FileNames->Str, "failed to read file contents");
goto Done;
}
//
// Align
//
if (Alignment != 0) {
while ((TotalFileSize % Alignment) != 0) {
if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) {
Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file");
goto Done;
}
TotalFileSize++;
}
}
TotalFileSize += FileSize;
if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
Error (NULL, 0, 0, OutFileName, "failed to write to output file");
goto Done;
}
_free (Buffer);
Buffer = NULL;
} else {
Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered");
}
fclose (InFptr);
InFptr = NULL;
FileNames = FileNames->Next;
}
Status = STATUS_SUCCESS;
Done:
fclose (OutFptr);
if (InFptr != NULL) {
fclose (InFptr);
}
if (Buffer != NULL) {
_free (Buffer);
}
if (Status == STATUS_ERROR) {
remove (OutFileName);
}
return Status;
}
static
STATUS
ProcessCommandLine (
int argc,
char *argv[]
)
/*++
Routine Description:
Process the command line arguments
Arguments:
argc - Standard C entry point arguments
argv[] - Standard C entry point arguments
Returns:
STATUS_SUCCESS - no problems encountered while processing
STATUS_WARNING - warnings, but no errors, were encountered while processing
STATUS_ERROR - errors were encountered while processing
--*/
{
int ThingsToDo;
unsigned int Temp;
STRING_LIST *Str;
//
// Skip program name arg, process others
//
argc--;
argv++;
if (argc == 0) {
Usage ();
return STATUS_ERROR;
}
//
// Clear out our globals, then start walking the arguments
//
memset ((void *) &mGlobals, 0, sizeof (mGlobals));
mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE;
mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT;
ThingsToDo = 0;
while (argc > 0) {
if (strcmp (argv[0], "-?") == 0) {
Usage ();
return STATUS_ERROR;
} else if (strcmp (argv[0], "-hfile") == 0) {
//
// -hfile FileName
//
// Used to specify an output C #include file to create that contains
// #define statements for all the flashmap region offsets and sizes.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an output file name");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.CIncludeFileName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-flashdevice") == 0) {
//
// -flashdevice FLASH_DEVICE_NAME
//
// Used to select which flash device definition to operate on.
// Check for additional argument
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires a flash device name to use");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.FlashDevice = argv[0];
} else if (strcmp (argv[0], "-mco") == 0) {
//
// -mco OutFileName
//
// Used to specify a microcode output binary file to create.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.MCOFileName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-asmincfile") == 0) {
//
// -asmincfile FileName
//
// Used to specify the name of the output assembly include file that contains
// equates for the flash region addresses and sizes.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.AsmIncludeFileName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-mci") == 0) {
//
// -mci FileName
//
// Used to specify an input microcode text file to parse.
// Check for additional argument
//
if (argc < 2) {
Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.MCIFileName = argv[0];
} else if (strcmp (argv[0], "-flashdeviceimage") == 0) {
//
// -flashdeviceimage FlashDeviceImage
//
// Used to specify which flash device image definition from the input flash definition file
// to create.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.FlashDeviceImage = argv[0];
} else if (strcmp (argv[0], "-imageout") == 0) {
//
// -imageout FileName
//
// Used to specify the name of the output FD image file to create.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an output image filename to create");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.ImageOutFileName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-dsc") == 0) {
//
// -dsc FileName
//
// Used to specify the name of the output DSC file to create.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.DscFileName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-fdf") == 0) {
//
// -fdf FileName
//
// Used to specify the name of the input flash definition file.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.FlashDefinitionFileName = argv[0];
} else if (strcmp (argv[0], "-discover") == 0) {
//
// -discover FDFileName
//
// Debug functionality used to scan an existing FD image, trying to find
// firmware volumes at 64K boundaries.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an input FD image file name");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.DiscoverFDImageName = argv[0];
ThingsToDo++;
} else if (strcmp (argv[0], "-baseaddr") == 0) {
//
// -baseaddr Addr
//
// Used to specify a base address when doing a discover of an FD image.
// Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires a base address");
return STATUS_ERROR;
}
argc--;
argv++;
if (tolower (argv[0][1]) == 'x') {
sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress);
} else {
sscanf (argv[0], "%d", &mGlobals.BaseAddress);
}
} else if (strcmp (argv[0], "-padvalue") == 0) {
//
// -padvalue Value
//
// Used to specify the value to pad with when aligning data while
// creating an FD image. Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires a byte value");
return STATUS_ERROR;
}
argc--;
argv++;
if (tolower (argv[0][1]) == 'x') {
sscanf (argv[0] + 2, "%x", &Temp);
mGlobals.MicrocodePadByteValue = (char) Temp;
} else {
sscanf (argv[0], "%d", &Temp);
mGlobals.MicrocodePadByteValue = (char) Temp;
}
} else if (strcmp (argv[0], "-align") == 0) {
//
// -align Alignment
//
// Used to specify how each data file is aligned in the region
// when creating an FD image. Check for additional argument.
//
if (argc < 2) {
Error (NULL, 0, 0, argv[0], "option requires an alignment");
return STATUS_ERROR;
}
argc--;
argv++;
if (tolower (argv[0][1]) == 'x') {
sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment);
} else {
sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment);
}
} else if (strcmp (argv[0], "-mcmerge") == 0) {
//
// -mcmerge FileName(s)
//
// Used to concatenate multiple microde binary files. Can specify
// multiple file names with the one -mcmerge flag. Check for additional argument.
//
if ((argc < 2) || (argv[1][0] == '-')) {
Error (NULL, 0, 0, argv[0], "option requires one or more input file names");
return STATUS_ERROR;
}
//
// Take input files until another option or end of list
//
ThingsToDo++;
while ((argc > 1) && (argv[1][0] != '-')) {
Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST));
if (Str == NULL) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
return STATUS_ERROR;
}
memset (Str, 0, sizeof (STRING_LIST));
Str->Str = argv[1];
if (mGlobals.MCIFileNames == NULL) {
mGlobals.MCIFileNames = Str;
} else {
mGlobals.LastMCIFileNames->Next = Str;
}
mGlobals.LastMCIFileNames = Str;
argc--;
argv++;
}
} else if (strcmp (argv[0], "-strsub") == 0) {
//
// -strsub SrcFile DestFile
//
// Used to perform string substitutions on a file, writing the result to a new
// file. Check for two additional arguments.
//
if (argc < 3) {
Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution");
return STATUS_ERROR;
}
argc--;
argv++;
mGlobals.StringReplaceInFileName = argv[0];
argc--;
argv++;
mGlobals.StringReplaceOutFileName = argv[0];
ThingsToDo++;
} else {
Error (NULL, 0, 0, argv[0], "invalid option");
return STATUS_ERROR;
}
argc--;
argv++;
}
//
// If no outputs requested, then report an error
//
if (ThingsToDo == 0) {
Error (NULL, 0, 0, "nothing to do", NULL);
return STATUS_ERROR;
}
//
// If they want an asm file, #include file, or C file to be created, then they have to specify a
// flash device name and flash definition file name.
//
if ((mGlobals.CIncludeFileName != NULL) &&
((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {
Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL);
return STATUS_ERROR;
}
if ((mGlobals.AsmIncludeFileName != NULL) &&
((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {
Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL);
return STATUS_ERROR;
}
//
// If they want a dsc file to be created, then they have to specify a
// flash device name and a flash definition file name
//
if (mGlobals.DscFileName != NULL) {
if (mGlobals.FlashDevice == NULL) {
Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL);
return STATUS_ERROR;
}
if (mGlobals.FlashDefinitionFileName == NULL) {
Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL);
return STATUS_ERROR;
}
}
//
// If they specified an output microcode file name, then they have to specify an input
// file name, and vice versa.
//
if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) {
Error (NULL, 0, 0, "must specify output microcode file name", NULL);
return STATUS_ERROR;
}
if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) {
Error (NULL, 0, 0, "must specify input microcode file name", NULL);
return STATUS_ERROR;
}
//
// If doing merge, then have to specify output file name
//
if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) {
Error (NULL, 0, 0, "must specify output microcode file name", NULL);
return STATUS_ERROR;
}
//
// If they want an output image to be created, then they have to specify
// the flash device and the flash device image to use.
//
if (mGlobals.ImageOutFileName != NULL) {
if (mGlobals.FlashDevice == NULL) {
Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL);
return STATUS_ERROR;
}
if (mGlobals.FlashDeviceImage == NULL) {
Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL);
return STATUS_ERROR;
}
if (mGlobals.FlashDefinitionFileName == NULL) {
Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL);
return STATUS_ERROR;
}
}
return STATUS_SUCCESS;
}
static
void
Usage (
VOID
)
/*++
Routine Description:
Print utility command line help
Arguments:
None
Returns:
NA
--*/
{
int i;
char *Msg[] = {
"Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice",
" -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile",
" -discover FDImage -dsc DscFile -asmincfile AsmIncFile",
" -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile",
" -baseaddr BaseAddr -align Alignment -padvalue PadValue",
" -mcmerge MCIFile(s)",
" where",
" FlashDefFile - input Flash Definition File",
" FlashDevice - flash device to use (from flash definition file)",
" FlashDeviceImage - flash device image to use (from flash definition file)",
" MCIFile - input microcode file to parse",
" MCOFile - output binary microcode image to create from MCIFile",
" HFile - output #include file to create",
" FDImage - name of input FDImage file to scan",
" ImageOutFile - output image file to create",
" DscFile - output DSC file to create",
" AsmIncFile - output ASM include file to create",
" InStrFile - input file to replace symbol names, writing result to OutStrFile",
" BaseAddr - base address of FDImage (used with -discover)",
" Alignment - alignment to use when merging microcode binaries",
" PadValue - byte value to use as pad value when aligning microcode binaries",
" MCIFile(s) - one or more microcode binary files to merge/concatenate",
"",
NULL
};
for (i = 0; Msg[i] != NULL; i++) {
fprintf (stdout, "%s\n", Msg[i]);
}
}

View File

@ -0,0 +1,81 @@
#/*++
#
# Copyright (c) 2004 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
# license, no part of this software or documentation may be
# reproduced, stored in a retrieval system, or transmitted in any
# form or by any means without the express written consent of
# Intel Corporation.
#
#
# Module Name:
#
# Makefile
#
# Abstract:
#
# makefile for building the FlashMap utility
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
!INCLUDE PlatformTools.env
INCLUDE_PATHS = -I $(TIANO_TOOLS_SOURCE)\Common
#
# Target specific information
#
TARGET_NAME = FlashMap
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\FlashMap.exe
LIBS = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib"
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\FlashMap.obj \
$(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj \
$(TIANO_TOOLS_OUTPUT)\Symbols.obj \
$(TIANO_TOOLS_OUTPUT)\Microcode.obj
# $(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj
#C_FLAGS = $(C_FLAGS) /D TRACK_MALLOC_FREE
C_FLAGS = $(C_FLAGS) /D _malloc=malloc /D _free=free
#
# Compile each source file
#
$(TIANO_TOOLS_OUTPUT)\FlashMap.obj : $(TARGET_SRC_DIR)\FlashMap.c $(TARGET_SRC_DIR)\Symbols.h $(INC_DEPS)
$(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\FlashMap.c /Fo$@
$(TIANO_TOOLS_OUTPUT)\Symbols.obj : $(TARGET_SRC_DIR)\Symbols.c $(INC_DEPS)
$(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\Symbols.c /Fo$@
$(TIANO_TOOLS_OUTPUT)\Microcode.obj : $(TARGET_SRC_DIR)\Microcode.c $(INC_DEPS)
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\Microcode.c /Fo$@
$(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj : $(TARGET_SRC_DIR)\FlashDefFile.c $(INC_DEPS)
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\FlashDefFile.c /Fo$@
$(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj : $(TARGET_SRC_DIR)\TrackMallocFree.c $(INC_DEPS)
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\TrackMallocFree.c /Fo$@
#
# Link the object files together to create the final executable
#
$(TARGET_EXE) : $(OBJECTS) $(LIBS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)

View File

@ -0,0 +1,306 @@
/*++
Copyright (c) 2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Microcode.c
Abstract:
Utility for working with microcode patch files in the Intel
Platform Innovation Framework for EFI build environment.
--*/
#include <stdio.h>
#include <string.h> // for memset()
#include <ctype.h>
#include <stdlib.h> // for malloc()
#define INT8 char
#define UINT32 unsigned int
#include "EfiUtilityMsgs.h"
#include "Microcode.h"
#define MAX_LINE_LEN 256
//
// Structure definition for a microcode header
//
typedef struct {
unsigned int HeaderVersion;
unsigned int PatchId;
unsigned int Date;
unsigned int CpuId;
unsigned int Checksum;
unsigned int LoaderVersion;
unsigned int PlatformId;
unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid
unsigned int TotalSize; // number of bytes
unsigned int Reserved[3];
} MICROCODE_IMAGE_HEADER;
static
STATUS
MicrocodeReadData (
FILE *InFptr,
unsigned int *Data
);
void
MicrocodeConstructor (
void
)
/*++
Routine Description:
Constructor of module Microcode
Arguments:
None
Returns:
None
--*/
{
}
void
MicrocodeDestructor (
void
)
/*++
Routine Description:
Destructor of module Microcode
Arguments:
None
Returns:
None
--*/
{
}
static
STATUS
MicrocodeReadData (
FILE *InFptr,
unsigned int *Data
)
/*++
Routine Description:
Read a 32-bit microcode data value from a text file and convert to raw binary form.
Arguments:
InFptr - file pointer to input text file
Data - pointer to where to return the data parsed
Returns:
STATUS_SUCCESS - no errors or warnings, Data contains valid information
STATUS_ERROR - errors were encountered
--*/
{
char Line[MAX_LINE_LEN];
char *cptr;
Line[MAX_LINE_LEN - 1] = 0;
*Data = 0;
if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {
return STATUS_ERROR;
}
//
// If it was a binary file, then it may have overwritten our null terminator
//
if (Line[MAX_LINE_LEN - 1] != 0) {
return STATUS_ERROR;
}
//
// Look for
// dd 000000001h ; comment
// dd XXXXXXXX
// DD XXXXXXXXX
// DD XXXXXXXXX
//
for (cptr = Line; *cptr && isspace(*cptr); cptr++) {
}
if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {
//
// Skip blanks and look for a hex digit
//
cptr += 3;
for (; *cptr && isspace(*cptr); cptr++) {
}
if (isxdigit (*cptr)) {
if (sscanf (cptr, "%X", Data) != 1) {
return STATUS_ERROR;
}
}
return STATUS_SUCCESS;
}
return STATUS_ERROR;
}
STATUS
MicrocodeParseFile (
char *InFileName,
char *OutFileName
)
/*++
Routine Description:
Parse a microcode text file, and write the binary results to an output file.
Arguments:
InFileName - input text file to parse
OutFileName - output file to write raw binary data from parsed input file
Returns:
STATUS_SUCCESS - no errors or warnings
STATUS_ERROR - errors were encountered
--*/
{
FILE *InFptr;
FILE *OutFptr;
STATUS Status;
MICROCODE_IMAGE_HEADER *Header;
unsigned int Size;
unsigned int Size2;
unsigned int Data;
unsigned int Checksum;
char *Buffer;
char *Ptr;
unsigned int TotalSize;
Status = STATUS_ERROR;
InFptr = NULL;
OutFptr = NULL;
Buffer = NULL;
//
// Open the input text file
//
if ((InFptr = fopen (InFileName, "r")) == NULL) {
Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading");
return STATUS_ERROR;
}
//
// Make two passes on the input file. The first pass is to determine how
// much data is in the file so we can allocate a working buffer. Then
// we'll allocate a buffer and re-read the file into the buffer for processing.
//
Size = 0;
do {
Status = MicrocodeReadData (InFptr, &Data);
if (Status == STATUS_SUCCESS) {
Size += sizeof (Data);
}
} while (Status == STATUS_SUCCESS);
//
// Error if no data.
//
if (Size == 0) {
Error (NULL, 0, 0, InFileName, "no parse-able data found in file");
goto Done;
}
if (Size < sizeof (MICROCODE_IMAGE_HEADER)) {
Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header");
goto Done;
}
//
// Allocate a buffer for the data
//
Buffer = (char *) _malloc (Size);
if (Buffer == NULL) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
goto Done;
}
//
// Re-read the file, storing the data into our buffer
//
fseek (InFptr, 0, SEEK_SET);
Ptr = Buffer;
do {
Status = MicrocodeReadData (InFptr, &Data);
if (Status == STATUS_SUCCESS) {
*(unsigned int *) Ptr = Data;
Ptr += sizeof (Data);
}
} while (Status == STATUS_SUCCESS);
//
// Can't do much checking on the header because, per the spec, the
// DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
// and the TotalSize field is invalid (actually missing). Thus we can't
// even verify the Reserved fields are 0.
//
Header = (MICROCODE_IMAGE_HEADER *) Buffer;
if (Header->DataSize == 0) {
TotalSize = 2048;
} else {
TotalSize = Header->TotalSize;
}
if (TotalSize != Size) {
Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize);
goto Done;
}
//
// Checksum the contents
//
Ptr = Buffer;
Checksum = 0;
Size2 = 0;
while (Size2 < Size) {
Checksum += *(unsigned int *) Ptr;
Ptr += 4;
Size2 += 4;
}
if (Checksum != 0) {
Error (NULL, 0, 0, InFileName, "checksum failed on file contents");
goto Done;
}
//
// Open the output file and write the buffer contents
//
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing");
goto Done;
}
if (fwrite (Buffer, Size, 1, OutFptr) != 1) {
Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file");
goto Done;
}
Status = STATUS_SUCCESS;
Done:
if (Buffer != NULL) {
free (Buffer);
}
if (InFptr != NULL) {
fclose (InFptr);
}
if (OutFptr != NULL) {
fclose (OutFptr);
if (Status == STATUS_ERROR) {
remove (OutFileName);
}
}
return Status;
}

View File

@ -0,0 +1,87 @@
/*++
Copyright (c) 2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Microcode.h
Abstract:
Header file for flash management utility in the Intel Platform
Innovation Framework for EFI build environment.
--*/
#ifndef _MICROCODE_H_
#define _MICROCODE_H_
void
MicrocodeConstructor (
void
);
/*++
Routine Description:
Constructor of module Microcode
Arguments:
None
Returns:
None
--*/
void
MicrocodeDestructor (
void
);
/*++
Routine Description:
Destructor of module Microcode
Arguments:
None
Returns:
None
--*/
STATUS
MicrocodeParseFile (
char *InFileName,
char *OutFileName
);
/*++
Routine Description:
Parse a microcode text file, and write the binary results to an output file.
Arguments:
InFileName - input text file to parse
OutFileName - output file to write raw binary data from parsed input file
Returns:
STATUS_SUCCESS - no errors or warnings
STATUS_ERROR - errors were encountered
--*/
#endif // #ifndef _MICROCODE_H_

View File

@ -0,0 +1,647 @@
/*++
Copyright (c) 2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Symbol.c
Abstract:
Class-like implementation for a symbol table.
--*/
// GC_TODO: fix comment to set correct module name: Symbols.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//
// for isspace()
//
#include <ctype.h>
#include "Tiano.h"
#include "EfiUtilityMsgs.h"
#include "Symbols.h"
#define MAX_LINE_LEN 512
//
// Linked list to keep track of all symbols
//
typedef struct _SYMBOL {
struct _SYMBOL *Next;
int Type;
char *Name;
char *Value;
} SYMBOL;
static
SYMBOL *
FreeSymbols (
SYMBOL *Syms
);
static
int
ExpandMacros (
char *SourceLine,
char *DestLine,
int LineLen
);
static SYMBOL *mSymbolTable = NULL;
void
SymbolsConstructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
{
SymbolsDestructor ();
}
void
SymbolsDestructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
{
mSymbolTable = FreeSymbols (mSymbolTable);
}
char *
GetSymbolValue (
char *SymbolName
)
/*++
Routine Description:
Look up a symbol in our symbol table.
Arguments:
SymbolName
Returns:
Pointer to the value of the symbol if found
NULL if the symbol is not found
--*/
// GC_TODO: SymbolName - add argument and description to function comment
{
SYMBOL *Symbol;
//
// Walk the symbol table
//
Symbol = mSymbolTable;
while (Symbol) {
if (stricmp (SymbolName, Symbol->Name) == 0) {
return Symbol->Value;
}
Symbol = Symbol->Next;
}
return NULL;
}
int
SymbolAdd (
char *Name,
char *Value,
int Mode
)
/*++
Routine Description:
Add a symbol name/value to the symbol table
Arguments:
Name - name of symbol to add
Value - value of symbol to add
Mode - currrently unused
Returns:
Length of symbol added.
Notes:
If Value == NULL, then this routine will assume that the Name field
looks something like "MySymName = MySymValue", and will try to parse
it that way and add the symbol name/pair from the string.
--*/
{
SYMBOL *Symbol;
SYMBOL *NewSymbol;
int Len;
char *Start;
char *Cptr;
char CSave;
char *SaveCptr;
Len = 0;
SaveCptr = NULL;
CSave = 0;
//
// If value pointer is null, then they passed us a line something like:
// varname = value, or simply var =
//
if (Value == NULL) {
Start = Name;
while (*Name && isspace (*Name)) {
Name++;
}
if (Name == NULL) {
return -1;
}
//
// Find the end of the name. Either space or a '='.
//
for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++)
;
if (Value == NULL) {
return -1;
}
//
// Look for the '='
//
Cptr = Value;
while (*Value && (*Value != '=')) {
Value++;
}
if (Value == NULL) {
return -1;
}
//
// Now truncate the name
//
*Cptr = 0;
//
// Skip over the = and then any spaces
//
Value++;
while (*Value && isspace (*Value)) {
Value++;
}
//
// Find end of string, checking for quoted string
//
if (*Value == '\"') {
Value++;
for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++)
;
} else {
for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++)
;
}
//
// Null terminate the value string
//
CSave = *Cptr;
SaveCptr = Cptr;
*Cptr = 0;
Len = (int) (Cptr - Start);
}
//
// We now have a symbol name and a value. Look for an existing variable
// and overwrite it.
//
Symbol = mSymbolTable;
while (Symbol) {
//
// Check for symbol name match
//
if (stricmp (Name, Symbol->Name) == 0) {
_free (Symbol->Value);
Symbol->Value = (char *) _malloc (strlen (Value) + 1);
if (Symbol->Value == NULL) {
Error (NULL, 0, 0, NULL, "failed to allocate memory");
return -1;
}
strcpy (Symbol->Value, Value);
//
// If value == "NULL", then make it a 0-length string
//
if (stricmp (Symbol->Value, "NULL") == 0) {
Symbol->Value[0] = 0;
}
return Len;
}
Symbol = Symbol->Next;
}
//
// Does not exist, create a new one
//
NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL));
if (NewSymbol == NULL) {
Error (NULL, 0, 0, NULL, "memory allocation failure");
return -1;
}
memset ((char *) NewSymbol, 0, sizeof (SYMBOL));
NewSymbol->Name = (char *) _malloc (strlen (Name) + 1);
if (NewSymbol->Name == NULL) {
Error (NULL, 0, 0, NULL, "memory allocation failure");
_free (NewSymbol);
return -1;
}
NewSymbol->Value = (char *) _malloc (strlen (Value) + 1);
if (NewSymbol->Value == NULL) {
Error (NULL, 0, 0, NULL, "memory allocation failure");
_free (NewSymbol->Name);
_free (NewSymbol);
return -1;
}
strcpy (NewSymbol->Name, Name);
strcpy (NewSymbol->Value, Value);
//
// Remove trailing spaces
//
Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1;
while (Cptr > NewSymbol->Value) {
if (isspace (*Cptr)) {
*Cptr = 0;
Cptr--;
} else {
break;
}
}
//
// Add it to the head of the list.
//
NewSymbol->Next = mSymbolTable;
mSymbolTable = NewSymbol;
//
// If value == "NULL", then make it a 0-length string
//
if (stricmp (NewSymbol->Value, "NULL") == 0) {
NewSymbol->Value[0] = 0;
}
//
// Restore the terminator we inserted if they passed in var=value
//
if (SaveCptr != NULL) {
*SaveCptr = CSave;
}
_free (NewSymbol->Value);
_free (NewSymbol->Name);
_free (NewSymbol);
return Len;
}
static
STATUS
RemoveSymbol (
char *Name,
char SymbolType
)
/*++
Routine Description:
Remove a symbol name/value from the symbol table
Arguments:
Name - name of symbol to remove
SymbolType - type of symbol to remove
Returns:
STATUS_SUCCESS - matching symbol found and removed
STATUS_ERROR - matching symbol not found in symbol table
--*/
{
SYMBOL *Symbol;
SYMBOL *PrevSymbol;
PrevSymbol = NULL;
Symbol = mSymbolTable;
//
// Walk the linked list of symbols in the symbol table looking
// for a match of both symbol name and type.
//
while (Symbol) {
if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) {
//
// If the symbol has a value associated with it, free the memory
// allocated for the value.
// Then free the memory allocated for the symbols string name.
//
if (Symbol->Value) {
_free (Symbol->Value);
}
_free (Symbol->Name);
//
// Link the previous symbol to the next symbol to effectively
// remove this symbol from the linked list.
//
if (PrevSymbol) {
PrevSymbol->Next = Symbol->Next;
} else {
mSymbolTable = Symbol->Next;
}
_free (Symbol);
return STATUS_SUCCESS;
}
PrevSymbol = Symbol;
Symbol = Symbol->Next;
}
return STATUS_WARNING;
}
static
SYMBOL *
FreeSymbols (
SYMBOL *Syms
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Syms - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
SYMBOL *Next;
while (Syms) {
if (Syms->Name != NULL) {
_free (Syms->Name);
}
if (Syms->Value != NULL) {
_free (Syms->Value);
}
Next = Syms->Next;
_free (Syms);
Syms = Next;
}
return Syms;
}
static
int
ExpandMacros (
char *SourceLine,
char *DestLine,
int LineLen
)
/*++
Routine Description:
Given a line of text, replace all variables of format $(NAME) with values
from our symbol table.
Arguments:
SourceLine - input line of text to do symbol replacements on
DestLine - on output, SourceLine with symbols replaced
LineLen - length of DestLine, so we don't exceed its allocated length
Returns:
STATUS_SUCCESS - no problems encountered
STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine
STATUS_ERROR - memory allocation failure
--*/
{
static int NestDepth = 0;
char *FromPtr;
char *ToPtr;
char *SaveStart;
char *Cptr;
char *value;
int Expanded;
int ExpandedCount;
INT8 *LocalDestLine;
STATUS Status;
int LocalLineLen;
NestDepth++;
Status = STATUS_SUCCESS;
LocalDestLine = (char *) _malloc (LineLen);
if (LocalDestLine == NULL) {
Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);
return STATUS_ERROR;
}
FromPtr = SourceLine;
ToPtr = LocalDestLine;
//
// Walk the entire line, replacing $(MACRO_NAME).
//
LocalLineLen = LineLen;
ExpandedCount = 0;
while (*FromPtr && (LocalLineLen > 0)) {
if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {
//
// Save the start in case it's undefined, in which case we copy it as-is.
//
SaveStart = FromPtr;
Expanded = 0;
//
// Macro expansion time. Find the end (no spaces allowed)
//
FromPtr += 2;
for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++)
;
if (*Cptr) {
//
// Truncate the string at the closing parenthesis for ease-of-use.
// Then copy the string directly to the destination line in case we don't find
// a definition for it.
//
*Cptr = 0;
strcpy (ToPtr, SaveStart);
if ((value = GetSymbolValue (FromPtr)) != NULL) {
strcpy (ToPtr, value);
LocalLineLen -= strlen (value);
ToPtr += strlen (value);
Expanded = 1;
ExpandedCount++;
}
if (!Expanded) {
//
// Restore closing parenthesis, and advance to next character
//
*Cptr = ')';
FromPtr = SaveStart + 1;
ToPtr++;
} else {
FromPtr = Cptr + 1;
}
} else {
Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro");
strcpy (ToPtr, FromPtr);
Status = STATUS_WARNING;
goto Done;
}
} else {
*ToPtr = *FromPtr;
FromPtr++;
ToPtr++;
LocalLineLen--;
}
}
if (*FromPtr == 0) {
*ToPtr = 0;
}
//
// If we expanded at least one string successfully, then make a recursive call to try again.
//
if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) {
Status = ExpandMacros (LocalDestLine, DestLine, LineLen);
_free (LocalDestLine);
NestDepth = 0;
return Status;
}
Done:
if (Status != STATUS_ERROR) {
strcpy (DestLine, LocalDestLine);
}
NestDepth = 0;
_free (LocalDestLine);
return Status;
}
STATUS
SymbolsFileStringsReplace (
char *InFileName,
char *OutFileName
)
/*++
Routine Description:
Given input and output file names, read in the input file, replace variable
references of format $(NAME) with appropriate values from our symbol table,
and write the result out to the output file.
Arguments:
InFileName - name of input text file to replace variable references
OutFileName - name of output text file to write results to
Returns:
STATUS_SUCCESS - no problems encountered
STATUS_ERROR - failed to open input or output file
--*/
{
STATUS Status;
FILE *InFptr;
FILE *OutFptr;
char Line[MAX_LINE_LEN];
char OutLine[MAX_LINE_LEN];
Status = STATUS_ERROR;
//
// Open input and output files
//
InFptr = NULL;
OutFptr = NULL;
if ((InFptr = fopen (InFileName, "r")) == NULL) {
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
goto Done;
}
if ((OutFptr = fopen (OutFileName, "w")) == NULL) {
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
goto Done;
}
//
// Read lines from input file until done
//
while (fgets (Line, sizeof (Line), InFptr) != NULL) {
ExpandMacros (Line, OutLine, sizeof (OutLine));
fprintf (OutFptr, OutLine);
}
Status = STATUS_SUCCESS;
Done:
if (InFptr != NULL) {
fclose (InFptr);
}
if (OutFptr != NULL) {
fclose (OutFptr);
}
return Status;
}

View File

@ -0,0 +1,125 @@
/*++
Copyright (c) 2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Symbols.h
Abstract:
Defines and prototypes for a class-like symbol table service.
--*/
#ifndef _SYMBOLS_H_
#define _SYMBOLS_H_
#ifdef __cplusplus
extern "C"
{
#endif
int
SymbolAdd (
char *Name,
char *Value,
int Mode
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Name - GC_TODO: add argument description
Value - GC_TODO: add argument description
Mode - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATUS
SymbolsFileStringsReplace (
char *InFileName,
char *OutFileName
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
InFileName - GC_TODO: add argument description
OutFileName - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
void
SymbolsConstructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
void
SymbolsDestructor (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
#ifdef __cplusplus
}
#endif
#endif // #ifndef _SYMBOLS_H_

View File

@ -0,0 +1,542 @@
/*++
Copyright (c) 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenAcpiTable.c
Abstract:
A utility that extracts the .DATA section from a PE/COFF image.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Tiano.h"
#include "TianoCommon.h"
#include "EfiImage.h" // for PE32 structure definitions
#include "EfiUtilityMsgs.h"
//
// Version of this utility
//
#define UTILITY_NAME "GenAcpiTable"
#define UTILITY_VERSION "v0.11"
//
// Define the max length of a filename
//
#define MAX_PATH 256
#define DEFAULT_OUTPUT_EXTENSION ".acpi"
//
// Use this to track our command-line options and globals
//
struct {
INT8 OutFileName[MAX_PATH];
INT8 InFileName[MAX_PATH];
} mOptions;
//
// Use these to convert from machine type value to a named type
//
typedef struct {
UINT16 Value;
INT8 *Name;
} STRING_LOOKUP;
static STRING_LOOKUP mMachineTypes[] = {
EFI_IMAGE_MACHINE_IA32,
"IA32",
EFI_IMAGE_MACHINE_IA64,
"IA64",
EFI_IMAGE_MACHINE_EBC,
"EBC",
0,
NULL
};
static STRING_LOOKUP mSubsystemTypes[] = {
EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,
"EFI application",
EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,
"EFI boot service driver",
EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,
"EFI runtime driver",
0,
NULL
};
//
// Function prototypes
//
static
void
Usage (
VOID
);
static
STATUS
ParseCommandLine (
int Argc,
char *Argv[]
);
static
STATUS
CheckPE32File (
INT8 *FileName,
FILE *Fptr,
UINT16 *MachineType,
UINT16 *SubSystem
);
static
STATUS
ProcessFile (
INT8 *InFileName,
INT8 *OutFileName
);
static
void
DumpImage (
INT8 *FileName
);
main (
int Argc,
char *Argv[]
)
/*++
Routine Description:
Arguments:
Argc - standard C main() argument count
Argv - standard C main() argument list
Returns:
0 success
non-zero otherwise
--*/
// GC_TODO: ] - add argument and description to function comment
{
UINT32 Status;
SetUtilityName (UTILITY_NAME);
//
// Parse the command line arguments
//
if (ParseCommandLine (Argc, Argv)) {
return STATUS_ERROR;
}
//
// Make sure we don't have the same filename for input and output files
//
if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {
Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");
goto Finish;
}
//
// Process the file
//
ProcessFile (mOptions.InFileName, mOptions.OutFileName);
Finish:
Status = GetUtilityStatus ();
return Status;
}
static
STATUS
ProcessFile (
INT8 *InFileName,
INT8 *OutFileName
)
/*++
Routine Description:
Process a PE32 EFI file.
Arguments:
InFileName - Name of the PE32 EFI file to process.
OutFileName - Name of the output file for the processed data.
Returns:
0 - successful
--*/
{
STATUS Status;
UINTN Index;
FILE *InFptr;
FILE *OutFptr;
UINT16 MachineType;
UINT16 SubSystem;
UINT32 PESigOffset;
EFI_IMAGE_FILE_HEADER FileHeader;
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
EFI_IMAGE_SECTION_HEADER SectionHeader;
UINT8 *Buffer;
long SaveFilePosition;
InFptr = NULL;
OutFptr = NULL;
Buffer = NULL;
Status = STATUS_ERROR;
//
// Try to open the input file
//
if ((InFptr = fopen (InFileName, "rb")) == NULL) {
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
return STATUS_ERROR;
}
//
// Double-check the file to make sure it's what we expect it to be
//
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
goto Finish;
}
//
// Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit
// offset (from the start of the file) to the PE signature, which always
// follows the MSDOS stub. The PE signature is immediately followed by the
// COFF file header.
//
//
if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);
goto Finish;
}
if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");
goto Finish;
}
if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");
goto Finish;
}
//
// We should now be at the COFF file header. Read it in and verify it's
// of an image type we support.
//
if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read file header from image");
goto Finish;
}
if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64)) {
Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);
goto Finish;
}
//
// Read in the optional header. Assume PE32, and if not, then re-read as PE32+
//
SaveFilePosition = ftell (InFptr);
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
goto Finish;
}
if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
if (fseek (InFptr, SaveFilePosition, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to .data section");
goto Finish;
}
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
goto Finish;
}
}
//
// Search for the ".data" section
//
for (Index = 0; Index < FileHeader.NumberOfSections; Index++) {
if (fread (&SectionHeader, sizeof (EFI_IMAGE_SECTION_HEADER), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
goto Finish;
}
if (strcmp (SectionHeader.Name, ".data") == 0) {
if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to .data section");
goto Finish;
}
Buffer = (UINT8 *) malloc (SectionHeader.Misc.VirtualSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Finish;
}
if (fread (Buffer, SectionHeader.Misc.VirtualSize, 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to .data section");
goto Finish;
}
//
// Now open our output file
//
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
goto Finish;
}
if (fwrite (Buffer, SectionHeader.Misc.VirtualSize, 1, OutFptr) != 1) {
Error (NULL, 0, 0, OutFileName, "failed to write .data section");
goto Finish;
}
Status = STATUS_SUCCESS;
goto Finish;
}
}
Status = STATUS_ERROR;
Finish:
if (InFptr != NULL) {
fclose (InFptr);
}
//
// Close the output file. If there was an error, delete the output file so
// that a subsequent build will rebuild it.
//
if (OutFptr != NULL) {
fclose (OutFptr);
if (GetUtilityStatus () == STATUS_ERROR) {
remove (OutFileName);
}
}
//
// Free up our buffer
//
if (Buffer != NULL) {
free (Buffer);
}
return Status;
}
static
STATUS
CheckPE32File (
INT8 *FileName,
FILE *Fptr,
UINT16 *MachineType,
UINT16 *SubSystem
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FileName - GC_TODO: add argument description
Fptr - GC_TODO: add argument description
MachineType - GC_TODO: add argument description
SubSystem - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
/*++
Routine Description:
Given a file pointer to a supposed PE32 image file, verify that it is indeed a
PE32 image file, and then return the machine type in the supplied pointer.
Arguments:
Fptr File pointer to the already-opened PE32 file
MachineType Location to stuff the machine type of the PE32 file. This is needed
because the image may be Itanium-based, IA32, or EBC.
Returns:
0 success
non-zero otherwise
--*/
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_FILE_HEADER FileHdr;
EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;
UINT32 PESig;
STATUS Status;
Status = STATUS_ERROR;
//
// Position to the start of the file
//
fseek (Fptr, 0, SEEK_SET);
//
// Read the DOS header
//
if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");
goto Finish;
}
//
// Check the magic number (0x5A4D)
//
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");
goto Finish;
}
//
// Position into the file and check the PE signature
//
fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");
goto Finish;
}
//
// Check the PE signature in the header "PE\0\0"
//
if (PESig != EFI_IMAGE_NT_SIGNATURE) {
Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");
goto Finish;
}
//
// Read the file header
//
if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");
goto Finish;
}
//
// Read the optional header so we can get the subsystem
//
if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");
goto Finish;
}
*SubSystem = OptionalHdr.Subsystem;
//
// Good to go
//
Status = STATUS_SUCCESS;
Finish:
fseek (Fptr, 0, SEEK_SET);
return Status;
}
static
int
ParseCommandLine (
int Argc,
char *Argv[]
)
/*++
Routine Description:
Given the Argc/Argv program arguments, and a pointer to an options structure,
parse the command-line options and check their validity.
Arguments:
Argc - standard C main() argument count
Argv - standard C main() argument list
Returns:
STATUS_SUCCESS success
non-zero otherwise
--*/
// GC_TODO: ] - add argument and description to function comment
{
//
// Clear out the options
//
memset ((char *) &mOptions, 0, sizeof (mOptions));
//
// Skip over the program name
//
Argc--;
Argv++;
if (Argc != 2) {
Usage ();
return STATUS_ERROR;
}
strcpy (mOptions.InFileName, Argv[0]);
//
// Next argument
//
Argv++;
Argc--;
strcpy (mOptions.OutFileName, Argv[0]);
return STATUS_SUCCESS;
}
static
void
Usage (
VOID
)
/*++
Routine Description:
Print usage information for this utility.
Arguments:
None.
Returns:
Nothing.
--*/
{
int Index;
static const char *Msg[] = {
UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility",
" Generate an ACPI Table image from an EFI PE32 image",
" Usage: "UTILITY_NAME " InFileName OutFileName",
" where:",
" InFileName - name of the input PE32 file",
" OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,
"",
NULL
};
for (Index = 0; Msg[Index] != NULL; Index++) {
fprintf (stdout, "%s\n", Msg[Index]);
}
}

View File

@ -0,0 +1,68 @@
#/*++
#
# Copyright (c) 2002 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name:
#
# makefile
#
# Abstract:
#
# makefile for building the GenAcpiTable utility.
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Define the toolchain which is used to set build options and toolchain paths
#
TOOLCHAIN = TOOLCHAIN_MSVC
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = GenAcpiTable
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
INC_DEPS = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h
#
# Build the EXE by compiling the source files, then linking the resultant
# object files together.
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,50 @@
/*++
Copyright (c) 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
CreateGuid.c
Abstract:
Library routine to create a GUID
--*/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void
CreateGuid (
GUID *Guid
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Guid - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
CoCreateGuid (Guid);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
#/*++
#
# Copyright (c) 2002 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
# license, no part of this software or documentation may be
# reproduced, stored in a retrieval system, or transmitted in any
# form or by any means without the express written consent of
# Intel Corporation.
#
#
# Module Name:
#
# Makefile
#
# Abstract:
#
# makefile for the GenCapsuleHdr utility.
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = GenCapsuleHdr
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
SRC = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
ETO = $(TIANO_TOOLS_OUTPUT)
#
# Build targets
#
all: $(TARGET_EXE)
LIBS = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib" ole32.lib
OBJECTS = $(ETO)\$(TARGET_NAME).obj \
$(ETO)\CreateGuid.obj
#
# Compile each source file
#
$(ETO)\$(TARGET_NAME).obj : $(SRC)\$(TARGET_NAME).c $(INC_DEPS)
$(CC) $(C_FLAGS) $(SRC)\$(TARGET_NAME).c /Fo$@
$(ETO)\CreateGuid.obj : $(SRC)\CreateGuid.c $(INC_DEPS)
$(CC) $(C_FLAGS) $(SRC)\CreateGuid.c /Fo$@
#
# Link the object files together
#
$(TARGET_EXE) : $(OBJECTS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
clean:

View File

@ -0,0 +1,89 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenFdImage.h
Abstract:
This file contains the relevant declarations required
to generate the Firmware Device
--*/
//
// Coded to EFI 2.0 Coding Standard
//
#ifndef _EFI_GEN_FD_IMAGE_H
#define _EFI_GEN_FD_IMAGE_H
//
// Included Header files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <assert.h>
#include "TianoCommon.h"
#include "ParseInf.h"
#include "GenFvImage.h"
//
// Defines
//
#define FILE_NAME_SIZE 256
//
// Type Definition
//
typedef struct {
UINT64 FdSize;
UINT64 FdBaseAddress;
UINT8 PadValue;
CHAR8 OutFileName[FILE_NAME_SIZE];
} FDINFO;
//
// Exported Function Prototype
//
EFI_STATUS
GenerateFdImage (
IN UINT64 BaseAddress,
IN UINT64 Size,
IN UINT8 PadByte,
IN CHAR8 *OutFile,
IN CHAR8 **FileList
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
BaseAddress - GC_TODO: add argument description
Size - GC_TODO: add argument description
PadByte - GC_TODO: add argument description
OutFile - GC_TODO: add argument description
FileList - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
#endif

View File

@ -0,0 +1,864 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenFdImageDll.C
Abstarct:
This file contains the relevant functions required to complete
the API to generate Firmware Device
--*/
// GC_TODO: fix comment to add: Abstract:
//
// This tells the compiler to export the DLL functions
//
#define GEN_FD_IMAGE_EXPORTS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <assert.h>
#include "TianoCommon.h"
#include "GenFdImage.h"
#include "GenFvImage.h"
#include "ParseInf.h"
//
// Global declaration
//
UINTN ValidLineNum = 0;
UINTN NumFvFiles = 0;
static UINT64 LastAddress = 0;
CHAR8 **TokenStr;
CHAR8 **OrgStrTokPtr;
FDINFO *FdInfo;
FDINFO *OrgFdInfoPtr;
FVINFO **FvInfo;
FVINFO **OrgFvInfoPtr;
//
// Global function declarations
//
EFI_STATUS
BuildFirmwareDeviceBinaryFromFwVolumes (
IN UINT64 FvBaseAddress,
IN CHAR8 *FvFileName,
IN CHAR8 *FdFileName
);
INTN
CompareItems (
IN const VOID *Arg1,
IN const VOID *Arg2
)
/*++
Description:
This function is used by qsort to sort the Fv list based on FvBaseAddress
Input:
Arg1
Arg2
Return:
None
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: Arg1 - add argument and description to function comment
// GC_TODO: Arg2 - add argument and description to function comment
{
if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {
return 1;
} else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {
return -1;
} else {
return 0;
}
}
VOID
BuildTokenList (
IN CHAR8 *Token
)
/*++
Description:
This function builds the token list in an array which will be parsed later
Input:
Token String,
Return:
None
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: Token - add argument and description to function comment
{
strcpy (*TokenStr, Token);
TokenStr++;
}
VOID
TrimLine (
IN CHAR8 *Line
)
/*++
Description:
This function cleans up the line by removing all whitespace and
comments
Input:
Line String,
Return:
None
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: Line - add argument and description to function comment
{
CHAR8 TmpLine[FILE_NAME_SIZE];
CHAR8 c;
CHAR8 *Ptr0;
UINTN i;
UINTN j;
//
// Change '#' to '//' for Comment style
//
// if((Ptr0=strchr(Line, '#')) != NULL) {
//
if ((Ptr0 = strstr (Line, "//")) != NULL) {
Line[Ptr0 - Line] = 0;
}
i = j = 0;
while ((c = Line[i]) != 0) {
if ((c != ' ') && (c != '\t') && (c != '\n')) {
TmpLine[j++] = c;
}
i++;
}
TmpLine[j] = 0;
strcpy (Line, TmpLine);
}
VOID
ValidLineCount (
IN FILE *Fp
)
/*++
Description:
This function calculated number of valid lines in a input file.
Input:
Fp Pointer to a file handle which has been opened.
Return:
None
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: Fp - add argument and description to function comment
{
CHAR8 Buff[FILE_NAME_SIZE];
while (fgets (Buff, sizeof (Buff), Fp)) {
TrimLine (Buff);
if (Buff[0] == 0) {
continue;
}
ValidLineNum++;
}
}
VOID
ParseInputFile (
IN FILE *Fp
)
/*++
Description:
This function parses the input file and tokenize the string
Input:
Fp Pointer to a file handle which has been opened.
Return:
None
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: Fp - add argument and description to function comment
{
CHAR8 *Token;
CHAR8 Buff[FILE_NAME_SIZE];
CHAR8 OrgLine[FILE_NAME_SIZE];
CHAR8 Str[FILE_NAME_SIZE];
CHAR8 Delimit[] = "=";
while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
strcpy (OrgLine, Buff);
TrimLine (Buff);
if (Buff[0] == 0) {
continue;
}
Token = strtok (Buff, Delimit);
while (Token != NULL) {
strcpy (Str, Token);
BuildTokenList (Str);
Token = strtok (NULL, Delimit);
}
}
}
EFI_STATUS
InitializeComps (
VOID
)
/*++
Description:
This function intializes the relevant global variable which is being
used to store the information retrieved from INF file.
Input:
None
Return:
EFI_STATUS
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
UINTN Index;
FdInfo = malloc (sizeof (FDINFO));
if (FdInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
OrgFdInfoPtr = FdInfo;
FvInfo = malloc (sizeof (int) * NumFvFiles);
if (FvInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
OrgFvInfoPtr = FvInfo;
for (Index = 0; Index < NumFvFiles; Index++) {
*FvInfo = malloc (sizeof (FVINFO));
if (*FvInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
memset (*FvInfo, 0, sizeof (FVINFO));
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
return EFI_SUCCESS;
}
VOID
InitializeInFileInfo (
VOID
)
/*++
Description:
This function intializes the relevant global variable which is being
used to store the information retrieved from INF file.
Input:
NONE
Return:
NONE
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
{
UINTN OptionFlag;
UINT64 StringValue;
OptionFlag = 0;
TokenStr = OrgStrTokPtr;
while (*TokenStr != NULL) {
if (stricmp (*TokenStr, "[options]") == 0) {
OptionFlag = 1;
}
if (OptionFlag) {
if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {
*TokenStr++;
if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
printf ("\nERROR: Cannot determine the FV base address.");
return ;
}
(*FvInfo)->FvBaseAddress = StringValue;
} else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {
*TokenStr++;
strcpy ((*FvInfo)->FvFile, *TokenStr);
}
}
TokenStr++;
}
}
EFI_STATUS
GetFvRelatedInfoFromInfFile (
IN CHAR8 *FileName
)
/*++
Description:
This function reads the input file, parse it and create a list of tokens
which is parsed and used, to intialize the data related to Firmware Volume.
Input:
FileName FileName which needed to be read to parse data
Return:
EFI_STATUS
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: FileName - add argument and description to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINTN Index;
Fp = fopen (FileName, "r");
if (Fp == NULL) {
printf ("Error in opening %s file\n", FileName);
return EFI_ABORTED;
}
ValidLineCount (Fp);
if (ValidLineNum == 0) {
printf ("\nFile doesn't contain any valid informations");
return EFI_ABORTED;
}
TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));
memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));
OrgStrTokPtr = TokenStr;
for (Index = 0; Index < (2 * ValidLineNum); Index++) {
*TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
memset (*TokenStr, 0, FILE_NAME_SIZE);
TokenStr++;
}
*TokenStr = NULL;
TokenStr = OrgStrTokPtr;
fseek (Fp, 0L, SEEK_SET);
ParseInputFile (Fp);
InitializeInFileInfo ();
if (Fp) {
fclose (Fp);
}
return EFI_SUCCESS;
}
EFI_STATUS
WriteFwBinary (
IN CHAR8 *FileName,
IN UINT64 StartAddress,
IN UINT64 Size,
IN UINT8 *Buffer
)
/*++
Description:
This function reads the input file, parse it and create a list of tokens
which is parsed and used, to intialize the data related to Firmware Volume.
Input:
FileName FileName which needed to be read to parse data
StartAddress This will set the file position.
Size Size in bytes needed to be written
Buffer Buffer needed to e written
Return:
EFI_STATUS
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: FileName - add argument and description to function comment
// GC_TODO: StartAddress - add argument and description to function comment
// GC_TODO: Size - add argument and description to function comment
// GC_TODO: Buffer - add argument and description to function comment
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINTN NumByte;
Fp = fopen (FileName, "a+b");
if (Fp == NULL) {
printf ("\nERROR:Error in opening file %s ", FileName);
return EFI_INVALID_PARAMETER;
}
fseek (Fp, (UINTN) StartAddress, SEEK_SET);
NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);
//
// Check to ensure that buffer has been copied successfully
//
if (NumByte != Size) {
printf ("\nERROR: Error in copying the buffer into file");
return EFI_ABORTED;
}
if (Fp) {
fclose (Fp);
}
return EFI_SUCCESS;
}
EFI_STATUS
BuildFirmwareDeviceBinaryFromFwVolumes (
IN UINT64 FvBaseAddress,
IN CHAR8 *FvFileName,
IN CHAR8 *FdFileName
)
/*++
Description:
This function reads the input file, parse it and create a list of tokens
which is parsed and used, to intialize the data related to Firmware Volume.
Input:
FvBaseAddress Base Address. This info is retrieved from INF file
FvFileName InputFileName
FdFileName Output File Name
Return:
EFI_STATUS
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: FvBaseAddress - add argument and description to function comment
// GC_TODO: FvFileName - add argument and description to function comment
// GC_TODO: FdFileName - add argument and description to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINT64 FileSize;
UINT64 NumByteRead;
UINT64 PadByteSize;
UINTN Index;
UINT64 BaseAddress;
UINT8 *Buffer;
EFI_STATUS Status;
static UINT64 StartAddress = 0;
Fp = fopen (FvFileName, "r+b");
if (Fp == NULL) {
printf ("\nERROR:Error in opening file %s", FvFileName);
return EFI_ABORTED;
}
BaseAddress = FdInfo->FdBaseAddress;
//
// Check if Base Address of Firmware Volume falls below the Base Address
// Firmware Device, if yes, then abort this process.
//
if (FvBaseAddress < BaseAddress) {
printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");
return EFI_ABORTED;
}
//
// Check if there are any hole between two Firmware Volumes. If any hole
// exists, fill the hole with PadByte data.
//
if (FvBaseAddress > LastAddress) {
PadByteSize = (FvBaseAddress - LastAddress);
Buffer = malloc ((UINTN) PadByteSize);
for (Index = 0; Index < PadByteSize; Index++) {
*Buffer = FdInfo->PadValue;
Buffer++;
}
Buffer -= PadByteSize;
Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);
if (Buffer) {
free (Buffer);
}
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error in writing the binary image to file");
return Status;
}
StartAddress += PadByteSize;
LastAddress += PadByteSize;
}
//
// Proceed with next Firmware Volume updates
//
FileSize = _filelength (fileno (Fp));
if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {
printf (
"\nERROR:Unable to update Firmware Device. File %s is larger than \
available space.",
FvFileName
);
if (Fp) {
fclose (Fp);
}
return EFI_ABORTED;
}
Buffer = malloc ((UINTN) FileSize);
if (Buffer == NULL) {
printf ("Error in allocating buffer to read specific file\n");
return EFI_OUT_OF_RESOURCES;
}
NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);
if (Buffer) {
free ((VOID *) Buffer);
}
if (Fp) {
fclose (Fp);
}
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error in writing the binary image to file");
return Status;
}
StartAddress += NumByteRead;
LastAddress += FileSize;
return EFI_SUCCESS;
}
VOID
CleanUpMemory (
VOID
)
/*++
Description:
This function cleans up any allocated buffer
Input:
NONE
Return:
NONE
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
{
UINTN Index;
if (FdInfo) {
free (FdInfo);
}
FvInfo = OrgFvInfoPtr;
if (FvInfo) {
for (Index = 0; Index < NumFvFiles; Index++) {
if (*FvInfo) {
free (*FvInfo);
}
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
free (FvInfo);
}
}
GEN_FD_IMAGE_API
EFI_STATUS
GenerateFdImage (
IN UINT64 BaseAddress,
IN UINT64 Size,
IN UINT8 PadByte,
IN CHAR8 *OutFile,
IN CHAR8 **FileList
)
/*++
Description:
This function reads the input file, parse it and create a list of tokens
which is parsed and used, to intialize the data related to Firmware Volume.
Input:
BaseAddress Base Address for this Firmware Device
Size, Total Size of the Firmware Device
PadByte Pad byte data
OutFile Output File Name
FileList File List pointer to INF file names.
Return:
EFI_STATUS
--*/
// GC_TODO: function comment is missing 'Routine Description:'
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: function comment is missing 'Returns:'
// GC_TODO: BaseAddress - add argument and description to function comment
// GC_TODO: Size - add argument and description to function comment
// GC_TODO: PadByte - add argument and description to function comment
// GC_TODO: OutFile - add argument and description to function comment
// GC_TODO: FileList - add argument and description to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
UINTN Index;
UINTN PadSize;
UINTN FileSize;
CHAR8 **InFile;
FILE *Fp;
UINT8 *Buffer;
UINTN NumByte;
//
// Ensure, if there are any previous Firmware Device exists,
// If yes, make it to 0 bytes
//
if ((Fp = fopen (OutFile, "w")) != NULL) {
fclose (Fp);
}
InFile = FileList;
while (*InFile != NULL) {
NumFvFiles++;
InFile++;
}
InitializeComps ();
//
// Restore the orginal pointers
//
FvInfo = OrgFvInfoPtr;
InFile = FileList;
while (*InFile != NULL) {
strcpy ((*FvInfo)->FvInfoFile, *InFile);
Status = GetFvRelatedInfoFromInfFile (*InFile);
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error occurred in processsing INF file");
CleanUpMemory ();
return Status;
}
InFile++;
FvInfo++;
}
FdInfo->FdSize = Size;
FdInfo->FdBaseAddress = BaseAddress;
FdInfo->PadValue = PadByte;
FvInfo = OrgFvInfoPtr;
strcpy (FdInfo->OutFileName, OutFile);
for (Index = 0; Index < NumFvFiles; Index++) {
Status = GenerateFvImage ((*FvInfo)->FvInfoFile);
if (Status != EFI_SUCCESS) {
CleanUpMemory ();
return Status;
}
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
//
// Sort the Firmware Volume informations. Firmware Volume with lower
// base addresses will be processed first and hiher base address one
// will be processed later.
//
qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);
LastAddress = (*FvInfo)->FvBaseAddress;
for (Index = 0; Index < NumFvFiles; Index++) {
Status = BuildFirmwareDeviceBinaryFromFwVolumes (
(*FvInfo)->FvBaseAddress,
(*FvInfo)->FvFile,
FdInfo->OutFileName
);
if (Status != EFI_SUCCESS) {
CleanUpMemory ();
return Status;
}
FvInfo++;
}
//
// Check if any space left after copying data from all Firmware Volumes
// If yes, then fill those location with PadValue.
//
if ((FdInfo->FdBaseAddress + Size) > LastAddress) {
PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);
Buffer = malloc (PadSize);
if (Buffer == NULL) {
CleanUpMemory ();
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < PadSize; Index++) {
*Buffer = FdInfo->PadValue;
Buffer++;
}
Buffer -= PadSize;
Fp = fopen (OutFile, "a+b");
if (Fp == NULL) {
printf ("\nERROR:Opening file %s", OutFile);
CleanUpMemory ();
return EFI_ABORTED;
}
FileSize = _filelength (fileno (Fp));
fseek (Fp, FileSize, SEEK_SET);
NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);
if (Buffer) {
free (Buffer);
}
fclose (Fp);
if (NumByte != (sizeof (UINT8) * PadSize)) {
printf ("\nERROR: Copying data from buffer to File %s ", OutFile);
CleanUpMemory ();
return EFI_ABORTED;
}
}
//
// Clean up all the memory which has been allocated so far.
//
CleanUpMemory ();
return EFI_SUCCESS;
}

View File

@ -0,0 +1,330 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenFdImageExe.c
Abstract:
This contains all code necessary to build the GenFdImage.exe utility.
This utility relies heavily on the GenFdImage Lib. Definitions for both
can be found in the GenFdImage Utility Specification, review draft.
--*/
//
// Coded to EFI 2.0 Coding Standards
//
//
// Include files
//
#include "GenFdImage.h"
#include "GenFdImageExe.h"
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
Displays the standard utility information to SDTOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"%s, EFI 2.0 Firmware Device Image Generation Utility. ""Version %i.%i, %s.\n\n",
UTILITY_NAME,
UTILITY_MAJOR_VERSION,
UTILITY_MINOR_VERSION,
UTILITY_DATE
);
}
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
Displays the utility usage syntax to STDOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"Usage: %s -B BaseAddress -S Size -F FillByte"" [-I FvInfFileName] -O OutputFileName \n",
UTILITY_NAME
);
printf (" Where:\n");
printf ("\tBaseAddress is the starting address of the FD Image\n\n");
printf ("\tSize is the size of the FD Image.\n\n");
printf ("\tFillByte is the desired value of free space in the Image\n\n");
printf ("\tFvInfFileName is the name of an FV Image description file.\n\n");
printf ("\tOutputFileName is the desired output file name.\n\n");
}
EFI_STATUS
main (
IN INTN argc,
IN CHAR8 **argv
)
/*++
Routine Description:
This utility uses GenFdImage.lib to build a Firmware Device Image
which will include several Firmware Volume Images.
Arguments:
Base Address Base Address of the firmware volume..
Size Size of the Firmware Volume
FillByte The byte value which would be needed to pad
between various Firmware Volumes
FvInfFile Fv inf file
OutputFileName The name of output file which would be created
Returns:
EFI_SUCCESS No error conditions detected.
EFI_INVALID_PARAMETER One or more of the input parameters is invalid.
EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable.
Most commonly this will be memory allocation or
file creation.
EFI_LOAD_ERROR GenFvImage.lib could not be loaded.
EFI_ABORTED Error executing the GenFvImage lib.
--*/
// GC_TODO: argc - add argument and description to function comment
// GC_TODO: argv - add argument and description to function comment
{
UINTN Index;
UINTN FvFilesCount;
UINT8 i;
UINT64 StartAddress;
UINT64 Size;
UINT64 FillByteVal;
CHAR8 **FvInfFileList;
CHAR8 **OrgFvInfFileList;
CHAR8 OutputFileName[_MAX_PATH];
EFI_STATUS Status;
INTN arg_counter;
//
// Echo for makefile debug
//
printf ("\n\n");
for (arg_counter = 0; arg_counter < argc; arg_counter++) {
printf ("%s ", argv[arg_counter]);
}
printf ("\n\n");
//
// Display utility information
//
PrintUtilityInfo ();
//
// Verify the correct number of arguments
//
if (argc < MIN_ARGS) {
printf ("ERROR: missing 1 or more input arguments.\n\n");
PrintUsage ();
return EFI_INVALID_PARAMETER;
}
//
// Initialize variables
//
StartAddress = 0;
Size = 0;
FillByteVal = 0;
FvFilesCount = 0;
for (i = 1; i < argc; i++) {
if (stricmp (argv[i], "-I") == 0) {
FvFilesCount++;
}
}
FvInfFileList = malloc (sizeof (UINTN) * (FvFilesCount + 1));
if (FvInfFileList == NULL) {
printf ("ERROR: allocating memory for FvInfFileList in -main- function.\n");
return EFI_OUT_OF_RESOURCES;
}
memset (FvInfFileList, 0, sizeof (UINTN) * (FvFilesCount + 1));
OrgFvInfFileList = FvInfFileList;
for (Index = 0; Index < FvFilesCount; Index++) {
*FvInfFileList = malloc (_MAX_PATH);
memset (*FvInfFileList, 0, _MAX_PATH);
FvInfFileList++;
}
strcpy (OutputFileName, "");
//
// Parse the command line arguments
//
FvInfFileList = OrgFvInfFileList;
for (i = 1; i < argc; i += 2) {
//
// Make sure argument pair begin with - or /
//
if (argv[i][0] != '-' && argv[i][0] != '/') {
PrintUsage ();
printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");
return EFI_INVALID_PARAMETER;
}
//
// Make sure argument specifier is only one letter
//
if (argv[i][2] != 0) {
PrintUsage ();
printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);
return EFI_INVALID_PARAMETER;
}
//
// Determine argument to read
//
switch (argv[i][1]) {
case 'I':
case 'i':
if ((FvInfFileList != NULL) && (strlen (*FvInfFileList) == 0)) {
strcpy (*FvInfFileList, argv[i + 1]);
FvInfFileList++;
} else {
printf ("ERROR: FvInfFile Name is more than specifed.\n");
return EFI_INVALID_PARAMETER;
}
break;
case 'O':
case 'o':
if (strlen (OutputFileName) == 0) {
strcpy (OutputFileName, argv[i + 1]);
} else {
PrintUsage ();
printf ("ERROR: OutputFileName may only be specified once.\n");
return EFI_INVALID_PARAMETER;
}
break;
case 'B':
case 'b':
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &StartAddress);
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Bad FD Image start address specified");
return EFI_INVALID_PARAMETER;
}
break;
case 'S':
case 's':
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &Size);
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Bad FD Image size specified");
return EFI_INVALID_PARAMETER;
}
break;
case 'F':
case 'f':
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &FillByteVal);
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Not a recognized Fill Byte value");
return EFI_INVALID_PARAMETER;
}
break;
default:
PrintUsage ();
printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);
return EFI_INVALID_PARAMETER;
break;
}
}
//
// Call the GenFdImage Lib
//
FvInfFileList = OrgFvInfFileList;
Status = GenerateFdImage (
StartAddress,
Size,
(UINT8) FillByteVal,
OutputFileName,
FvInfFileList
);
if (EFI_ERROR (Status)) {
switch (Status) {
case EFI_INVALID_PARAMETER:
printf ("\nERROR: Invalid parameter passed to GenFdImage lib.\n");
break;
case EFI_ABORTED:
printf ("\nERROR: Error detected while creating the file image.\n");
break;
case EFI_OUT_OF_RESOURCES:
printf ("\nERROR: GenFdImage Lib could not allocate required resources.\n");
break;
case EFI_VOLUME_CORRUPTED:
printf ("\nERROR: No base address was specified \n");
break;
case EFI_LOAD_ERROR:
printf ("\nERROR: An error occurred loading one of the required support Lib.\n");
break;
default:
printf ("\nERROR: GenFdImage lib returned unknown status %X.\n", Status);
break;
}
return Status;
}
return EFI_SUCCESS;
}

View File

@ -0,0 +1,91 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenFdImageExe.h
Abstract:
Definitions for the Boot Strap File Image generation utility.
--*/
#ifndef _EFI_GEN_FD_IMAGE_EXE_H
#define _EFI_GEN_FD_IMAGE_EXE_H
//
// Utility Name
//
#define UTILITY_NAME "GenFdImage"
//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 0
#define UTILITY_DATE __DATE__
//
// The maximum number of arguments accepted from the command line.
//
#define MIN_ARGS 10
//
// The function that displays general utility information
//
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
//
// The function that displays the utility usage message.
//
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
#endif

View File

@ -0,0 +1,848 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenFdImageLib.C
Abstract:
This file contains the functions required to generate
the Firmware Device
--*/
//
// Coded to EFI 2.0 Coding Standards
//
//
// Include file in build
//
#include "GenFdImage.h"
//
// Global declarations
//
UINTN ValidLineNum = 0;
UINTN NumFvFiles = 0;
static UINT64 LastAddress = 0;
CHAR8 **TokenStr;
CHAR8 **OrgStrTokPtr;
FDINFO *FdInfo;
FDINFO *OrgFdInfoPtr;
FVINFO **FvInfo;
FVINFO **OrgFvInfoPtr;
//
// Internal Functions
//
INTN
CompareItems (
IN const VOID *Arg1,
IN const VOID *Arg2
)
/*++
Routine Description:
This function is used by qsort to sort the Fv list based on FvBaseAddress
Arguments:
Arg1
Arg2
Returns:
None
--*/
// GC_TODO: Arg1 - add argument and description to function comment
// GC_TODO: Arg2 - add argument and description to function comment
{
if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {
return 1;
} else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {
return -1;
} else {
return 0;
}
}
VOID
BuildTokenList (
IN CHAR8 *Token
)
/*++
Routine Description:
This function builds the token list in an array which will be parsed later
Arguments:
Token String,
Returns:
None
--*/
{
strcpy (*TokenStr, Token);
TokenStr++;
}
VOID
TrimLine (
IN CHAR8 *Line
)
/*++
Routine Description:
This function cleans up the line by removing all whitespace and
comments.
Arguments:
Line String,
Returns:
None
--*/
{
CHAR8 TmpLine[FILE_NAME_SIZE];
CHAR8 c;
CHAR8 *Ptr0;
UINTN i;
UINTN j;
//
// Change '#' to '//' for Comment style
//
// if((Ptr0=strchr(Line, '#')) != NULL) {
//
if ((Ptr0 = strstr (Line, "//")) != NULL) {
Line[Ptr0 - Line] = 0;
}
i = 0;
j = 0;
while ((c = Line[i]) != 0) {
if ((c != ' ') && (c != '\t') && (c != '\n')) {
TmpLine[j++] = c;
}
i++;
}
TmpLine[j] = 0;
strcpy (Line, TmpLine);
}
VOID
ValidLineCount (
IN FILE *Fp
)
/*++
Routine Description:
This function calculates number of valid lines in a input file.
Arguments:
Fp Pointer to a file handle which has been opened.
Returns:
None
--*/
{
CHAR8 Buff[FILE_NAME_SIZE];
while (fgets (Buff, sizeof (Buff), Fp)) {
TrimLine (Buff);
if (Buff[0] == 0) {
continue;
}
ValidLineNum++;
}
}
VOID
ParseInputFile (
IN FILE *Fp
)
/*++
Routine Description:
This function parses the input file and tokenizes the string
Arguments:
Fp Pointer to a file handle which has been opened.
Returns:
None
--*/
{
CHAR8 *Token;
CHAR8 Buff[FILE_NAME_SIZE];
CHAR8 OrgLine[FILE_NAME_SIZE];
CHAR8 Str[FILE_NAME_SIZE];
CHAR8 Delimit[] = "=";
while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
strcpy (OrgLine, Buff);
TrimLine (Buff);
if (Buff[0] == 0) {
continue;
}
Token = strtok (Buff, Delimit);
while (Token != NULL) {
strcpy (Str, Token);
BuildTokenList (Str);
Token = strtok (NULL, Delimit);
}
}
}
EFI_STATUS
InitializeComps (
VOID
)
/*++
Routine Description:
This function intializes the relevant global variable
used to store the information retrieved from the INF file.
Arguments:
None
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
UINTN Index;
FdInfo = malloc (sizeof (FDINFO));
if (FdInfo == NULL) {
printf ("ERROR: allocating memory (struct FDINFO) in"" function InitializeComps.\n");
return EFI_OUT_OF_RESOURCES;
}
OrgFdInfoPtr = FdInfo;
FvInfo = malloc (sizeof (INTN) * NumFvFiles);
if (FvInfo == NULL) {
printf ("ERROR: allocating memory (INTN * NumFvFiles) in"" function InitializeComps.\n");
return EFI_OUT_OF_RESOURCES;
}
OrgFvInfoPtr = FvInfo;
for (Index = 0; Index < NumFvFiles; Index++) {
*FvInfo = malloc (sizeof (FVINFO));
if (*FvInfo == NULL) {
printf ("ERROR: allocating memory (FVINFO) in"" function InitializeComps.\n");
return EFI_OUT_OF_RESOURCES;
}
memset (*FvInfo, 0, sizeof (FVINFO));
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
return EFI_SUCCESS;
}
VOID
InitializeInFileInfo (
VOID
)
/*++
Routine Description:
This function intializes the relevant global variable
used to store the information retrieved from the INF file.
Arguments:
None
Returns:
None
--*/
{
UINTN OptionFlag;
UINT64 StringValue;
OptionFlag = 0;
TokenStr = OrgStrTokPtr;
while (*TokenStr != NULL) {
if (stricmp (*TokenStr, "[options]") == 0) {
OptionFlag = 1;
}
if (OptionFlag) {
if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {
*TokenStr++;
if (AsciiStringToUint64 (
*TokenStr,
FALSE,
&StringValue
) != EFI_SUCCESS) {
printf ("\nERROR: Cannot determine the FV base address.");
return ;
}
(*FvInfo)->FvBaseAddress = StringValue;
} else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {
*TokenStr++;
strcpy ((*FvInfo)->FvFile, *TokenStr);
}
}
TokenStr++;
}
}
EFI_STATUS
GetFvRelatedInfoFromInfFile (
IN CHAR8 *FileName
)
/*++
Routine Description:
This function reads the input file, parses it and create a list of tokens
which are parsed and used, to intialize the data related to the Firmware
Volume.
Arguments:
FileName FileName which needed to be read to parse data
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINTN Index;
Fp = fopen (FileName, "r");
if (Fp == NULL) {
printf ("Error in opening %s file\n", FileName);
return EFI_ABORTED;
}
ValidLineCount (Fp);
if (ValidLineNum == 0) {
printf ("\nFile doesn't contain any valid informations");
return EFI_ABORTED;
}
TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));
memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));
OrgStrTokPtr = TokenStr;
for (Index = 0; Index < (2 * ValidLineNum); Index++) {
*TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
memset (*TokenStr, 0, FILE_NAME_SIZE);
TokenStr++;
}
*TokenStr = NULL;
TokenStr = OrgStrTokPtr;
fseek (Fp, 0L, SEEK_SET);
ParseInputFile (Fp);
InitializeInFileInfo ();
if (Fp) {
fclose (Fp);
}
return EFI_SUCCESS;
}
EFI_STATUS
WriteFwBinary (
IN CHAR8 *FileName,
IN UINT64 StartAddress,
IN UINT64 Size,
IN UINT8 *Buffer
)
/*++
Routine Description:
This function reads the input file, parses it and creates a list of tokens
which are parsed and used to intialize the data related to the Firmware
Volume.
Arguments:
FileName FileName which needed to be read to parse data
StartAddress This will set the file position.
Size Size in bytes needed to be written
Buffer Buffer needed to e written
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINTN NumByte;
Fp = fopen (FileName, "a+b");
if (Fp == NULL) {
printf ("\nERROR:Error in opening file %s ", FileName);
return EFI_INVALID_PARAMETER;
}
fseek (Fp, (UINTN) StartAddress, SEEK_SET);
NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);
//
// Check to ensure that buffer has been copied successfully
//
if (NumByte != Size) {
printf ("\nERROR: Error in copying the buffer into file");
return EFI_ABORTED;
}
if (Fp) {
fclose (Fp);
}
return EFI_SUCCESS;
}
EFI_STATUS
BuildFirmwareDeviceBinaryFromFwVolumes (
IN UINT64 FvBaseAddress,
IN CHAR8 *FvFileName,
IN CHAR8 *FdFileName
)
/*++
Routine Description:
This function reads the input file, parses it and creates a list of tokens
which are parsed and used to intialize the data related to the Firmware
Volume.
Arguments:
FvBaseAddress Base Address. This info is retrieved from INF file
FvFileName InputFileName
FdFileName Output File Name
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
FILE *Fp;
UINT64 FileSize;
UINT64 NumByteRead;
UINT64 PadByteSize;
UINT64 BaseAddress;
UINTN Index;
UINT8 *Buffer;
EFI_STATUS Status;
static UINT64 StartAddress = 0;
Fp = fopen (FvFileName, "r+b");
if (Fp == NULL) {
printf ("\nERROR:Error in opening file %s", FvFileName);
return EFI_ABORTED;
}
BaseAddress = FdInfo->FdBaseAddress;
//
// Check if Base Address of Firmware Volume falls below the Base Address
// Firmware Device, if yes, then abort this process.
//
if (FvBaseAddress < BaseAddress) {
printf ("\nERROR: Firmware Volume Base Address falls below Firmware ""Device Address.\n");
return EFI_ABORTED;
}
//
// Check if there are any holes between two Firmware Volumes. If any holes
// exist, fill the hole with PadByted data.
//
if (FvBaseAddress > LastAddress) {
PadByteSize = (FvBaseAddress - LastAddress);
Buffer = malloc ((UINTN) PadByteSize);
if (Buffer == NULL) {
printf ("ERROR: allocating (Buffer) memory in"" function BuildFirmwareDeviceBinaryFromFwVolumes.\n");
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < PadByteSize; Index++) {
*Buffer = FdInfo->PadValue;
Buffer++;
}
Buffer -= PadByteSize;
Status = WriteFwBinary (
FdFileName,
StartAddress,
(UINT64) PadByteSize,
Buffer
);
if (Buffer) {
free (Buffer);
}
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error in writing the binary image to file");
return Status;
}
StartAddress += PadByteSize;
LastAddress += PadByteSize;
}
//
// Proceed with next Firmware Volume updates
//
FileSize = _filelength (fileno (Fp));
if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {
printf (
"\nERROR:Unable to update Firmware Device. File %s is larger than \
available space.",
FvFileName
);
if (Fp) {
fclose (Fp);
}
return EFI_ABORTED;
}
Buffer = malloc ((UINTN) FileSize);
if (Buffer == NULL) {
printf ("Error in allocating buffer to read specific file\n");
return EFI_OUT_OF_RESOURCES;
}
NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);
if (Buffer) {
free ((VOID *) Buffer);
}
if (Fp) {
fclose (Fp);
}
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error in writing the binary image to file");
return Status;
}
StartAddress += NumByteRead;
LastAddress += FileSize;
return EFI_SUCCESS;
}
VOID
CleanUpMemory (
VOID
)
/*++
Routine Description:
This function cleans up any allocated buffer
Arguments:
None
Returns:
None
--*/
{
UINTN Index;
if (FdInfo) {
free (FdInfo);
}
FvInfo = OrgFvInfoPtr;
if (FvInfo) {
for (Index = 0; Index < NumFvFiles; Index++) {
if (*FvInfo) {
free (*FvInfo);
}
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
free (FvInfo);
}
}
EFI_STATUS
GenerateFdImage (
IN UINT64 BaseAddress,
IN UINT64 Size,
IN UINT8 PadByte,
IN CHAR8 *OutFile,
IN CHAR8 **FileList
)
/*++
Routine Description:
This function reads the input file, parses it and creates a list of tokens
which are parsed and used to intialize the data related to the Firmware
Volume.
Arguments:
BaseAddress Base Address for this Firmware Device
Size, Total Size of the Firmware Device
PadByte Pad byte data
OutFile Output File Name
FileList File List pointer to INF file names.
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_ABORTED - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
UINTN Index;
UINTN PadSize;
UINTN FileSize;
UINTN NumByte;
CHAR8 **InFile;
FILE *Fp;
UINT8 *Buffer;
//
// If any previous Firmware Device existed,
// make it to 0 bytes
//
if ((Fp = fopen (OutFile, "w")) != NULL) {
fclose (Fp);
}
InFile = FileList;
while (*InFile != NULL) {
NumFvFiles++;
InFile++;
}
InitializeComps ();
//
// Restore the orginal pointers
//
FvInfo = OrgFvInfoPtr;
InFile = FileList;
while (*InFile != NULL) {
strcpy ((*FvInfo)->FvInfoFile, *InFile);
Status = GetFvRelatedInfoFromInfFile (*InFile);
if (Status != EFI_SUCCESS) {
printf ("\nERROR: Error occurred in processsing INF file");
CleanUpMemory ();
return Status;
}
InFile++;
FvInfo++;
}
FdInfo->FdSize = Size;
FdInfo->FdBaseAddress = BaseAddress;
FdInfo->PadValue = PadByte;
FvInfo = OrgFvInfoPtr;
strcpy (FdInfo->OutFileName, OutFile);
for (Index = 0; Index < NumFvFiles; Index++) {
Status = GenerateFvImage ((*FvInfo)->FvInfoFile);
if (Status != EFI_SUCCESS) {
CleanUpMemory ();
return Status;
}
FvInfo++;
}
FvInfo = OrgFvInfoPtr;
//
// Sort the Firmware Volume information. Firmware Volume with lower
// base addresses will be processed first and higher base address one
// will be processed later.
//
qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);
LastAddress = (*FvInfo)->FvBaseAddress;
for (Index = 0; Index < NumFvFiles; Index++) {
Status = BuildFirmwareDeviceBinaryFromFwVolumes (
(*FvInfo)->FvBaseAddress,
(*FvInfo)->FvFile,
FdInfo->OutFileName
);
if (Status != EFI_SUCCESS) {
CleanUpMemory ();
return Status;
}
FvInfo++;
}
//
// Check if any space left after copying data from all Firmware Volumes
// If yes, then fill those location with PadValue.
//
if ((FdInfo->FdBaseAddress + Size) > LastAddress) {
PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);
Buffer = malloc (PadSize);
if (Buffer == NULL) {
printf ("\nERROR: allocating PadSize memory in function GenerateFdImage.\n");
CleanUpMemory ();
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < PadSize; Index++) {
*Buffer = FdInfo->PadValue;
Buffer++;
}
Buffer -= PadSize;
Fp = fopen (OutFile, "a+b");
if (Fp == NULL) {
printf ("\nERROR:Opening file %s", OutFile);
CleanUpMemory ();
return EFI_ABORTED;
}
FileSize = _filelength (fileno (Fp));
fseek (Fp, FileSize, SEEK_SET);
NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);
if (Buffer) {
free (Buffer);
}
fclose (Fp);
if (NumByte != (sizeof (UINT8) * PadSize)) {
printf ("\nERROR: Copying data from buffer to File %s ", OutFile);
CleanUpMemory ();
return EFI_ABORTED;
}
}
//
// Clean up all the memory which has been allocated so far.
//
CleanUpMemory ();
return EFI_SUCCESS;
}

View File

@ -0,0 +1,100 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Define some macros we use here. Should get rid of them someday and
# get rid of the extra level of indirection.
#
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
#
# Common information
#
INC=$(INC) \
-I "$(TIANO_TOOLS_SOURCE)\GenFvImage"
#
# Target specific information
#
TARGET_NAME=GenFdImage
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_LIB = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).lib
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.c"
TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.h" \
"$(TARGET_SOURCE_DIR)\GenFdImage.h" \
"$(COMMON_SOURCE)\ParseInf.h" \
"$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"
TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \
"$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \
"$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"
TARGET_LIB_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageLib.c"
TARGET_LIB_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImage.h" \
"$(TIANO_TOOLS_SOURCE)\GenFvImage\GenFvImage.h" \
"$(COMMON_SOURCE)\ParseInf.h" \
"$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"
TARGET_LIB_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \
"$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \
"$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"
#
# Build targets
#
all: $(TARGET_LIB) $(TARGET_EXE)
#
# Build EXE
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_LIB)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
#
# Build LIB
#
$(TARGET_LIB): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj $(TARGET_LIB_LIBS)
$(LIB) $(LIB_FLAGS) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj /OUT:$(TARGET_LIB)
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj: $(TARGET_LIB_SOURCE) $(TARGET_LIB_INCLUDE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_LIB_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* > NUL
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,919 @@
/*++
Copyright (c) 1999-2004 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
GenTEImage.c
Abstract:
Utility program to shrink a PE32 image down by replacing
the DOS, PE, and optional headers with a minimal header.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Tiano.h"
#include "TianoCommon.h"
#include "EfiImage.h" // for PE32 structure definitions
#include "EfiUtilityMsgs.h"
//
// Version of this utility
//
#define UTILITY_NAME "GenTEImage"
#define UTILITY_VERSION "v0.11"
//
// Define the max length of a filename
//
#define MAX_PATH 256
#define DEFAULT_OUTPUT_EXTENSION ".te"
//
// Use this to track our command-line options and globals
//
struct {
INT8 OutFileName[MAX_PATH];
INT8 InFileName[MAX_PATH];
INT8 Verbose;
INT8 Dump;
} mOptions;
//
// Use these to convert from machine type value to a named type
//
typedef struct {
UINT16 Value;
INT8 *Name;
} STRING_LOOKUP;
static STRING_LOOKUP mMachineTypes[] = {
EFI_IMAGE_MACHINE_IA32,
"IA32",
EFI_IMAGE_MACHINE_IA64,
"IA64",
EFI_IMAGE_MACHINE_EBC,
"EBC",
0,
NULL
};
static STRING_LOOKUP mSubsystemTypes[] = {
EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,
"EFI application",
EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,
"EFI boot service driver",
EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,
"EFI runtime driver",
0,
NULL
};
//
// Function prototypes
//
static
void
Usage (
VOID
);
static
STATUS
ParseCommandLine (
int Argc,
char *Argv[]
);
static
STATUS
CheckPE32File (
INT8 *FileName,
FILE *Fptr,
UINT16 *MachineType,
UINT16 *SubSystem
);
static
STATUS
ProcessFile (
INT8 *InFileName,
INT8 *OutFileName
);
static
void
DumpImage (
INT8 *FileName
);
static
INT8 *
GetMachineTypeStr (
UINT16 MachineType
);
static
INT8 *
GetSubsystemTypeStr (
UINT16 SubsystemType
);
main (
int Argc,
char *Argv[]
)
/*++
Routine Description:
Arguments:
Argc - standard C main() argument count
Argv - standard C main() argument list
Returns:
0 success
non-zero otherwise
--*/
// GC_TODO: ] - add argument and description to function comment
{
INT8 *Ext;
UINT32 Status;
SetUtilityName (UTILITY_NAME);
//
// Parse the command line arguments
//
if (ParseCommandLine (Argc, Argv)) {
return STATUS_ERROR;
}
//
// If dumping an image, then do that and quit
//
if (mOptions.Dump) {
DumpImage (mOptions.InFileName);
goto Finish;
}
//
// Determine the output filename. Either what they specified on
// the command line, or the first input filename with a different extension.
//
if (!mOptions.OutFileName[0]) {
strcpy (mOptions.OutFileName, mOptions.InFileName);
//
// Find the last . on the line and replace the filename extension with
// the default
//
for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
(Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');
Ext--
)
;
//
// If dot here, then insert extension here, otherwise append
//
if (*Ext != '.') {
Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
}
strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
}
//
// Make sure we don't have the same filename for input and output files
//
if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {
Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");
goto Finish;
}
//
// Process the file
//
ProcessFile (mOptions.InFileName, mOptions.OutFileName);
Finish:
Status = GetUtilityStatus ();
return Status;
}
static
STATUS
ProcessFile (
INT8 *InFileName,
INT8 *OutFileName
)
/*++
Routine Description:
Process a PE32 EFI file.
Arguments:
InFileName - the file name pointer to the input file
OutFileName - the file name pointer to the output file
Returns:
STATUS_SUCCESS - the process has been finished successfully
STATUS_ERROR - error occured during the processing
--*/
{
STATUS Status;
FILE *InFptr;
FILE *OutFptr;
UINT16 MachineType;
UINT16 SubSystem;
EFI_TE_IMAGE_HEADER TEImageHeader;
UINT32 PESigOffset;
EFI_IMAGE_FILE_HEADER FileHeader;
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
UINT32 BytesStripped;
UINT32 FileSize;
UINT8 *Buffer;
long SaveFilePosition;
InFptr = NULL;
OutFptr = NULL;
Buffer = NULL;
Status = STATUS_ERROR;
//
// Try to open the input file
//
if ((InFptr = fopen (InFileName, "rb")) == NULL) {
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
return STATUS_ERROR;
}
//
// Double-check the file to make sure it's what we expect it to be
//
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
goto Finish;
}
//
// Initialize our new header
//
memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));
//
// Seek to the end to get the file size
//
fseek (InFptr, 0, SEEK_END);
FileSize = ftell (InFptr);
fseek (InFptr, 0, SEEK_SET);
//
// Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit
// offset (from the start of the file) to the PE signature, which always
// follows the MSDOS stub. The PE signature is immediately followed by the
// COFF file header.
//
//
if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);
goto Finish;
}
if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");
goto Finish;
}
if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");
goto Finish;
}
//
// We should now be at the COFF file header. Read it in and verify it's
// of an image type we support.
//
if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read file header from image");
goto Finish;
}
if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) {
Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);
goto Finish;
}
//
// Calculate the total number of bytes we're going to strip off. The '4' is for the
// PE signature PE\0\0. Then sanity check the size.
//
BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader;
if (BytesStripped >= FileSize) {
Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size");
goto Finish;
}
if (BytesStripped &~0xFFFF) {
Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL);
goto Finish;
}
TEImageHeader.StrippedSize = (UINT16) BytesStripped;
//
// Read in the optional header. Assume PE32, and if not, then re-read as PE32+
//
SaveFilePosition = ftell (InFptr);
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
goto Finish;
}
if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Fill in our new header with required data directory entries
//
TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint;
//
// - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);
//
// We're going to pack the subsystem into 1 byte. Make sure it fits
//
if (OptionalHeader32.Subsystem &~0xFF) {
Error (
NULL,
0,
0,
InFileName,
NULL,
"image subsystem 0x%X cannot be packed into 1 byte",
(UINT32) OptionalHeader32.Subsystem
);
goto Finish;
}
TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem;
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
}
} else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
//
// Rewind and re-read the optional header
//
fseek (InFptr, SaveFilePosition, SEEK_SET);
if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file");
goto Finish;
}
TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint;
//
// - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);
//
// We're going to pack the subsystem into 1 byte. Make sure it fits
//
if (OptionalHeader64.Subsystem &~0xFF) {
Error (
NULL,
0,
0,
InFileName,
NULL,
"image subsystem 0x%X cannot be packed into 1 byte",
(UINT32) OptionalHeader64.Subsystem
);
goto Finish;
}
TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem;
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
}
} else {
Error (
NULL,
0,
0,
InFileName,
"unsupported magic number 0x%X found in optional header",
(UINT32) OptionalHeader32.Magic
);
goto Finish;
}
//
// Fill in the remainder of our new image header
//
TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;
TEImageHeader.Machine = FileHeader.Machine;
//
// We're going to pack the number of sections into a single byte. Make sure it fits.
//
if (FileHeader.NumberOfSections &~0xFF) {
Error (
NULL,
0,
0,
InFileName,
NULL,
"image's number of sections 0x%X cannot be packed into 1 byte",
(UINT32) FileHeader.NumberOfSections
);
goto Finish;
}
TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections;
//
// Now open our output file
//
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
goto Finish;
}
//
// Write the TE header
//
if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) {
Error (NULL, 0, 0, "failed to write image header to output file", NULL);
goto Finish;
}
//
// Position into the input file, read the part we're not stripping, and
// write it out.
//
fseek (InFptr, BytesStripped, SEEK_SET);
Buffer = (UINT8 *) malloc (FileSize - BytesStripped);
if (Buffer == NULL) {
Error (NULL, 0, 0, "application error", "failed to allocate memory");
goto Finish;
}
if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) {
Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file");
goto Finish;
}
if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) {
Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file");
goto Finish;
}
Status = STATUS_SUCCESS;
Finish:
if (InFptr != NULL) {
fclose (InFptr);
}
//
// Close the output file. If there was an error, delete the output file so
// that a subsequent build will rebuild it.
//
if (OutFptr != NULL) {
fclose (OutFptr);
if (GetUtilityStatus () == STATUS_ERROR) {
remove (OutFileName);
}
}
//
// Free up our buffer
//
if (Buffer != NULL) {
free (Buffer);
}
return Status;
}
static
STATUS
CheckPE32File (
INT8 *FileName,
FILE *Fptr,
UINT16 *MachineType,
UINT16 *SubSystem
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FileName - GC_TODO: add argument description
Fptr - GC_TODO: add argument description
MachineType - GC_TODO: add argument description
SubSystem - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
/*++
Routine Description:
Given a file pointer to a supposed PE32 image file, verify that it is indeed a
PE32 image file, and then return the machine type in the supplied pointer.
Arguments:
Fptr File pointer to the already-opened PE32 file
MachineType Location to stuff the machine type of the PE32 file. This is needed
because the image may be Itanium-based, IA32, or EBC.
Returns:
0 success
non-zero otherwise
--*/
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_FILE_HEADER FileHdr;
EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;
UINT32 PESig;
STATUS Status;
Status = STATUS_ERROR;
//
// Position to the start of the file
//
fseek (Fptr, 0, SEEK_SET);
//
// Read the DOS header
//
if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");
goto Finish;
}
//
// Check the magic number (0x5A4D)
//
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");
goto Finish;
}
//
// Position into the file and check the PE signature
//
fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");
goto Finish;
}
//
// Check the PE signature in the header "PE\0\0"
//
if (PESig != EFI_IMAGE_NT_SIGNATURE) {
Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");
goto Finish;
}
//
// Read the file header
//
if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");
goto Finish;
}
//
// Read the optional header so we can get the subsystem
//
if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");
goto Finish;
}
*SubSystem = OptionalHdr.Subsystem;
if (mOptions.Verbose) {
fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem);
}
//
// Good to go
//
Status = STATUS_SUCCESS;
Finish:
fseek (Fptr, 0, SEEK_SET);
return Status;
}
static
int
ParseCommandLine (
int Argc,
char *Argv[]
)
/*++
Routine Description:
Given the Argc/Argv program arguments, and a pointer to an options structure,
parse the command-line options and check their validity.
Arguments:
Argc - standard C main() argument count
Argv - standard C main() argument list
Returns:
STATUS_SUCCESS success
non-zero otherwise
--*/
// GC_TODO: ] - add argument and description to function comment
{
//
// Clear out the options
//
memset ((char *) &mOptions, 0, sizeof (mOptions));
//
// Skip over the program name
//
Argc--;
Argv++;
//
// If no arguments, assume they want usage info
//
if (Argc == 0) {
Usage ();
return STATUS_ERROR;
}
//
// Process until no more arguments
//
while ((Argc > 0) && ((Argv[0][0] == '-') || (Argv[0][0] == '/'))) {
//
// To simplify string comparisons, replace slashes with dashes
//
Argv[0][0] = '-';
if (stricmp (Argv[0], "-o") == 0) {
//
// Output filename specified with -o
// Make sure there's another parameter
//
if (Argc > 1) {
strcpy (mOptions.OutFileName, Argv[1]);
} else {
Error (NULL, 0, 0, Argv[0], "missing output file name with option");
Usage ();
return STATUS_ERROR;
}
Argv++;
Argc--;
} else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {
//
// Help option
//
Usage ();
return STATUS_ERROR;
} else if (stricmp (Argv[0], "-v") == 0) {
//
// -v for verbose
//
mOptions.Verbose = 1;
} else if (stricmp (Argv[0], "-dump") == 0) {
//
// -dump for dumping an image
//
mOptions.Dump = 1;
} else {
Error (NULL, 0, 0, Argv[0], "unrecognized option");
Usage ();
return STATUS_ERROR;
}
//
// Next argument
//
Argv++;
Argc--;
}
//
// Better be one more arg for input file name
//
if (Argc == 0) {
Error (NULL, 0, 0, "input file name required", NULL);
Usage ();
return STATUS_ERROR;
}
if (Argc != 1) {
Error (NULL, 0, 0, Argv[1], "extra arguments on command line");
return STATUS_ERROR;
}
strcpy (mOptions.InFileName, Argv[0]);
return STATUS_SUCCESS;
}
static
void
Usage (
VOID
)
/*++
Routine Description:
Print usage information for this utility.
Arguments:
None.
Returns:
Nothing.
--*/
{
int Index;
static const char *Msg[] = {
UTILITY_NAME " version "UTILITY_VERSION " - TE image utility",
" Generate a TE image from an EFI PE32 image",
" Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName",
" [-e|-b] [FileName(s)]",
" where:",
" -v - for verbose output",
" -dump - to dump the input file to a text file",
" -h -? - for this help information",
" -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,
" InFileName - name of the input PE32 file",
"",
NULL
};
for (Index = 0; Msg[Index] != NULL; Index++) {
fprintf (stdout, "%s\n", Msg[Index]);
}
}
static
VOID
DumpImage (
INT8 *FileName
)
/*++
Routine Description:
Dump a specified image information
Arguments:
FileName - File name pointer to the image to dump
Returns:
Nothing.
--*/
{
FILE *InFptr;
EFI_TE_IMAGE_HEADER TEImageHeader;
INT8 *NamePtr;
//
// Open the input file
//
InFptr = NULL;
if ((InFptr = fopen (FileName, "rb")) == NULL) {
Error (NULL, 0, 0, FileName, "failed to open input file for reading");
return ;
}
if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) {
Error (NULL, 0, 0, FileName, "failed to read image header from input file");
goto Finish;
}
if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {
Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)");
goto Finish;
}
//
// Dump the header
//
fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER));
fprintf (stdout, " Signature: 0x%04X (TE)\n", (UINT32) TEImageHeader.Signature);
NamePtr = GetMachineTypeStr (TEImageHeader.Machine);
fprintf (stdout, " Machine: 0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr);
NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem);
fprintf (stdout, " Subsystem: 0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr);
fprintf (stdout, " Number of sections 0x%02X\n", (UINT32) TEImageHeader.NumberOfSections);
fprintf (stdout, " Stripped size: 0x%04X\n", (UINT32) TEImageHeader.StrippedSize);
fprintf (stdout, " Entry point: 0x%08X\n", TEImageHeader.AddressOfEntryPoint);
fprintf (stdout, " Base of code: 0x%08X\n", TEImageHeader.BaseOfCode);
fprintf (stdout, " Data directories:\n");
fprintf (
stdout,
" %8X [%8X] RVA [size] of Base Relocation Directory\n",
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
);
fprintf (
stdout,
" %8X [%8X] RVA [size] of Debug Directory\n",
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size
);
Finish:
if (InFptr != NULL) {
fclose (InFptr);
}
}
static
INT8 *
GetMachineTypeStr (
UINT16 MachineType
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
MachineType - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
int Index;
for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {
if (mMachineTypes[Index].Value == MachineType) {
return mMachineTypes[Index].Name;
}
}
return "unknown";
}
static
INT8 *
GetSubsystemTypeStr (
UINT16 SubsystemType
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
SubsystemType - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
int Index;
for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {
if (mSubsystemTypes[Index].Value == SubsystemType) {
return mSubsystemTypes[Index].Name;
}
}
return "unknown";
}

View File

@ -0,0 +1,68 @@
#/*++
#
# Copyright (c) 2002 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name:
#
# makefile
#
# Abstract:
#
# makefile for building the GenTEImage utility.
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Define the toolchain which is used to set build options and toolchain paths
#
TOOLCHAIN = TOOLCHAIN_MSVC
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = GenTEImage
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
INC_DEPS = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h
#
# Build the EXE by compiling the source files, then linking the resultant
# object files together.
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,973 @@
/*++
Copyright (c) 1999 - 2005 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
PeiRebaseExe.c
Abstract:
This contains all code necessary to build the PeiRebase.exe utility.
This utility relies heavily on the PeiRebase DLL. Definitions for both
can be found in the PEI Rebase Utility Specification, review draft.
--*/
#include "PeiRebaseExe.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "CommonLib.h"
#include "ParseInf.h"
#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
#include "FvLib.h"
#include "EfiUtilityMsgs.h"
extern EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader;
EFI_STATUS
ReadHeader (
IN FILE *InputFile,
OUT UINT32 *FvSize,
OUT BOOLEAN *ErasePolarity
);
int
main (
int argc,
char **argv
)
/*++
Routine Description:
This utility relocates PEI XIP PE32s in a FV.
Arguments:
argc - Number of command line arguments
argv[]:
BaseAddress The base address to use for rebasing the FV. The correct
format is a hex number preceded by 0x.
InputFileName The name of the input FV file.
OutputFileName The name of the output FV file.
Arguments come in pair in any order.
-I InputFileName
-O OutputFileName
-B BaseAddress
Returns:
0 No error conditions detected.
1 One or more of the input parameters is invalid.
2 A resource required by the utility was unavailable.
Most commonly this will be memory allocation or file creation.
3 PeiRebase.dll could not be loaded.
4 Error executing the PEI rebase.
--*/
{
UINT8 Index;
CHAR8 InputFileName[_MAX_PATH];
CHAR8 OutputFileName[_MAX_PATH];
EFI_PHYSICAL_ADDRESS BaseAddress;
BOOLEAN BaseAddressSet;
EFI_STATUS Status;
FILE *InputFile;
FILE *OutputFile;
UINT64 FvOffset;
UINT32 FileCount;
int BytesRead;
EFI_FIRMWARE_VOLUME_HEADER *FvImage;
UINT32 FvSize;
EFI_FFS_FILE_HEADER *CurrentFile;
BOOLEAN ErasePolarity;
EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress;
ErasePolarity = FALSE;
//
// Set utility name for error/warning reporting purposes.
//
SetUtilityName (UTILITY_NAME);
//
// Verify the correct number of arguments
//
if (argc != MAX_ARGS) {
PrintUsage ();
return STATUS_ERROR;
}
//
// Initialize variables
//
InputFileName[0] = 0;
OutputFileName[0] = 0;
BaseAddress = 0;
BaseAddressSet = FALSE;
FvOffset = 0;
FileCount = 0;
ErasePolarity = FALSE;
InputFile = NULL;
OutputFile = NULL;
FvImage = NULL;
//
// Parse the command line arguments
//
for (Index = 1; Index < MAX_ARGS; Index += 2) {
//
// Make sure argument pair begin with - or /
//
if (argv[Index][0] != '-' && argv[Index][0] != '/') {
PrintUsage ();
Error (NULL, 0, 0, argv[Index], "unrecognized option");
return STATUS_ERROR;
}
//
// Make sure argument specifier is only one letter
//
if (argv[Index][2] != 0) {
PrintUsage ();
Error (NULL, 0, 0, argv[Index], "unrecognized option");
return STATUS_ERROR;
}
//
// Determine argument to read
//
switch (argv[Index][1]) {
case 'I':
case 'i':
if (strlen (InputFileName) == 0) {
strcpy (InputFileName, argv[Index + 1]);
} else {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified");
return STATUS_ERROR;
}
break;
case 'O':
case 'o':
if (strlen (OutputFileName) == 0) {
strcpy (OutputFileName, argv[Index + 1]);
} else {
PrintUsage ();
Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");
return STATUS_ERROR;
}
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;
default:
PrintUsage ();
Error (NULL, 0, 0, argv[Index], "unrecognized argument");
return STATUS_ERROR;
break;
}
}
//
// Open the file containing the FV
//
InputFile = fopen (InputFileName, "rb");
if (InputFile == NULL) {
Error (NULL, 0, 0, InputFileName, "could not open input file for reading");
return STATUS_ERROR;
}
//
// Determine size of FV
//
Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "could not parse the FV header", NULL);
goto Finish;
}
//
// Allocate a buffer for the FV image
//
FvImage = malloc (FvSize);
if (FvImage == NULL) {
Error (NULL, 0, 0, "application error", "memory allocation failed");
goto Finish;
}
//
// Read the entire FV to the buffer
//
BytesRead = fread (FvImage, 1, FvSize, InputFile);
fclose (InputFile);
InputFile = NULL;
if ((unsigned int) BytesRead != FvSize) {
Error (NULL, 0, 0, InputFileName, "failed to read from file");
goto Finish;
}
//
// Prepare to walk the FV image
//
InitializeFvLib (FvImage, FvSize);
//
// Get the first file
//
Status = GetNextFile (NULL, &CurrentFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL);
goto Finish;
}
//
// Check if each file should be rebased
//
while (CurrentFile != NULL) {
//
// Rebase this file
//
CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);
Status = FfsRebase (CurrentFile, CurrentFileBaseAddress);
if (EFI_ERROR (Status)) {
switch (Status) {
case EFI_INVALID_PARAMETER:
Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL);
break;
case EFI_ABORTED:
Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL);
break;
case EFI_OUT_OF_RESOURCES:
Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL);
break;
case EFI_NOT_FOUND:
Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL);
break;
default:
Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status);
break;
}
goto Finish;
}
//
// Get the next file
//
Status = GetNextFile (CurrentFile, &CurrentFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL);
goto Finish;
}
}
//
// Open the output file
//
OutputFile = fopen (OutputFileName, "wb");
if (OutputFile == NULL) {
Error (NULL, 0, 0, OutputFileName, "failed to open output file");
goto Finish;
}
if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) {
Error (NULL, 0, 0, "failed to write to output file", 0);
goto Finish;
}
Finish:
if (InputFile != NULL) {
fclose (InputFile);
}
//
// If we created an output file, and there was an error, remove it so
// subsequent builds will rebuild it.
//
if (OutputFile != NULL) {
if (GetUtilityStatus () == STATUS_ERROR) {
remove (OutputFileName);
}
fclose (OutputFile);
}
if (FvImage != NULL) {
free (FvImage);
}
return GetUtilityStatus ();
}
EFI_STATUS
ReadHeader (
IN FILE *InputFile,
OUT UINT32 *FvSize,
OUT BOOLEAN *ErasePolarity
)
/*++
Routine Description:
This function determines the size of the FV and the erase polarity. The
erase polarity is the FALSE value for file state.
Arguments:
InputFile The file that contains the FV image.
FvSize The size of the FV.
ErasePolarity The FV erase polarity.
Returns:
EFI_SUCCESS Function completed successfully.
EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
EFI_ABORTED The function encountered an error.
--*/
{
EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
EFI_FV_BLOCK_MAP_ENTRY BlockMap;
UINTN Signature[2];
UINTN BytesRead;
UINT32 Size;
BytesRead = 0;
Size = 0;
//
// Check input parameters
//
if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) {
Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter");
return EFI_INVALID_PARAMETER;
}
//
// Read the header
//
fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
Signature[0] = VolumeHeader.Signature;
Signature[1] = 0;
//
// Get erase polarity
//
if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {
*ErasePolarity = TRUE;
}
do {
fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
if (BlockMap.NumBlocks != 0) {
Size += BlockMap.NumBlocks * BlockMap.BlockLength;
}
} while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0));
if (VolumeHeader.FvLength != Size) {
Error (NULL, 0, 0, "volume size not consistant with block maps", NULL);
return EFI_ABORTED;
}
*FvSize = Size;
rewind (InputFile);
return EFI_SUCCESS;
}
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
Displays the standard utility information to SDTOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"%s, PEI Rebase Utility. Version %i.%i, %s.\n\n",
UTILITY_NAME,
UTILITY_MAJOR_VERSION,
UTILITY_MINOR_VERSION,
UTILITY_DATE
);
}
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
Displays the utility usage syntax to STDOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
UTILITY_NAME
);
printf (" Where:\n");
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
printf (" OutputFileName is the desired output file name.\n");
printf (" BaseAddress is the FV base address to rebase agains.\n");
printf (" Argument pair may be in any order.\n\n");
}
EFI_STATUS
FfsRebase (
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
/*++
Routine Description:
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.
Arguments:
FfsFile A pointer to Ffs file image.
BaseAddress The base address to use for rebasing the file image.
Returns:
EFI_SUCCESS The image was properly rebased.
EFI_INVALID_PARAMETER An input parameter is invalid.
EFI_ABORTED An error occurred while rebasing the input file image.
EFI_OUT_OF_RESOURCES Could not allocate a required resource.
EFI_NOT_FOUND No compressed sections could be found.
--*/
{
EFI_STATUS Status;
EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UINTN MemoryImagePointer;
UINTN MemoryImagePointerAligned;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS EntryPoint;
UINT32 Pe32ImageSize;
UINT32 NewPe32BaseAddress;
UINTN Index;
EFI_FILE_SECTION_POINTER CurrentPe32Section;
EFI_FFS_FILE_STATE SavedState;
EFI_IMAGE_NT_HEADERS *PeHdr;
UINT32 *PeHdrSizeOfImage;
UINT32 *PeHdrChecksum;
UINT32 FoundCount;
EFI_TE_IMAGE_HEADER *TEImageHeader;
UINT8 *TEBuffer;
EFI_IMAGE_DOS_HEADER *DosHeader;
UINT8 FileGuidString[80];
UINT32 TailSize;
EFI_FFS_FILE_TAIL TailValue;
//
// Verify input parameters
//
if (FfsFile == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Convert the GUID to a string so we can at least report which file
// if we find an error.
//
PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
TailSize = sizeof (EFI_FFS_FILE_TAIL);
} else {
TailSize = 0;
}
//
// Do some cursory checks on the FFS file contents
//
Status = VerifyFfsFile (FfsFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString);
return EFI_INVALID_PARAMETER;
}
//
// Check if XIP file type. If not XIP, don't rebase.
//
if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) {
return EFI_SUCCESS;
}
//
// Rebase each PE32 section
//
Status = EFI_SUCCESS;
FoundCount = 0;
for (Index = 1;; Index++) {
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
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
//
memset (&ImageContext, 0, sizeof (ImageContext));
ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));
ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
Status = mPeCoffLoader.GetImageInfo (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);
return Status;
}
//
// Allocate a buffer for the image to be loaded into.
//
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation failure", NULL);
return EFI_OUT_OF_RESOURCES;
}
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
ImageContext.ImageAddress = MemoryImagePointerAligned;
Status = mPeCoffLoader.LoadImage (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);
free ((VOID *) MemoryImagePointer);
return Status;
}
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = mPeCoffLoader.RelocateImage (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);
free ((VOID *) MemoryImagePointer);
return Status;
}
ImageAddress = ImageContext.ImageAddress;
ImageSize = ImageContext.ImageSize;
EntryPoint = ImageContext.EntryPoint;
if (ImageSize > Pe32ImageSize) {
Error (
NULL,
0,
0,
"rebased image is larger than original PE32 image",
"0x%X > 0x%X, file %s",
ImageSize,
Pe32ImageSize,
FileGuidString
);
free ((VOID *) MemoryImagePointer);
return EFI_ABORTED;
}
//
// 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
// so it will be loaded properly later if the PEIM is reloaded into memory...
//
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
} else {
Error (
NULL,
0,
0,
"unknown machine type in PE32 image",
"machine type=0x%X, file=%s",
(UINT32) PeHdr->FileHeader.Machine,
FileGuidString
);
free ((VOID *) MemoryImagePointer);
return EFI_ABORTED;
}
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
if (*PeHdrChecksum) {
*PeHdrChecksum = 0;
}
}
memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);
free ((VOID *) MemoryImagePointer);
//
// Now update file checksum
//
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
TailSize = sizeof (EFI_FFS_FILE_TAIL);
} else {
TailSize = 0;
}
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State;
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *) FfsFile,
GetLength (FfsFile->Size) - TailSize
);
} else {
FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
}
FfsFile->State = SavedState;
}
//
// Update tail if present
//
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
}
}
//
// Now process TE sections
//
for (Index = 1;; Index++) {
Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
break;
}
FoundCount++;
//
// Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
// by GenTEImage
//
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
NewPe32BaseAddress = ((UINT32) BaseAddress) +
(
(UINTN) CurrentPe32Section.Pe32Section +
sizeof (EFI_COMMON_SECTION_HEADER) +
sizeof (EFI_TE_IMAGE_HEADER) -
TEImageHeader->StrippedSize -
(UINTN) FfsFile
);
//
// Allocate a buffer to unshrink the image into.
//
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
sizeof (EFI_TE_IMAGE_HEADER);
Pe32ImageSize += TEImageHeader->StrippedSize;
TEBuffer = (UINT8 *) malloc (Pe32ImageSize);
if (TEBuffer == NULL) {
Error (NULL, 0, 0, "failed to allocate memory", NULL);
return EFI_OUT_OF_RESOURCES;
}
//
// Expand the image into our buffer and fill in critical fields in the DOS header
// Fill in fields required by the loader.
// At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value
// itself.
//
memset (TEBuffer, 0, Pe32ImageSize);
DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;
DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;
*(UINT32 *) (TEBuffer + 0x3C) = 0x40;
PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);
PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
PeHdr->FileHeader.Machine = TEImageHeader->Machine;
PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;
//
// Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and
// the 0x40 bytes for our DOS 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));
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
PeHdr->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)
) {
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;
//
// Copy the rest of the image to its original offset
//
memcpy (
TEBuffer + TEImageHeader->StrippedSize,
(UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
sizeof (EFI_TE_IMAGE_HEADER)
);
//
// Initialize context
//
memset (&ImageContext, 0, sizeof (ImageContext));
ImageContext.Handle = (VOID *) TEBuffer;
ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
Status = mPeCoffLoader.GetImageInfo (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);
free (TEBuffer);
return Status;
}
//
// Allocate a buffer for the image to be loaded into.
//
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
if (MemoryImagePointer == 0) {
Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);
free (TEBuffer);
return EFI_OUT_OF_RESOURCES;
}
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
ImageContext.ImageAddress = MemoryImagePointerAligned;
Status = mPeCoffLoader.LoadImage (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);
free (TEBuffer);
free ((VOID *) MemoryImagePointer);
return Status;
}
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = mPeCoffLoader.RelocateImage (&mPeCoffLoader, &ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);
free ((VOID *) MemoryImagePointer);
free (TEBuffer);
return Status;
}
ImageAddress = ImageContext.ImageAddress;
ImageSize = ImageContext.ImageSize;
EntryPoint = ImageContext.EntryPoint;
//
// 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
// so it will be loaded properly later if the PEIM is reloaded into memory...
//
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
} else {
Error (
NULL,
0,
0,
"unknown machine type in TE image",
"machine type=0x%X, file=%s",
(UINT32) PeHdr->FileHeader.Machine,
FileGuidString
);
free ((VOID *) MemoryImagePointer);
free (TEBuffer);
return EFI_ABORTED;
}
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
if (*PeHdrChecksum) {
*PeHdrChecksum = 0;
}
}
TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
memcpy (
(UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),
(VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
sizeof (EFI_TE_IMAGE_HEADER)
);
free ((VOID *) MemoryImagePointer);
free (TEBuffer);
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
TailSize = sizeof (EFI_FFS_FILE_TAIL);
} else {
TailSize = 0;
}
//
// Now update file checksum
//
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State;
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *) FfsFile,
GetLength (FfsFile->Size) - TailSize
);
} else {
FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
}
FfsFile->State = SavedState;
}
//
// Update tail if present
//
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
}
}
//
// 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;
}
EFI_STATUS
FfsRebaseImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINT32 *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
Arguments:
FileHandle - The handle to the PE/COFF file
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
CHAR8 *Destination8;
CHAR8 *Source8;
UINT32 Length;
Destination8 = Buffer;
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
Length = *ReadSize;
while (Length--) {
*(Destination8++) = *(Source8++);
}
return EFI_SUCCESS;
}

View File

@ -0,0 +1,153 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
PeiRebaseExe.h
Abstract:
Definitions for the PeiRebase exe utility.
--*/
#ifndef _EFI_PEIM_FIXUP_EXE_H
#define _EFI_PEIM_FIXUP_EXE_H
#include "Efi2WinNt.h"
#include "EfiFirmwareFileSystem.h"
#include "EfiFirmwareVolumeHeader.h"
//
// Utility Name
//
#define UTILITY_NAME "PeiRebase"
//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 1
#define UTILITY_DATE __DATE__
//
// The maximum number of arguments accepted from the command line.
//
#define MAX_ARGS 7
//
// The file copy buffer size
//
#define FILE_COPY_BUFFER_SIZE 512
//
// The function that displays general utility information
//
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
//
// The function that displays the utility usage message.
//
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
//
// Internal function declarations
//
EFI_STATUS
FfsRebaseImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINT32 *ReadSize,
OUT VOID *Buffer
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FileHandle - GC_TODO: add argument description
FileOffset - GC_TODO: add argument description
ReadSize - GC_TODO: add argument description
Buffer - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
EFI_STATUS
FfsRebase (
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FfsFile - GC_TODO: add argument description
BaseAddress - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
#endif

View File

@ -0,0 +1,71 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name:
#
# makefile
#
# Abstract:
#
# makefile for building the PeiRebase utility.
#
# Revision History
#
#--*/
#
# Make sure environmental variable EFI_SOURCE is set
#
!IFNDEF EFI_SOURCE
!ERROR EFI_SOURCE environmental variable not set
!ENDIF
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = PeiRebase
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\PeiRebase.exe
TARGET_EXE_LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\PeiRebase.obj
#
# Compile each source file
#
$(TIANO_TOOLS_OUTPUT)\PeiRebase.obj : $(TARGET_SRC_DIR)\PeiRebaseExe.c $(INC_DEPS) $(TARGET_EXE_LIBS)
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\PeiRebaseExe.c /Fo$@
#
# Link the object files together
#
$(TARGET_EXE) : $(OBJECTS) $(TARGET_EXE_LIBS)
@echo LINKING
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) $(TARGET_EXE_LIBS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,58 @@
#/*++
#
# Copyright (c) 2005 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = SecApResetVectorFixup
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
#
# Build EXE
#
$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)
$(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@
$(TARGET_EXE): $(OBJECTS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)
clean:
@if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,363 @@
/*++
Copyright (c) 2005 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
SecApResetVectorFixup.c
Abstract:
This utility is part of build process for IA32 Fvrecovery.fv whose total size
is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset
vector at the zero vector of Fv header.
PEI FV after using the tool
-------------------------
|zzz |
| |
| |
| FFS |
| |
| |
| |
|---------------------- |
| PAD |
| |
|.......................| ---
| | |
|xxx | | 128K
|---------------------- | |
| VTF (SEC) | |
------------------------- ---
1. zzz --> Zero vector, which is beyond the 128K limited address space
2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD
file area.
3. After the build process ,the PAD guid is changed to a new GUID to avoid
the PAD definition confusing. If there is some problem, try to disable
UpdatePadFileGuid
--*/
#include "SecApResetVectorFixup.h"
EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f };
EFI_GUID NewFvPadFileNameGuid = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 };
//
// jmp 0xf000:0xffd0 (0xFFFFFFD0)
//
UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0};
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
Displays the standard utility information to SDTOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n",
UTILITY_NAME,
UTILITY_MAJOR_VERSION,
UTILITY_MINOR_VERSION
);
}
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
Displays the utility usage syntax to STDOUT
Arguments:
None
Returns:
None
--*/
{
printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME);
printf (" Where:\n");
printf ("\tInputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n");
printf ("\tOutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n");
}
VOID
UpdatePadFileGuid (
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
IN EFI_FFS_FILE_HEADER *FileHeader,
IN UINT32 FileLength,
IN OUT EFI_GUID *Guid
)
/*++
Routine Description:
Update the Pad File Guid to change it to other guid and update
the checksum
Arguments:
FvHeader - EFI_FIRMWARE_VOLUME_HEADER
FileHeader - The FFS PAD file header.
FileLength - The FFS PAD file length.
Guid - The Guid to compare and if it is PAD Guid, update it to new Guid
Returns:
VOID
--*/
{
if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {
//
// Set new Pad file guid
//
memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID));
FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD;
FileHeader->Attributes = 0;
//
// Fill in checksums and state, must be zero during checksum calculation.
//
FileHeader->IntegrityCheck.Checksum.Header = 0;
FileHeader->IntegrityCheck.Checksum.File = 0;
FileHeader->State = 0;
FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));
if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength);
} else {
FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
}
FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
FileHeader->State = (UINT8)~(FileHeader->State);
}
}
}
STATUS
main (
IN INTN argc,
IN CHAR8 **argv
)
/*++
Routine Description:
Main function.
Arguments:
argc - Number of command line parameters.
argv - Array of pointers to parameter strings.
Returns:
STATUS_SUCCESS - Utility exits successfully.
STATUS_ERROR - Some error occurred during execution.
--*/
{
FILE *FpIn;
FILE *FpOut;
UINT32 FvrecoveryFileSize;
UINT8 *FileBuffer;
UINT8 *FileBufferRaw;
UINT64 FvLength;
UINT32 Offset;
UINT32 FileLength;
UINT32 FileOccupiedSize;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_FFS_FILE_HEADER *FileHeader;
EFI_GUID *TempGuid;
UINT8 *FixPoint;
UINT32 TempResult;
UINT32 Index;
UINT32 IpiVector;
TempGuid = NULL;
SetUtilityName (UTILITY_NAME);
//
// Display utility information
//
PrintUtilityInfo ();
//
// Verify the correct number of arguments
//
if (argc != MAX_ARGS) {
Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
PrintUsage ();
return STATUS_ERROR;
}
//
// Open the Input Fvrecovery.fv file
//
if ((FpIn = fopen (argv[1], "rb")) == NULL) {
Error (NULL, 0, 0, "Unable to open file", argv[1]);
return STATUS_ERROR;
}
//
// Get the Input Fvrecovery.fv file size
//
fseek (FpIn, 0, SEEK_END);
FvrecoveryFileSize = ftell (FpIn);
//
// Read the contents of input file to memory buffer
//
FileBuffer = NULL;
FileBufferRaw = NULL;
FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000);
if (NULL == FileBufferRaw) {
Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
fclose (FpIn);
return STATUS_ERROR;
}
TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF);
FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult);
fseek (FpIn, 0, SEEK_SET);
TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn);
if (TempResult != FvrecoveryFileSize) {
Error (NULL, 0, 0, "Read input file error!", NULL);
free ((VOID *)FileBufferRaw);
fclose (FpIn);
return STATUS_ERROR;
}
//
// Close the input Fvrecovery.fv file
//
fclose (FpIn);
//
// Find the pad FFS file
//
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer;
FvLength = FvHeader->FvLength;
FileHeader = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength);
FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
Offset = (UINT32)FileHeader - (UINT32)FileBuffer;
while (Offset < FvLength) {
TempGuid = (EFI_GUID *)&(FileHeader->Name);
FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) {
break;
}
FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize);
Offset = (UINT32)FileHeader - (UINT32)FileBuffer;
}
if (Offset >= FvLength) {
Error (NULL, 0, 0, "No pad file found!", NULL);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
//
// Find the position to place Ap reset vector, the offset
// between the position and the end of Fvrecovery.fv file
// should not exceed 128kB to prevent Ap reset vector from
// outside legacy E and F segment
//
FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER));
TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF);
FixPoint +=TempResult;
if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) {
Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) {
FixPoint += 0x1000;
}
FixPoint -= 0x1000;
if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) {
Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
//
// Fix up Ap reset vector and calculate the IPI vector
//
for (Index = 0; Index < 5; Index++) {
FixPoint[Index] = ApResetVector[Index];
}
TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint);
TempResult >>= 12;
IpiVector = TempResult & 0x0FF;
UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid);
//
// Open the output Fvrecovery.fv file
//
if ((FpOut = fopen (argv[2], "w+b")) == NULL) {
Error (NULL, 0, 0, "Unable to open file", argv[2]);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
//
// Write the output Fvrecovery.fv file
//
if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) {
Error (NULL, 0, 0, "Write output file error!", NULL);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
//
//
//
fseek (FpOut, -8, SEEK_END);
if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) {
Error (NULL, 0, 0, "Write output file error!", NULL);
free ((VOID *)FileBufferRaw);
return STATUS_ERROR;
}
//
// Close the output Fvrecovery.fv file
//
fclose (FpOut);
free ((VOID *)FileBufferRaw);
return STATUS_SUCCESS;
}

View File

@ -0,0 +1,102 @@
/*++
Copyright (c) 2005 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
SecApResetVectorFixup.h
Abstract:
Definitions for the SecApResetVectorFixup utility.
--*/
#ifndef _SEC_AP_RESET_VECTOR_FIXUP_H
#define _SEC_AP_RESET_VECTOR_FIXUP_H
#include <stdio.h>
#include <stdlib.h>
#include "EfiCommon.h"
#include "EfiImage.h"
#include "EfiImageFormat.h"
#include "EfiFirmwareFileSystem.h"
#include "EfiFirmwareVolumeHeader.h"
#include "EfiUtilityMsgs.c"
#include "CommonLib.h"
//
// Utility Name
//
#define UTILITY_NAME "SecApResetVectorFixup"
//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 1
#define UTILITY_DATE __DATE__
//
// The maximum number of arguments accepted from the command line.
//
#define MAX_ARGS 3
#define BUF_SIZE (8 * 1024)
#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
(ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
Displays the standard utility information to SDTOUT
Arguments:
None
Returns:
None
--*/
;
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
Displays the utility usage syntax to STDOUT
Arguments:
None
Returns:
None
--*/
;
#endif

View File

@ -0,0 +1,57 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Target specific information
#
TARGET_NAME = SecFixup
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c
#
# Build targets
#
all: $(TARGET_EXE)
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
#
# Build EXE
#
$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)
$(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@
$(TARGET_EXE): $(OBJECTS)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)
clean:
@if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,362 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
SecFixup.c
Abstract:
This utility is part of build process for IA32 SEC FFS file.
It fixup the reset vector data. The reset vector data binary file
will be wrapped as a RAW section and be located immediately after
the PE/TE section.
The SEC EXE file can be either PE or TE file.
--*/
#include <stdio.h>
#include "EfiCommon.h"
#include "EfiImage.h"
#include "EfiImageFormat.h"
#include "EfiUtilityMsgs.c"
#include "SecFixup.h"
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
Displays the standard utility information to SDTOUT
Arguments:
None
Returns:
None
--*/
{
printf (
"%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",
UTILITY_NAME,
UTILITY_MAJOR_VERSION,
UTILITY_MINOR_VERSION
);
}
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
Displays the utility usage syntax to STDOUT
Arguments:
None
Returns:
None
--*/
{
printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME);
printf (" Where:\n");
printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");
printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");
printf ("\tOutputFileName - Name of the output file.\n\n");
}
STATUS
main (
IN INTN argc,
IN CHAR8 **argv
)
/*++
Routine Description:
Main function.
Arguments:
argc - Number of command line parameters.
argv - Array of pointers to parameter strings.
Returns:
STATUS_SUCCESS - Utility exits successfully.
STATUS_ERROR - Some error occurred during execution.
--*/
{
FILE *FpIn;
FILE *FpOut;
UINT32 AddressOfEntryPoint;
INT32 DestRel;
STATUS Status;
UINT32 SecFileSize;
SetUtilityName (UTILITY_NAME);
//
// Display utility information
//
PrintUtilityInfo ();
//
// Verify the correct number of arguments
//
if (argc != MAX_ARGS) {
Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
PrintUsage ();
return STATUS_ERROR;
}
//
// Open the SEC exe file
//
if ((FpIn = fopen (argv[1], "rb")) == NULL) {
Error (NULL, 0, 0, "Unable to open file", argv[1]);
return STATUS_ERROR;
}
//
// Get the entry point of the EXE file
//
Status = GetEntryPoint (FpIn, &AddressOfEntryPoint);
if (Status != STATUS_SUCCESS) {
fclose (FpIn);
return STATUS_ERROR;
}
//
// Get the SEC file size
//
fseek (FpIn, 0, SEEK_END);
SecFileSize = ftell (FpIn);
//
// Close the SEC file
//
fclose (FpIn);
//
// Open the reset vector data file
//
if ((FpIn = fopen (argv[2], "rb")) == NULL) {
Error (NULL, 0, 0, "Unable to open file", argv[2]);
return STATUS_ERROR;
}
//
// Open the output file
//
if ((FpOut = fopen (argv[3], "w+b")) == NULL) {
Error (NULL, 0, 0, "Unable to open file", argv[3]);
fclose (FpIn);
return STATUS_ERROR;
}
//
// Copy the input file to the output file
//
if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) {
fclose (FpIn);
fclose (FpOut);
return STATUS_ERROR;
}
//
// Close the reset vector data file
//
fclose (FpIn);
//
// Fix the destination relative in the jmp instruction
// in the reset vector data structure
//
fseek (FpOut, -DEST_REL_OFFSET, SEEK_END);
DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2);
if (DestRel <= -65536) {
Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL);
fclose (FpOut);
return STATUS_ERROR;
}
if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) {
Error (NULL, 0, 0, "Failed to write to the output file", NULL);
fclose (FpOut);
return STATUS_ERROR;
}
//
// Close the output file
//
fclose (FpOut);
return STATUS_SUCCESS;
}
STATUS
GetEntryPoint (
IN FILE *ExeFile,
OUT UINT32 *EntryPoint
)
/*++
Routine Description:
Get the address of the entry point of a PE/TE file.
Arguments:
PeFile - File pointer to the specified PE/TE file.
EntryPoint - Buffer for the address of the entry point to be returned.
Returns:
STATUS_SUCCESS - Function completed successfully.
STATUS_ERROR - Error occured.
--*/
// GC_TODO: ExeFile - add argument and description to function comment
{
EFI_IMAGE_DOS_HEADER DosHeader;
EFI_IMAGE_NT_HEADERS32 NtHeader;
EFI_TE_IMAGE_HEADER TeHeader;
//
// Check if it is a TE file
//
fseek (ExeFile, 0, SEEK_SET);
//
// Attempt to read the TE header
//
if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) {
if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) {
Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);
return STATUS_ERROR;
}
*EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize;
return STATUS_SUCCESS;
}
}
//
// Check if it is a PE file
//
fseek (ExeFile, 0, SEEK_SET);
//
// Attempt to read the DOS header
//
if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) {
goto InvalidFile;
}
//
// Check the magic number
//
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
goto InvalidFile;
}
//
// Position into the file and read the NT PE header
//
fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET);
if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) {
goto InvalidFile;
}
//
// Check the PE signature in the header
//
if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) {
goto InvalidFile;
}
//
// Make sure the PE file is PE32 for IA32
//
if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 ||
NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);
return STATUS_ERROR;
}
//
// Get the entry point from the optional header
//
*EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint;
return STATUS_SUCCESS;
InvalidFile:
Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL);
return STATUS_ERROR;
}
STATUS
CopyFile (
FILE *FpIn,
FILE *FpOut
)
/*++
Routine Description:
Copy file.
Arguments:
FpIn - File pointer to the source file.
FpOut - File pointer to the destination file.
Returns:
STATUS_SUCCESS - Function completed successfully.
STATUS_ERROR - Error occured.
--*/
{
INTN FileSize;
INTN Offset;
INTN Length;
UINT8 Buffer[BUF_SIZE];
fseek (FpIn, 0, SEEK_END);
FileSize = ftell (FpIn);
fseek (FpIn, 0, SEEK_SET);
fseek (FpOut, 0, SEEK_SET);
Offset = 0;
while (Offset < FileSize) {
Length = sizeof (Buffer);
if (FileSize - Offset < Length) {
Length = FileSize - Offset;
}
if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) {
Error (NULL, 0, 0, "Copy file error", NULL);
return STATUS_ERROR;
}
Offset += Length;
}
return STATUS_SUCCESS;
}

View File

@ -0,0 +1,146 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
SecFixup.h
Abstract:
Definitions for the SecFixup utility.
--*/
#ifndef _SEC_FIXUP_H
#define _SEC_FIXUP_H
//
// Utility Name
//
#define UTILITY_NAME "SecFixup"
//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 1
#define UTILITY_DATE __DATE__
//
// The maximum number of arguments accepted from the command line.
//
#define MAX_ARGS 4
#define DEST_REL_OFFSET 13
#define BUF_SIZE (8 * 1024)
//
// The function that displays general utility information
//
VOID
PrintUtilityInfo (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
//
// The function that displays the utility usage message.
//
VOID
PrintUsage (
VOID
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
None
Returns:
GC_TODO: add return values
--*/
;
//
// The function that gets the entry point of a PE/TE file.
//
STATUS
GetEntryPoint (
IN FILE *ExeFile,
OUT UINT32 *EntryPoint
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
ExeFile - GC_TODO: add argument description
EntryPoint - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
//
// The function that copies a file.
//
STATUS
CopyFile (
FILE *FpIn,
FILE *FpOut
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
FpIn - GC_TODO: add argument description
FpOut - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
#endif

View File

@ -0,0 +1,70 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Define some macros we use here. Should get rid of them someday and
# get rid of the extra level of indirection.
#
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
#
# Common information
#
INC=$(INC)
#
# Target specific information
#
TARGET_NAME=SplitFile
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\SplitFile.c"
TARGET_EXE_INCLUDE =
#
# Build targets
#
all: $(TARGET_EXE)
#
# Build EXE
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,131 @@
/*
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
*/
// GC_TODO: fix comment to start with /*++
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
void
helpmsg (
void
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Returns:
GC_TODO: add return values
--*/
{
printf (
"SplitFile Filename Offset\n"" Filename = Input file to split\n"" Offset = offset at which to split file\n"
"\n\n""SplitFile will break a file in two pieces at the requested offset\n"
" outputting Filename1 and Filename2\n"
);
}
int
main (
int argc,
char*argv[]
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
argc - GC_TODO: add argument description
] - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
FILE *In;
FILE *Out1;
FILE *Out2;
char OutName1[512];
char OutName2[512];
unsigned long Index;
unsigned long splitpoint;
char CharC;
if (argc != 3) {
helpmsg ();
return -1;
}
In = fopen (argv[1], "rb");
if (In == NULL) {
printf ("Unable to open file \"%s\"\n", argv[1]);
return -1;
}
strncpy (OutName1, argv[1], 510);
strncpy (OutName2, argv[1], 510);
strcat (OutName1, "1");
strcat (OutName2, "2");
Out1 = fopen (OutName1, "wb");
if (Out1 == NULL) {
printf ("Unable to open file \"%s\"\n", OutName1);
return -1;
}
Out2 = fopen (OutName2, "wb");
if (Out2 == NULL) {
printf ("Unable to open file \"%s\"\n", OutName2);
return -1;
}
splitpoint = atoi (argv[2]);
for (Index = 0; Index < splitpoint; Index++) {
CharC = (char) fgetc (In);
if (feof (In)) {
break;
}
fputc (CharC, Out1);
}
for (;;) {
CharC = (char) fgetc (In);
if (feof (In)) {
break;
}
fputc (CharC, Out2);
}
fclose (In);
fclose (Out1);
fclose (Out2);
return 0;
}

View File

@ -0,0 +1,70 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation. All rights reserved.
#
# This software and associated documentation (if any) is furnished under
# a license and may only be used or copied in accordance with the terms
# of the license. Except as permitted by such license, no part of this
# software or documentation may be reproduced, stored in a retrieval
# system, or transmitted in any form or by any means without the express
# written consent of Intel Corporation.
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Define some macros we use here. Should get rid of them someday and
# get rid of the extra level of indirection.
#
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
#
# Common information
#
INC=$(INC)
#
# Target specific information
#
TARGET_NAME=Strip
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\Strip.c"
TARGET_EXE_INCLUDE =
#
# Build targets
#
all: $(TARGET_EXE)
#
# Build EXE
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL

View File

@ -0,0 +1,105 @@
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Strip.c
Abstract:
Quick Exe2Bin equivalent.
--*/
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <malloc.h>
int
main (
int argc,
char *argv[]
)
/*++
Routine Description:
Converts executable files to binary files.
Arguments:
argc - Number of command line arguments
argv[] - Array of pointers to the command line arguments
Returns:
Zero - Function completed successfully.
Non-zero - Function exited with errors.
--*/
{
FILE *InFile;
FILE *OutFile;
int Index;
int FileSize;
char *Buffer;
char *Ptrx;
if (argc < 3) {
printf ("Need more args, such as file name to convert and output name\n");
return -1;
}
InFile = fopen (argv[1], "rb");
OutFile = fopen (argv[2], "wb");
if (!InFile) {
printf ("no file, exit\n");
return -1;
}
if (OutFile == NULL) {
printf ("Unable to open output file.\n");
return -1;
}
fseek (InFile, 0, SEEK_END);
FileSize = ftell (InFile);
if (FileSize < 0x200) {
printf ("%d is not a legal size, exit\n", FileSize);
return -1;
}
fseek (InFile, 0, SEEK_SET);
Buffer = malloc (FileSize);
if (Buffer == NULL) {
printf ("Error: Out of resources.\n");
return -1;
}
fread (Buffer, 1, FileSize, InFile);
Ptrx = Buffer + 0x200;
Index = FileSize - 0x200;
fwrite (Ptrx, Index, 1, OutFile);
fclose (InFile);
fclose (OutFile);
free (Buffer);
return 0;
}

View File

@ -0,0 +1,63 @@
#/*++
#
# Copyright (c) 2001 Intel Corporation
#
# Module Name: makefile
#
# Abstract:
#
# This file is used to build the EFI utility.
#
#--*/
#
# Do this if you want to compile from this directory
#
!IFNDEF TOOLCHAIN
TOOLCHAIN = TOOLCHAIN_MSVC
!ENDIF
!INCLUDE PlatformTools.env
#
# Define some macros we use here. Should get rid of them someday and
# get rid of the extra level of indirection.
#
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
#
# Common information
#
INC=$(INC)
#
# Target specific information
#
TARGET_NAME=ZeroDebugData
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\ZeroDebugData.c"
TARGET_EXE_INCLUDE =
#
# Build targets
#
all: $(TARGET_EXE)
#
# Build EXE
#
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE)
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
clean:
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).*

View File

@ -0,0 +1,390 @@
/*++
Copyright (c) 2001 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
ZeroDebugData.c
Abstract:
Zero the Debug Data Fields of Portable Executable (PE) format file.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
void
PrintUsage (
void
)
/*++
Routine Description:
print usage of ZeroDebugData command
Arguments:
None
Returns:
None
--*/
// GC_TODO: void - add argument and description to function comment
{
//
// print usage of command
//
printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");
}
int
ReadFromFile (
FILE *fp,
long offset,
void *buffer,
int size
)
/*++
Routine Description:
read data from a specified location of file
Arguments:
fp - file pointer
offset - number of bytes from beginning of file
buffer - buffer used to store data
size - size of buffer
Returns:
= 0 - Success
= -1 - Failed
--*/
{
//
// set file pointer to the specified location of file
//
if (fseek (fp, offset, SEEK_SET) != 0) {
printf ("Error: Cannot move the current location of the file.\n");
return -1;
}
//
// read data from the file
//
if (fread (buffer, size, 1, fp) != 1) {
printf ("Error: Cannot read data from the file.\n");
return -1;
}
return 0;
}
int
ZeroDebugData (
FILE *fp,
FILE *fpData
)
/*++
Routine Description:
Zero the debug data fields of the file
Arguments:
fp - file pointer
fpData - pointer to output file that ZeroDebugData progress is written to
Returns:
= 0 - Success
= -1 - Failed
--*/
{
unsigned char header[4];
unsigned long offset;
unsigned long NumberOfRvaAndSizes;
unsigned int nvalue;
unsigned long lvalue;
unsigned long Size;
unsigned long Pointer;
unsigned char *Buffer;
unsigned long Index;
//
// read the header of file
//
if (ReadFromFile (fp, 0, header, 2) != 0) {
printf ("Error: open image file\n");
return -1;
}
//
// "MZ" -- the header of image file (PE)
//
if (strncmp ((char *) header, "MZ", 2) != 0) {
printf ("Error: Invalid Image file.\n");
return -1;
}
//
// At location 0x3C, the stub has the file offset to the
// PE signature.
//
if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {
return -1;
}
//
// read the header of optional
//
if (ReadFromFile (fp, offset, header, 4) != 0) {
return -1;
}
//
// "PE\0\0" -- the signature of optional header
//
if (strncmp ((char *) header, "PE\0\0", 4) != 0) {
printf ("Error: Invalid PE format file.\n");
return -1;
}
//
// Add 16 to skip COFF file header, and get to optional header.
//
offset += 24;
//
// Check the magic field, 0x10B for PE32 and 0x20B for PE32+
//
if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {
return -1;
}
//
// If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.
// Else it is 108.
//
switch (nvalue & 0xFFFF) {
case 0x10B:
offset += 92;
printf ("Info: Image is PE32. ");
break;
case 0x20B:
offset += 108;
printf ("Info: Image is PE32+. ");
break;
default:
printf ("Error: Magic value is unknown.\n");
return -1;
}
//
// get the value of NumberOfRvaAndSizes
//
if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {
printf ("Error: read NumberOfRvaAndSizes error.\n");
return -1;
}
//
// printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes);
//
//
// Finding Debug Table, offset of Debug Table
// is 4 + 6 * 8 = 52.
//
if (NumberOfRvaAndSizes >= 7) {
if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {
return -1;
}
//
// Read the SizeOfData(16) and PointerToRawData(24)
//
if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) {
printf ("error: Size = %d\n", Size);
return -1;
}
printf ("Debug data: size = %xh, ", Size);
fprintf (fpData, "Debug data: size = %xh, ", Size);
if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) {
printf ("error: LoadOffset = %xh\n", Pointer);
return -1;
}
//
// printf ("LoadOffset = %xh, ", Pointer);
//
fprintf (fpData, "LoadOffset = %xh, ", Pointer);
if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) {
printf ("error: FileOffset = %xh\n", Pointer);
return -1;
}
printf ("FileOffset = %xh, ", Pointer);
fprintf (fpData, "FileOffset = %xh, \n", Pointer);
if ((lvalue != 0) && (Pointer != 0)) {
//
// prepare buffer
//
Buffer = malloc (Size + 1);
if (Buffer == NULL) {
printf ("Error: Cannot allocate memory.\n");
return -1;
}
//
// set file pointer to the specified location of file
//
if (fseek (fp, Pointer, SEEK_SET) != 0) {
printf ("Error: Cannot move the current location of the file.\n");
free (Buffer);
return -1;
}
//
// read data from PE file
//
if (fread (Buffer, Size, 1, fp) != 1) {
printf ("Error: Cannot read data from the file.\n");
free (Buffer);
return -1;
}
//
// write to data file
//
for (Index = 0; Index < Size;) {
fprintf (fpData, "%02x ", Buffer[Index]);
Index++;
if (Index % 8 == 0) {
fprintf (fpData, "\n");
}
}
fprintf (fpData, "\n");
//
// zero buffer and write back to PE file
//
if (fseek (fp, Pointer, SEEK_SET) != 0) {
printf ("Error: Cannot move the current location of the file.\n");
free (Buffer);
return -1;
}
memset (Buffer, 0, Size);
if (fwrite (Buffer, Size, 1, fp) != 1) {
perror ("Error: Cannot write zero to the file.\n");
free (Buffer);
return -1;
}
//
// set file pointer to the specified location of file
//
if (fseek (fp, lvalue + 4, SEEK_SET) != 0) {
printf ("Error: Cannot move the current location of the file.\n");
free (Buffer);
return -1;
}
if (fwrite (Buffer, 4, 1, fp) != 1) {
perror ("Error: Cannot write zero to the file.\n");
free (Buffer);
return -1;
}
free (Buffer);
}
}
return 0;
}
int
main (
int argc,
char *argv[]
)
/*++
Routine Description:
Prints the zero debug data of the PE file to the DebugData file.
Executes the ZeroDebugData function.
Arguments:
argc - Standard C argument, number of command line arguments.
argv[] - Standard C argument, array of pointers to the input files,
such as the PE and DebugData files.
Returns:
zero - success
nonzero - failure
--*/
{
FILE *fp;
FILE *fpData;
char DataFile[1024] = "";
//
// check the number of parameters
//
if (argc < 2) {
printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");
return -1;
}
//
// open the DebugData file, if not exists, return
//
if (argc >= 3) {
strcpy (DataFile, argv[2]);
} else {
strcpy (DataFile, "DebugData.dat");
}
fpData = fopen (DataFile, "a+");
if (fpData == NULL) {
fpData = fopen (DataFile, "w");
if (fpData == NULL) {
printf ("Error: Cannot open the data file!\n");
return -1;
}
}
//
// open the PE file
//
fp = fopen (argv[1], "r+b");
if (fp == NULL) {
printf ("Error: Cannot open the PE file!\n");
return -1;
}
//
// Zero the Debug Data to the PE file
//
printf ("Zero Debug Data to file %s:\n", argv[1]);
fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]);
if ((int *) ZeroDebugData (fp, fpData) != 0) {
printf ("Error: Zero Debug Data PE file\n");
fclose (fp);
return -1;
}
printf (" success\n");
//
// close the PE file
//
fflush (fpData);
fflush (fp);
fclose (fpData);
fclose (fp);
return 0;
}