From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.20; helo=mga02.intel.com; envelope-from=yonghong.zhu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 51AE7203564DB for ; Wed, 29 Nov 2017 05:58:07 -0800 (PST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Nov 2017 06:02:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,473,1505804400"; d="scan'208";a="154377135" Received: from shwdeopenpsi168.ccr.corp.intel.com ([10.239.158.129]) by orsmga004.jf.intel.com with ESMTP; 29 Nov 2017 06:02:11 -0800 From: Yonghong Zhu To: edk2-devel@lists.01.org Cc: Liming Gao Date: Wed, 29 Nov 2017 22:02:03 +0800 Message-Id: <1511964126-6716-2-git-send-email-yonghong.zhu@intel.com> X-Mailer: git-send-email 2.6.1.windows.1 In-Reply-To: <1511964126-6716-1-git-send-email-yonghong.zhu@intel.com> References: <1511964126-6716-1-git-send-email-yonghong.zhu@intel.com> Subject: [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Nov 2017 13:58:07 -0000 Update GenFfs tool to get alignment value from SectionFile when use the new option -n 0. Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yonghong Zhu --- BaseTools/Source/C/GenFfs/GenFfs.c | 135 ++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index cb16f38..e2fb3e0 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -10,10 +10,17 @@ http://opensource.org/licenses/bsd-license.php 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 #include #include @@ -22,10 +29,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include "CommonLib.h" #include "ParseInf.h" #include "EfiUtilityMsgs.h" +#include "FvLib.h" +#include "PeCoffLib.h" #define UTILITY_NAME "GenFfs" #define UTILITY_MAJOR_VERSION 0 #define UTILITY_MINOR_VERSION 1 @@ -151,12 +160,14 @@ Returns: 128K,256K,512K,1M,2M,4M,8M,16M\n"); fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\ Section file will be contained in this FFS file.\n"); fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\ SectionAlign points to section alignment, which support\n\ - the alignment scope 1~16M. It is specified together\n\ - with sectionfile to point its alignment in FFS file.\n"); + the alignment scope 0~16M. If SectionAlign is specified\n\ + as 0, tool get alignment value from SectionFile. It is\n\ + specified together with sectionfile to point its\n\ + alignment in FFS file.\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"); fprintf (stdout, " --version Show program's version number and exit.\n"); fprintf (stdout, " -h, --help Show this help message and exit.\n"); @@ -455,10 +466,106 @@ Returns: *BufferLength = Size; 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; + + 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, CHAR8 *argv[] ) @@ -495,10 +602,12 @@ Returns: FILE *FfsFile; UINT32 Index; UINT64 LogLevel; UINT8 PeSectionNum; UINT32 HeaderSize; + UINT32 Alignment; + CHAR8 AlignmentBuffer[8]; // // Init local variables // LogLevel = 0; @@ -688,11 +797,31 @@ Returns: // // Section File alignment requirement // if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) { - Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum])); + if ((argv[1] != NULL) && (stricmp("0", argv[1]) == 0)) { + Status = GetAlignmentFromFile(InputFileName[InputFileNum], &Alignment); + if (EFI_ERROR(Status)) { + Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]); + goto Finish; + } + if (Alignment < 0x400){ + sprintf (AlignmentBuffer, "%d", Alignment); + } + else if (Alignment >= 0x400) { + if (Alignment >= 0x100000) { + sprintf (AlignmentBuffer, "%dM", Alignment/0x100000); + } else { + sprintf (AlignmentBuffer, "%dK", Alignment/0x400); + } + } + Status = StringtoAlignment (AlignmentBuffer, &(InputFileAlign[InputFileNum])); + } + else { + Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum])); + } if (EFI_ERROR (Status)) { Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); goto Finish; } argc -= 2; -- 2.6.1.windows.1