X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FGenSec%2FGenSec.c;h=46149762586ef0d7b849b3fa7333f462d5d40a3f;hp=87d4fa88b92dd61937a91bfb85cebf1a4e5276c8;hb=9a8d7aa7f796ce68ece2815d268889ac4e2ac318;hpb=77e4cf5f11ed4543cbd91a9c45c7209e36bfd97a diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index 87d4fa88b9..4614976258 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -1,7 +1,7 @@ /** @file Creates output file that is a properly formed section per the PI spec. -Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -11,6 +11,12 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ +#ifndef __GNUC__ +#include +#include +#include +#include +#endif #include #include @@ -27,6 +33,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "Crc32.h" #include "EfiUtilityMsgs.h" #include "ParseInf.h" +#include "FvLib.h" +#include "PeCoffLib.h" // // GenSec Tool Information @@ -74,7 +82,8 @@ STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED", STATIC CHAR8 *mAlignName[] = { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", - "1K", "2K", "4K", "8K", "16K", "32K", "64K" + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", + "512K", "1M", "2M", "4M", "8M", "16M" }; // @@ -146,7 +155,7 @@ Returns: // // Copyright declaration // - fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n"); + fprintf (stdout, "Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.\n\n"); // // Details Option @@ -184,8 +193,12 @@ Returns: used in Ver section.\n"); fprintf (stdout, " --sectionalign SectionAlign\n\ SectionAlign points to section alignment, which support\n\ - the alignment scope 1~64K. It is specified in same\n\ - order that the section file is input.\n"); + the alignment scope 0~16M. If SectionAlign is specified\n\ + as 0, tool get alignment value from SectionFile. It is\n\ + specified in same order that the section file is input.\n"); + fprintf (stdout, " --dummy dummyfile\n\ + compare dummpyfile with input_file to decide whether\n\ + need to set PROCESSING_REQUIRED attribute.\n"); fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n"); fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n"); fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n"); @@ -356,7 +369,7 @@ StringtoAlignment ( Routine Description: - Converts Align String to align value (1~64K). + Converts Align String to align value (1~16M). Arguments: @@ -897,16 +910,22 @@ Returns: return Status; } - if (FileBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - if (InputLength == 0) { - free (FileBuffer); + if (FileBuffer != NULL) { + free (FileBuffer); + } Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName); return EFI_NOT_FOUND; } + // + // InputLength != 0, but FileBuffer == NULL means out of resources. + // + if (FileBuffer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); + return EFI_OUT_OF_RESOURCES; + } + // // Now data is in FileBuffer + Offset // @@ -975,6 +994,103 @@ Returns: 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; +} + +STATIC +EFI_STATUS +GetAlignmentFromFile(char *InFile, UINT32 *Alignment) + /* + InFile is input file for getting alignment + return the alignment + */ +{ + FILE *InFileHandle; + UINT8 *PeFileBuffer; + UINTN PeFileSize; + UINT32 CurSecHdrSize; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_COMMON_SECTION_HEADER *CommonHeader; + EFI_STATUS Status; + + InFileHandle = NULL; + PeFileBuffer = NULL; + *Alignment = 0; + + memset (&ImageContext, 0, sizeof (ImageContext)); + + InFileHandle = fopen(LongFilePath(InFile), "rb"); + if (InFileHandle == NULL){ + Error (NULL, 0, 0001, "Error opening file", InFile); + return EFI_ABORTED; + } + PeFileSize = _filelength (fileno(InFileHandle)); + PeFileBuffer = (UINT8 *) malloc (PeFileSize); + if (PeFileBuffer == NULL) { + fclose (InFileHandle); + Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle); + return EFI_OUT_OF_RESOURCES; + } + fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); + fclose (InFileHandle); + CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer; + CurSecHdrSize = GetSectionHeaderLength(CommonHeader); + ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize); + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead; + Status = PeCoffLoaderGetImageInfo(&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status); + return Status; + } + *Alignment = ImageContext.SectionAlignment; + // Free the allocated memory resource + if (PeFileBuffer != NULL) { + free (PeFileBuffer); + PeFileBuffer = NULL; + } + return EFI_SUCCESS; +} + int main ( int argc, @@ -1021,6 +1137,13 @@ Returns: UINT32 *InputFileAlign; UINT32 InputFileAlignNum; EFI_COMMON_SECTION_HEADER *SectionHeader; + CHAR8 *DummyFileName; + FILE *DummyFile; + UINTN DummyFileSize; + UINT8 *DummyFileBuffer; + FILE *InFile; + UINT8 *InFileBuffer; + UINTN InFileSize; InputFileAlign = NULL; InputFileAlignNum = 0; @@ -1042,6 +1165,13 @@ Returns: SectGuidHeaderLength = 0; VersionSect = NULL; UiSect = NULL; + DummyFileSize = 0; + DummyFileName = NULL; + DummyFile = NULL; + DummyFileBuffer = NULL; + InFile = NULL; + InFileSize = 0; + InFileBuffer = NULL; SetUtilityName (UTILITY_NAME); @@ -1112,8 +1242,22 @@ Returns: argv += 2; continue; } + if (stricmp (argv[0], "--dummy") == 0) { + DummyFileName = argv[1]; + if (DummyFileName == NULL) { + Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL"); + goto Finish; + } + argc -= 2; + argv += 2; + continue; + } if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) { + if (argv[1] == NULL) { + Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL"); + goto Finish; + } if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) { SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED; } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) { @@ -1231,11 +1375,14 @@ Returns: } memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32))); } - - Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum])); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; + if (stricmp(argv[1], "0") == 0) { + InputFileAlign[InputFileAlignNum] = 0; + } else { + Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum])); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); + goto Finish; + } } argc -= 2; argv += 2; @@ -1278,9 +1425,83 @@ Returns: Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section"); goto Finish; } + for (Index = 0; Index < InputFileAlignNum; Index++) + { + if (InputFileAlign[Index] == 0) { + Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index])); + if (EFI_ERROR(Status)) { + Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]); + goto Finish; + } + } + } VerboseMsg ("%s tool start.", UTILITY_NAME); + if (DummyFileName != NULL) { + // + // Open file and read contents + // + DummyFile = fopen (LongFilePath (DummyFileName), "rb"); + if (DummyFile == NULL) { + Error (NULL, 0, 0001, "Error opening file", DummyFileName); + goto Finish; + } + + fseek (DummyFile, 0, SEEK_END); + DummyFileSize = ftell (DummyFile); + fseek (DummyFile, 0, SEEK_SET); + DummyFileBuffer = (UINT8 *) malloc (DummyFileSize); + if (DummyFileBuffer == NULL) { + fclose(DummyFile); + Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); + goto Finish; + } + + fread(DummyFileBuffer, 1, DummyFileSize, DummyFile); + fclose(DummyFile); + DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize); + + if (InputFileName == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); + goto Finish; + } + InFile = fopen(LongFilePath(InputFileName[0]), "rb"); + if (InFile == NULL) { + Error (NULL, 0, 0001, "Error opening file", InputFileName[0]); + goto Finish; + } + + fseek (InFile, 0, SEEK_END); + InFileSize = ftell (InFile); + fseek (InFile, 0, SEEK_SET); + InFileBuffer = (UINT8 *) malloc (InFileSize); + if (InFileBuffer == NULL) { + fclose(InFile); + Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); + goto Finish; + } + + fread(InFileBuffer, 1, InFileSize, InFile); + fclose(InFile); + DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize); + if (InFileSize > DummyFileSize){ + if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){ + SectGuidHeaderLength = InFileSize - DummyFileSize; + } + } + if (SectGuidHeaderLength == 0) { + SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED; + } + if (DummyFileBuffer != NULL) { + free (DummyFileBuffer); + DummyFileBuffer = NULL; + } + if (InFileBuffer != NULL) { + free (InFileBuffer); + } + } + // // Parse all command line parameters to get the corresponding section type. // @@ -1585,7 +1806,11 @@ Finish: if (OutFile != NULL) { fclose (OutFile); } - + + if (DummyFileBuffer != NULL) { + free (DummyFileBuffer); + } + VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ()); return GetUtilityStatus ();