+++ /dev/null
-/*++\r
-\r
-Copyright (c) 1999-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available \r
-under the terms and conditions of the BSD License which accompanies this \r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- SecFixup.c\r
-\r
-Abstract:\r
-\r
- This utility is part of build process for IA32 SEC FFS file.\r
- \r
- It fixup the reset vector data. The reset vector data binary file\r
- will be wrapped as a RAW section and be located immediately after\r
- the PE/TE section.\r
-\r
- The SEC EXE file can be either PE or TE file.\r
- \r
---*/\r
-\r
-#include <stdio.h>\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Common/EfiImage.h>\r
-#include <Common/FirmwareVolumeImageFormat.h>\r
-\r
-#include "EfiUtilityMsgs.c"\r
-#include "SecFixup.h"\r
-\r
-VOID\r
-PrintUtilityInfo (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Displays the standard utility information to SDTOUT\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- printf (\r
- "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",\r
- UTILITY_NAME,\r
- UTILITY_MAJOR_VERSION,\r
- UTILITY_MINOR_VERSION\r
- );\r
-}\r
-\r
-VOID\r
-PrintUsage (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Displays the utility usage syntax to STDOUT\r
-\r
-Arguments:\r
-\r
- None\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME);\r
- printf (" Where:\n");\r
- printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");\r
- printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");\r
- printf ("\tOutputFileName - Name of the output file.\n\n");\r
-}\r
-\r
-STATUS\r
-main (\r
- IN INTN argc,\r
- IN CHAR8 **argv\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Main function.\r
-\r
-Arguments:\r
-\r
- argc - Number of command line parameters.\r
- argv - Array of pointers to parameter strings.\r
-\r
-Returns:\r
- STATUS_SUCCESS - Utility exits successfully.\r
- STATUS_ERROR - Some error occurred during execution.\r
-\r
---*/\r
-{\r
- FILE *FpIn;\r
-\r
- FILE *FpOut;\r
- UINT32 AddressOfEntryPoint;\r
- INT32 DestRel;\r
- STATUS Status;\r
- UINT32 SecFileSize;\r
-\r
- SetUtilityName (UTILITY_NAME);\r
-\r
- //\r
- // Display utility information\r
- //\r
- PrintUtilityInfo ();\r
-\r
- //\r
- // Verify the correct number of arguments\r
- //\r
- if (argc != MAX_ARGS) {\r
- Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);\r
- PrintUsage ();\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Open the SEC exe file\r
- //\r
- if ((FpIn = fopen (argv[1], "rb")) == NULL) {\r
- Error (NULL, 0, 0, "Unable to open file", argv[1]);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Get the entry point of the EXE file\r
- //\r
- Status = GetEntryPoint (FpIn, &AddressOfEntryPoint);\r
- if (Status != STATUS_SUCCESS) {\r
- fclose (FpIn);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Get the SEC file size\r
- //\r
- fseek (FpIn, 0, SEEK_END);\r
- SecFileSize = ftell (FpIn);\r
-\r
- //\r
- // Close the SEC file\r
- //\r
- fclose (FpIn);\r
-\r
- //\r
- // Open the reset vector data file\r
- //\r
- if ((FpIn = fopen (argv[2], "rb")) == NULL) {\r
- Error (NULL, 0, 0, "Unable to open file", argv[2]);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Open the output file\r
- //\r
- if ((FpOut = fopen (argv[3], "w+b")) == NULL) {\r
- Error (NULL, 0, 0, "Unable to open file", argv[3]);\r
- fclose (FpIn);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Copy the input file to the output file\r
- //\r
- if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) {\r
- fclose (FpIn);\r
- fclose (FpOut);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Close the reset vector data file\r
- //\r
- fclose (FpIn);\r
-\r
- //\r
- // Fix the destination relative in the jmp instruction\r
- // in the reset vector data structure\r
- //\r
- fseek (FpOut, -DEST_REL_OFFSET, SEEK_END);\r
- DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2);\r
- if (DestRel <= -65536) {\r
- Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL);\r
- fclose (FpOut);\r
- return STATUS_ERROR;\r
- }\r
-\r
- if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) {\r
- Error (NULL, 0, 0, "Failed to write to the output file", NULL);\r
- fclose (FpOut);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Close the output file\r
- //\r
- fclose (FpOut);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-STATUS\r
-GetEntryPoint (\r
- IN FILE *ExeFile,\r
- OUT UINT32 *EntryPoint\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the address of the entry point of a PE/TE file.\r
-\r
-Arguments:\r
-\r
- PeFile - File pointer to the specified PE/TE file.\r
- EntryPoint - Buffer for the address of the entry point to be returned.\r
-\r
-Returns:\r
- STATUS_SUCCESS - Function completed successfully.\r
- STATUS_ERROR - Error occured.\r
-\r
---*/\r
-// GC_TODO: ExeFile - add argument and description to function comment\r
-{\r
- EFI_IMAGE_DOS_HEADER DosHeader;\r
- EFI_IMAGE_NT_HEADERS32 NtHeader;\r
- EFI_TE_IMAGE_HEADER TeHeader;\r
-\r
- //\r
- // Check if it is a TE file\r
- //\r
- fseek (ExeFile, 0, SEEK_SET);\r
- //\r
- // Attempt to read the TE header\r
- //\r
- if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) {\r
- if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
- if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) {\r
- Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);\r
- return STATUS_ERROR;\r
- }\r
-\r
- *EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize;\r
- return STATUS_SUCCESS;\r
- }\r
- }\r
- //\r
- // Check if it is a PE file\r
- //\r
- fseek (ExeFile, 0, SEEK_SET);\r
- //\r
- // Attempt to read the DOS header\r
- //\r
- if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) {\r
- goto InvalidFile;\r
- }\r
- //\r
- // Check the magic number\r
- //\r
- if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- goto InvalidFile;\r
- }\r
- //\r
- // Position into the file and read the NT PE header\r
- //\r
- fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET);\r
- if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) {\r
- goto InvalidFile;\r
- }\r
- //\r
- // Check the PE signature in the header\r
- //\r
- if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- goto InvalidFile;\r
- }\r
- //\r
- // Make sure the PE file is PE32 for IA32\r
- //\r
- if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 ||\r
- NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
- ) {\r
- Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);\r
- return STATUS_ERROR;\r
- }\r
- //\r
- // Get the entry point from the optional header\r
- //\r
- *EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint;\r
- return STATUS_SUCCESS;\r
-\r
-InvalidFile:\r
- Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL);\r
- return STATUS_ERROR;\r
-}\r
-\r
-STATUS\r
-CopyFile (\r
- FILE *FpIn,\r
- FILE *FpOut\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Copy file.\r
-\r
-Arguments:\r
-\r
- FpIn - File pointer to the source file.\r
- FpOut - File pointer to the destination file.\r
-\r
-Returns:\r
- STATUS_SUCCESS - Function completed successfully.\r
- STATUS_ERROR - Error occured.\r
-\r
---*/\r
-{\r
- INTN FileSize;\r
-\r
- INTN Offset;\r
-\r
- INTN Length;\r
- UINT8 Buffer[BUF_SIZE];\r
-\r
- fseek (FpIn, 0, SEEK_END);\r
- FileSize = ftell (FpIn);\r
-\r
- fseek (FpIn, 0, SEEK_SET);\r
- fseek (FpOut, 0, SEEK_SET);\r
-\r
- Offset = 0;\r
- while (Offset < FileSize) {\r
- Length = sizeof (Buffer);\r
- if (FileSize - Offset < Length) {\r
- Length = FileSize - Offset;\r
- }\r
-\r
- if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) {\r
- Error (NULL, 0, 0, "Copy file error", NULL);\r
- return STATUS_ERROR;\r
- }\r
-\r
- Offset += Length;\r
- }\r
-\r
- return STATUS_SUCCESS;\r
-}\r