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:
246
Tools/Source/TianoTools/CreateMtFile/CreateMtFile.c
Normal file
246
Tools/Source/TianoTools/CreateMtFile/CreateMtFile.c
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
CreateMtFile.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Simple utility to create a pad file containing fixed data.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
|
||||||
|
#define PROGRAM_NAME "CreateMtFile"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
INT8 *OutFileName;
|
||||||
|
INT8 ByteValue;
|
||||||
|
UINT32 FileSize;
|
||||||
|
} OPTIONS;
|
||||||
|
|
||||||
|
static
|
||||||
|
EFI_STATUS
|
||||||
|
ProcessArgs (
|
||||||
|
IN INT32 Argc,
|
||||||
|
IN INT8 *Argv[],
|
||||||
|
IN OUT OPTIONS *Options
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
IN INT32 Argc,
|
||||||
|
IN INT8 *Argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Main entry point for this utility.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Standard C entry point args Argc and Argv
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS if good to go
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
||||||
|
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
|
||||||
|
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *OutFptr;
|
||||||
|
OPTIONS Options;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process the command-line arguments.
|
||||||
|
//
|
||||||
|
if (ProcessArgs (Argc, Argv, &Options) != EFI_SUCCESS) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the output file
|
||||||
|
//
|
||||||
|
if ((OutFptr = fopen (Options.OutFileName, "wb")) == NULL) {
|
||||||
|
fprintf (
|
||||||
|
stdout,
|
||||||
|
PROGRAM_NAME " ERROR: Could not open output file '%s' for writing\n",
|
||||||
|
Options.OutFileName
|
||||||
|
);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Write the pad bytes. Do it the slow way (one at a time) for now.
|
||||||
|
//
|
||||||
|
while (Options.FileSize > 0) {
|
||||||
|
if (fwrite (&Options.ByteValue, 1, 1, OutFptr) != 1) {
|
||||||
|
fclose (OutFptr);
|
||||||
|
fprintf (stdout, PROGRAM_NAME " ERROR: Failed to write to output file\n");
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Options.FileSize--;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the file
|
||||||
|
//
|
||||||
|
fclose (OutFptr);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
EFI_STATUS
|
||||||
|
ProcessArgs (
|
||||||
|
IN INT32 Argc,
|
||||||
|
IN INT8 *Argv[],
|
||||||
|
IN OUT OPTIONS *Options
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Process the command line arguments.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argc - argument count as passed in to the entry point function
|
||||||
|
Argv - array of arguments as passed in to the entry point function
|
||||||
|
Options - stucture of where to put the values of the parsed arguments
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS if everything looks good
|
||||||
|
EFI_INVALID_PARAMETER otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
{
|
||||||
|
UINT32 Multiplier;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear the options
|
||||||
|
//
|
||||||
|
memset ((char *) Options, 0, sizeof (OPTIONS));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Skip program name
|
||||||
|
//
|
||||||
|
Argv++;
|
||||||
|
Argc--;
|
||||||
|
if (Argc < 2) {
|
||||||
|
Usage ();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If first arg is dash-option, then print usage.
|
||||||
|
//
|
||||||
|
if (Argv[0][0] == '-') {
|
||||||
|
Usage ();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// First arg is file name
|
||||||
|
//
|
||||||
|
Options->OutFileName = Argv[0];
|
||||||
|
Argc--;
|
||||||
|
Argv++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Second arg is file size. Allow 0x1000, 0x100K, 1024, 1K
|
||||||
|
//
|
||||||
|
Multiplier = 1;
|
||||||
|
if ((Argv[0][strlen (Argv[0]) - 1] == 'k') || (Argv[0][strlen (Argv[0]) - 1] == 'K')) {
|
||||||
|
Multiplier = 1024;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Look for 0x prefix on file size
|
||||||
|
//
|
||||||
|
if ((Argv[0][0] == '0') && ((Argv[0][1] == 'x') || (Argv[0][1] == 'X'))) {
|
||||||
|
if (sscanf (Argv[0], "%x", &Options->FileSize) != 1) {
|
||||||
|
fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);
|
||||||
|
Usage ();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Otherwise must be a decimal number
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
if (sscanf (Argv[0], "%d", &Options->FileSize) != 1) {
|
||||||
|
fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]);
|
||||||
|
Usage ();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Options->FileSize *= Multiplier;
|
||||||
|
//
|
||||||
|
// Assume byte value of 0xff
|
||||||
|
//
|
||||||
|
Options->ByteValue = (INT8) (UINT8) 0xFF;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Print utility usage info
|
||||||
|
//
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT32 Index;
|
||||||
|
static const INT8 *Text[] = {
|
||||||
|
" ",
|
||||||
|
"Usage: "PROGRAM_NAME " OutFileName FileSize",
|
||||||
|
" where:",
|
||||||
|
" OutFileName is the name of the output file to generate",
|
||||||
|
" FileSize is the size of the file to create",
|
||||||
|
" Examples:",
|
||||||
|
" "PROGRAM_NAME " OutFile.bin 32K",
|
||||||
|
" "PROGRAM_NAME " OutFile.bin 0x1000",
|
||||||
|
" ",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Index = 0; Text[Index] != NULL; Index++) {
|
||||||
|
fprintf (stdout, "%s\n", Text[Index]);
|
||||||
|
}
|
||||||
|
}
|
67
Tools/Source/TianoTools/CreateMtFile/Makefile
Normal file
67
Tools/Source/TianoTools/CreateMtFile/Makefile
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 1999 - 2001 Intel Corporation. All rights reserved
|
||||||
|
# This software and associated documentation (if any) is furnished
|
||||||
|
# under a license and may only be used or copied in accordance
|
||||||
|
# with the terms of the license. Except as permitted by such
|
||||||
|
# license, no part of this software or documentation may be
|
||||||
|
# reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
# form or by any means without the express written consent of
|
||||||
|
# Intel Corporation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# Makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the CreateMtFile utility.
|
||||||
|
#
|
||||||
|
# Revision History
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define the toolchain which is used to set build options and toolchain paths
|
||||||
|
#
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = CreateMtFile
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the EXE by compiling the source files, then linking the resultant
|
||||||
|
# object files together.
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\CreateMtFile.obj : $(TARGET_SRC_DIR)\CreateMtFile.c
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\CreateMtFile.c /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
163
Tools/Source/TianoTools/EfiCompress/EfiCompressMain.c
Normal file
163
Tools/Source/TianoTools/EfiCompress/EfiCompressMain.c
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
EfiCompressMain.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
The main function for the compression utility.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
#include "EfiCompress.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
INT32 argc,
|
||||||
|
CHAR8 *argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Compresses the input files
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - number of arguments passed into the command line.
|
||||||
|
argv[] - files to compress and files to output compressed data to.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
int: 0 for successful execution of the function.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
FILE *infile;
|
||||||
|
FILE *outfile;
|
||||||
|
UINT32 SrcSize;
|
||||||
|
UINT32 DstSize;
|
||||||
|
UINT8 *SrcBuffer;
|
||||||
|
UINT8 *DstBuffer;
|
||||||
|
UINT8 Buffer[8];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Added for makefile debug - KCE
|
||||||
|
//
|
||||||
|
INT32 arg_counter;
|
||||||
|
printf ("\n\n");
|
||||||
|
for (arg_counter = 0; arg_counter < argc; arg_counter++) {
|
||||||
|
printf ("%s ", argv[arg_counter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("\n\n");
|
||||||
|
|
||||||
|
SrcBuffer = DstBuffer = NULL;
|
||||||
|
|
||||||
|
infile = outfile = NULL;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
printf ("Usage: EFICOMPRESS <infile> <outfile>\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((outfile = fopen (argv[2], "wb")) == NULL) {
|
||||||
|
printf ("Can't open output file\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((infile = fopen (argv[1], "rb")) == NULL) {
|
||||||
|
printf ("Can't open input file\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the size of source file
|
||||||
|
//
|
||||||
|
SrcSize = 0;
|
||||||
|
while (fread (Buffer, 1, 1, infile)) {
|
||||||
|
SrcSize++;
|
||||||
|
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read in the source data
|
||||||
|
//
|
||||||
|
if ((SrcBuffer = malloc (SrcSize)) == NULL) {
|
||||||
|
printf ("Can't allocate memory\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind (infile);
|
||||||
|
if (fread (SrcBuffer, 1, SrcSize, infile) != SrcSize) {
|
||||||
|
printf ("Can't read from source\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get destination data size and do the compression
|
||||||
|
//
|
||||||
|
DstSize = 0;
|
||||||
|
Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
if ((DstBuffer = malloc (DstSize)) == NULL) {
|
||||||
|
printf ("Can't allocate memory\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
printf ("Compress Error\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("\nOrig Size = %ld\n", SrcSize);
|
||||||
|
printf ("Comp Size = %ld\n", DstSize);
|
||||||
|
|
||||||
|
if (DstBuffer == NULL) {
|
||||||
|
printf ("No destination to write to.\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Write out the result
|
||||||
|
//
|
||||||
|
if (fwrite (DstBuffer, 1, DstSize, outfile) != DstSize) {
|
||||||
|
printf ("Can't write to destination file\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (SrcBuffer) {
|
||||||
|
free (SrcBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DstBuffer) {
|
||||||
|
free (DstBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infile) {
|
||||||
|
fclose (infile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outfile) {
|
||||||
|
fclose (outfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
77
Tools/Source/TianoTools/EfiCompress/makefile
Normal file
77
Tools/Source/TianoTools/EfiCompress/makefile
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define some macros we use here. Should get rid of them someday and
|
||||||
|
# get rid of the extra level of indirection.
|
||||||
|
#
|
||||||
|
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUGBUG: Override standard flags, cannot be built without warnings.
|
||||||
|
#
|
||||||
|
|
||||||
|
C_FLAGS=/nologo /W4 /GX /Zi /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common information
|
||||||
|
#
|
||||||
|
|
||||||
|
INC=$(INC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME=EfiCompress
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\EfiCompressMain.c"
|
||||||
|
TARGET_EXE_INCLUDE = "$(COMMON_SOURCE)\EfiCompress.h"
|
||||||
|
TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\EfiCompressMain.obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Main.* > NUL
|
1543
Tools/Source/TianoTools/EfiRom/EfiRom.c
Normal file
1543
Tools/Source/TianoTools/EfiRom/EfiRom.c
Normal file
File diff suppressed because it is too large
Load Diff
70
Tools/Source/TianoTools/EfiRom/Makefile
Normal file
70
Tools/Source/TianoTools/EfiRom/Makefile
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the EfiRom utility.
|
||||||
|
#
|
||||||
|
# Revision History
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define the toolchain which is used to set build options and toolchain paths
|
||||||
|
#
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = EfiRom
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\EfiRom.exe
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\EfiRom.obj \
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\EfiCompress.obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the EXE by compiling the source files, then linking the resultant
|
||||||
|
# object files together.
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\EfiRom.obj : $(TARGET_SRC_DIR)\EfiRom.c
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\EfiRom.c /Fo$@
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\EfiCompress.obj : $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c
|
||||||
|
$(CC) $(C_FLAGS) $(EDK_TOOLS_SOURCE)\Common\EfiCompress.c /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
2787
Tools/Source/TianoTools/FlashMap/FlashDefFile.c
Normal file
2787
Tools/Source/TianoTools/FlashMap/FlashDefFile.c
Normal file
File diff suppressed because it is too large
Load Diff
281
Tools/Source/TianoTools/FlashMap/FlashDefFile.h
Normal file
281
Tools/Source/TianoTools/FlashMap/FlashDefFile.h
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
FlashDefFile.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Header file for flash management utility in the Intel Platform
|
||||||
|
Innovation Framework for EFI build environment.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _FLASH_DEF_FILE_H_
|
||||||
|
#define _FLASH_DEF_FILE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
FDFConstructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
void
|
||||||
|
FDFDestructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFParseFile (
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateCIncludeFile (
|
||||||
|
char *FlashDeviceName,
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateCFlashMapDataFile (
|
||||||
|
char *FlashDeviceName,
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateAsmIncludeFile (
|
||||||
|
char *FlashDeviceName,
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFParseFile (
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateImage (
|
||||||
|
char *FlashDeviceName,
|
||||||
|
char *ImageName,
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
ImageName - GC_TODO: add argument description
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateDscFile (
|
||||||
|
char *FlashDeviceName,
|
||||||
|
char *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDFCreateSymbols (
|
||||||
|
char *FlashDeviceName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FlashDeviceName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
FDDiscover (
|
||||||
|
char *FDFileName,
|
||||||
|
unsigned int BaseAddr
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FDFileName - GC_TODO: add argument description
|
||||||
|
BaseAddr - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef _FLASH_DEF_FILE_H_
|
745
Tools/Source/TianoTools/FlashMap/FlashMap.c
Normal file
745
Tools/Source/TianoTools/FlashMap/FlashMap.c
Normal file
@ -0,0 +1,745 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004-2005 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
FlashMap.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Utility for flash management in the Intel Platform Innovation Framework
|
||||||
|
for EFI build environment.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "Tiano.h"
|
||||||
|
|
||||||
|
#ifndef INT8
|
||||||
|
#define INT8 char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
#include "Microcode.h"
|
||||||
|
#include "FlashDefFile.h"
|
||||||
|
#include "Symbols.h"
|
||||||
|
|
||||||
|
#define UTILITY_NAME "FlashMap"
|
||||||
|
|
||||||
|
typedef struct _STRING_LIST {
|
||||||
|
struct _STRING_LIST *Next;
|
||||||
|
char *Str;
|
||||||
|
} STRING_LIST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Keep our globals in one of these structures
|
||||||
|
//
|
||||||
|
static struct {
|
||||||
|
char *CIncludeFileName;
|
||||||
|
char *FlashDevice;
|
||||||
|
char *FlashDeviceImage;
|
||||||
|
char *MCIFileName;
|
||||||
|
char *MCOFileName;
|
||||||
|
char *ImageOutFileName;
|
||||||
|
char *DscFileName;
|
||||||
|
char *AsmIncludeFileName;
|
||||||
|
char *FlashDefinitionFileName;
|
||||||
|
char *StringReplaceInFileName;
|
||||||
|
char *StringReplaceOutFileName;
|
||||||
|
char *DiscoverFDImageName;
|
||||||
|
char MicrocodePadByteValue;
|
||||||
|
unsigned int MicrocodeAlignment;
|
||||||
|
STRING_LIST *MCIFileNames;
|
||||||
|
STRING_LIST *LastMCIFileNames;
|
||||||
|
unsigned int BaseAddress;
|
||||||
|
} mGlobals;
|
||||||
|
|
||||||
|
#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF
|
||||||
|
#define DEFAULT_MC_ALIGNMENT 16
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessCommandLine (
|
||||||
|
int argc,
|
||||||
|
char *argv[]
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
MergeMicrocodeFiles (
|
||||||
|
char *OutFileName,
|
||||||
|
STRING_LIST *FileNames,
|
||||||
|
unsigned int Alignment,
|
||||||
|
char PadByteValue
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
int argc,
|
||||||
|
char *argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Parse the command line arguments and then call worker functions to do the work
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
argc - number of elements in argv
|
||||||
|
argv - array of command-line arguments
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - no problems encountered while processing
|
||||||
|
STATUS_WARNING - warnings, but no errors, were encountered while processing
|
||||||
|
STATUS_ERROR - errors were encountered while processing
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
STATUS Status;
|
||||||
|
|
||||||
|
SetUtilityName (UTILITY_NAME);
|
||||||
|
Status = ProcessCommandLine (argc, argv);
|
||||||
|
if (Status != STATUS_SUCCESS) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check for discovery of an FD (command line option)
|
||||||
|
//
|
||||||
|
if (mGlobals.DiscoverFDImageName != NULL) {
|
||||||
|
Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they're doing microcode file parsing, then do that
|
||||||
|
//
|
||||||
|
if (mGlobals.MCIFileName != NULL) {
|
||||||
|
MicrocodeConstructor ();
|
||||||
|
MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName);
|
||||||
|
MicrocodeDestructor ();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they're doing microcode file merging, then do that now
|
||||||
|
//
|
||||||
|
if (mGlobals.MCIFileNames != NULL) {
|
||||||
|
MergeMicrocodeFiles (
|
||||||
|
mGlobals.MCOFileName,
|
||||||
|
mGlobals.MCIFileNames,
|
||||||
|
mGlobals.MicrocodeAlignment,
|
||||||
|
mGlobals.MicrocodePadByteValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If using a flash definition file, then process that and return
|
||||||
|
//
|
||||||
|
if (mGlobals.FlashDefinitionFileName != NULL) {
|
||||||
|
FDFConstructor ();
|
||||||
|
SymbolsConstructor ();
|
||||||
|
Status = FDFParseFile (mGlobals.FlashDefinitionFileName);
|
||||||
|
if (GetUtilityStatus () != STATUS_ERROR) {
|
||||||
|
//
|
||||||
|
// If they want us to do a string-replace on a file, then add the symbol definitions to
|
||||||
|
// the symbol table, and then do the string replace.
|
||||||
|
//
|
||||||
|
if (mGlobals.StringReplaceInFileName != NULL) {
|
||||||
|
Status = FDFCreateSymbols (mGlobals.FlashDevice);
|
||||||
|
Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want us to create a .h defines file or .c flashmap data file, then do so now
|
||||||
|
//
|
||||||
|
if (mGlobals.CIncludeFileName != NULL) {
|
||||||
|
Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName);
|
||||||
|
}
|
||||||
|
if (mGlobals.AsmIncludeFileName != NULL) {
|
||||||
|
Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want us to create an image, do that now
|
||||||
|
//
|
||||||
|
if (mGlobals.ImageOutFileName != NULL) {
|
||||||
|
Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want to create an output DSC file, do that now
|
||||||
|
//
|
||||||
|
if (mGlobals.DscFileName != NULL) {
|
||||||
|
Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SymbolsDestructor ();
|
||||||
|
FDFDestructor ();
|
||||||
|
}
|
||||||
|
Done:
|
||||||
|
//
|
||||||
|
// Free up memory
|
||||||
|
//
|
||||||
|
while (mGlobals.MCIFileNames != NULL) {
|
||||||
|
mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next;
|
||||||
|
_free (mGlobals.MCIFileNames);
|
||||||
|
mGlobals.MCIFileNames = mGlobals.LastMCIFileNames;
|
||||||
|
}
|
||||||
|
return GetUtilityStatus ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
MergeMicrocodeFiles (
|
||||||
|
char *OutFileName,
|
||||||
|
STRING_LIST *FileNames,
|
||||||
|
unsigned int Alignment,
|
||||||
|
char PadByteValue
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Merge binary microcode files into a single file, taking into consideration
|
||||||
|
the alignment and pad value.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
OutFileName - name of the output file to create
|
||||||
|
FileNames - linked list of input microcode files to merge
|
||||||
|
Alignment - alignment for each microcode file in the output image
|
||||||
|
PadByteValue - value to use when padding to meet alignment requirements
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS - merge completed successfully or with acceptable warnings
|
||||||
|
STATUS_ERROR - merge failed, output file not created
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
long FileSize;
|
||||||
|
long TotalFileSize;
|
||||||
|
FILE *InFptr;
|
||||||
|
FILE *OutFptr;
|
||||||
|
char *Buffer;
|
||||||
|
STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open the output file
|
||||||
|
//
|
||||||
|
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Walk the list of files
|
||||||
|
//
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
Buffer = NULL;
|
||||||
|
InFptr = NULL;
|
||||||
|
TotalFileSize = 0;
|
||||||
|
while (FileNames != NULL) {
|
||||||
|
//
|
||||||
|
// Open the file, determine the size, then read it in and write
|
||||||
|
// it back out.
|
||||||
|
//
|
||||||
|
if ((InFptr = fopen (FileNames->Str, "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, FileNames->Str, "failed to open input file for reading");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
fseek (InFptr, 0, SEEK_END);
|
||||||
|
FileSize = ftell (InFptr);
|
||||||
|
fseek (InFptr, 0, SEEK_SET);
|
||||||
|
if (FileSize != 0) {
|
||||||
|
Buffer = (char *) _malloc (FileSize);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
Error (NULL, 0, 0, "memory allocation failure", NULL);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (fread (Buffer, FileSize, 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileNames->Str, "failed to read file contents");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Align
|
||||||
|
//
|
||||||
|
if (Alignment != 0) {
|
||||||
|
while ((TotalFileSize % Alignment) != 0) {
|
||||||
|
if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
TotalFileSize++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TotalFileSize += FileSize;
|
||||||
|
if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to write to output file");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
_free (Buffer);
|
||||||
|
Buffer = NULL;
|
||||||
|
} else {
|
||||||
|
Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered");
|
||||||
|
}
|
||||||
|
fclose (InFptr);
|
||||||
|
InFptr = NULL;
|
||||||
|
FileNames = FileNames->Next;
|
||||||
|
}
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Done:
|
||||||
|
fclose (OutFptr);
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
if (Buffer != NULL) {
|
||||||
|
_free (Buffer);
|
||||||
|
}
|
||||||
|
if (Status == STATUS_ERROR) {
|
||||||
|
remove (OutFileName);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessCommandLine (
|
||||||
|
int argc,
|
||||||
|
char *argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Process the command line arguments
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
argc - Standard C entry point arguments
|
||||||
|
argv[] - Standard C entry point arguments
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - no problems encountered while processing
|
||||||
|
STATUS_WARNING - warnings, but no errors, were encountered while processing
|
||||||
|
STATUS_ERROR - errors were encountered while processing
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int ThingsToDo;
|
||||||
|
unsigned int Temp;
|
||||||
|
STRING_LIST *Str;
|
||||||
|
//
|
||||||
|
// Skip program name arg, process others
|
||||||
|
//
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (argc == 0) {
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Clear out our globals, then start walking the arguments
|
||||||
|
//
|
||||||
|
memset ((void *) &mGlobals, 0, sizeof (mGlobals));
|
||||||
|
mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE;
|
||||||
|
mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT;
|
||||||
|
ThingsToDo = 0;
|
||||||
|
while (argc > 0) {
|
||||||
|
if (strcmp (argv[0], "-?") == 0) {
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
} else if (strcmp (argv[0], "-hfile") == 0) {
|
||||||
|
//
|
||||||
|
// -hfile FileName
|
||||||
|
//
|
||||||
|
// Used to specify an output C #include file to create that contains
|
||||||
|
// #define statements for all the flashmap region offsets and sizes.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an output file name");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.CIncludeFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-flashdevice") == 0) {
|
||||||
|
//
|
||||||
|
// -flashdevice FLASH_DEVICE_NAME
|
||||||
|
//
|
||||||
|
// Used to select which flash device definition to operate on.
|
||||||
|
// Check for additional argument
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires a flash device name to use");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.FlashDevice = argv[0];
|
||||||
|
} else if (strcmp (argv[0], "-mco") == 0) {
|
||||||
|
//
|
||||||
|
// -mco OutFileName
|
||||||
|
//
|
||||||
|
// Used to specify a microcode output binary file to create.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.MCOFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-asmincfile") == 0) {
|
||||||
|
//
|
||||||
|
// -asmincfile FileName
|
||||||
|
//
|
||||||
|
// Used to specify the name of the output assembly include file that contains
|
||||||
|
// equates for the flash region addresses and sizes.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.AsmIncludeFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-mci") == 0) {
|
||||||
|
//
|
||||||
|
// -mci FileName
|
||||||
|
//
|
||||||
|
// Used to specify an input microcode text file to parse.
|
||||||
|
// Check for additional argument
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.MCIFileName = argv[0];
|
||||||
|
} else if (strcmp (argv[0], "-flashdeviceimage") == 0) {
|
||||||
|
//
|
||||||
|
// -flashdeviceimage FlashDeviceImage
|
||||||
|
//
|
||||||
|
// Used to specify which flash device image definition from the input flash definition file
|
||||||
|
// to create.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.FlashDeviceImage = argv[0];
|
||||||
|
} else if (strcmp (argv[0], "-imageout") == 0) {
|
||||||
|
//
|
||||||
|
// -imageout FileName
|
||||||
|
//
|
||||||
|
// Used to specify the name of the output FD image file to create.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an output image filename to create");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.ImageOutFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-dsc") == 0) {
|
||||||
|
//
|
||||||
|
// -dsc FileName
|
||||||
|
//
|
||||||
|
// Used to specify the name of the output DSC file to create.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.DscFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-fdf") == 0) {
|
||||||
|
//
|
||||||
|
// -fdf FileName
|
||||||
|
//
|
||||||
|
// Used to specify the name of the input flash definition file.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.FlashDefinitionFileName = argv[0];
|
||||||
|
} else if (strcmp (argv[0], "-discover") == 0) {
|
||||||
|
//
|
||||||
|
// -discover FDFileName
|
||||||
|
//
|
||||||
|
// Debug functionality used to scan an existing FD image, trying to find
|
||||||
|
// firmware volumes at 64K boundaries.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an input FD image file name");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.DiscoverFDImageName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else if (strcmp (argv[0], "-baseaddr") == 0) {
|
||||||
|
//
|
||||||
|
// -baseaddr Addr
|
||||||
|
//
|
||||||
|
// Used to specify a base address when doing a discover of an FD image.
|
||||||
|
// Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires a base address");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (tolower (argv[0][1]) == 'x') {
|
||||||
|
sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress);
|
||||||
|
} else {
|
||||||
|
sscanf (argv[0], "%d", &mGlobals.BaseAddress);
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[0], "-padvalue") == 0) {
|
||||||
|
//
|
||||||
|
// -padvalue Value
|
||||||
|
//
|
||||||
|
// Used to specify the value to pad with when aligning data while
|
||||||
|
// creating an FD image. Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires a byte value");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (tolower (argv[0][1]) == 'x') {
|
||||||
|
sscanf (argv[0] + 2, "%x", &Temp);
|
||||||
|
mGlobals.MicrocodePadByteValue = (char) Temp;
|
||||||
|
} else {
|
||||||
|
sscanf (argv[0], "%d", &Temp);
|
||||||
|
mGlobals.MicrocodePadByteValue = (char) Temp;
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[0], "-align") == 0) {
|
||||||
|
//
|
||||||
|
// -align Alignment
|
||||||
|
//
|
||||||
|
// Used to specify how each data file is aligned in the region
|
||||||
|
// when creating an FD image. Check for additional argument.
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires an alignment");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (tolower (argv[0][1]) == 'x') {
|
||||||
|
sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment);
|
||||||
|
} else {
|
||||||
|
sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment);
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[0], "-mcmerge") == 0) {
|
||||||
|
//
|
||||||
|
// -mcmerge FileName(s)
|
||||||
|
//
|
||||||
|
// Used to concatenate multiple microde binary files. Can specify
|
||||||
|
// multiple file names with the one -mcmerge flag. Check for additional argument.
|
||||||
|
//
|
||||||
|
if ((argc < 2) || (argv[1][0] == '-')) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires one or more input file names");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Take input files until another option or end of list
|
||||||
|
//
|
||||||
|
ThingsToDo++;
|
||||||
|
while ((argc > 1) && (argv[1][0] != '-')) {
|
||||||
|
Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST));
|
||||||
|
if (Str == NULL) {
|
||||||
|
Error (NULL, 0, 0, "memory allocation failure", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
memset (Str, 0, sizeof (STRING_LIST));
|
||||||
|
Str->Str = argv[1];
|
||||||
|
if (mGlobals.MCIFileNames == NULL) {
|
||||||
|
mGlobals.MCIFileNames = Str;
|
||||||
|
} else {
|
||||||
|
mGlobals.LastMCIFileNames->Next = Str;
|
||||||
|
}
|
||||||
|
mGlobals.LastMCIFileNames = Str;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[0], "-strsub") == 0) {
|
||||||
|
//
|
||||||
|
// -strsub SrcFile DestFile
|
||||||
|
//
|
||||||
|
// Used to perform string substitutions on a file, writing the result to a new
|
||||||
|
// file. Check for two additional arguments.
|
||||||
|
//
|
||||||
|
if (argc < 3) {
|
||||||
|
Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.StringReplaceInFileName = argv[0];
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
mGlobals.StringReplaceOutFileName = argv[0];
|
||||||
|
ThingsToDo++;
|
||||||
|
} else {
|
||||||
|
Error (NULL, 0, 0, argv[0], "invalid option");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If no outputs requested, then report an error
|
||||||
|
//
|
||||||
|
if (ThingsToDo == 0) {
|
||||||
|
Error (NULL, 0, 0, "nothing to do", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want an asm file, #include file, or C file to be created, then they have to specify a
|
||||||
|
// flash device name and flash definition file name.
|
||||||
|
//
|
||||||
|
if ((mGlobals.CIncludeFileName != NULL) &&
|
||||||
|
((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {
|
||||||
|
Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if ((mGlobals.AsmIncludeFileName != NULL) &&
|
||||||
|
((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) {
|
||||||
|
Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want a dsc file to be created, then they have to specify a
|
||||||
|
// flash device name and a flash definition file name
|
||||||
|
//
|
||||||
|
if (mGlobals.DscFileName != NULL) {
|
||||||
|
if (mGlobals.FlashDevice == NULL) {
|
||||||
|
Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (mGlobals.FlashDefinitionFileName == NULL) {
|
||||||
|
Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they specified an output microcode file name, then they have to specify an input
|
||||||
|
// file name, and vice versa.
|
||||||
|
//
|
||||||
|
if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) {
|
||||||
|
Error (NULL, 0, 0, "must specify output microcode file name", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) {
|
||||||
|
Error (NULL, 0, 0, "must specify input microcode file name", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If doing merge, then have to specify output file name
|
||||||
|
//
|
||||||
|
if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) {
|
||||||
|
Error (NULL, 0, 0, "must specify output microcode file name", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If they want an output image to be created, then they have to specify
|
||||||
|
// the flash device and the flash device image to use.
|
||||||
|
//
|
||||||
|
if (mGlobals.ImageOutFileName != NULL) {
|
||||||
|
if (mGlobals.FlashDevice == NULL) {
|
||||||
|
Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (mGlobals.FlashDeviceImage == NULL) {
|
||||||
|
Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (mGlobals.FlashDefinitionFileName == NULL) {
|
||||||
|
Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Print utility command line help
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
NA
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *Msg[] = {
|
||||||
|
"Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice",
|
||||||
|
" -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile",
|
||||||
|
" -discover FDImage -dsc DscFile -asmincfile AsmIncFile",
|
||||||
|
" -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile",
|
||||||
|
" -baseaddr BaseAddr -align Alignment -padvalue PadValue",
|
||||||
|
" -mcmerge MCIFile(s)",
|
||||||
|
" where",
|
||||||
|
" FlashDefFile - input Flash Definition File",
|
||||||
|
" FlashDevice - flash device to use (from flash definition file)",
|
||||||
|
" FlashDeviceImage - flash device image to use (from flash definition file)",
|
||||||
|
" MCIFile - input microcode file to parse",
|
||||||
|
" MCOFile - output binary microcode image to create from MCIFile",
|
||||||
|
" HFile - output #include file to create",
|
||||||
|
" FDImage - name of input FDImage file to scan",
|
||||||
|
" ImageOutFile - output image file to create",
|
||||||
|
" DscFile - output DSC file to create",
|
||||||
|
" AsmIncFile - output ASM include file to create",
|
||||||
|
" InStrFile - input file to replace symbol names, writing result to OutStrFile",
|
||||||
|
" BaseAddr - base address of FDImage (used with -discover)",
|
||||||
|
" Alignment - alignment to use when merging microcode binaries",
|
||||||
|
" PadValue - byte value to use as pad value when aligning microcode binaries",
|
||||||
|
" MCIFile(s) - one or more microcode binary files to merge/concatenate",
|
||||||
|
"",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
for (i = 0; Msg[i] != NULL; i++) {
|
||||||
|
fprintf (stdout, "%s\n", Msg[i]);
|
||||||
|
}
|
||||||
|
}
|
81
Tools/Source/TianoTools/FlashMap/Makefile
Normal file
81
Tools/Source/TianoTools/FlashMap/Makefile
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
# This software and associated documentation (if any) is furnished
|
||||||
|
# under a license and may only be used or copied in accordance
|
||||||
|
# with the terms of the license. Except as permitted by such
|
||||||
|
# license, no part of this software or documentation may be
|
||||||
|
# reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
# form or by any means without the express written consent of
|
||||||
|
# Intel Corporation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# Makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the FlashMap utility
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
INCLUDE_PATHS = -I $(TIANO_TOOLS_SOURCE)\Common
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
TARGET_NAME = FlashMap
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\FlashMap.exe
|
||||||
|
LIBS = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\FlashMap.obj \
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj \
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\Symbols.obj \
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\Microcode.obj
|
||||||
|
|
||||||
|
# $(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj
|
||||||
|
|
||||||
|
#C_FLAGS = $(C_FLAGS) /D TRACK_MALLOC_FREE
|
||||||
|
C_FLAGS = $(C_FLAGS) /D _malloc=malloc /D _free=free
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compile each source file
|
||||||
|
#
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\FlashMap.obj : $(TARGET_SRC_DIR)\FlashMap.c $(TARGET_SRC_DIR)\Symbols.h $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\FlashMap.c /Fo$@
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\Symbols.obj : $(TARGET_SRC_DIR)\Symbols.c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(INCLUDE_PATHS) $(TARGET_SRC_DIR)\Symbols.c /Fo$@
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\Microcode.obj : $(TARGET_SRC_DIR)\Microcode.c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\Microcode.c /Fo$@
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\FlashDefFile.obj : $(TARGET_SRC_DIR)\FlashDefFile.c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\FlashDefFile.c /Fo$@
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\TrackMallocFree.obj : $(TARGET_SRC_DIR)\TrackMallocFree.c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_SRC_DIR)\TrackMallocFree.c /Fo$@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Link the object files together to create the final executable
|
||||||
|
#
|
||||||
|
$(TARGET_EXE) : $(OBJECTS) $(LIBS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
306
Tools/Source/TianoTools/FlashMap/Microcode.c
Normal file
306
Tools/Source/TianoTools/FlashMap/Microcode.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Microcode.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Utility for working with microcode patch files in the Intel
|
||||||
|
Platform Innovation Framework for EFI build environment.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h> // for memset()
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h> // for malloc()
|
||||||
|
#define INT8 char
|
||||||
|
#define UINT32 unsigned int
|
||||||
|
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
#include "Microcode.h"
|
||||||
|
|
||||||
|
#define MAX_LINE_LEN 256
|
||||||
|
|
||||||
|
//
|
||||||
|
// Structure definition for a microcode header
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
unsigned int HeaderVersion;
|
||||||
|
unsigned int PatchId;
|
||||||
|
unsigned int Date;
|
||||||
|
unsigned int CpuId;
|
||||||
|
unsigned int Checksum;
|
||||||
|
unsigned int LoaderVersion;
|
||||||
|
unsigned int PlatformId;
|
||||||
|
unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid
|
||||||
|
unsigned int TotalSize; // number of bytes
|
||||||
|
unsigned int Reserved[3];
|
||||||
|
} MICROCODE_IMAGE_HEADER;
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
MicrocodeReadData (
|
||||||
|
FILE *InFptr,
|
||||||
|
unsigned int *Data
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
MicrocodeConstructor (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Constructor of module Microcode
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MicrocodeDestructor (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Destructor of module Microcode
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
MicrocodeReadData (
|
||||||
|
FILE *InFptr,
|
||||||
|
unsigned int *Data
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Read a 32-bit microcode data value from a text file and convert to raw binary form.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
InFptr - file pointer to input text file
|
||||||
|
Data - pointer to where to return the data parsed
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - no errors or warnings, Data contains valid information
|
||||||
|
STATUS_ERROR - errors were encountered
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
char Line[MAX_LINE_LEN];
|
||||||
|
char *cptr;
|
||||||
|
|
||||||
|
Line[MAX_LINE_LEN - 1] = 0;
|
||||||
|
*Data = 0;
|
||||||
|
if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If it was a binary file, then it may have overwritten our null terminator
|
||||||
|
//
|
||||||
|
if (Line[MAX_LINE_LEN - 1] != 0) {
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Look for
|
||||||
|
// dd 000000001h ; comment
|
||||||
|
// dd XXXXXXXX
|
||||||
|
// DD XXXXXXXXX
|
||||||
|
// DD XXXXXXXXX
|
||||||
|
//
|
||||||
|
for (cptr = Line; *cptr && isspace(*cptr); cptr++) {
|
||||||
|
}
|
||||||
|
if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {
|
||||||
|
//
|
||||||
|
// Skip blanks and look for a hex digit
|
||||||
|
//
|
||||||
|
cptr += 3;
|
||||||
|
for (; *cptr && isspace(*cptr); cptr++) {
|
||||||
|
}
|
||||||
|
if (isxdigit (*cptr)) {
|
||||||
|
if (sscanf (cptr, "%X", Data) != 1) {
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
MicrocodeParseFile (
|
||||||
|
char *InFileName,
|
||||||
|
char *OutFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Parse a microcode text file, and write the binary results to an output file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
InFileName - input text file to parse
|
||||||
|
OutFileName - output file to write raw binary data from parsed input file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - no errors or warnings
|
||||||
|
STATUS_ERROR - errors were encountered
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *InFptr;
|
||||||
|
FILE *OutFptr;
|
||||||
|
STATUS Status;
|
||||||
|
MICROCODE_IMAGE_HEADER *Header;
|
||||||
|
unsigned int Size;
|
||||||
|
unsigned int Size2;
|
||||||
|
unsigned int Data;
|
||||||
|
unsigned int Checksum;
|
||||||
|
char *Buffer;
|
||||||
|
char *Ptr;
|
||||||
|
unsigned int TotalSize;
|
||||||
|
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
InFptr = NULL;
|
||||||
|
OutFptr = NULL;
|
||||||
|
Buffer = NULL;
|
||||||
|
//
|
||||||
|
// Open the input text file
|
||||||
|
//
|
||||||
|
if ((InFptr = fopen (InFileName, "r")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make two passes on the input file. The first pass is to determine how
|
||||||
|
// much data is in the file so we can allocate a working buffer. Then
|
||||||
|
// we'll allocate a buffer and re-read the file into the buffer for processing.
|
||||||
|
//
|
||||||
|
Size = 0;
|
||||||
|
do {
|
||||||
|
Status = MicrocodeReadData (InFptr, &Data);
|
||||||
|
if (Status == STATUS_SUCCESS) {
|
||||||
|
Size += sizeof (Data);
|
||||||
|
}
|
||||||
|
} while (Status == STATUS_SUCCESS);
|
||||||
|
//
|
||||||
|
// Error if no data.
|
||||||
|
//
|
||||||
|
if (Size == 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "no parse-able data found in file");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (Size < sizeof (MICROCODE_IMAGE_HEADER)) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Allocate a buffer for the data
|
||||||
|
//
|
||||||
|
Buffer = (char *) _malloc (Size);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
Error (NULL, 0, 0, "memory allocation failure", NULL);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Re-read the file, storing the data into our buffer
|
||||||
|
//
|
||||||
|
fseek (InFptr, 0, SEEK_SET);
|
||||||
|
Ptr = Buffer;
|
||||||
|
do {
|
||||||
|
Status = MicrocodeReadData (InFptr, &Data);
|
||||||
|
if (Status == STATUS_SUCCESS) {
|
||||||
|
*(unsigned int *) Ptr = Data;
|
||||||
|
Ptr += sizeof (Data);
|
||||||
|
}
|
||||||
|
} while (Status == STATUS_SUCCESS);
|
||||||
|
//
|
||||||
|
// Can't do much checking on the header because, per the spec, the
|
||||||
|
// DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
|
||||||
|
// and the TotalSize field is invalid (actually missing). Thus we can't
|
||||||
|
// even verify the Reserved fields are 0.
|
||||||
|
//
|
||||||
|
Header = (MICROCODE_IMAGE_HEADER *) Buffer;
|
||||||
|
if (Header->DataSize == 0) {
|
||||||
|
TotalSize = 2048;
|
||||||
|
} else {
|
||||||
|
TotalSize = Header->TotalSize;
|
||||||
|
}
|
||||||
|
if (TotalSize != Size) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Checksum the contents
|
||||||
|
//
|
||||||
|
Ptr = Buffer;
|
||||||
|
Checksum = 0;
|
||||||
|
Size2 = 0;
|
||||||
|
while (Size2 < Size) {
|
||||||
|
Checksum += *(unsigned int *) Ptr;
|
||||||
|
Ptr += 4;
|
||||||
|
Size2 += 4;
|
||||||
|
}
|
||||||
|
if (Checksum != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "checksum failed on file contents");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the output file and write the buffer contents
|
||||||
|
//
|
||||||
|
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (fwrite (Buffer, Size, 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Done:
|
||||||
|
if (Buffer != NULL) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
if (OutFptr != NULL) {
|
||||||
|
fclose (OutFptr);
|
||||||
|
if (Status == STATUS_ERROR) {
|
||||||
|
remove (OutFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
87
Tools/Source/TianoTools/FlashMap/Microcode.h
Normal file
87
Tools/Source/TianoTools/FlashMap/Microcode.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Microcode.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Header file for flash management utility in the Intel Platform
|
||||||
|
Innovation Framework for EFI build environment.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _MICROCODE_H_
|
||||||
|
#define _MICROCODE_H_
|
||||||
|
|
||||||
|
void
|
||||||
|
MicrocodeConstructor (
|
||||||
|
void
|
||||||
|
);
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Constructor of module Microcode
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
void
|
||||||
|
MicrocodeDestructor (
|
||||||
|
void
|
||||||
|
);
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Destructor of module Microcode
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
MicrocodeParseFile (
|
||||||
|
char *InFileName,
|
||||||
|
char *OutFileName
|
||||||
|
);
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Parse a microcode text file, and write the binary results to an output file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
InFileName - input text file to parse
|
||||||
|
OutFileName - output file to write raw binary data from parsed input file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - no errors or warnings
|
||||||
|
STATUS_ERROR - errors were encountered
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #ifndef _MICROCODE_H_
|
647
Tools/Source/TianoTools/FlashMap/Symbols.c
Normal file
647
Tools/Source/TianoTools/FlashMap/Symbols.c
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Symbol.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Class-like implementation for a symbol table.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
// GC_TODO: fix comment to set correct module name: Symbols.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
//
|
||||||
|
// for isspace()
|
||||||
|
//
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "Tiano.h"
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
#include "Symbols.h"
|
||||||
|
|
||||||
|
#define MAX_LINE_LEN 512
|
||||||
|
|
||||||
|
//
|
||||||
|
// Linked list to keep track of all symbols
|
||||||
|
//
|
||||||
|
typedef struct _SYMBOL {
|
||||||
|
struct _SYMBOL *Next;
|
||||||
|
int Type;
|
||||||
|
char *Name;
|
||||||
|
char *Value;
|
||||||
|
} SYMBOL;
|
||||||
|
|
||||||
|
static
|
||||||
|
SYMBOL *
|
||||||
|
FreeSymbols (
|
||||||
|
SYMBOL *Syms
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
ExpandMacros (
|
||||||
|
char *SourceLine,
|
||||||
|
char *DestLine,
|
||||||
|
int LineLen
|
||||||
|
);
|
||||||
|
|
||||||
|
static SYMBOL *mSymbolTable = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolsConstructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
SymbolsDestructor ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolsDestructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
mSymbolTable = FreeSymbols (mSymbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
GetSymbolValue (
|
||||||
|
char *SymbolName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Look up a symbol in our symbol table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
SymbolName
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Pointer to the value of the symbol if found
|
||||||
|
NULL if the symbol is not found
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: SymbolName - add argument and description to function comment
|
||||||
|
{
|
||||||
|
SYMBOL *Symbol;
|
||||||
|
//
|
||||||
|
// Walk the symbol table
|
||||||
|
//
|
||||||
|
Symbol = mSymbolTable;
|
||||||
|
while (Symbol) {
|
||||||
|
if (stricmp (SymbolName, Symbol->Name) == 0) {
|
||||||
|
return Symbol->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol = Symbol->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SymbolAdd (
|
||||||
|
char *Name,
|
||||||
|
char *Value,
|
||||||
|
int Mode
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Add a symbol name/value to the symbol table
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Name - name of symbol to add
|
||||||
|
Value - value of symbol to add
|
||||||
|
Mode - currrently unused
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Length of symbol added.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
If Value == NULL, then this routine will assume that the Name field
|
||||||
|
looks something like "MySymName = MySymValue", and will try to parse
|
||||||
|
it that way and add the symbol name/pair from the string.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
SYMBOL *Symbol;
|
||||||
|
|
||||||
|
SYMBOL *NewSymbol;
|
||||||
|
int Len;
|
||||||
|
char *Start;
|
||||||
|
char *Cptr;
|
||||||
|
char CSave;
|
||||||
|
char *SaveCptr;
|
||||||
|
|
||||||
|
Len = 0;
|
||||||
|
SaveCptr = NULL;
|
||||||
|
CSave = 0;
|
||||||
|
//
|
||||||
|
// If value pointer is null, then they passed us a line something like:
|
||||||
|
// varname = value, or simply var =
|
||||||
|
//
|
||||||
|
if (Value == NULL) {
|
||||||
|
Start = Name;
|
||||||
|
while (*Name && isspace (*Name)) {
|
||||||
|
Name++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Name == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Find the end of the name. Either space or a '='.
|
||||||
|
//
|
||||||
|
for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++)
|
||||||
|
;
|
||||||
|
if (Value == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Look for the '='
|
||||||
|
//
|
||||||
|
Cptr = Value;
|
||||||
|
while (*Value && (*Value != '=')) {
|
||||||
|
Value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Value == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Now truncate the name
|
||||||
|
//
|
||||||
|
*Cptr = 0;
|
||||||
|
//
|
||||||
|
// Skip over the = and then any spaces
|
||||||
|
//
|
||||||
|
Value++;
|
||||||
|
while (*Value && isspace (*Value)) {
|
||||||
|
Value++;
|
||||||
|
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Find end of string, checking for quoted string
|
||||||
|
//
|
||||||
|
if (*Value == '\"') {
|
||||||
|
Value++;
|
||||||
|
for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++)
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Null terminate the value string
|
||||||
|
//
|
||||||
|
CSave = *Cptr;
|
||||||
|
SaveCptr = Cptr;
|
||||||
|
*Cptr = 0;
|
||||||
|
Len = (int) (Cptr - Start);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// We now have a symbol name and a value. Look for an existing variable
|
||||||
|
// and overwrite it.
|
||||||
|
//
|
||||||
|
Symbol = mSymbolTable;
|
||||||
|
while (Symbol) {
|
||||||
|
//
|
||||||
|
// Check for symbol name match
|
||||||
|
//
|
||||||
|
if (stricmp (Name, Symbol->Name) == 0) {
|
||||||
|
_free (Symbol->Value);
|
||||||
|
Symbol->Value = (char *) _malloc (strlen (Value) + 1);
|
||||||
|
if (Symbol->Value == NULL) {
|
||||||
|
Error (NULL, 0, 0, NULL, "failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (Symbol->Value, Value);
|
||||||
|
//
|
||||||
|
// If value == "NULL", then make it a 0-length string
|
||||||
|
//
|
||||||
|
if (stricmp (Symbol->Value, "NULL") == 0) {
|
||||||
|
Symbol->Value[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol = Symbol->Next;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Does not exist, create a new one
|
||||||
|
//
|
||||||
|
NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL));
|
||||||
|
if (NewSymbol == NULL) {
|
||||||
|
Error (NULL, 0, 0, NULL, "memory allocation failure");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset ((char *) NewSymbol, 0, sizeof (SYMBOL));
|
||||||
|
NewSymbol->Name = (char *) _malloc (strlen (Name) + 1);
|
||||||
|
if (NewSymbol->Name == NULL) {
|
||||||
|
Error (NULL, 0, 0, NULL, "memory allocation failure");
|
||||||
|
_free (NewSymbol);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewSymbol->Value = (char *) _malloc (strlen (Value) + 1);
|
||||||
|
if (NewSymbol->Value == NULL) {
|
||||||
|
Error (NULL, 0, 0, NULL, "memory allocation failure");
|
||||||
|
_free (NewSymbol->Name);
|
||||||
|
_free (NewSymbol);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (NewSymbol->Name, Name);
|
||||||
|
strcpy (NewSymbol->Value, Value);
|
||||||
|
//
|
||||||
|
// Remove trailing spaces
|
||||||
|
//
|
||||||
|
Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1;
|
||||||
|
while (Cptr > NewSymbol->Value) {
|
||||||
|
if (isspace (*Cptr)) {
|
||||||
|
*Cptr = 0;
|
||||||
|
Cptr--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Add it to the head of the list.
|
||||||
|
//
|
||||||
|
NewSymbol->Next = mSymbolTable;
|
||||||
|
mSymbolTable = NewSymbol;
|
||||||
|
//
|
||||||
|
// If value == "NULL", then make it a 0-length string
|
||||||
|
//
|
||||||
|
if (stricmp (NewSymbol->Value, "NULL") == 0) {
|
||||||
|
NewSymbol->Value[0] = 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Restore the terminator we inserted if they passed in var=value
|
||||||
|
//
|
||||||
|
if (SaveCptr != NULL) {
|
||||||
|
*SaveCptr = CSave;
|
||||||
|
}
|
||||||
|
_free (NewSymbol->Value);
|
||||||
|
_free (NewSymbol->Name);
|
||||||
|
_free (NewSymbol);
|
||||||
|
return Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
RemoveSymbol (
|
||||||
|
char *Name,
|
||||||
|
char SymbolType
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Remove a symbol name/value from the symbol table
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Name - name of symbol to remove
|
||||||
|
SymbolType - type of symbol to remove
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS - matching symbol found and removed
|
||||||
|
STATUS_ERROR - matching symbol not found in symbol table
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
SYMBOL *Symbol;
|
||||||
|
|
||||||
|
SYMBOL *PrevSymbol;
|
||||||
|
|
||||||
|
PrevSymbol = NULL;
|
||||||
|
Symbol = mSymbolTable;
|
||||||
|
//
|
||||||
|
// Walk the linked list of symbols in the symbol table looking
|
||||||
|
// for a match of both symbol name and type.
|
||||||
|
//
|
||||||
|
while (Symbol) {
|
||||||
|
if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) {
|
||||||
|
//
|
||||||
|
// If the symbol has a value associated with it, free the memory
|
||||||
|
// allocated for the value.
|
||||||
|
// Then free the memory allocated for the symbols string name.
|
||||||
|
//
|
||||||
|
if (Symbol->Value) {
|
||||||
|
_free (Symbol->Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_free (Symbol->Name);
|
||||||
|
//
|
||||||
|
// Link the previous symbol to the next symbol to effectively
|
||||||
|
// remove this symbol from the linked list.
|
||||||
|
//
|
||||||
|
if (PrevSymbol) {
|
||||||
|
PrevSymbol->Next = Symbol->Next;
|
||||||
|
} else {
|
||||||
|
mSymbolTable = Symbol->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
_free (Symbol);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevSymbol = Symbol;
|
||||||
|
Symbol = Symbol->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
SYMBOL *
|
||||||
|
FreeSymbols (
|
||||||
|
SYMBOL *Syms
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Syms - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
SYMBOL *Next;
|
||||||
|
while (Syms) {
|
||||||
|
if (Syms->Name != NULL) {
|
||||||
|
_free (Syms->Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Syms->Value != NULL) {
|
||||||
|
_free (Syms->Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Next = Syms->Next;
|
||||||
|
_free (Syms);
|
||||||
|
Syms = Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Syms;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
ExpandMacros (
|
||||||
|
char *SourceLine,
|
||||||
|
char *DestLine,
|
||||||
|
int LineLen
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given a line of text, replace all variables of format $(NAME) with values
|
||||||
|
from our symbol table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
SourceLine - input line of text to do symbol replacements on
|
||||||
|
DestLine - on output, SourceLine with symbols replaced
|
||||||
|
LineLen - length of DestLine, so we don't exceed its allocated length
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS - no problems encountered
|
||||||
|
STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine
|
||||||
|
STATUS_ERROR - memory allocation failure
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
static int NestDepth = 0;
|
||||||
|
char *FromPtr;
|
||||||
|
char *ToPtr;
|
||||||
|
char *SaveStart;
|
||||||
|
char *Cptr;
|
||||||
|
char *value;
|
||||||
|
int Expanded;
|
||||||
|
int ExpandedCount;
|
||||||
|
INT8 *LocalDestLine;
|
||||||
|
STATUS Status;
|
||||||
|
int LocalLineLen;
|
||||||
|
|
||||||
|
NestDepth++;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
LocalDestLine = (char *) _malloc (LineLen);
|
||||||
|
if (LocalDestLine == NULL) {
|
||||||
|
Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
FromPtr = SourceLine;
|
||||||
|
ToPtr = LocalDestLine;
|
||||||
|
//
|
||||||
|
// Walk the entire line, replacing $(MACRO_NAME).
|
||||||
|
//
|
||||||
|
LocalLineLen = LineLen;
|
||||||
|
ExpandedCount = 0;
|
||||||
|
while (*FromPtr && (LocalLineLen > 0)) {
|
||||||
|
if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) {
|
||||||
|
//
|
||||||
|
// Save the start in case it's undefined, in which case we copy it as-is.
|
||||||
|
//
|
||||||
|
SaveStart = FromPtr;
|
||||||
|
Expanded = 0;
|
||||||
|
//
|
||||||
|
// Macro expansion time. Find the end (no spaces allowed)
|
||||||
|
//
|
||||||
|
FromPtr += 2;
|
||||||
|
for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++)
|
||||||
|
;
|
||||||
|
if (*Cptr) {
|
||||||
|
//
|
||||||
|
// Truncate the string at the closing parenthesis for ease-of-use.
|
||||||
|
// Then copy the string directly to the destination line in case we don't find
|
||||||
|
// a definition for it.
|
||||||
|
//
|
||||||
|
*Cptr = 0;
|
||||||
|
strcpy (ToPtr, SaveStart);
|
||||||
|
if ((value = GetSymbolValue (FromPtr)) != NULL) {
|
||||||
|
strcpy (ToPtr, value);
|
||||||
|
LocalLineLen -= strlen (value);
|
||||||
|
ToPtr += strlen (value);
|
||||||
|
Expanded = 1;
|
||||||
|
ExpandedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Expanded) {
|
||||||
|
//
|
||||||
|
// Restore closing parenthesis, and advance to next character
|
||||||
|
//
|
||||||
|
*Cptr = ')';
|
||||||
|
FromPtr = SaveStart + 1;
|
||||||
|
ToPtr++;
|
||||||
|
} else {
|
||||||
|
FromPtr = Cptr + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro");
|
||||||
|
strcpy (ToPtr, FromPtr);
|
||||||
|
Status = STATUS_WARNING;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*ToPtr = *FromPtr;
|
||||||
|
FromPtr++;
|
||||||
|
ToPtr++;
|
||||||
|
LocalLineLen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*FromPtr == 0) {
|
||||||
|
*ToPtr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If we expanded at least one string successfully, then make a recursive call to try again.
|
||||||
|
//
|
||||||
|
if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) {
|
||||||
|
Status = ExpandMacros (LocalDestLine, DestLine, LineLen);
|
||||||
|
_free (LocalDestLine);
|
||||||
|
NestDepth = 0;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Done:
|
||||||
|
if (Status != STATUS_ERROR) {
|
||||||
|
strcpy (DestLine, LocalDestLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
NestDepth = 0;
|
||||||
|
_free (LocalDestLine);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
SymbolsFileStringsReplace (
|
||||||
|
char *InFileName,
|
||||||
|
char *OutFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given input and output file names, read in the input file, replace variable
|
||||||
|
references of format $(NAME) with appropriate values from our symbol table,
|
||||||
|
and write the result out to the output file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
InFileName - name of input text file to replace variable references
|
||||||
|
OutFileName - name of output text file to write results to
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS - no problems encountered
|
||||||
|
STATUS_ERROR - failed to open input or output file
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
STATUS Status;
|
||||||
|
FILE *InFptr;
|
||||||
|
FILE *OutFptr;
|
||||||
|
char Line[MAX_LINE_LEN];
|
||||||
|
char OutLine[MAX_LINE_LEN];
|
||||||
|
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
//
|
||||||
|
// Open input and output files
|
||||||
|
//
|
||||||
|
InFptr = NULL;
|
||||||
|
OutFptr = NULL;
|
||||||
|
if ((InFptr = fopen (InFileName, "r")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((OutFptr = fopen (OutFileName, "w")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read lines from input file until done
|
||||||
|
//
|
||||||
|
while (fgets (Line, sizeof (Line), InFptr) != NULL) {
|
||||||
|
ExpandMacros (Line, OutLine, sizeof (OutLine));
|
||||||
|
fprintf (OutFptr, OutLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Done:
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OutFptr != NULL) {
|
||||||
|
fclose (OutFptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
125
Tools/Source/TianoTools/FlashMap/Symbols.h
Normal file
125
Tools/Source/TianoTools/FlashMap/Symbols.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Symbols.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Defines and prototypes for a class-like symbol table service.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _SYMBOLS_H_
|
||||||
|
#define _SYMBOLS_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
SymbolAdd (
|
||||||
|
char *Name,
|
||||||
|
char *Value,
|
||||||
|
int Mode
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Name - GC_TODO: add argument description
|
||||||
|
Value - GC_TODO: add argument description
|
||||||
|
Mode - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
SymbolsFileStringsReplace (
|
||||||
|
char *InFileName,
|
||||||
|
char *OutFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
InFileName - GC_TODO: add argument description
|
||||||
|
OutFileName - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolsConstructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
void
|
||||||
|
SymbolsDestructor (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef _SYMBOLS_H_
|
542
Tools/Source/TianoTools/GenAcpiTable/GenAcpiTable.c
Normal file
542
Tools/Source/TianoTools/GenAcpiTable/GenAcpiTable.c
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenAcpiTable.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
A utility that extracts the .DATA section from a PE/COFF image.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Tiano.h"
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
#include "EfiImage.h" // for PE32 structure definitions
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Version of this utility
|
||||||
|
//
|
||||||
|
#define UTILITY_NAME "GenAcpiTable"
|
||||||
|
#define UTILITY_VERSION "v0.11"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the max length of a filename
|
||||||
|
//
|
||||||
|
#define MAX_PATH 256
|
||||||
|
#define DEFAULT_OUTPUT_EXTENSION ".acpi"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use this to track our command-line options and globals
|
||||||
|
//
|
||||||
|
struct {
|
||||||
|
INT8 OutFileName[MAX_PATH];
|
||||||
|
INT8 InFileName[MAX_PATH];
|
||||||
|
} mOptions;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use these to convert from machine type value to a named type
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINT16 Value;
|
||||||
|
INT8 *Name;
|
||||||
|
} STRING_LOOKUP;
|
||||||
|
|
||||||
|
static STRING_LOOKUP mMachineTypes[] = {
|
||||||
|
EFI_IMAGE_MACHINE_IA32,
|
||||||
|
"IA32",
|
||||||
|
EFI_IMAGE_MACHINE_IA64,
|
||||||
|
"IA64",
|
||||||
|
EFI_IMAGE_MACHINE_EBC,
|
||||||
|
"EBC",
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static STRING_LOOKUP mSubsystemTypes[] = {
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,
|
||||||
|
"EFI application",
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,
|
||||||
|
"EFI boot service driver",
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,
|
||||||
|
"EFI runtime driver",
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// Function prototypes
|
||||||
|
//
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ParseCommandLine (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
CheckPE32File (
|
||||||
|
INT8 *FileName,
|
||||||
|
FILE *Fptr,
|
||||||
|
UINT16 *MachineType,
|
||||||
|
UINT16 *SubSystem
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessFile (
|
||||||
|
INT8 *InFileName,
|
||||||
|
INT8 *OutFileName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
DumpImage (
|
||||||
|
INT8 *FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
main (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argc - standard C main() argument count
|
||||||
|
|
||||||
|
Argv - standard C main() argument list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
{
|
||||||
|
UINT32 Status;
|
||||||
|
|
||||||
|
SetUtilityName (UTILITY_NAME);
|
||||||
|
//
|
||||||
|
// Parse the command line arguments
|
||||||
|
//
|
||||||
|
if (ParseCommandLine (Argc, Argv)) {
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure we don't have the same filename for input and output files
|
||||||
|
//
|
||||||
|
if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {
|
||||||
|
Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Process the file
|
||||||
|
//
|
||||||
|
ProcessFile (mOptions.InFileName, mOptions.OutFileName);
|
||||||
|
Finish:
|
||||||
|
Status = GetUtilityStatus ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessFile (
|
||||||
|
INT8 *InFileName,
|
||||||
|
INT8 *OutFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Process a PE32 EFI file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
InFileName - Name of the PE32 EFI file to process.
|
||||||
|
OutFileName - Name of the output file for the processed data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 - successful
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
FILE *InFptr;
|
||||||
|
FILE *OutFptr;
|
||||||
|
UINT16 MachineType;
|
||||||
|
UINT16 SubSystem;
|
||||||
|
UINT32 PESigOffset;
|
||||||
|
EFI_IMAGE_FILE_HEADER FileHeader;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
|
||||||
|
EFI_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
|
UINT8 *Buffer;
|
||||||
|
long SaveFilePosition;
|
||||||
|
|
||||||
|
InFptr = NULL;
|
||||||
|
OutFptr = NULL;
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
//
|
||||||
|
// Try to open the input file
|
||||||
|
//
|
||||||
|
if ((InFptr = fopen (InFileName, "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Double-check the file to make sure it's what we expect it to be
|
||||||
|
//
|
||||||
|
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit
|
||||||
|
// offset (from the start of the file) to the PE signature, which always
|
||||||
|
// follows the MSDOS stub. The PE signature is immediately followed by the
|
||||||
|
// COFF file header.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// We should now be at the COFF file header. Read it in and verify it's
|
||||||
|
// of an image type we support.
|
||||||
|
//
|
||||||
|
if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read file header from image");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64)) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read in the optional header. Assume PE32, and if not, then re-read as PE32+
|
||||||
|
//
|
||||||
|
SaveFilePosition = ftell (InFptr);
|
||||||
|
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if (fseek (InFptr, SaveFilePosition, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to .data section");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Search for the ".data" section
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < FileHeader.NumberOfSections; Index++) {
|
||||||
|
if (fread (&SectionHeader, sizeof (EFI_IMAGE_SECTION_HEADER), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (SectionHeader.Name, ".data") == 0) {
|
||||||
|
if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to .data section");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = (UINT8 *) malloc (SectionHeader.Misc.VirtualSize);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
if (fread (Buffer, SectionHeader.Misc.VirtualSize, 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to .data section");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Now open our output file
|
||||||
|
//
|
||||||
|
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite (Buffer, SectionHeader.Misc.VirtualSize, 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to write .data section");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
|
||||||
|
Finish:
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the output file. If there was an error, delete the output file so
|
||||||
|
// that a subsequent build will rebuild it.
|
||||||
|
//
|
||||||
|
if (OutFptr != NULL) {
|
||||||
|
fclose (OutFptr);
|
||||||
|
if (GetUtilityStatus () == STATUS_ERROR) {
|
||||||
|
remove (OutFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free up our buffer
|
||||||
|
//
|
||||||
|
if (Buffer != NULL) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
CheckPE32File (
|
||||||
|
INT8 *FileName,
|
||||||
|
FILE *Fptr,
|
||||||
|
UINT16 *MachineType,
|
||||||
|
UINT16 *SubSystem
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
Fptr - GC_TODO: add argument description
|
||||||
|
MachineType - GC_TODO: add argument description
|
||||||
|
SubSystem - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given a file pointer to a supposed PE32 image file, verify that it is indeed a
|
||||||
|
PE32 image file, and then return the machine type in the supplied pointer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Fptr File pointer to the already-opened PE32 file
|
||||||
|
MachineType Location to stuff the machine type of the PE32 file. This is needed
|
||||||
|
because the image may be Itanium-based, IA32, or EBC.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
EFI_IMAGE_DOS_HEADER DosHeader;
|
||||||
|
EFI_IMAGE_FILE_HEADER FileHdr;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;
|
||||||
|
UINT32 PESig;
|
||||||
|
STATUS Status;
|
||||||
|
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
//
|
||||||
|
// Position to the start of the file
|
||||||
|
//
|
||||||
|
fseek (Fptr, 0, SEEK_SET);
|
||||||
|
//
|
||||||
|
// Read the DOS header
|
||||||
|
//
|
||||||
|
if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the magic number (0x5A4D)
|
||||||
|
//
|
||||||
|
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
|
||||||
|
Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Position into the file and check the PE signature
|
||||||
|
//
|
||||||
|
fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
|
||||||
|
if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the PE signature in the header "PE\0\0"
|
||||||
|
//
|
||||||
|
if (PESig != EFI_IMAGE_NT_SIGNATURE) {
|
||||||
|
Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the file header
|
||||||
|
//
|
||||||
|
if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the optional header so we can get the subsystem
|
||||||
|
//
|
||||||
|
if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
*SubSystem = OptionalHdr.Subsystem;
|
||||||
|
//
|
||||||
|
// Good to go
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Finish:
|
||||||
|
fseek (Fptr, 0, SEEK_SET);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
ParseCommandLine (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given the Argc/Argv program arguments, and a pointer to an options structure,
|
||||||
|
parse the command-line options and check their validity.
|
||||||
|
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argc - standard C main() argument count
|
||||||
|
Argv - standard C main() argument list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Clear out the options
|
||||||
|
//
|
||||||
|
memset ((char *) &mOptions, 0, sizeof (mOptions));
|
||||||
|
//
|
||||||
|
// Skip over the program name
|
||||||
|
//
|
||||||
|
Argc--;
|
||||||
|
Argv++;
|
||||||
|
|
||||||
|
if (Argc != 2) {
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (mOptions.InFileName, Argv[0]);
|
||||||
|
//
|
||||||
|
// Next argument
|
||||||
|
//
|
||||||
|
Argv++;
|
||||||
|
Argc--;
|
||||||
|
|
||||||
|
strcpy (mOptions.OutFileName, Argv[0]);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Print usage information for this utility.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Nothing.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
static const char *Msg[] = {
|
||||||
|
UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility",
|
||||||
|
" Generate an ACPI Table image from an EFI PE32 image",
|
||||||
|
" Usage: "UTILITY_NAME " InFileName OutFileName",
|
||||||
|
" where:",
|
||||||
|
" InFileName - name of the input PE32 file",
|
||||||
|
" OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,
|
||||||
|
"",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
for (Index = 0; Msg[Index] != NULL; Index++) {
|
||||||
|
fprintf (stdout, "%s\n", Msg[Index]);
|
||||||
|
}
|
||||||
|
}
|
68
Tools/Source/TianoTools/GenAcpiTable/Makefile
Normal file
68
Tools/Source/TianoTools/GenAcpiTable/Makefile
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2002 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the GenAcpiTable utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define the toolchain which is used to set build options and toolchain paths
|
||||||
|
#
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = GenAcpiTable
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
|
||||||
|
|
||||||
|
INC_DEPS = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the EXE by compiling the source files, then linking the resultant
|
||||||
|
# object files together.
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
50
Tools/Source/TianoTools/GenCapsuleHdr/CreateGuid.c
Normal file
50
Tools/Source/TianoTools/GenCapsuleHdr/CreateGuid.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2003 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
CreateGuid.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Library routine to create a GUID
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
CreateGuid (
|
||||||
|
GUID *Guid
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Guid - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CoCreateGuid (Guid);
|
||||||
|
}
|
2667
Tools/Source/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c
Normal file
2667
Tools/Source/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c
Normal file
File diff suppressed because it is too large
Load Diff
75
Tools/Source/TianoTools/GenCapsuleHdr/Makefile
Normal file
75
Tools/Source/TianoTools/GenCapsuleHdr/Makefile
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2002 Intel Corporation. All rights reserved
|
||||||
|
# This software and associated documentation (if any) is furnished
|
||||||
|
# under a license and may only be used or copied in accordance
|
||||||
|
# with the terms of the license. Except as permitted by such
|
||||||
|
# license, no part of this software or documentation may be
|
||||||
|
# reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
# form or by any means without the express written consent of
|
||||||
|
# Intel Corporation.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# Makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for the GenCapsuleHdr utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
TARGET_NAME = GenCapsuleHdr
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
SRC = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
ETO = $(TIANO_TOOLS_OUTPUT)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
LIBS = $(LIBS) "$(TIANO_TOOLS_OUTPUT)\Common.lib" ole32.lib
|
||||||
|
|
||||||
|
OBJECTS = $(ETO)\$(TARGET_NAME).obj \
|
||||||
|
$(ETO)\CreateGuid.obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compile each source file
|
||||||
|
#
|
||||||
|
$(ETO)\$(TARGET_NAME).obj : $(SRC)\$(TARGET_NAME).c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(SRC)\$(TARGET_NAME).c /Fo$@
|
||||||
|
|
||||||
|
$(ETO)\CreateGuid.obj : $(SRC)\CreateGuid.c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(SRC)\CreateGuid.c /Fo$@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Link the object files together
|
||||||
|
#
|
||||||
|
$(TARGET_EXE) : $(OBJECTS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
89
Tools/Source/TianoTools/GenFdImage/GenFdImage.h
Normal file
89
Tools/Source/TianoTools/GenFdImage/GenFdImage.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenFdImage.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This file contains the relevant declarations required
|
||||||
|
to generate the Firmware Device
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Coded to EFI 2.0 Coding Standard
|
||||||
|
//
|
||||||
|
#ifndef _EFI_GEN_FD_IMAGE_H
|
||||||
|
#define _EFI_GEN_FD_IMAGE_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// Included Header files
|
||||||
|
//
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
#include "ParseInf.h"
|
||||||
|
#include "GenFvImage.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Defines
|
||||||
|
//
|
||||||
|
#define FILE_NAME_SIZE 256
|
||||||
|
|
||||||
|
//
|
||||||
|
// Type Definition
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINT64 FdSize;
|
||||||
|
UINT64 FdBaseAddress;
|
||||||
|
UINT8 PadValue;
|
||||||
|
CHAR8 OutFileName[FILE_NAME_SIZE];
|
||||||
|
} FDINFO;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Exported Function Prototype
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
GenerateFdImage (
|
||||||
|
IN UINT64 BaseAddress,
|
||||||
|
IN UINT64 Size,
|
||||||
|
IN UINT8 PadByte,
|
||||||
|
IN CHAR8 *OutFile,
|
||||||
|
IN CHAR8 **FileList
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
BaseAddress - GC_TODO: add argument description
|
||||||
|
Size - GC_TODO: add argument description
|
||||||
|
PadByte - GC_TODO: add argument description
|
||||||
|
OutFile - GC_TODO: add argument description
|
||||||
|
FileList - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
864
Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
Normal file
864
Tools/Source/TianoTools/GenFdImage/GenFdImageDll.c
Normal file
@ -0,0 +1,864 @@
|
|||||||
|
/*++
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
GenFdImageDll.C
|
||||||
|
|
||||||
|
Abstarct:
|
||||||
|
This file contains the relevant functions required to complete
|
||||||
|
the API to generate Firmware Device
|
||||||
|
--*/
|
||||||
|
|
||||||
|
// GC_TODO: fix comment to add: Abstract:
|
||||||
|
//
|
||||||
|
// This tells the compiler to export the DLL functions
|
||||||
|
//
|
||||||
|
#define GEN_FD_IMAGE_EXPORTS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
#include "GenFdImage.h"
|
||||||
|
#include "GenFvImage.h"
|
||||||
|
#include "ParseInf.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global declaration
|
||||||
|
//
|
||||||
|
UINTN ValidLineNum = 0;
|
||||||
|
|
||||||
|
UINTN NumFvFiles = 0;
|
||||||
|
static UINT64 LastAddress = 0;
|
||||||
|
|
||||||
|
CHAR8 **TokenStr;
|
||||||
|
CHAR8 **OrgStrTokPtr;
|
||||||
|
|
||||||
|
FDINFO *FdInfo;
|
||||||
|
FDINFO *OrgFdInfoPtr;
|
||||||
|
|
||||||
|
FVINFO **FvInfo;
|
||||||
|
FVINFO **OrgFvInfoPtr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global function declarations
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
BuildFirmwareDeviceBinaryFromFwVolumes (
|
||||||
|
IN UINT64 FvBaseAddress,
|
||||||
|
IN CHAR8 *FvFileName,
|
||||||
|
IN CHAR8 *FdFileName
|
||||||
|
);
|
||||||
|
|
||||||
|
INTN
|
||||||
|
CompareItems (
|
||||||
|
IN const VOID *Arg1,
|
||||||
|
IN const VOID *Arg2
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function is used by qsort to sort the Fv list based on FvBaseAddress
|
||||||
|
|
||||||
|
Input:
|
||||||
|
Arg1
|
||||||
|
Arg2
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: Arg1 - add argument and description to function comment
|
||||||
|
// GC_TODO: Arg2 - add argument and description to function comment
|
||||||
|
{
|
||||||
|
if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {
|
||||||
|
return 1;
|
||||||
|
} else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
BuildTokenList (
|
||||||
|
IN CHAR8 *Token
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function builds the token list in an array which will be parsed later
|
||||||
|
|
||||||
|
Input:
|
||||||
|
Token String,
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: Token - add argument and description to function comment
|
||||||
|
{
|
||||||
|
|
||||||
|
strcpy (*TokenStr, Token);
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TrimLine (
|
||||||
|
IN CHAR8 *Line
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function cleans up the line by removing all whitespace and
|
||||||
|
comments
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
Line String,
|
||||||
|
|
||||||
|
Return:
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: Line - add argument and description to function comment
|
||||||
|
{
|
||||||
|
CHAR8 TmpLine[FILE_NAME_SIZE];
|
||||||
|
CHAR8 c;
|
||||||
|
CHAR8 *Ptr0;
|
||||||
|
UINTN i;
|
||||||
|
UINTN j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Change '#' to '//' for Comment style
|
||||||
|
//
|
||||||
|
// if((Ptr0=strchr(Line, '#')) != NULL) {
|
||||||
|
//
|
||||||
|
if ((Ptr0 = strstr (Line, "//")) != NULL) {
|
||||||
|
Line[Ptr0 - Line] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
|
||||||
|
while ((c = Line[i]) != 0) {
|
||||||
|
if ((c != ' ') && (c != '\t') && (c != '\n')) {
|
||||||
|
TmpLine[j++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TmpLine[j] = 0;
|
||||||
|
strcpy (Line, TmpLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ValidLineCount (
|
||||||
|
IN FILE *Fp
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function calculated number of valid lines in a input file.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
Fp Pointer to a file handle which has been opened.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: Fp - add argument and description to function comment
|
||||||
|
{
|
||||||
|
CHAR8 Buff[FILE_NAME_SIZE];
|
||||||
|
|
||||||
|
while (fgets (Buff, sizeof (Buff), Fp)) {
|
||||||
|
TrimLine (Buff);
|
||||||
|
if (Buff[0] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidLineNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ParseInputFile (
|
||||||
|
IN FILE *Fp
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function parses the input file and tokenize the string
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
Fp Pointer to a file handle which has been opened.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: Fp - add argument and description to function comment
|
||||||
|
{
|
||||||
|
CHAR8 *Token;
|
||||||
|
CHAR8 Buff[FILE_NAME_SIZE];
|
||||||
|
CHAR8 OrgLine[FILE_NAME_SIZE];
|
||||||
|
CHAR8 Str[FILE_NAME_SIZE];
|
||||||
|
CHAR8 Delimit[] = "=";
|
||||||
|
|
||||||
|
while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
|
||||||
|
strcpy (OrgLine, Buff);
|
||||||
|
TrimLine (Buff);
|
||||||
|
|
||||||
|
if (Buff[0] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = strtok (Buff, Delimit);
|
||||||
|
|
||||||
|
while (Token != NULL) {
|
||||||
|
strcpy (Str, Token);
|
||||||
|
BuildTokenList (Str);
|
||||||
|
Token = strtok (NULL, Delimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
InitializeComps (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function intializes the relevant global variable which is being
|
||||||
|
used to store the information retrieved from INF file.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
FdInfo = malloc (sizeof (FDINFO));
|
||||||
|
|
||||||
|
if (FdInfo == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrgFdInfoPtr = FdInfo;
|
||||||
|
|
||||||
|
FvInfo = malloc (sizeof (int) * NumFvFiles);
|
||||||
|
|
||||||
|
if (FvInfo == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrgFvInfoPtr = FvInfo;
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
*FvInfo = malloc (sizeof (FVINFO));
|
||||||
|
|
||||||
|
if (*FvInfo == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (*FvInfo, 0, sizeof (FVINFO));
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InitializeInFileInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function intializes the relevant global variable which is being
|
||||||
|
used to store the information retrieved from INF file.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
NONE
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
NONE
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
{
|
||||||
|
UINTN OptionFlag;
|
||||||
|
UINT64 StringValue;
|
||||||
|
|
||||||
|
OptionFlag = 0;
|
||||||
|
TokenStr = OrgStrTokPtr;
|
||||||
|
|
||||||
|
while (*TokenStr != NULL) {
|
||||||
|
if (stricmp (*TokenStr, "[options]") == 0) {
|
||||||
|
OptionFlag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionFlag) {
|
||||||
|
if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {
|
||||||
|
*TokenStr++;
|
||||||
|
if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Cannot determine the FV base address.");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
(*FvInfo)->FvBaseAddress = StringValue;
|
||||||
|
} else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {
|
||||||
|
*TokenStr++;
|
||||||
|
strcpy ((*FvInfo)->FvFile, *TokenStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
GetFvRelatedInfoFromInfFile (
|
||||||
|
IN CHAR8 *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function reads the input file, parse it and create a list of tokens
|
||||||
|
which is parsed and used, to intialize the data related to Firmware Volume.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
FileName FileName which needed to be read to parse data
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: FileName - add argument and description to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
Fp = fopen (FileName, "r");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("Error in opening %s file\n", FileName);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidLineCount (Fp);
|
||||||
|
|
||||||
|
if (ValidLineNum == 0) {
|
||||||
|
printf ("\nFile doesn't contain any valid informations");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));
|
||||||
|
memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));
|
||||||
|
OrgStrTokPtr = TokenStr;
|
||||||
|
|
||||||
|
for (Index = 0; Index < (2 * ValidLineNum); Index++) {
|
||||||
|
*TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
|
||||||
|
memset (*TokenStr, 0, FILE_NAME_SIZE);
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*TokenStr = NULL;
|
||||||
|
TokenStr = OrgStrTokPtr;
|
||||||
|
fseek (Fp, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
ParseInputFile (Fp);
|
||||||
|
InitializeInFileInfo ();
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
WriteFwBinary (
|
||||||
|
IN CHAR8 *FileName,
|
||||||
|
IN UINT64 StartAddress,
|
||||||
|
IN UINT64 Size,
|
||||||
|
IN UINT8 *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function reads the input file, parse it and create a list of tokens
|
||||||
|
which is parsed and used, to intialize the data related to Firmware Volume.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
FileName FileName which needed to be read to parse data
|
||||||
|
StartAddress This will set the file position.
|
||||||
|
Size Size in bytes needed to be written
|
||||||
|
Buffer Buffer needed to e written
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: FileName - add argument and description to function comment
|
||||||
|
// GC_TODO: StartAddress - add argument and description to function comment
|
||||||
|
// GC_TODO: Size - add argument and description to function comment
|
||||||
|
// GC_TODO: Buffer - add argument and description to function comment
|
||||||
|
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
UINTN NumByte;
|
||||||
|
|
||||||
|
Fp = fopen (FileName, "a+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Error in opening file %s ", FileName);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (Fp, (UINTN) StartAddress, SEEK_SET);
|
||||||
|
NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check to ensure that buffer has been copied successfully
|
||||||
|
//
|
||||||
|
if (NumByte != Size) {
|
||||||
|
printf ("\nERROR: Error in copying the buffer into file");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BuildFirmwareDeviceBinaryFromFwVolumes (
|
||||||
|
IN UINT64 FvBaseAddress,
|
||||||
|
IN CHAR8 *FvFileName,
|
||||||
|
IN CHAR8 *FdFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function reads the input file, parse it and create a list of tokens
|
||||||
|
which is parsed and used, to intialize the data related to Firmware Volume.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
FvBaseAddress Base Address. This info is retrieved from INF file
|
||||||
|
FvFileName InputFileName
|
||||||
|
FdFileName Output File Name
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: FvBaseAddress - add argument and description to function comment
|
||||||
|
// GC_TODO: FvFileName - add argument and description to function comment
|
||||||
|
// GC_TODO: FdFileName - add argument and description to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
UINT64 FileSize;
|
||||||
|
UINT64 NumByteRead;
|
||||||
|
UINT64 PadByteSize;
|
||||||
|
UINTN Index;
|
||||||
|
UINT64 BaseAddress;
|
||||||
|
UINT8 *Buffer;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
static UINT64 StartAddress = 0;
|
||||||
|
|
||||||
|
Fp = fopen (FvFileName, "r+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Error in opening file %s", FvFileName);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseAddress = FdInfo->FdBaseAddress;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if Base Address of Firmware Volume falls below the Base Address
|
||||||
|
// Firmware Device, if yes, then abort this process.
|
||||||
|
//
|
||||||
|
if (FvBaseAddress < BaseAddress) {
|
||||||
|
printf ("\nERROR: Firmware Volume Base Address falls below Firmware Device Address.\n");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if there are any hole between two Firmware Volumes. If any hole
|
||||||
|
// exists, fill the hole with PadByte data.
|
||||||
|
//
|
||||||
|
if (FvBaseAddress > LastAddress) {
|
||||||
|
PadByteSize = (FvBaseAddress - LastAddress);
|
||||||
|
Buffer = malloc ((UINTN) PadByteSize);
|
||||||
|
|
||||||
|
for (Index = 0; Index < PadByteSize; Index++) {
|
||||||
|
*Buffer = FdInfo->PadValue;
|
||||||
|
Buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer -= PadByteSize;
|
||||||
|
Status = WriteFwBinary (FdFileName, StartAddress, (UINT64) PadByteSize, Buffer);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error in writing the binary image to file");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartAddress += PadByteSize;
|
||||||
|
LastAddress += PadByteSize;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Proceed with next Firmware Volume updates
|
||||||
|
//
|
||||||
|
FileSize = _filelength (fileno (Fp));
|
||||||
|
|
||||||
|
if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {
|
||||||
|
printf (
|
||||||
|
"\nERROR:Unable to update Firmware Device. File %s is larger than \
|
||||||
|
available space.",
|
||||||
|
FvFileName
|
||||||
|
);
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = malloc ((UINTN) FileSize);
|
||||||
|
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("Error in allocating buffer to read specific file\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
|
||||||
|
|
||||||
|
Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free ((VOID *) Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error in writing the binary image to file");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartAddress += NumByteRead;
|
||||||
|
LastAddress += FileSize;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanUpMemory (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function cleans up any allocated buffer
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
NONE
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
NONE
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if (FdInfo) {
|
||||||
|
free (FdInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
if (FvInfo) {
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
if (*FvInfo) {
|
||||||
|
free (*FvInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
free (FvInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GEN_FD_IMAGE_API
|
||||||
|
EFI_STATUS
|
||||||
|
GenerateFdImage (
|
||||||
|
IN UINT64 BaseAddress,
|
||||||
|
IN UINT64 Size,
|
||||||
|
IN UINT8 PadByte,
|
||||||
|
IN CHAR8 *OutFile,
|
||||||
|
IN CHAR8 **FileList
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function reads the input file, parse it and create a list of tokens
|
||||||
|
which is parsed and used, to intialize the data related to Firmware Volume.
|
||||||
|
|
||||||
|
Input:
|
||||||
|
|
||||||
|
BaseAddress Base Address for this Firmware Device
|
||||||
|
Size, Total Size of the Firmware Device
|
||||||
|
PadByte Pad byte data
|
||||||
|
OutFile Output File Name
|
||||||
|
FileList File List pointer to INF file names.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: function comment is missing 'Routine Description:'
|
||||||
|
// GC_TODO: function comment is missing 'Arguments:'
|
||||||
|
// GC_TODO: function comment is missing 'Returns:'
|
||||||
|
// GC_TODO: BaseAddress - add argument and description to function comment
|
||||||
|
// GC_TODO: Size - add argument and description to function comment
|
||||||
|
// GC_TODO: PadByte - add argument and description to function comment
|
||||||
|
// GC_TODO: OutFile - add argument and description to function comment
|
||||||
|
// GC_TODO: FileList - add argument and description to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN PadSize;
|
||||||
|
UINTN FileSize;
|
||||||
|
CHAR8 **InFile;
|
||||||
|
FILE *Fp;
|
||||||
|
UINT8 *Buffer;
|
||||||
|
UINTN NumByte;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ensure, if there are any previous Firmware Device exists,
|
||||||
|
// If yes, make it to 0 bytes
|
||||||
|
//
|
||||||
|
if ((Fp = fopen (OutFile, "w")) != NULL) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile = FileList;
|
||||||
|
|
||||||
|
while (*InFile != NULL) {
|
||||||
|
NumFvFiles++;
|
||||||
|
InFile++;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeComps ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore the orginal pointers
|
||||||
|
//
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
InFile = FileList;
|
||||||
|
|
||||||
|
while (*InFile != NULL) {
|
||||||
|
strcpy ((*FvInfo)->FvInfoFile, *InFile);
|
||||||
|
Status = GetFvRelatedInfoFromInfFile (*InFile);
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error occurred in processsing INF file");
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile++;
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdInfo->FdSize = Size;
|
||||||
|
FdInfo->FdBaseAddress = BaseAddress;
|
||||||
|
FdInfo->PadValue = PadByte;
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
strcpy (FdInfo->OutFileName, OutFile);
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
Status = GenerateFvImage ((*FvInfo)->FvInfoFile);
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sort the Firmware Volume informations. Firmware Volume with lower
|
||||||
|
// base addresses will be processed first and hiher base address one
|
||||||
|
// will be processed later.
|
||||||
|
//
|
||||||
|
qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);
|
||||||
|
|
||||||
|
LastAddress = (*FvInfo)->FvBaseAddress;
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
Status = BuildFirmwareDeviceBinaryFromFwVolumes (
|
||||||
|
(*FvInfo)->FvBaseAddress,
|
||||||
|
(*FvInfo)->FvFile,
|
||||||
|
FdInfo->OutFileName
|
||||||
|
);
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if any space left after copying data from all Firmware Volumes
|
||||||
|
// If yes, then fill those location with PadValue.
|
||||||
|
//
|
||||||
|
if ((FdInfo->FdBaseAddress + Size) > LastAddress) {
|
||||||
|
|
||||||
|
PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);
|
||||||
|
Buffer = malloc (PadSize);
|
||||||
|
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < PadSize; Index++) {
|
||||||
|
*Buffer = FdInfo->PadValue;
|
||||||
|
Buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer -= PadSize;
|
||||||
|
|
||||||
|
Fp = fopen (OutFile, "a+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Opening file %s", OutFile);
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSize = _filelength (fileno (Fp));
|
||||||
|
fseek (Fp, FileSize, SEEK_SET);
|
||||||
|
NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (Fp);
|
||||||
|
|
||||||
|
if (NumByte != (sizeof (UINT8) * PadSize)) {
|
||||||
|
printf ("\nERROR: Copying data from buffer to File %s ", OutFile);
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Clean up all the memory which has been allocated so far.
|
||||||
|
//
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
330
Tools/Source/TianoTools/GenFdImage/GenFdImageExe.c
Normal file
330
Tools/Source/TianoTools/GenFdImage/GenFdImageExe.c
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenFdImageExe.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This contains all code necessary to build the GenFdImage.exe utility.
|
||||||
|
This utility relies heavily on the GenFdImage Lib. Definitions for both
|
||||||
|
can be found in the GenFdImage Utility Specification, review draft.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Coded to EFI 2.0 Coding Standards
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Include files
|
||||||
|
//
|
||||||
|
#include "GenFdImage.h"
|
||||||
|
#include "GenFdImageExe.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the standard utility information to SDTOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"%s, EFI 2.0 Firmware Device Image Generation Utility. ""Version %i.%i, %s.\n\n",
|
||||||
|
UTILITY_NAME,
|
||||||
|
UTILITY_MAJOR_VERSION,
|
||||||
|
UTILITY_MINOR_VERSION,
|
||||||
|
UTILITY_DATE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the utility usage syntax to STDOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"Usage: %s -B BaseAddress -S Size -F FillByte"" [-I FvInfFileName] -O OutputFileName \n",
|
||||||
|
UTILITY_NAME
|
||||||
|
);
|
||||||
|
printf (" Where:\n");
|
||||||
|
printf ("\tBaseAddress is the starting address of the FD Image\n\n");
|
||||||
|
printf ("\tSize is the size of the FD Image.\n\n");
|
||||||
|
printf ("\tFillByte is the desired value of free space in the Image\n\n");
|
||||||
|
printf ("\tFvInfFileName is the name of an FV Image description file.\n\n");
|
||||||
|
printf ("\tOutputFileName is the desired output file name.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
main (
|
||||||
|
IN INTN argc,
|
||||||
|
IN CHAR8 **argv
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This utility uses GenFdImage.lib to build a Firmware Device Image
|
||||||
|
which will include several Firmware Volume Images.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Base Address Base Address of the firmware volume..
|
||||||
|
Size Size of the Firmware Volume
|
||||||
|
FillByte The byte value which would be needed to pad
|
||||||
|
between various Firmware Volumes
|
||||||
|
FvInfFile Fv inf file
|
||||||
|
OutputFileName The name of output file which would be created
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS No error conditions detected.
|
||||||
|
EFI_INVALID_PARAMETER One or more of the input parameters is invalid.
|
||||||
|
EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable.
|
||||||
|
Most commonly this will be memory allocation or
|
||||||
|
file creation.
|
||||||
|
EFI_LOAD_ERROR GenFvImage.lib could not be loaded.
|
||||||
|
EFI_ABORTED Error executing the GenFvImage lib.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: argc - add argument and description to function comment
|
||||||
|
// GC_TODO: argv - add argument and description to function comment
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
UINTN FvFilesCount;
|
||||||
|
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
UINT64 StartAddress;
|
||||||
|
UINT64 Size;
|
||||||
|
UINT64 FillByteVal;
|
||||||
|
|
||||||
|
CHAR8 **FvInfFileList;
|
||||||
|
CHAR8 **OrgFvInfFileList;
|
||||||
|
CHAR8 OutputFileName[_MAX_PATH];
|
||||||
|
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
INTN arg_counter;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Echo for makefile debug
|
||||||
|
//
|
||||||
|
printf ("\n\n");
|
||||||
|
for (arg_counter = 0; arg_counter < argc; arg_counter++) {
|
||||||
|
printf ("%s ", argv[arg_counter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("\n\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Display utility information
|
||||||
|
//
|
||||||
|
PrintUtilityInfo ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify the correct number of arguments
|
||||||
|
//
|
||||||
|
if (argc < MIN_ARGS) {
|
||||||
|
printf ("ERROR: missing 1 or more input arguments.\n\n");
|
||||||
|
PrintUsage ();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize variables
|
||||||
|
//
|
||||||
|
StartAddress = 0;
|
||||||
|
Size = 0;
|
||||||
|
FillByteVal = 0;
|
||||||
|
FvFilesCount = 0;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (stricmp (argv[i], "-I") == 0) {
|
||||||
|
FvFilesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfFileList = malloc (sizeof (UINTN) * (FvFilesCount + 1));
|
||||||
|
if (FvInfFileList == NULL) {
|
||||||
|
printf ("ERROR: allocating memory for FvInfFileList in -main- function.\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (FvInfFileList, 0, sizeof (UINTN) * (FvFilesCount + 1));
|
||||||
|
|
||||||
|
OrgFvInfFileList = FvInfFileList;
|
||||||
|
|
||||||
|
for (Index = 0; Index < FvFilesCount; Index++) {
|
||||||
|
*FvInfFileList = malloc (_MAX_PATH);
|
||||||
|
memset (*FvInfFileList, 0, _MAX_PATH);
|
||||||
|
FvInfFileList++;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (OutputFileName, "");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parse the command line arguments
|
||||||
|
//
|
||||||
|
FvInfFileList = OrgFvInfFileList;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i += 2) {
|
||||||
|
//
|
||||||
|
// Make sure argument pair begin with - or /
|
||||||
|
//
|
||||||
|
if (argv[i][0] != '-' && argv[i][0] != '/') {
|
||||||
|
PrintUsage ();
|
||||||
|
printf ("ERROR: Argument pair must begin with \"-\" or \"/\"\n");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure argument specifier is only one letter
|
||||||
|
//
|
||||||
|
if (argv[i][2] != 0) {
|
||||||
|
PrintUsage ();
|
||||||
|
printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Determine argument to read
|
||||||
|
//
|
||||||
|
switch (argv[i][1]) {
|
||||||
|
|
||||||
|
case 'I':
|
||||||
|
case 'i':
|
||||||
|
if ((FvInfFileList != NULL) && (strlen (*FvInfFileList) == 0)) {
|
||||||
|
strcpy (*FvInfFileList, argv[i + 1]);
|
||||||
|
FvInfFileList++;
|
||||||
|
} else {
|
||||||
|
printf ("ERROR: FvInfFile Name is more than specifed.\n");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
if (strlen (OutputFileName) == 0) {
|
||||||
|
strcpy (OutputFileName, argv[i + 1]);
|
||||||
|
} else {
|
||||||
|
PrintUsage ();
|
||||||
|
printf ("ERROR: OutputFileName may only be specified once.\n");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &StartAddress);
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Bad FD Image start address specified");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
case 's':
|
||||||
|
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &Size);
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Bad FD Image size specified");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
Status = AsciiStringToUint64 (argv[i + 1], FALSE, &FillByteVal);
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Not a recognized Fill Byte value");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PrintUsage ();
|
||||||
|
printf ("ERROR: Unrecognized argument \"%s\".\n", argv[i]);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Call the GenFdImage Lib
|
||||||
|
//
|
||||||
|
FvInfFileList = OrgFvInfFileList;
|
||||||
|
|
||||||
|
Status = GenerateFdImage (
|
||||||
|
StartAddress,
|
||||||
|
Size,
|
||||||
|
(UINT8) FillByteVal,
|
||||||
|
OutputFileName,
|
||||||
|
FvInfFileList
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
switch (Status) {
|
||||||
|
|
||||||
|
case EFI_INVALID_PARAMETER:
|
||||||
|
printf ("\nERROR: Invalid parameter passed to GenFdImage lib.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_ABORTED:
|
||||||
|
printf ("\nERROR: Error detected while creating the file image.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_OUT_OF_RESOURCES:
|
||||||
|
printf ("\nERROR: GenFdImage Lib could not allocate required resources.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_VOLUME_CORRUPTED:
|
||||||
|
printf ("\nERROR: No base address was specified \n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_LOAD_ERROR:
|
||||||
|
printf ("\nERROR: An error occurred loading one of the required support Lib.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf ("\nERROR: GenFdImage lib returned unknown status %X.\n", Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
91
Tools/Source/TianoTools/GenFdImage/GenFdImageExe.h
Normal file
91
Tools/Source/TianoTools/GenFdImage/GenFdImageExe.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenFdImageExe.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Definitions for the Boot Strap File Image generation utility.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _EFI_GEN_FD_IMAGE_EXE_H
|
||||||
|
#define _EFI_GEN_FD_IMAGE_EXE_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility Name
|
||||||
|
//
|
||||||
|
#define UTILITY_NAME "GenFdImage"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility version information
|
||||||
|
//
|
||||||
|
#define UTILITY_MAJOR_VERSION 0
|
||||||
|
#define UTILITY_MINOR_VERSION 0
|
||||||
|
#define UTILITY_DATE __DATE__
|
||||||
|
|
||||||
|
//
|
||||||
|
// The maximum number of arguments accepted from the command line.
|
||||||
|
//
|
||||||
|
#define MIN_ARGS 10
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays general utility information
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays the utility usage message.
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
848
Tools/Source/TianoTools/GenFdImage/GenFdImageLib.c
Normal file
848
Tools/Source/TianoTools/GenFdImage/GenFdImageLib.c
Normal file
@ -0,0 +1,848 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenFdImageLib.C
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This file contains the functions required to generate
|
||||||
|
the Firmware Device
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Coded to EFI 2.0 Coding Standards
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Include file in build
|
||||||
|
//
|
||||||
|
#include "GenFdImage.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global declarations
|
||||||
|
//
|
||||||
|
UINTN ValidLineNum = 0;
|
||||||
|
UINTN NumFvFiles = 0;
|
||||||
|
|
||||||
|
static UINT64 LastAddress = 0;
|
||||||
|
|
||||||
|
CHAR8 **TokenStr;
|
||||||
|
CHAR8 **OrgStrTokPtr;
|
||||||
|
|
||||||
|
FDINFO *FdInfo;
|
||||||
|
FDINFO *OrgFdInfoPtr;
|
||||||
|
|
||||||
|
FVINFO **FvInfo;
|
||||||
|
FVINFO **OrgFvInfoPtr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal Functions
|
||||||
|
//
|
||||||
|
INTN
|
||||||
|
CompareItems (
|
||||||
|
IN const VOID *Arg1,
|
||||||
|
IN const VOID *Arg2
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function is used by qsort to sort the Fv list based on FvBaseAddress
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Arg1
|
||||||
|
Arg2
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: Arg1 - add argument and description to function comment
|
||||||
|
// GC_TODO: Arg2 - add argument and description to function comment
|
||||||
|
{
|
||||||
|
if ((*(FVINFO **) Arg1)->FvBaseAddress > (*(FVINFO **) Arg2)->FvBaseAddress) {
|
||||||
|
return 1;
|
||||||
|
} else if ((*(FVINFO **) Arg1)->FvBaseAddress < (*(FVINFO **) Arg2)->FvBaseAddress) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
BuildTokenList (
|
||||||
|
IN CHAR8 *Token
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function builds the token list in an array which will be parsed later
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Token String,
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
strcpy (*TokenStr, Token);
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TrimLine (
|
||||||
|
IN CHAR8 *Line
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function cleans up the line by removing all whitespace and
|
||||||
|
comments.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Line String,
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CHAR8 TmpLine[FILE_NAME_SIZE];
|
||||||
|
CHAR8 c;
|
||||||
|
CHAR8 *Ptr0;
|
||||||
|
|
||||||
|
UINTN i;
|
||||||
|
UINTN j;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Change '#' to '//' for Comment style
|
||||||
|
//
|
||||||
|
// if((Ptr0=strchr(Line, '#')) != NULL) {
|
||||||
|
//
|
||||||
|
if ((Ptr0 = strstr (Line, "//")) != NULL) {
|
||||||
|
Line[Ptr0 - Line] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
j = 0;
|
||||||
|
while ((c = Line[i]) != 0) {
|
||||||
|
if ((c != ' ') && (c != '\t') && (c != '\n')) {
|
||||||
|
TmpLine[j++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TmpLine[j] = 0;
|
||||||
|
strcpy (Line, TmpLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ValidLineCount (
|
||||||
|
IN FILE *Fp
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function calculates number of valid lines in a input file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Fp Pointer to a file handle which has been opened.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CHAR8 Buff[FILE_NAME_SIZE];
|
||||||
|
|
||||||
|
while (fgets (Buff, sizeof (Buff), Fp)) {
|
||||||
|
TrimLine (Buff);
|
||||||
|
if (Buff[0] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidLineNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ParseInputFile (
|
||||||
|
IN FILE *Fp
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function parses the input file and tokenizes the string
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Fp Pointer to a file handle which has been opened.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CHAR8 *Token;
|
||||||
|
CHAR8 Buff[FILE_NAME_SIZE];
|
||||||
|
CHAR8 OrgLine[FILE_NAME_SIZE];
|
||||||
|
CHAR8 Str[FILE_NAME_SIZE];
|
||||||
|
CHAR8 Delimit[] = "=";
|
||||||
|
|
||||||
|
while (fgets (Buff, sizeof (Buff), Fp) != NULL) {
|
||||||
|
strcpy (OrgLine, Buff);
|
||||||
|
TrimLine (Buff);
|
||||||
|
|
||||||
|
if (Buff[0] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = strtok (Buff, Delimit);
|
||||||
|
|
||||||
|
while (Token != NULL) {
|
||||||
|
strcpy (Str, Token);
|
||||||
|
BuildTokenList (Str);
|
||||||
|
Token = strtok (NULL, Delimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
InitializeComps (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function intializes the relevant global variable
|
||||||
|
used to store the information retrieved from the INF file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
FdInfo = malloc (sizeof (FDINFO));
|
||||||
|
|
||||||
|
if (FdInfo == NULL) {
|
||||||
|
printf ("ERROR: allocating memory (struct FDINFO) in"" function InitializeComps.\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrgFdInfoPtr = FdInfo;
|
||||||
|
|
||||||
|
FvInfo = malloc (sizeof (INTN) * NumFvFiles);
|
||||||
|
|
||||||
|
if (FvInfo == NULL) {
|
||||||
|
printf ("ERROR: allocating memory (INTN * NumFvFiles) in"" function InitializeComps.\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrgFvInfoPtr = FvInfo;
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
*FvInfo = malloc (sizeof (FVINFO));
|
||||||
|
|
||||||
|
if (*FvInfo == NULL) {
|
||||||
|
printf ("ERROR: allocating memory (FVINFO) in"" function InitializeComps.\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (*FvInfo, 0, sizeof (FVINFO));
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InitializeInFileInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function intializes the relevant global variable
|
||||||
|
used to store the information retrieved from the INF file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN OptionFlag;
|
||||||
|
|
||||||
|
UINT64 StringValue;
|
||||||
|
|
||||||
|
OptionFlag = 0;
|
||||||
|
TokenStr = OrgStrTokPtr;
|
||||||
|
|
||||||
|
while (*TokenStr != NULL) {
|
||||||
|
if (stricmp (*TokenStr, "[options]") == 0) {
|
||||||
|
OptionFlag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionFlag) {
|
||||||
|
if (stricmp (*TokenStr, "EFI_FV_BASE_ADDRESS") == 0) {
|
||||||
|
*TokenStr++;
|
||||||
|
if (AsciiStringToUint64 (
|
||||||
|
*TokenStr,
|
||||||
|
FALSE,
|
||||||
|
&StringValue
|
||||||
|
) != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Cannot determine the FV base address.");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
(*FvInfo)->FvBaseAddress = StringValue;
|
||||||
|
} else if (stricmp (*TokenStr, "EFI_FV_FILE_NAME") == 0) {
|
||||||
|
*TokenStr++;
|
||||||
|
strcpy ((*FvInfo)->FvFile, *TokenStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
GetFvRelatedInfoFromInfFile (
|
||||||
|
IN CHAR8 *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function reads the input file, parses it and create a list of tokens
|
||||||
|
which are parsed and used, to intialize the data related to the Firmware
|
||||||
|
Volume.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName FileName which needed to be read to parse data
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
Fp = fopen (FileName, "r");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("Error in opening %s file\n", FileName);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidLineCount (Fp);
|
||||||
|
|
||||||
|
if (ValidLineNum == 0) {
|
||||||
|
printf ("\nFile doesn't contain any valid informations");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenStr = (CHAR8 **) malloc (sizeof (UINTN) * (2 * ValidLineNum));
|
||||||
|
memset (TokenStr, 0, sizeof (UINTN) * (2 * ValidLineNum));
|
||||||
|
OrgStrTokPtr = TokenStr;
|
||||||
|
|
||||||
|
for (Index = 0; Index < (2 * ValidLineNum); Index++) {
|
||||||
|
*TokenStr = (CHAR8 *) malloc (sizeof (CHAR8) * FILE_NAME_SIZE);
|
||||||
|
memset (*TokenStr, 0, FILE_NAME_SIZE);
|
||||||
|
TokenStr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*TokenStr = NULL;
|
||||||
|
TokenStr = OrgStrTokPtr;
|
||||||
|
fseek (Fp, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
ParseInputFile (Fp);
|
||||||
|
InitializeInFileInfo ();
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
WriteFwBinary (
|
||||||
|
IN CHAR8 *FileName,
|
||||||
|
IN UINT64 StartAddress,
|
||||||
|
IN UINT64 Size,
|
||||||
|
IN UINT8 *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function reads the input file, parses it and creates a list of tokens
|
||||||
|
which are parsed and used to intialize the data related to the Firmware
|
||||||
|
Volume.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName FileName which needed to be read to parse data
|
||||||
|
StartAddress This will set the file position.
|
||||||
|
Size Size in bytes needed to be written
|
||||||
|
Buffer Buffer needed to e written
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
|
||||||
|
UINTN NumByte;
|
||||||
|
|
||||||
|
Fp = fopen (FileName, "a+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Error in opening file %s ", FileName);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (Fp, (UINTN) StartAddress, SEEK_SET);
|
||||||
|
NumByte = fwrite ((VOID *) Buffer, sizeof (UINT8), (UINTN) Size, Fp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check to ensure that buffer has been copied successfully
|
||||||
|
//
|
||||||
|
if (NumByte != Size) {
|
||||||
|
printf ("\nERROR: Error in copying the buffer into file");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
BuildFirmwareDeviceBinaryFromFwVolumes (
|
||||||
|
IN UINT64 FvBaseAddress,
|
||||||
|
IN CHAR8 *FvFileName,
|
||||||
|
IN CHAR8 *FdFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function reads the input file, parses it and creates a list of tokens
|
||||||
|
which are parsed and used to intialize the data related to the Firmware
|
||||||
|
Volume.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FvBaseAddress Base Address. This info is retrieved from INF file
|
||||||
|
FvFileName InputFileName
|
||||||
|
FdFileName Output File Name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
FILE *Fp;
|
||||||
|
|
||||||
|
UINT64 FileSize;
|
||||||
|
UINT64 NumByteRead;
|
||||||
|
UINT64 PadByteSize;
|
||||||
|
UINT64 BaseAddress;
|
||||||
|
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
UINT8 *Buffer;
|
||||||
|
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
static UINT64 StartAddress = 0;
|
||||||
|
|
||||||
|
Fp = fopen (FvFileName, "r+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Error in opening file %s", FvFileName);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseAddress = FdInfo->FdBaseAddress;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if Base Address of Firmware Volume falls below the Base Address
|
||||||
|
// Firmware Device, if yes, then abort this process.
|
||||||
|
//
|
||||||
|
if (FvBaseAddress < BaseAddress) {
|
||||||
|
printf ("\nERROR: Firmware Volume Base Address falls below Firmware ""Device Address.\n");
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if there are any holes between two Firmware Volumes. If any holes
|
||||||
|
// exist, fill the hole with PadByted data.
|
||||||
|
//
|
||||||
|
if (FvBaseAddress > LastAddress) {
|
||||||
|
PadByteSize = (FvBaseAddress - LastAddress);
|
||||||
|
Buffer = malloc ((UINTN) PadByteSize);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("ERROR: allocating (Buffer) memory in"" function BuildFirmwareDeviceBinaryFromFwVolumes.\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < PadByteSize; Index++) {
|
||||||
|
*Buffer = FdInfo->PadValue;
|
||||||
|
Buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer -= PadByteSize;
|
||||||
|
Status = WriteFwBinary (
|
||||||
|
FdFileName,
|
||||||
|
StartAddress,
|
||||||
|
(UINT64) PadByteSize,
|
||||||
|
Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error in writing the binary image to file");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartAddress += PadByteSize;
|
||||||
|
LastAddress += PadByteSize;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Proceed with next Firmware Volume updates
|
||||||
|
//
|
||||||
|
FileSize = _filelength (fileno (Fp));
|
||||||
|
|
||||||
|
if ((FvBaseAddress + FileSize) > (FdInfo->FdBaseAddress + FdInfo->FdSize)) {
|
||||||
|
printf (
|
||||||
|
"\nERROR:Unable to update Firmware Device. File %s is larger than \
|
||||||
|
available space.",
|
||||||
|
FvFileName
|
||||||
|
);
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer = malloc ((UINTN) FileSize);
|
||||||
|
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("Error in allocating buffer to read specific file\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumByteRead = fread ((VOID *) Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);
|
||||||
|
|
||||||
|
Status = WriteFwBinary (FdFileName, StartAddress, FileSize, Buffer);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free ((VOID *) Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fp) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error in writing the binary image to file");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartAddress += NumByteRead;
|
||||||
|
LastAddress += FileSize;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanUpMemory (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function cleans up any allocated buffer
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if (FdInfo) {
|
||||||
|
free (FdInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
if (FvInfo) {
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
if (*FvInfo) {
|
||||||
|
free (*FvInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
free (FvInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
GenerateFdImage (
|
||||||
|
IN UINT64 BaseAddress,
|
||||||
|
IN UINT64 Size,
|
||||||
|
IN UINT8 PadByte,
|
||||||
|
IN CHAR8 *OutFile,
|
||||||
|
IN CHAR8 **FileList
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function reads the input file, parses it and creates a list of tokens
|
||||||
|
which are parsed and used to intialize the data related to the Firmware
|
||||||
|
Volume.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
BaseAddress Base Address for this Firmware Device
|
||||||
|
Size, Total Size of the Firmware Device
|
||||||
|
PadByte Pad byte data
|
||||||
|
OutFile Output File Name
|
||||||
|
FileList File List pointer to INF file names.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_ABORTED - add return value to function comment
|
||||||
|
// GC_TODO: EFI_SUCCESS - add return value to function comment
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
UINTN Index;
|
||||||
|
UINTN PadSize;
|
||||||
|
UINTN FileSize;
|
||||||
|
UINTN NumByte;
|
||||||
|
|
||||||
|
CHAR8 **InFile;
|
||||||
|
|
||||||
|
FILE *Fp;
|
||||||
|
|
||||||
|
UINT8 *Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If any previous Firmware Device existed,
|
||||||
|
// make it to 0 bytes
|
||||||
|
//
|
||||||
|
if ((Fp = fopen (OutFile, "w")) != NULL) {
|
||||||
|
fclose (Fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile = FileList;
|
||||||
|
|
||||||
|
while (*InFile != NULL) {
|
||||||
|
NumFvFiles++;
|
||||||
|
InFile++;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeComps ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore the orginal pointers
|
||||||
|
//
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
InFile = FileList;
|
||||||
|
|
||||||
|
while (*InFile != NULL) {
|
||||||
|
strcpy ((*FvInfo)->FvInfoFile, *InFile);
|
||||||
|
Status = GetFvRelatedInfoFromInfFile (*InFile);
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
printf ("\nERROR: Error occurred in processsing INF file");
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile++;
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdInfo->FdSize = Size;
|
||||||
|
FdInfo->FdBaseAddress = BaseAddress;
|
||||||
|
FdInfo->PadValue = PadByte;
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
strcpy (FdInfo->OutFileName, OutFile);
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
Status = GenerateFvImage ((*FvInfo)->FvInfoFile);
|
||||||
|
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo = OrgFvInfoPtr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sort the Firmware Volume information. Firmware Volume with lower
|
||||||
|
// base addresses will be processed first and higher base address one
|
||||||
|
// will be processed later.
|
||||||
|
//
|
||||||
|
qsort ((VOID *) FvInfo, NumFvFiles, sizeof (FVINFO *), CompareItems);
|
||||||
|
|
||||||
|
LastAddress = (*FvInfo)->FvBaseAddress;
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumFvFiles; Index++) {
|
||||||
|
Status = BuildFirmwareDeviceBinaryFromFwVolumes (
|
||||||
|
(*FvInfo)->FvBaseAddress,
|
||||||
|
(*FvInfo)->FvFile,
|
||||||
|
FdInfo->OutFileName
|
||||||
|
);
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
CleanUpMemory ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FvInfo++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if any space left after copying data from all Firmware Volumes
|
||||||
|
// If yes, then fill those location with PadValue.
|
||||||
|
//
|
||||||
|
if ((FdInfo->FdBaseAddress + Size) > LastAddress) {
|
||||||
|
|
||||||
|
PadSize = (UINTN) ((FdInfo->FdBaseAddress + FdInfo->FdSize) - LastAddress);
|
||||||
|
Buffer = malloc (PadSize);
|
||||||
|
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("\nERROR: allocating PadSize memory in function GenerateFdImage.\n");
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < PadSize; Index++) {
|
||||||
|
*Buffer = FdInfo->PadValue;
|
||||||
|
Buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer -= PadSize;
|
||||||
|
|
||||||
|
Fp = fopen (OutFile, "a+b");
|
||||||
|
|
||||||
|
if (Fp == NULL) {
|
||||||
|
printf ("\nERROR:Opening file %s", OutFile);
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSize = _filelength (fileno (Fp));
|
||||||
|
fseek (Fp, FileSize, SEEK_SET);
|
||||||
|
NumByte = fwrite (Buffer, sizeof (UINT8), PadSize, Fp);
|
||||||
|
|
||||||
|
if (Buffer) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (Fp);
|
||||||
|
|
||||||
|
if (NumByte != (sizeof (UINT8) * PadSize)) {
|
||||||
|
printf ("\nERROR: Copying data from buffer to File %s ", OutFile);
|
||||||
|
CleanUpMemory ();
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Clean up all the memory which has been allocated so far.
|
||||||
|
//
|
||||||
|
CleanUpMemory ();
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
100
Tools/Source/TianoTools/GenFdImage/Makefile
Normal file
100
Tools/Source/TianoTools/GenFdImage/Makefile
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define some macros we use here. Should get rid of them someday and
|
||||||
|
# get rid of the extra level of indirection.
|
||||||
|
#
|
||||||
|
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common information
|
||||||
|
#
|
||||||
|
|
||||||
|
INC=$(INC) \
|
||||||
|
-I "$(TIANO_TOOLS_SOURCE)\GenFvImage"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME=GenFdImage
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
|
||||||
|
TARGET_LIB = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).lib
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.c"
|
||||||
|
TARGET_EXE_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImageExe.h" \
|
||||||
|
"$(TARGET_SOURCE_DIR)\GenFdImage.h" \
|
||||||
|
"$(COMMON_SOURCE)\ParseInf.h" \
|
||||||
|
"$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"
|
||||||
|
TARGET_EXE_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \
|
||||||
|
"$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \
|
||||||
|
"$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"
|
||||||
|
|
||||||
|
TARGET_LIB_SOURCE = "$(TARGET_SOURCE_DIR)\GenFdImageLib.c"
|
||||||
|
TARGET_LIB_INCLUDE = "$(TARGET_SOURCE_DIR)\GenFdImage.h" \
|
||||||
|
"$(TIANO_TOOLS_SOURCE)\GenFvImage\GenFvImage.h" \
|
||||||
|
"$(COMMON_SOURCE)\ParseInf.h" \
|
||||||
|
"$(EDK_SOURCE)\Foundation\Include\TianoCommon.h"
|
||||||
|
TARGET_LIB_LIBS = "$(TIANO_TOOLS_OUTPUT)\Common.lib" \
|
||||||
|
"$(TIANO_TOOLS_OUTPUT)\GenFvImage.lib" \
|
||||||
|
"$(TIANO_TOOLS_OUTPUT)\PeimFixup.lib"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_LIB) $(TARGET_EXE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_LIB)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build LIB
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TARGET_LIB): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj $(TARGET_LIB_LIBS)
|
||||||
|
$(LIB) $(LIB_FLAGS) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj /OUT:$(TARGET_LIB)
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj: $(TARGET_LIB_SOURCE) $(TARGET_LIB_INCLUDE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_LIB_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.obj
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME)Lib.* > NUL
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del /q $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
919
Tools/Source/TianoTools/GenTEImage/GenTEImage.c
Normal file
919
Tools/Source/TianoTools/GenTEImage/GenTEImage.c
Normal file
@ -0,0 +1,919 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999-2004 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
GenTEImage.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Utility program to shrink a PE32 image down by replacing
|
||||||
|
the DOS, PE, and optional headers with a minimal header.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Tiano.h"
|
||||||
|
#include "TianoCommon.h"
|
||||||
|
#include "EfiImage.h" // for PE32 structure definitions
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Version of this utility
|
||||||
|
//
|
||||||
|
#define UTILITY_NAME "GenTEImage"
|
||||||
|
#define UTILITY_VERSION "v0.11"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the max length of a filename
|
||||||
|
//
|
||||||
|
#define MAX_PATH 256
|
||||||
|
#define DEFAULT_OUTPUT_EXTENSION ".te"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use this to track our command-line options and globals
|
||||||
|
//
|
||||||
|
struct {
|
||||||
|
INT8 OutFileName[MAX_PATH];
|
||||||
|
INT8 InFileName[MAX_PATH];
|
||||||
|
INT8 Verbose;
|
||||||
|
INT8 Dump;
|
||||||
|
} mOptions;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use these to convert from machine type value to a named type
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINT16 Value;
|
||||||
|
INT8 *Name;
|
||||||
|
} STRING_LOOKUP;
|
||||||
|
|
||||||
|
static STRING_LOOKUP mMachineTypes[] = {
|
||||||
|
EFI_IMAGE_MACHINE_IA32,
|
||||||
|
"IA32",
|
||||||
|
EFI_IMAGE_MACHINE_IA64,
|
||||||
|
"IA64",
|
||||||
|
EFI_IMAGE_MACHINE_EBC,
|
||||||
|
"EBC",
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static STRING_LOOKUP mSubsystemTypes[] = {
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION,
|
||||||
|
"EFI application",
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,
|
||||||
|
"EFI boot service driver",
|
||||||
|
EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,
|
||||||
|
"EFI runtime driver",
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// Function prototypes
|
||||||
|
//
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ParseCommandLine (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
CheckPE32File (
|
||||||
|
INT8 *FileName,
|
||||||
|
FILE *Fptr,
|
||||||
|
UINT16 *MachineType,
|
||||||
|
UINT16 *SubSystem
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessFile (
|
||||||
|
INT8 *InFileName,
|
||||||
|
INT8 *OutFileName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
DumpImage (
|
||||||
|
INT8 *FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
INT8 *
|
||||||
|
GetMachineTypeStr (
|
||||||
|
UINT16 MachineType
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
INT8 *
|
||||||
|
GetSubsystemTypeStr (
|
||||||
|
UINT16 SubsystemType
|
||||||
|
);
|
||||||
|
|
||||||
|
main (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argc - standard C main() argument count
|
||||||
|
|
||||||
|
Argv - standard C main() argument list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
{
|
||||||
|
INT8 *Ext;
|
||||||
|
UINT32 Status;
|
||||||
|
|
||||||
|
SetUtilityName (UTILITY_NAME);
|
||||||
|
//
|
||||||
|
// Parse the command line arguments
|
||||||
|
//
|
||||||
|
if (ParseCommandLine (Argc, Argv)) {
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If dumping an image, then do that and quit
|
||||||
|
//
|
||||||
|
if (mOptions.Dump) {
|
||||||
|
DumpImage (mOptions.InFileName);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Determine the output filename. Either what they specified on
|
||||||
|
// the command line, or the first input filename with a different extension.
|
||||||
|
//
|
||||||
|
if (!mOptions.OutFileName[0]) {
|
||||||
|
strcpy (mOptions.OutFileName, mOptions.InFileName);
|
||||||
|
//
|
||||||
|
// Find the last . on the line and replace the filename extension with
|
||||||
|
// the default
|
||||||
|
//
|
||||||
|
for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1;
|
||||||
|
(Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\');
|
||||||
|
Ext--
|
||||||
|
)
|
||||||
|
;
|
||||||
|
//
|
||||||
|
// If dot here, then insert extension here, otherwise append
|
||||||
|
//
|
||||||
|
if (*Ext != '.') {
|
||||||
|
Ext = mOptions.OutFileName + strlen (mOptions.OutFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (Ext, DEFAULT_OUTPUT_EXTENSION);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure we don't have the same filename for input and output files
|
||||||
|
//
|
||||||
|
if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) {
|
||||||
|
Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Process the file
|
||||||
|
//
|
||||||
|
ProcessFile (mOptions.InFileName, mOptions.OutFileName);
|
||||||
|
Finish:
|
||||||
|
Status = GetUtilityStatus ();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
ProcessFile (
|
||||||
|
INT8 *InFileName,
|
||||||
|
INT8 *OutFileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Process a PE32 EFI file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
InFileName - the file name pointer to the input file
|
||||||
|
OutFileName - the file name pointer to the output file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS - the process has been finished successfully
|
||||||
|
STATUS_ERROR - error occured during the processing
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
STATUS Status;
|
||||||
|
FILE *InFptr;
|
||||||
|
FILE *OutFptr;
|
||||||
|
UINT16 MachineType;
|
||||||
|
UINT16 SubSystem;
|
||||||
|
EFI_TE_IMAGE_HEADER TEImageHeader;
|
||||||
|
UINT32 PESigOffset;
|
||||||
|
EFI_IMAGE_FILE_HEADER FileHeader;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64;
|
||||||
|
UINT32 BytesStripped;
|
||||||
|
UINT32 FileSize;
|
||||||
|
UINT8 *Buffer;
|
||||||
|
long SaveFilePosition;
|
||||||
|
|
||||||
|
InFptr = NULL;
|
||||||
|
OutFptr = NULL;
|
||||||
|
Buffer = NULL;
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to open the input file
|
||||||
|
//
|
||||||
|
if ((InFptr = fopen (InFileName, "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to open input file for reading");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Double-check the file to make sure it's what we expect it to be
|
||||||
|
//
|
||||||
|
if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) {
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize our new header
|
||||||
|
//
|
||||||
|
memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Seek to the end to get the file size
|
||||||
|
//
|
||||||
|
fseek (InFptr, 0, SEEK_END);
|
||||||
|
FileSize = ftell (InFptr);
|
||||||
|
fseek (InFptr, 0, SEEK_SET);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit
|
||||||
|
// offset (from the start of the file) to the PE signature, which always
|
||||||
|
// follows the MSDOS stub. The PE signature is immediately followed by the
|
||||||
|
// COFF file header.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
if (fseek (InFptr, 0x3C, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to seek to PE signature");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// We should now be at the COFF file header. Read it in and verify it's
|
||||||
|
// of an image type we support.
|
||||||
|
//
|
||||||
|
if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read file header from image");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Calculate the total number of bytes we're going to strip off. The '4' is for the
|
||||||
|
// PE signature PE\0\0. Then sanity check the size.
|
||||||
|
//
|
||||||
|
BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader;
|
||||||
|
if (BytesStripped >= FileSize) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BytesStripped &~0xFFFF) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader.StrippedSize = (UINT16) BytesStripped;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read in the optional header. Assume PE32, and if not, then re-read as PE32+
|
||||||
|
//
|
||||||
|
SaveFilePosition = ftell (InFptr);
|
||||||
|
if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
//
|
||||||
|
// Fill in our new header with required data directory entries
|
||||||
|
//
|
||||||
|
TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint;
|
||||||
|
//
|
||||||
|
// - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);
|
||||||
|
//
|
||||||
|
// We're going to pack the subsystem into 1 byte. Make sure it fits
|
||||||
|
//
|
||||||
|
if (OptionalHeader32.Subsystem &~0xFF) {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
InFileName,
|
||||||
|
NULL,
|
||||||
|
"image subsystem 0x%X cannot be packed into 1 byte",
|
||||||
|
(UINT32) OptionalHeader32.Subsystem
|
||||||
|
);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem;
|
||||||
|
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
||||||
|
TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
|
||||||
|
}
|
||||||
|
} else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
//
|
||||||
|
// Rewind and re-read the optional header
|
||||||
|
//
|
||||||
|
fseek (InFptr, SaveFilePosition, SEEK_SET);
|
||||||
|
if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint;
|
||||||
|
//
|
||||||
|
// - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER);
|
||||||
|
//
|
||||||
|
// We're going to pack the subsystem into 1 byte. Make sure it fits
|
||||||
|
//
|
||||||
|
if (OptionalHeader64.Subsystem &~0xFF) {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
InFileName,
|
||||||
|
NULL,
|
||||||
|
"image subsystem 0x%X cannot be packed into 1 byte",
|
||||||
|
(UINT32) OptionalHeader64.Subsystem
|
||||||
|
);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem;
|
||||||
|
TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode;
|
||||||
|
TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
InFileName,
|
||||||
|
"unsupported magic number 0x%X found in optional header",
|
||||||
|
(UINT32) OptionalHeader32.Magic
|
||||||
|
);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Fill in the remainder of our new image header
|
||||||
|
//
|
||||||
|
TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;
|
||||||
|
TEImageHeader.Machine = FileHeader.Machine;
|
||||||
|
//
|
||||||
|
// We're going to pack the number of sections into a single byte. Make sure it fits.
|
||||||
|
//
|
||||||
|
if (FileHeader.NumberOfSections &~0xFF) {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
InFileName,
|
||||||
|
NULL,
|
||||||
|
"image's number of sections 0x%X cannot be packed into 1 byte",
|
||||||
|
(UINT32) FileHeader.NumberOfSections
|
||||||
|
);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now open our output file
|
||||||
|
//
|
||||||
|
if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to open output file for writing");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Write the TE header
|
||||||
|
//
|
||||||
|
if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, "failed to write image header to output file", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Position into the input file, read the part we're not stripping, and
|
||||||
|
// write it out.
|
||||||
|
//
|
||||||
|
fseek (InFptr, BytesStripped, SEEK_SET);
|
||||||
|
Buffer = (UINT8 *) malloc (FileSize - BytesStripped);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
Error (NULL, 0, 0, "application error", "failed to allocate memory");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Finish:
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the output file. If there was an error, delete the output file so
|
||||||
|
// that a subsequent build will rebuild it.
|
||||||
|
//
|
||||||
|
if (OutFptr != NULL) {
|
||||||
|
fclose (OutFptr);
|
||||||
|
if (GetUtilityStatus () == STATUS_ERROR) {
|
||||||
|
remove (OutFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free up our buffer
|
||||||
|
//
|
||||||
|
if (Buffer != NULL) {
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
STATUS
|
||||||
|
CheckPE32File (
|
||||||
|
INT8 *FileName,
|
||||||
|
FILE *Fptr,
|
||||||
|
UINT16 *MachineType,
|
||||||
|
UINT16 *SubSystem
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName - GC_TODO: add argument description
|
||||||
|
Fptr - GC_TODO: add argument description
|
||||||
|
MachineType - GC_TODO: add argument description
|
||||||
|
SubSystem - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given a file pointer to a supposed PE32 image file, verify that it is indeed a
|
||||||
|
PE32 image file, and then return the machine type in the supplied pointer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Fptr File pointer to the already-opened PE32 file
|
||||||
|
MachineType Location to stuff the machine type of the PE32 file. This is needed
|
||||||
|
because the image may be Itanium-based, IA32, or EBC.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
EFI_IMAGE_DOS_HEADER DosHeader;
|
||||||
|
EFI_IMAGE_FILE_HEADER FileHdr;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER OptionalHdr;
|
||||||
|
UINT32 PESig;
|
||||||
|
STATUS Status;
|
||||||
|
|
||||||
|
Status = STATUS_ERROR;
|
||||||
|
//
|
||||||
|
// Position to the start of the file
|
||||||
|
//
|
||||||
|
fseek (Fptr, 0, SEEK_SET);
|
||||||
|
//
|
||||||
|
// Read the DOS header
|
||||||
|
//
|
||||||
|
if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the magic number (0x5A4D)
|
||||||
|
//
|
||||||
|
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
|
||||||
|
Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Position into the file and check the PE signature
|
||||||
|
//
|
||||||
|
fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
|
||||||
|
if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read PE signature bytes");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the PE signature in the header "PE\0\0"
|
||||||
|
//
|
||||||
|
if (PESig != EFI_IMAGE_NT_SIGNATURE) {
|
||||||
|
Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the file header
|
||||||
|
//
|
||||||
|
if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read PE file header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the optional header so we can get the subsystem
|
||||||
|
//
|
||||||
|
if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
*SubSystem = OptionalHdr.Subsystem;
|
||||||
|
if (mOptions.Verbose) {
|
||||||
|
fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Good to go
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Finish:
|
||||||
|
fseek (Fptr, 0, SEEK_SET);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
ParseCommandLine (
|
||||||
|
int Argc,
|
||||||
|
char *Argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Given the Argc/Argv program arguments, and a pointer to an options structure,
|
||||||
|
parse the command-line options and check their validity.
|
||||||
|
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argc - standard C main() argument count
|
||||||
|
Argv - standard C main() argument list
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
STATUS_SUCCESS success
|
||||||
|
non-zero otherwise
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ] - add argument and description to function comment
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Clear out the options
|
||||||
|
//
|
||||||
|
memset ((char *) &mOptions, 0, sizeof (mOptions));
|
||||||
|
//
|
||||||
|
// Skip over the program name
|
||||||
|
//
|
||||||
|
Argc--;
|
||||||
|
Argv++;
|
||||||
|
//
|
||||||
|
// If no arguments, assume they want usage info
|
||||||
|
//
|
||||||
|
if (Argc == 0) {
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Process until no more arguments
|
||||||
|
//
|
||||||
|
while ((Argc > 0) && ((Argv[0][0] == '-') || (Argv[0][0] == '/'))) {
|
||||||
|
//
|
||||||
|
// To simplify string comparisons, replace slashes with dashes
|
||||||
|
//
|
||||||
|
Argv[0][0] = '-';
|
||||||
|
if (stricmp (Argv[0], "-o") == 0) {
|
||||||
|
//
|
||||||
|
// Output filename specified with -o
|
||||||
|
// Make sure there's another parameter
|
||||||
|
//
|
||||||
|
if (Argc > 1) {
|
||||||
|
strcpy (mOptions.OutFileName, Argv[1]);
|
||||||
|
} else {
|
||||||
|
Error (NULL, 0, 0, Argv[0], "missing output file name with option");
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Argv++;
|
||||||
|
Argc--;
|
||||||
|
} else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {
|
||||||
|
//
|
||||||
|
// Help option
|
||||||
|
//
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
} else if (stricmp (Argv[0], "-v") == 0) {
|
||||||
|
//
|
||||||
|
// -v for verbose
|
||||||
|
//
|
||||||
|
mOptions.Verbose = 1;
|
||||||
|
} else if (stricmp (Argv[0], "-dump") == 0) {
|
||||||
|
//
|
||||||
|
// -dump for dumping an image
|
||||||
|
//
|
||||||
|
mOptions.Dump = 1;
|
||||||
|
} else {
|
||||||
|
Error (NULL, 0, 0, Argv[0], "unrecognized option");
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Next argument
|
||||||
|
//
|
||||||
|
Argv++;
|
||||||
|
Argc--;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Better be one more arg for input file name
|
||||||
|
//
|
||||||
|
if (Argc == 0) {
|
||||||
|
Error (NULL, 0, 0, "input file name required", NULL);
|
||||||
|
Usage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Argc != 1) {
|
||||||
|
Error (NULL, 0, 0, Argv[1], "extra arguments on command line");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (mOptions.InFileName, Argv[0]);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
Usage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Print usage information for this utility.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Nothing.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
static const char *Msg[] = {
|
||||||
|
UTILITY_NAME " version "UTILITY_VERSION " - TE image utility",
|
||||||
|
" Generate a TE image from an EFI PE32 image",
|
||||||
|
" Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName",
|
||||||
|
" [-e|-b] [FileName(s)]",
|
||||||
|
" where:",
|
||||||
|
" -v - for verbose output",
|
||||||
|
" -dump - to dump the input file to a text file",
|
||||||
|
" -h -? - for this help information",
|
||||||
|
" -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION,
|
||||||
|
" InFileName - name of the input PE32 file",
|
||||||
|
"",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
for (Index = 0; Msg[Index] != NULL; Index++) {
|
||||||
|
fprintf (stdout, "%s\n", Msg[Index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
DumpImage (
|
||||||
|
INT8 *FileName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Dump a specified image information
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileName - File name pointer to the image to dump
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Nothing.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *InFptr;
|
||||||
|
EFI_TE_IMAGE_HEADER TEImageHeader;
|
||||||
|
INT8 *NamePtr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open the input file
|
||||||
|
//
|
||||||
|
InFptr = NULL;
|
||||||
|
|
||||||
|
if ((InFptr = fopen (FileName, "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to open input file for reading");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) {
|
||||||
|
Error (NULL, 0, 0, FileName, "failed to read image header from input file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {
|
||||||
|
Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Dump the header
|
||||||
|
//
|
||||||
|
fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
fprintf (stdout, " Signature: 0x%04X (TE)\n", (UINT32) TEImageHeader.Signature);
|
||||||
|
NamePtr = GetMachineTypeStr (TEImageHeader.Machine);
|
||||||
|
fprintf (stdout, " Machine: 0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr);
|
||||||
|
NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem);
|
||||||
|
fprintf (stdout, " Subsystem: 0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr);
|
||||||
|
fprintf (stdout, " Number of sections 0x%02X\n", (UINT32) TEImageHeader.NumberOfSections);
|
||||||
|
fprintf (stdout, " Stripped size: 0x%04X\n", (UINT32) TEImageHeader.StrippedSize);
|
||||||
|
fprintf (stdout, " Entry point: 0x%08X\n", TEImageHeader.AddressOfEntryPoint);
|
||||||
|
fprintf (stdout, " Base of code: 0x%08X\n", TEImageHeader.BaseOfCode);
|
||||||
|
fprintf (stdout, " Data directories:\n");
|
||||||
|
fprintf (
|
||||||
|
stdout,
|
||||||
|
" %8X [%8X] RVA [size] of Base Relocation Directory\n",
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
|
||||||
|
);
|
||||||
|
fprintf (
|
||||||
|
stdout,
|
||||||
|
" %8X [%8X] RVA [size] of Debug Directory\n",
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
|
||||||
|
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size
|
||||||
|
);
|
||||||
|
|
||||||
|
Finish:
|
||||||
|
if (InFptr != NULL) {
|
||||||
|
fclose (InFptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
INT8 *
|
||||||
|
GetMachineTypeStr (
|
||||||
|
UINT16 MachineType
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
MachineType - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
|
||||||
|
for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) {
|
||||||
|
if (mMachineTypes[Index].Value == MachineType) {
|
||||||
|
return mMachineTypes[Index].Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
INT8 *
|
||||||
|
GetSubsystemTypeStr (
|
||||||
|
UINT16 SubsystemType
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
SubsystemType - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
int Index;
|
||||||
|
|
||||||
|
for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) {
|
||||||
|
if (mSubsystemTypes[Index].Value == SubsystemType) {
|
||||||
|
return mSubsystemTypes[Index].Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
68
Tools/Source/TianoTools/GenTEImage/Makefile
Normal file
68
Tools/Source/TianoTools/GenTEImage/Makefile
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2002 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the GenTEImage utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define the toolchain which is used to set build options and toolchain paths
|
||||||
|
#
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = GenTEImage
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
|
||||||
|
|
||||||
|
INC_DEPS = $(EDK_SOURCE)\Foundation\Efi\Include\EfiImage.h
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the EXE by compiling the source files, then linking the resultant
|
||||||
|
# object files together.
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj : $(TARGET_SRC_DIR)\$(TARGET_NAME).c $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\$(TARGET_NAME).c /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
973
Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
Normal file
973
Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
Normal file
@ -0,0 +1,973 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2005 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
PeiRebaseExe.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This contains all code necessary to build the PeiRebase.exe utility.
|
||||||
|
This utility relies heavily on the PeiRebase DLL. Definitions for both
|
||||||
|
can be found in the PEI Rebase Utility Specification, review draft.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "PeiRebaseExe.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "CommonLib.h"
|
||||||
|
#include "ParseInf.h"
|
||||||
|
#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
|
||||||
|
#include "FvLib.h"
|
||||||
|
|
||||||
|
#include "EfiUtilityMsgs.h"
|
||||||
|
|
||||||
|
extern EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ReadHeader (
|
||||||
|
IN FILE *InputFile,
|
||||||
|
OUT UINT32 *FvSize,
|
||||||
|
OUT BOOLEAN *ErasePolarity
|
||||||
|
);
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
int argc,
|
||||||
|
char **argv
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This utility relocates PEI XIP PE32s in a FV.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - Number of command line arguments
|
||||||
|
argv[]:
|
||||||
|
BaseAddress The base address to use for rebasing the FV. The correct
|
||||||
|
format is a hex number preceded by 0x.
|
||||||
|
InputFileName The name of the input FV file.
|
||||||
|
OutputFileName The name of the output FV file.
|
||||||
|
|
||||||
|
Arguments come in pair in any order.
|
||||||
|
-I InputFileName
|
||||||
|
-O OutputFileName
|
||||||
|
-B BaseAddress
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
0 No error conditions detected.
|
||||||
|
1 One or more of the input parameters is invalid.
|
||||||
|
2 A resource required by the utility was unavailable.
|
||||||
|
Most commonly this will be memory allocation or file creation.
|
||||||
|
3 PeiRebase.dll could not be loaded.
|
||||||
|
4 Error executing the PEI rebase.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT8 Index;
|
||||||
|
CHAR8 InputFileName[_MAX_PATH];
|
||||||
|
CHAR8 OutputFileName[_MAX_PATH];
|
||||||
|
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||||
|
BOOLEAN BaseAddressSet;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
FILE *InputFile;
|
||||||
|
FILE *OutputFile;
|
||||||
|
UINT64 FvOffset;
|
||||||
|
UINT32 FileCount;
|
||||||
|
int BytesRead;
|
||||||
|
EFI_FIRMWARE_VOLUME_HEADER *FvImage;
|
||||||
|
UINT32 FvSize;
|
||||||
|
EFI_FFS_FILE_HEADER *CurrentFile;
|
||||||
|
BOOLEAN ErasePolarity;
|
||||||
|
EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress;
|
||||||
|
|
||||||
|
ErasePolarity = FALSE;
|
||||||
|
//
|
||||||
|
// Set utility name for error/warning reporting purposes.
|
||||||
|
//
|
||||||
|
SetUtilityName (UTILITY_NAME);
|
||||||
|
//
|
||||||
|
// Verify the correct number of arguments
|
||||||
|
//
|
||||||
|
if (argc != MAX_ARGS) {
|
||||||
|
PrintUsage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize variables
|
||||||
|
//
|
||||||
|
InputFileName[0] = 0;
|
||||||
|
OutputFileName[0] = 0;
|
||||||
|
BaseAddress = 0;
|
||||||
|
BaseAddressSet = FALSE;
|
||||||
|
FvOffset = 0;
|
||||||
|
FileCount = 0;
|
||||||
|
ErasePolarity = FALSE;
|
||||||
|
InputFile = NULL;
|
||||||
|
OutputFile = NULL;
|
||||||
|
FvImage = NULL;
|
||||||
|
//
|
||||||
|
// Parse the command line arguments
|
||||||
|
//
|
||||||
|
for (Index = 1; Index < MAX_ARGS; Index += 2) {
|
||||||
|
//
|
||||||
|
// Make sure argument pair begin with - or /
|
||||||
|
//
|
||||||
|
if (argv[Index][0] != '-' && argv[Index][0] != '/') {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index], "unrecognized option");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure argument specifier is only one letter
|
||||||
|
//
|
||||||
|
if (argv[Index][2] != 0) {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index], "unrecognized option");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Determine argument to read
|
||||||
|
//
|
||||||
|
switch (argv[Index][1]) {
|
||||||
|
case 'I':
|
||||||
|
case 'i':
|
||||||
|
if (strlen (InputFileName) == 0) {
|
||||||
|
strcpy (InputFileName, argv[Index + 1]);
|
||||||
|
} else {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
if (strlen (OutputFileName) == 0) {
|
||||||
|
strcpy (OutputFileName, argv[Index + 1]);
|
||||||
|
} else {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
if (!BaseAddressSet) {
|
||||||
|
Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseAddressSet = TRUE;
|
||||||
|
} else {
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PrintUsage ();
|
||||||
|
Error (NULL, 0, 0, argv[Index], "unrecognized argument");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the file containing the FV
|
||||||
|
//
|
||||||
|
InputFile = fopen (InputFileName, "rb");
|
||||||
|
if (InputFile == NULL) {
|
||||||
|
Error (NULL, 0, 0, InputFileName, "could not open input file for reading");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Determine size of FV
|
||||||
|
//
|
||||||
|
Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "could not parse the FV header", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Allocate a buffer for the FV image
|
||||||
|
//
|
||||||
|
FvImage = malloc (FvSize);
|
||||||
|
if (FvImage == NULL) {
|
||||||
|
Error (NULL, 0, 0, "application error", "memory allocation failed");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the entire FV to the buffer
|
||||||
|
//
|
||||||
|
BytesRead = fread (FvImage, 1, FvSize, InputFile);
|
||||||
|
fclose (InputFile);
|
||||||
|
InputFile = NULL;
|
||||||
|
if ((unsigned int) BytesRead != FvSize) {
|
||||||
|
Error (NULL, 0, 0, InputFileName, "failed to read from file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Prepare to walk the FV image
|
||||||
|
//
|
||||||
|
InitializeFvLib (FvImage, FvSize);
|
||||||
|
//
|
||||||
|
// Get the first file
|
||||||
|
//
|
||||||
|
Status = GetNextFile (NULL, &CurrentFile);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if each file should be rebased
|
||||||
|
//
|
||||||
|
while (CurrentFile != NULL) {
|
||||||
|
//
|
||||||
|
// Rebase this file
|
||||||
|
//
|
||||||
|
CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);
|
||||||
|
Status = FfsRebase (CurrentFile, CurrentFileBaseAddress);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
switch (Status) {
|
||||||
|
|
||||||
|
case EFI_INVALID_PARAMETER:
|
||||||
|
Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_ABORTED:
|
||||||
|
Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_OUT_OF_RESOURCES:
|
||||||
|
Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_NOT_FOUND:
|
||||||
|
Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the next file
|
||||||
|
//
|
||||||
|
Status = GetNextFile (CurrentFile, &CurrentFile);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the output file
|
||||||
|
//
|
||||||
|
OutputFile = fopen (OutputFileName, "wb");
|
||||||
|
if (OutputFile == NULL) {
|
||||||
|
Error (NULL, 0, 0, OutputFileName, "failed to open output file");
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) {
|
||||||
|
Error (NULL, 0, 0, "failed to write to output file", 0);
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finish:
|
||||||
|
if (InputFile != NULL) {
|
||||||
|
fclose (InputFile);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If we created an output file, and there was an error, remove it so
|
||||||
|
// subsequent builds will rebuild it.
|
||||||
|
//
|
||||||
|
if (OutputFile != NULL) {
|
||||||
|
if (GetUtilityStatus () == STATUS_ERROR) {
|
||||||
|
remove (OutputFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (OutputFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FvImage != NULL) {
|
||||||
|
free (FvImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetUtilityStatus ();
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ReadHeader (
|
||||||
|
IN FILE *InputFile,
|
||||||
|
OUT UINT32 *FvSize,
|
||||||
|
OUT BOOLEAN *ErasePolarity
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function determines the size of the FV and the erase polarity. The
|
||||||
|
erase polarity is the FALSE value for file state.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
InputFile The file that contains the FV image.
|
||||||
|
FvSize The size of the FV.
|
||||||
|
ErasePolarity The FV erase polarity.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS Function completed successfully.
|
||||||
|
EFI_INVALID_PARAMETER A required parameter was NULL or is out of range.
|
||||||
|
EFI_ABORTED The function encountered an error.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
|
||||||
|
EFI_FV_BLOCK_MAP_ENTRY BlockMap;
|
||||||
|
UINTN Signature[2];
|
||||||
|
UINTN BytesRead;
|
||||||
|
UINT32 Size;
|
||||||
|
|
||||||
|
BytesRead = 0;
|
||||||
|
Size = 0;
|
||||||
|
//
|
||||||
|
// Check input parameters
|
||||||
|
//
|
||||||
|
if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) {
|
||||||
|
Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter");
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the header
|
||||||
|
//
|
||||||
|
fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
|
||||||
|
BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);
|
||||||
|
Signature[0] = VolumeHeader.Signature;
|
||||||
|
Signature[1] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get erase polarity
|
||||||
|
//
|
||||||
|
if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {
|
||||||
|
*ErasePolarity = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);
|
||||||
|
BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
|
||||||
|
|
||||||
|
if (BlockMap.NumBlocks != 0) {
|
||||||
|
Size += BlockMap.NumBlocks * BlockMap.BlockLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0));
|
||||||
|
|
||||||
|
if (VolumeHeader.FvLength != Size) {
|
||||||
|
Error (NULL, 0, 0, "volume size not consistant with block maps", NULL);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
*FvSize = Size;
|
||||||
|
|
||||||
|
rewind (InputFile);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the standard utility information to SDTOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"%s, PEI Rebase Utility. Version %i.%i, %s.\n\n",
|
||||||
|
UTILITY_NAME,
|
||||||
|
UTILITY_MAJOR_VERSION,
|
||||||
|
UTILITY_MINOR_VERSION,
|
||||||
|
UTILITY_DATE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the utility usage syntax to STDOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"Usage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",
|
||||||
|
UTILITY_NAME
|
||||||
|
);
|
||||||
|
printf (" Where:\n");
|
||||||
|
printf (" InputFileName is the name of the EFI FV file to rebase.\n");
|
||||||
|
printf (" OutputFileName is the desired output file name.\n");
|
||||||
|
printf (" BaseAddress is the FV base address to rebase agains.\n");
|
||||||
|
printf (" Argument pair may be in any order.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
FfsRebase (
|
||||||
|
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function determines if a file is XIP and should be rebased. It will
|
||||||
|
rebase any PE32 sections found in the file using the base address.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FfsFile A pointer to Ffs file image.
|
||||||
|
BaseAddress The base address to use for rebasing the file image.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS The image was properly rebased.
|
||||||
|
EFI_INVALID_PARAMETER An input parameter is invalid.
|
||||||
|
EFI_ABORTED An error occurred while rebasing the input file image.
|
||||||
|
EFI_OUT_OF_RESOURCES Could not allocate a required resource.
|
||||||
|
EFI_NOT_FOUND No compressed sections could be found.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
UINTN MemoryImagePointer;
|
||||||
|
UINTN MemoryImagePointerAligned;
|
||||||
|
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||||
|
UINT64 ImageSize;
|
||||||
|
EFI_PHYSICAL_ADDRESS EntryPoint;
|
||||||
|
UINT32 Pe32ImageSize;
|
||||||
|
UINT32 NewPe32BaseAddress;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_FILE_SECTION_POINTER CurrentPe32Section;
|
||||||
|
EFI_FFS_FILE_STATE SavedState;
|
||||||
|
EFI_IMAGE_NT_HEADERS *PeHdr;
|
||||||
|
UINT32 *PeHdrSizeOfImage;
|
||||||
|
UINT32 *PeHdrChecksum;
|
||||||
|
UINT32 FoundCount;
|
||||||
|
EFI_TE_IMAGE_HEADER *TEImageHeader;
|
||||||
|
UINT8 *TEBuffer;
|
||||||
|
EFI_IMAGE_DOS_HEADER *DosHeader;
|
||||||
|
UINT8 FileGuidString[80];
|
||||||
|
UINT32 TailSize;
|
||||||
|
EFI_FFS_FILE_TAIL TailValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify input parameters
|
||||||
|
//
|
||||||
|
if (FfsFile == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Convert the GUID to a string so we can at least report which file
|
||||||
|
// if we find an error.
|
||||||
|
//
|
||||||
|
PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
|
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
||||||
|
} else {
|
||||||
|
TailSize = 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Do some cursory checks on the FFS file contents
|
||||||
|
//
|
||||||
|
Status = VerifyFfsFile (FfsFile);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString);
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if XIP file type. If not XIP, don't rebase.
|
||||||
|
//
|
||||||
|
if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
|
||||||
|
FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
|
||||||
|
FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
|
||||||
|
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
|
||||||
|
) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Rebase each PE32 section
|
||||||
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
FoundCount = 0;
|
||||||
|
for (Index = 1;; Index++) {
|
||||||
|
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FoundCount++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section
|
||||||
|
//
|
||||||
|
NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize context
|
||||||
|
//
|
||||||
|
memset (&ImageContext, 0, sizeof (ImageContext));
|
||||||
|
ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));
|
||||||
|
ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
|
||||||
|
|
||||||
|
Status = mPeCoffLoader.GetImageInfo (&mPeCoffLoader, &ImageContext);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Allocate a buffer for the image to be loaded into.
|
||||||
|
//
|
||||||
|
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);
|
||||||
|
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
|
||||||
|
if (MemoryImagePointer == 0) {
|
||||||
|
Error (NULL, 0, 0, "memory allocation failure", NULL);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
|
||||||
|
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
|
||||||
|
|
||||||
|
|
||||||
|
ImageContext.ImageAddress = MemoryImagePointerAligned;
|
||||||
|
|
||||||
|
Status = mPeCoffLoader.LoadImage (&mPeCoffLoader, &ImageContext);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
||||||
|
Status = mPeCoffLoader.RelocateImage (&mPeCoffLoader, &ImageContext);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageAddress = ImageContext.ImageAddress;
|
||||||
|
ImageSize = ImageContext.ImageSize;
|
||||||
|
EntryPoint = ImageContext.EntryPoint;
|
||||||
|
|
||||||
|
if (ImageSize > Pe32ImageSize) {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"rebased image is larger than original PE32 image",
|
||||||
|
"0x%X > 0x%X, file %s",
|
||||||
|
ImageSize,
|
||||||
|
Pe32ImageSize,
|
||||||
|
FileGuidString
|
||||||
|
);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Since we may have updated the Codeview RVA, we need to insure the PE
|
||||||
|
// header indicates the image is large enough to contain the Codeview data
|
||||||
|
// so it will be loaded properly later if the PEIM is reloaded into memory...
|
||||||
|
//
|
||||||
|
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
|
||||||
|
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
|
||||||
|
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
|
||||||
|
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
|
||||||
|
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
|
||||||
|
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
|
||||||
|
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
|
||||||
|
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
|
||||||
|
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
|
||||||
|
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
|
||||||
|
} else {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"unknown machine type in PE32 image",
|
||||||
|
"machine type=0x%X, file=%s",
|
||||||
|
(UINT32) PeHdr->FileHeader.Machine,
|
||||||
|
FileGuidString
|
||||||
|
);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
|
||||||
|
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
|
||||||
|
if (*PeHdrChecksum) {
|
||||||
|
*PeHdrChecksum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);
|
||||||
|
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now update file checksum
|
||||||
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
|
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
||||||
|
} else {
|
||||||
|
TailSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||||
|
SavedState = FfsFile->State;
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = 0;
|
||||||
|
FfsFile->State = 0;
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
|
||||||
|
(UINT8 *) FfsFile,
|
||||||
|
GetLength (FfsFile->Size) - TailSize
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
FfsFile->State = SavedState;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Update tail if present
|
||||||
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
|
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
|
||||||
|
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Now process TE sections
|
||||||
|
//
|
||||||
|
for (Index = 1;; Index++) {
|
||||||
|
Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FoundCount++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
|
||||||
|
// by GenTEImage
|
||||||
|
//
|
||||||
|
TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
|
||||||
|
|
||||||
|
NewPe32BaseAddress = ((UINT32) BaseAddress) +
|
||||||
|
(
|
||||||
|
(UINTN) CurrentPe32Section.Pe32Section +
|
||||||
|
sizeof (EFI_COMMON_SECTION_HEADER) +
|
||||||
|
sizeof (EFI_TE_IMAGE_HEADER) -
|
||||||
|
TEImageHeader->StrippedSize -
|
||||||
|
(UINTN) FfsFile
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate a buffer to unshrink the image into.
|
||||||
|
//
|
||||||
|
Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
||||||
|
sizeof (EFI_TE_IMAGE_HEADER);
|
||||||
|
Pe32ImageSize += TEImageHeader->StrippedSize;
|
||||||
|
TEBuffer = (UINT8 *) malloc (Pe32ImageSize);
|
||||||
|
if (TEBuffer == NULL) {
|
||||||
|
Error (NULL, 0, 0, "failed to allocate memory", NULL);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Expand the image into our buffer and fill in critical fields in the DOS header
|
||||||
|
// Fill in fields required by the loader.
|
||||||
|
// At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value
|
||||||
|
// itself.
|
||||||
|
//
|
||||||
|
memset (TEBuffer, 0, Pe32ImageSize);
|
||||||
|
DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;
|
||||||
|
DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;
|
||||||
|
*(UINT32 *) (TEBuffer + 0x3C) = 0x40;
|
||||||
|
PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);
|
||||||
|
PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
|
||||||
|
PeHdr->FileHeader.Machine = TEImageHeader->Machine;
|
||||||
|
PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and
|
||||||
|
// the 0x40 bytes for our DOS header.
|
||||||
|
//
|
||||||
|
PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));
|
||||||
|
PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
|
||||||
|
PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem;
|
||||||
|
PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;
|
||||||
|
PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *
|
||||||
|
sizeof (EFI_IMAGE_SECTION_HEADER) - 12;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set NumberOfRvaAndSizes in the optional header to what we had available in the original image
|
||||||
|
//
|
||||||
|
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||
|
||||||
|
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
|
||||||
|
) {
|
||||||
|
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;
|
||||||
|
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||
|
||||||
|
(TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)
|
||||||
|
) {
|
||||||
|
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
|
||||||
|
PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
|
||||||
|
if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {
|
||||||
|
PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// NOTE: These values are defaults, and should be verified to be correct in the GenTE utility
|
||||||
|
//
|
||||||
|
PeHdr->OptionalHeader.SectionAlignment = 0x10;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the rest of the image to its original offset
|
||||||
|
//
|
||||||
|
memcpy (
|
||||||
|
TEBuffer + TEImageHeader->StrippedSize,
|
||||||
|
(UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),
|
||||||
|
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
||||||
|
sizeof (EFI_TE_IMAGE_HEADER)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize context
|
||||||
|
//
|
||||||
|
memset (&ImageContext, 0, sizeof (ImageContext));
|
||||||
|
ImageContext.Handle = (VOID *) TEBuffer;
|
||||||
|
ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
|
||||||
|
|
||||||
|
Status = mPeCoffLoader.GetImageInfo (&mPeCoffLoader, &ImageContext);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);
|
||||||
|
free (TEBuffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Allocate a buffer for the image to be loaded into.
|
||||||
|
//
|
||||||
|
MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));
|
||||||
|
if (MemoryImagePointer == 0) {
|
||||||
|
Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);
|
||||||
|
free (TEBuffer);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);
|
||||||
|
MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);
|
||||||
|
|
||||||
|
|
||||||
|
ImageContext.ImageAddress = MemoryImagePointerAligned;
|
||||||
|
Status = mPeCoffLoader.LoadImage (&mPeCoffLoader, &ImageContext);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);
|
||||||
|
free (TEBuffer);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
||||||
|
Status = mPeCoffLoader.RelocateImage (&mPeCoffLoader, &ImageContext);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
free (TEBuffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageAddress = ImageContext.ImageAddress;
|
||||||
|
ImageSize = ImageContext.ImageSize;
|
||||||
|
EntryPoint = ImageContext.EntryPoint;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Since we may have updated the Codeview RVA, we need to insure the PE
|
||||||
|
// header indicates the image is large enough to contain the Codeview data
|
||||||
|
// so it will be loaded properly later if the PEIM is reloaded into memory...
|
||||||
|
//
|
||||||
|
PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);
|
||||||
|
if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
|
||||||
|
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);
|
||||||
|
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);
|
||||||
|
} else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
|
||||||
|
PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);
|
||||||
|
PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);
|
||||||
|
} else {
|
||||||
|
Error (
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"unknown machine type in TE image",
|
||||||
|
"machine type=0x%X, file=%s",
|
||||||
|
(UINT32) PeHdr->FileHeader.Machine,
|
||||||
|
FileGuidString
|
||||||
|
);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
free (TEBuffer);
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*PeHdrSizeOfImage != ImageContext.ImageSize) {
|
||||||
|
*PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;
|
||||||
|
if (*PeHdrChecksum) {
|
||||||
|
*PeHdrChecksum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
|
||||||
|
memcpy (
|
||||||
|
(UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),
|
||||||
|
(VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),
|
||||||
|
GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -
|
||||||
|
sizeof (EFI_TE_IMAGE_HEADER)
|
||||||
|
);
|
||||||
|
free ((VOID *) MemoryImagePointer);
|
||||||
|
free (TEBuffer);
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
|
TailSize = sizeof (EFI_FFS_FILE_TAIL);
|
||||||
|
} else {
|
||||||
|
TailSize = 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Now update file checksum
|
||||||
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||||
|
SavedState = FfsFile->State;
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = 0;
|
||||||
|
FfsFile->State = 0;
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
|
||||||
|
(UINT8 *) FfsFile,
|
||||||
|
GetLength (FfsFile->Size) - TailSize
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
FfsFile->State = SavedState;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Update tail if present
|
||||||
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
|
TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));
|
||||||
|
*(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If we found no files, then emit an error if no compressed sections either
|
||||||
|
//
|
||||||
|
if (FoundCount == 0) {
|
||||||
|
Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
FfsRebaseImageRead (
|
||||||
|
IN VOID *FileHandle,
|
||||||
|
IN UINTN FileOffset,
|
||||||
|
IN OUT UINT32 *ReadSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileHandle - The handle to the PE/COFF file
|
||||||
|
|
||||||
|
FileOffset - The offset, in bytes, into the file to read
|
||||||
|
|
||||||
|
ReadSize - The number of bytes to read from the file starting at FileOffset
|
||||||
|
|
||||||
|
Buffer - A pointer to the buffer to read the data into.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CHAR8 *Destination8;
|
||||||
|
CHAR8 *Source8;
|
||||||
|
UINT32 Length;
|
||||||
|
|
||||||
|
Destination8 = Buffer;
|
||||||
|
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
|
||||||
|
Length = *ReadSize;
|
||||||
|
while (Length--) {
|
||||||
|
*(Destination8++) = *(Source8++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
153
Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.h
Normal file
153
Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
PeiRebaseExe.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Definitions for the PeiRebase exe utility.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _EFI_PEIM_FIXUP_EXE_H
|
||||||
|
#define _EFI_PEIM_FIXUP_EXE_H
|
||||||
|
|
||||||
|
#include "Efi2WinNt.h"
|
||||||
|
#include "EfiFirmwareFileSystem.h"
|
||||||
|
#include "EfiFirmwareVolumeHeader.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility Name
|
||||||
|
//
|
||||||
|
#define UTILITY_NAME "PeiRebase"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility version information
|
||||||
|
//
|
||||||
|
#define UTILITY_MAJOR_VERSION 0
|
||||||
|
#define UTILITY_MINOR_VERSION 1
|
||||||
|
#define UTILITY_DATE __DATE__
|
||||||
|
|
||||||
|
//
|
||||||
|
// The maximum number of arguments accepted from the command line.
|
||||||
|
//
|
||||||
|
#define MAX_ARGS 7
|
||||||
|
|
||||||
|
//
|
||||||
|
// The file copy buffer size
|
||||||
|
//
|
||||||
|
#define FILE_COPY_BUFFER_SIZE 512
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays general utility information
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays the utility usage message.
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal function declarations
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
FfsRebaseImageRead (
|
||||||
|
IN VOID *FileHandle,
|
||||||
|
IN UINTN FileOffset,
|
||||||
|
IN OUT UINT32 *ReadSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FileHandle - GC_TODO: add argument description
|
||||||
|
FileOffset - GC_TODO: add argument description
|
||||||
|
ReadSize - GC_TODO: add argument description
|
||||||
|
Buffer - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
FfsRebase (
|
||||||
|
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FfsFile - GC_TODO: add argument description
|
||||||
|
BaseAddress - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
71
Tools/Source/TianoTools/PeiRebase/makefile
Normal file
71
Tools/Source/TianoTools/PeiRebase/makefile
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name:
|
||||||
|
#
|
||||||
|
# makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# makefile for building the PeiRebase utility.
|
||||||
|
#
|
||||||
|
# Revision History
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure environmental variable EFI_SOURCE is set
|
||||||
|
#
|
||||||
|
!IFNDEF EFI_SOURCE
|
||||||
|
!ERROR EFI_SOURCE environmental variable not set
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = PeiRebase
|
||||||
|
TARGET_SRC_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\PeiRebase.exe
|
||||||
|
TARGET_EXE_LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\PeiRebase.obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compile each source file
|
||||||
|
#
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\PeiRebase.obj : $(TARGET_SRC_DIR)\PeiRebaseExe.c $(INC_DEPS) $(TARGET_EXE_LIBS)
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_SRC_DIR)\PeiRebaseExe.c /Fo$@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Link the object files together
|
||||||
|
#
|
||||||
|
$(TARGET_EXE) : $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
@echo LINKING
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(OBJECTS) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
58
Tools/Source/TianoTools/SecApResetVectorFixup/Makefile
Normal file
58
Tools/Source/TianoTools/SecApResetVectorFixup/Makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2005 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = SecApResetVectorFixup
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
TARGET_EXE_SOURCE = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
LIBS = $(TIANO_TOOLS_OUTPUT)\Common.lib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
@ -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
|
57
Tools/Source/TianoTools/SecFixup/Makefile
Normal file
57
Tools/Source/TianoTools/SecFixup/Makefile
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME = SecFixup
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
TARGET_EXE_SOURCE = $(TARGET_SOURCE_DIR)\$(TARGET_NAME).c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
OBJECTS = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(OBJECTS) : $(TARGET_EXE_SOURCE) $(INC_DEPS)
|
||||||
|
$(CC) $(C_FLAGS) $(TARGET_EXE_SOURCE) /Fo$@
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(OBJECTS)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(OBJECTS) $(LIBS) /out:$(TARGET_EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(EDK_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
362
Tools/Source/TianoTools/SecFixup/SecFixup.c
Normal file
362
Tools/Source/TianoTools/SecFixup/SecFixup.c
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
SecFixup.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This utility is part of build process for IA32 SEC FFS file.
|
||||||
|
|
||||||
|
It fixup the reset vector data. The reset vector data binary file
|
||||||
|
will be wrapped as a RAW section and be located immediately after
|
||||||
|
the PE/TE section.
|
||||||
|
|
||||||
|
The SEC EXE file can be either PE or TE file.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "EfiCommon.h"
|
||||||
|
#include "EfiImage.h"
|
||||||
|
#include "EfiImageFormat.h"
|
||||||
|
#include "EfiUtilityMsgs.c"
|
||||||
|
|
||||||
|
#include "SecFixup.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the standard utility information to SDTOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",
|
||||||
|
UTILITY_NAME,
|
||||||
|
UTILITY_MAJOR_VERSION,
|
||||||
|
UTILITY_MINOR_VERSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Displays the utility usage syntax to STDOUT
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME);
|
||||||
|
printf (" Where:\n");
|
||||||
|
printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");
|
||||||
|
printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");
|
||||||
|
printf ("\tOutputFileName - Name of the output file.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
main (
|
||||||
|
IN INTN argc,
|
||||||
|
IN CHAR8 **argv
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Main function.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - Number of command line parameters.
|
||||||
|
argv - Array of pointers to parameter strings.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - Utility exits successfully.
|
||||||
|
STATUS_ERROR - Some error occurred during execution.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *FpIn;
|
||||||
|
|
||||||
|
FILE *FpOut;
|
||||||
|
UINT32 AddressOfEntryPoint;
|
||||||
|
INT32 DestRel;
|
||||||
|
STATUS Status;
|
||||||
|
UINT32 SecFileSize;
|
||||||
|
|
||||||
|
SetUtilityName (UTILITY_NAME);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Display utility information
|
||||||
|
//
|
||||||
|
PrintUtilityInfo ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify the correct number of arguments
|
||||||
|
//
|
||||||
|
if (argc != MAX_ARGS) {
|
||||||
|
Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
|
||||||
|
PrintUsage ();
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the SEC exe file
|
||||||
|
//
|
||||||
|
if ((FpIn = fopen (argv[1], "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, "Unable to open file", argv[1]);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the entry point of the EXE file
|
||||||
|
//
|
||||||
|
Status = GetEntryPoint (FpIn, &AddressOfEntryPoint);
|
||||||
|
if (Status != STATUS_SUCCESS) {
|
||||||
|
fclose (FpIn);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the SEC file size
|
||||||
|
//
|
||||||
|
fseek (FpIn, 0, SEEK_END);
|
||||||
|
SecFileSize = ftell (FpIn);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close the SEC file
|
||||||
|
//
|
||||||
|
fclose (FpIn);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open the reset vector data file
|
||||||
|
//
|
||||||
|
if ((FpIn = fopen (argv[2], "rb")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, "Unable to open file", argv[2]);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Open the output file
|
||||||
|
//
|
||||||
|
if ((FpOut = fopen (argv[3], "w+b")) == NULL) {
|
||||||
|
Error (NULL, 0, 0, "Unable to open file", argv[3]);
|
||||||
|
fclose (FpIn);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Copy the input file to the output file
|
||||||
|
//
|
||||||
|
if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) {
|
||||||
|
fclose (FpIn);
|
||||||
|
fclose (FpOut);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the reset vector data file
|
||||||
|
//
|
||||||
|
fclose (FpIn);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix the destination relative in the jmp instruction
|
||||||
|
// in the reset vector data structure
|
||||||
|
//
|
||||||
|
fseek (FpOut, -DEST_REL_OFFSET, SEEK_END);
|
||||||
|
DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2);
|
||||||
|
if (DestRel <= -65536) {
|
||||||
|
Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL);
|
||||||
|
fclose (FpOut);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) {
|
||||||
|
Error (NULL, 0, 0, "Failed to write to the output file", NULL);
|
||||||
|
fclose (FpOut);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the output file
|
||||||
|
//
|
||||||
|
fclose (FpOut);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
GetEntryPoint (
|
||||||
|
IN FILE *ExeFile,
|
||||||
|
OUT UINT32 *EntryPoint
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Get the address of the entry point of a PE/TE file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
PeFile - File pointer to the specified PE/TE file.
|
||||||
|
EntryPoint - Buffer for the address of the entry point to be returned.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - Function completed successfully.
|
||||||
|
STATUS_ERROR - Error occured.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
// GC_TODO: ExeFile - add argument and description to function comment
|
||||||
|
{
|
||||||
|
EFI_IMAGE_DOS_HEADER DosHeader;
|
||||||
|
EFI_IMAGE_NT_HEADERS32 NtHeader;
|
||||||
|
EFI_TE_IMAGE_HEADER TeHeader;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if it is a TE file
|
||||||
|
//
|
||||||
|
fseek (ExeFile, 0, SEEK_SET);
|
||||||
|
//
|
||||||
|
// Attempt to read the TE header
|
||||||
|
//
|
||||||
|
if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) {
|
||||||
|
if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
|
||||||
|
if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) {
|
||||||
|
Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if it is a PE file
|
||||||
|
//
|
||||||
|
fseek (ExeFile, 0, SEEK_SET);
|
||||||
|
//
|
||||||
|
// Attempt to read the DOS header
|
||||||
|
//
|
||||||
|
if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) {
|
||||||
|
goto InvalidFile;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the magic number
|
||||||
|
//
|
||||||
|
if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
|
||||||
|
goto InvalidFile;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Position into the file and read the NT PE header
|
||||||
|
//
|
||||||
|
fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET);
|
||||||
|
if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) {
|
||||||
|
goto InvalidFile;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the PE signature in the header
|
||||||
|
//
|
||||||
|
if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) {
|
||||||
|
goto InvalidFile;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Make sure the PE file is PE32 for IA32
|
||||||
|
//
|
||||||
|
if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 ||
|
||||||
|
NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
|
||||||
|
) {
|
||||||
|
Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the entry point from the optional header
|
||||||
|
//
|
||||||
|
*EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
InvalidFile:
|
||||||
|
Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS
|
||||||
|
CopyFile (
|
||||||
|
FILE *FpIn,
|
||||||
|
FILE *FpOut
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Copy file.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FpIn - File pointer to the source file.
|
||||||
|
FpOut - File pointer to the destination file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
STATUS_SUCCESS - Function completed successfully.
|
||||||
|
STATUS_ERROR - Error occured.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
INTN FileSize;
|
||||||
|
|
||||||
|
INTN Offset;
|
||||||
|
|
||||||
|
INTN Length;
|
||||||
|
UINT8 Buffer[BUF_SIZE];
|
||||||
|
|
||||||
|
fseek (FpIn, 0, SEEK_END);
|
||||||
|
FileSize = ftell (FpIn);
|
||||||
|
|
||||||
|
fseek (FpIn, 0, SEEK_SET);
|
||||||
|
fseek (FpOut, 0, SEEK_SET);
|
||||||
|
|
||||||
|
Offset = 0;
|
||||||
|
while (Offset < FileSize) {
|
||||||
|
Length = sizeof (Buffer);
|
||||||
|
if (FileSize - Offset < Length) {
|
||||||
|
Length = FileSize - Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) {
|
||||||
|
Error (NULL, 0, 0, "Copy file error", NULL);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset += Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
146
Tools/Source/TianoTools/SecFixup/SecFixup.h
Normal file
146
Tools/Source/TianoTools/SecFixup/SecFixup.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
SecFixup.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Definitions for the SecFixup utility.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _SEC_FIXUP_H
|
||||||
|
#define _SEC_FIXUP_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility Name
|
||||||
|
//
|
||||||
|
#define UTILITY_NAME "SecFixup"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility version information
|
||||||
|
//
|
||||||
|
#define UTILITY_MAJOR_VERSION 0
|
||||||
|
#define UTILITY_MINOR_VERSION 1
|
||||||
|
#define UTILITY_DATE __DATE__
|
||||||
|
|
||||||
|
//
|
||||||
|
// The maximum number of arguments accepted from the command line.
|
||||||
|
//
|
||||||
|
#define MAX_ARGS 4
|
||||||
|
|
||||||
|
#define DEST_REL_OFFSET 13
|
||||||
|
#define BUF_SIZE (8 * 1024)
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays general utility information
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUtilityInfo (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that displays the utility usage message.
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
PrintUsage (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that gets the entry point of a PE/TE file.
|
||||||
|
//
|
||||||
|
STATUS
|
||||||
|
GetEntryPoint (
|
||||||
|
IN FILE *ExeFile,
|
||||||
|
OUT UINT32 *EntryPoint
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
ExeFile - GC_TODO: add argument description
|
||||||
|
EntryPoint - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The function that copies a file.
|
||||||
|
//
|
||||||
|
STATUS
|
||||||
|
CopyFile (
|
||||||
|
FILE *FpIn,
|
||||||
|
FILE *FpOut
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FpIn - GC_TODO: add argument description
|
||||||
|
FpOut - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
70
Tools/Source/TianoTools/SplitFile/Makefile
Normal file
70
Tools/Source/TianoTools/SplitFile/Makefile
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define some macros we use here. Should get rid of them someday and
|
||||||
|
# get rid of the extra level of indirection.
|
||||||
|
#
|
||||||
|
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common information
|
||||||
|
#
|
||||||
|
|
||||||
|
INC=$(INC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME=SplitFile
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\SplitFile.c"
|
||||||
|
TARGET_EXE_INCLUDE =
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
131
Tools/Source/TianoTools/SplitFile/SplitFile.c
Normal file
131
Tools/Source/TianoTools/SplitFile/SplitFile.c
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// GC_TODO: fix comment to start with /*++
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
helpmsg (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
printf (
|
||||||
|
"SplitFile Filename Offset\n"" Filename = Input file to split\n"" Offset = offset at which to split file\n"
|
||||||
|
"\n\n""SplitFile will break a file in two pieces at the requested offset\n"
|
||||||
|
" outputting Filename1 and Filename2\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
int argc,
|
||||||
|
char*argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - GC_TODO: add argument description
|
||||||
|
] - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *In;
|
||||||
|
|
||||||
|
FILE *Out1;
|
||||||
|
|
||||||
|
FILE *Out2;
|
||||||
|
char OutName1[512];
|
||||||
|
char OutName2[512];
|
||||||
|
unsigned long Index;
|
||||||
|
unsigned long splitpoint;
|
||||||
|
char CharC;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
helpmsg ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
In = fopen (argv[1], "rb");
|
||||||
|
if (In == NULL) {
|
||||||
|
printf ("Unable to open file \"%s\"\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy (OutName1, argv[1], 510);
|
||||||
|
strncpy (OutName2, argv[1], 510);
|
||||||
|
strcat (OutName1, "1");
|
||||||
|
strcat (OutName2, "2");
|
||||||
|
|
||||||
|
Out1 = fopen (OutName1, "wb");
|
||||||
|
if (Out1 == NULL) {
|
||||||
|
printf ("Unable to open file \"%s\"\n", OutName1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Out2 = fopen (OutName2, "wb");
|
||||||
|
if (Out2 == NULL) {
|
||||||
|
printf ("Unable to open file \"%s\"\n", OutName2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
splitpoint = atoi (argv[2]);
|
||||||
|
|
||||||
|
for (Index = 0; Index < splitpoint; Index++) {
|
||||||
|
CharC = (char) fgetc (In);
|
||||||
|
if (feof (In)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc (CharC, Out1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
CharC = (char) fgetc (In);
|
||||||
|
if (feof (In)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc (CharC, Out2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (In);
|
||||||
|
fclose (Out1);
|
||||||
|
fclose (Out2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
70
Tools/Source/TianoTools/Strip/Makefile
Normal file
70
Tools/Source/TianoTools/Strip/Makefile
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This software and associated documentation (if any) is furnished under
|
||||||
|
# a license and may only be used or copied in accordance with the terms
|
||||||
|
# of the license. Except as permitted by such license, no part of this
|
||||||
|
# software or documentation may be reproduced, stored in a retrieval
|
||||||
|
# system, or transmitted in any form or by any means without the express
|
||||||
|
# written consent of Intel Corporation.
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define some macros we use here. Should get rid of them someday and
|
||||||
|
# get rid of the extra level of indirection.
|
||||||
|
#
|
||||||
|
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common information
|
||||||
|
#
|
||||||
|
|
||||||
|
INC=$(INC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME=Strip
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\Strip.c"
|
||||||
|
TARGET_EXE_INCLUDE =
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE) $(TARGET_EXE_INCLUDE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* > NUL
|
105
Tools/Source/TianoTools/Strip/Strip.c
Normal file
105
Tools/Source/TianoTools/Strip/Strip.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Strip.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Quick Exe2Bin equivalent.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
int argc,
|
||||||
|
char *argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Converts executable files to binary files.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - Number of command line arguments
|
||||||
|
argv[] - Array of pointers to the command line arguments
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Zero - Function completed successfully.
|
||||||
|
Non-zero - Function exited with errors.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *InFile;
|
||||||
|
FILE *OutFile;
|
||||||
|
int Index;
|
||||||
|
int FileSize;
|
||||||
|
char *Buffer;
|
||||||
|
char *Ptrx;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
printf ("Need more args, such as file name to convert and output name\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile = fopen (argv[1], "rb");
|
||||||
|
OutFile = fopen (argv[2], "wb");
|
||||||
|
|
||||||
|
if (!InFile) {
|
||||||
|
printf ("no file, exit\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OutFile == NULL) {
|
||||||
|
printf ("Unable to open output file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (InFile, 0, SEEK_END);
|
||||||
|
FileSize = ftell (InFile);
|
||||||
|
|
||||||
|
if (FileSize < 0x200) {
|
||||||
|
printf ("%d is not a legal size, exit\n", FileSize);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (InFile, 0, SEEK_SET);
|
||||||
|
|
||||||
|
Buffer = malloc (FileSize);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("Error: Out of resources.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread (Buffer, 1, FileSize, InFile);
|
||||||
|
|
||||||
|
Ptrx = Buffer + 0x200;
|
||||||
|
|
||||||
|
Index = FileSize - 0x200;
|
||||||
|
|
||||||
|
fwrite (Ptrx, Index, 1, OutFile);
|
||||||
|
|
||||||
|
fclose (InFile);
|
||||||
|
fclose (OutFile);
|
||||||
|
free (Buffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
63
Tools/Source/TianoTools/ZeroDebugData/Makefile
Normal file
63
Tools/Source/TianoTools/ZeroDebugData/Makefile
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#/*++
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001 Intel Corporation
|
||||||
|
#
|
||||||
|
# Module Name: makefile
|
||||||
|
#
|
||||||
|
# Abstract:
|
||||||
|
#
|
||||||
|
# This file is used to build the EFI utility.
|
||||||
|
#
|
||||||
|
#--*/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do this if you want to compile from this directory
|
||||||
|
#
|
||||||
|
!IFNDEF TOOLCHAIN
|
||||||
|
TOOLCHAIN = TOOLCHAIN_MSVC
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!INCLUDE PlatformTools.env
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define some macros we use here. Should get rid of them someday and
|
||||||
|
# get rid of the extra level of indirection.
|
||||||
|
#
|
||||||
|
COMMON_SOURCE = $(EDK_TOOLS_COMMON)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Common information
|
||||||
|
#
|
||||||
|
|
||||||
|
INC=$(INC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Target specific information
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET_NAME=ZeroDebugData
|
||||||
|
TARGET_SOURCE_DIR = $(TIANO_TOOLS_SOURCE)\$(TARGET_NAME)
|
||||||
|
|
||||||
|
TARGET_EXE = $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).exe
|
||||||
|
|
||||||
|
TARGET_EXE_SOURCE = "$(TARGET_SOURCE_DIR)\ZeroDebugData.c"
|
||||||
|
TARGET_EXE_INCLUDE =
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build targets
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(TARGET_EXE)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build EXE
|
||||||
|
#
|
||||||
|
|
||||||
|
$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj: $(TARGET_EXE_SOURCE)
|
||||||
|
$(CC) $(C_FLAGS) $(INC) $(TARGET_EXE_SOURCE) /Fo$(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj
|
||||||
|
|
||||||
|
$(TARGET_EXE): $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_EXE_LIBS) $(TARGET_DLL)
|
||||||
|
$(LINK) $(MSVS_LINK_LIBPATHS) $(L_FLAGS) $(LIBS) /out:$(TARGET_EXE) $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).obj $(TARGET_LIB) $(TARGET_EXE_LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@if exist $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).* del $(TIANO_TOOLS_OUTPUT)\$(TARGET_NAME).*
|
390
Tools/Source/TianoTools/ZeroDebugData/ZeroDebugData.c
Normal file
390
Tools/Source/TianoTools/ZeroDebugData/ZeroDebugData.c
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2001 - 2002 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
ZeroDebugData.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
Zero the Debug Data Fields of Portable Executable (PE) format file.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
PrintUsage (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Routine Description:
|
||||||
|
print usage of ZeroDebugData command
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
--*/
|
||||||
|
// GC_TODO: void - add argument and description to function comment
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// print usage of command
|
||||||
|
//
|
||||||
|
printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ReadFromFile (
|
||||||
|
FILE *fp,
|
||||||
|
long offset,
|
||||||
|
void *buffer,
|
||||||
|
int size
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
Routine Description:
|
||||||
|
read data from a specified location of file
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
fp - file pointer
|
||||||
|
offset - number of bytes from beginning of file
|
||||||
|
buffer - buffer used to store data
|
||||||
|
size - size of buffer
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
= 0 - Success
|
||||||
|
= -1 - Failed
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// set file pointer to the specified location of file
|
||||||
|
//
|
||||||
|
if (fseek (fp, offset, SEEK_SET) != 0) {
|
||||||
|
printf ("Error: Cannot move the current location of the file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// read data from the file
|
||||||
|
//
|
||||||
|
if (fread (buffer, size, 1, fp) != 1) {
|
||||||
|
printf ("Error: Cannot read data from the file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ZeroDebugData (
|
||||||
|
FILE *fp,
|
||||||
|
FILE *fpData
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Zero the debug data fields of the file
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
fp - file pointer
|
||||||
|
fpData - pointer to output file that ZeroDebugData progress is written to
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
= 0 - Success
|
||||||
|
= -1 - Failed
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
unsigned char header[4];
|
||||||
|
unsigned long offset;
|
||||||
|
unsigned long NumberOfRvaAndSizes;
|
||||||
|
unsigned int nvalue;
|
||||||
|
unsigned long lvalue;
|
||||||
|
unsigned long Size;
|
||||||
|
unsigned long Pointer;
|
||||||
|
unsigned char *Buffer;
|
||||||
|
unsigned long Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// read the header of file
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, 0, header, 2) != 0) {
|
||||||
|
printf ("Error: open image file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// "MZ" -- the header of image file (PE)
|
||||||
|
//
|
||||||
|
if (strncmp ((char *) header, "MZ", 2) != 0) {
|
||||||
|
printf ("Error: Invalid Image file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// At location 0x3C, the stub has the file offset to the
|
||||||
|
// PE signature.
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// read the header of optional
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, offset, header, 4) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// "PE\0\0" -- the signature of optional header
|
||||||
|
//
|
||||||
|
if (strncmp ((char *) header, "PE\0\0", 4) != 0) {
|
||||||
|
printf ("Error: Invalid PE format file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Add 16 to skip COFF file header, and get to optional header.
|
||||||
|
//
|
||||||
|
offset += 24;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the magic field, 0x10B for PE32 and 0x20B for PE32+
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.
|
||||||
|
// Else it is 108.
|
||||||
|
//
|
||||||
|
switch (nvalue & 0xFFFF) {
|
||||||
|
case 0x10B:
|
||||||
|
offset += 92;
|
||||||
|
printf ("Info: Image is PE32. ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x20B:
|
||||||
|
offset += 108;
|
||||||
|
printf ("Info: Image is PE32+. ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf ("Error: Magic value is unknown.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// get the value of NumberOfRvaAndSizes
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {
|
||||||
|
printf ("Error: read NumberOfRvaAndSizes error.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Finding Debug Table, offset of Debug Table
|
||||||
|
// is 4 + 6 * 8 = 52.
|
||||||
|
//
|
||||||
|
if (NumberOfRvaAndSizes >= 7) {
|
||||||
|
if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Read the SizeOfData(16) and PointerToRawData(24)
|
||||||
|
//
|
||||||
|
if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) {
|
||||||
|
printf ("error: Size = %d\n", Size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Debug data: size = %xh, ", Size);
|
||||||
|
fprintf (fpData, "Debug data: size = %xh, ", Size);
|
||||||
|
|
||||||
|
if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) {
|
||||||
|
printf ("error: LoadOffset = %xh\n", Pointer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// printf ("LoadOffset = %xh, ", Pointer);
|
||||||
|
//
|
||||||
|
fprintf (fpData, "LoadOffset = %xh, ", Pointer);
|
||||||
|
|
||||||
|
if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) {
|
||||||
|
printf ("error: FileOffset = %xh\n", Pointer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("FileOffset = %xh, ", Pointer);
|
||||||
|
fprintf (fpData, "FileOffset = %xh, \n", Pointer);
|
||||||
|
|
||||||
|
if ((lvalue != 0) && (Pointer != 0)) {
|
||||||
|
//
|
||||||
|
// prepare buffer
|
||||||
|
//
|
||||||
|
Buffer = malloc (Size + 1);
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
printf ("Error: Cannot allocate memory.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// set file pointer to the specified location of file
|
||||||
|
//
|
||||||
|
if (fseek (fp, Pointer, SEEK_SET) != 0) {
|
||||||
|
printf ("Error: Cannot move the current location of the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// read data from PE file
|
||||||
|
//
|
||||||
|
if (fread (Buffer, Size, 1, fp) != 1) {
|
||||||
|
printf ("Error: Cannot read data from the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// write to data file
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < Size;) {
|
||||||
|
fprintf (fpData, "%02x ", Buffer[Index]);
|
||||||
|
|
||||||
|
Index++;
|
||||||
|
if (Index % 8 == 0) {
|
||||||
|
fprintf (fpData, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (fpData, "\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// zero buffer and write back to PE file
|
||||||
|
//
|
||||||
|
if (fseek (fp, Pointer, SEEK_SET) != 0) {
|
||||||
|
printf ("Error: Cannot move the current location of the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (Buffer, 0, Size);
|
||||||
|
if (fwrite (Buffer, Size, 1, fp) != 1) {
|
||||||
|
perror ("Error: Cannot write zero to the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// set file pointer to the specified location of file
|
||||||
|
//
|
||||||
|
if (fseek (fp, lvalue + 4, SEEK_SET) != 0) {
|
||||||
|
printf ("Error: Cannot move the current location of the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite (Buffer, 4, 1, fp) != 1) {
|
||||||
|
perror ("Error: Cannot write zero to the file.\n");
|
||||||
|
free (Buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (Buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (
|
||||||
|
int argc,
|
||||||
|
char *argv[]
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Prints the zero debug data of the PE file to the DebugData file.
|
||||||
|
Executes the ZeroDebugData function.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
argc - Standard C argument, number of command line arguments.
|
||||||
|
argv[] - Standard C argument, array of pointers to the input files,
|
||||||
|
such as the PE and DebugData files.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
zero - success
|
||||||
|
nonzero - failure
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
FILE *fpData;
|
||||||
|
char DataFile[1024] = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// check the number of parameters
|
||||||
|
//
|
||||||
|
if (argc < 2) {
|
||||||
|
printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// open the DebugData file, if not exists, return
|
||||||
|
//
|
||||||
|
if (argc >= 3) {
|
||||||
|
strcpy (DataFile, argv[2]);
|
||||||
|
} else {
|
||||||
|
strcpy (DataFile, "DebugData.dat");
|
||||||
|
}
|
||||||
|
|
||||||
|
fpData = fopen (DataFile, "a+");
|
||||||
|
if (fpData == NULL) {
|
||||||
|
fpData = fopen (DataFile, "w");
|
||||||
|
if (fpData == NULL) {
|
||||||
|
printf ("Error: Cannot open the data file!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// open the PE file
|
||||||
|
//
|
||||||
|
fp = fopen (argv[1], "r+b");
|
||||||
|
if (fp == NULL) {
|
||||||
|
printf ("Error: Cannot open the PE file!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Zero the Debug Data to the PE file
|
||||||
|
//
|
||||||
|
printf ("Zero Debug Data to file %s:\n", argv[1]);
|
||||||
|
fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]);
|
||||||
|
if ((int *) ZeroDebugData (fp, fpData) != 0) {
|
||||||
|
printf ("Error: Zero Debug Data PE file\n");
|
||||||
|
fclose (fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (" success\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// close the PE file
|
||||||
|
//
|
||||||
|
fflush (fpData);
|
||||||
|
fflush (fp);
|
||||||
|
fclose (fpData);
|
||||||
|
fclose (fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user