mirror of https://github.com/acidanthera/audk.git
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:
parent
291a871a27
commit
d25c4bf080
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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_
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
@ -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:
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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";
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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).*
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue