]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenSec/GenSec.c
BaseTools: argument genfds-multi-thread create GenSec command issue
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
index 56767d5a9b35e4df4de731e7af9e8b7fcfb24376..46149762586ef0d7b849b3fa7333f462d5d40a3f 100644 (file)
@@ -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.             \r
 \r
 **/\r
+#ifndef __GNUC__\r
+#include <windows.h>\r
+#include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#endif\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -27,6 +33,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "Crc32.h"\r
 #include "EfiUtilityMsgs.h"\r
 #include "ParseInf.h"\r
+#include "FvLib.h"\r
+#include "PeCoffLib.h"\r
 \r
 //\r
 // GenSec Tool Information\r
@@ -185,8 +193,9 @@ Returns:
                         used in Ver section.\n");\r
   fprintf (stdout, "  --sectionalign SectionAlign\n\\r
                         SectionAlign points to section alignment, which support\n\\r
-                        the alignment scope 1~16M. It is specified in same\n\\r
-                        order that the section file is input.\n");\r
+                        the alignment scope 0~16M. If SectionAlign is specified\n\\r
+                        as 0, tool get alignment value from SectionFile. It is\n\\r
+                        specified in same order that the section file is input.\n");\r
   fprintf (stdout, "  --dummy dummyfile\n\\r
                         compare dummpyfile with input_file to decide whether\n\\r
                         need to set PROCESSING_REQUIRED attribute.\n");\r
@@ -985,6 +994,103 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+FfsRebaseImageRead (\r
+    IN      VOID    *FileHandle,\r
+    IN      UINTN   FileOffset,\r
+    IN OUT  UINT32  *ReadSize,\r
+    OUT     VOID    *Buffer\r
+    )\r
+  /*++\r
+\r
+    Routine Description:\r
+\r
+    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+    Arguments:\r
+\r
+   FileHandle - The handle to the PE/COFF file\r
+\r
+   FileOffset - The offset, in bytes, into the file to read\r
+\r
+   ReadSize   - The number of bytes to read from the file starting at FileOffset\r
+\r
+   Buffer     - A pointer to the buffer to read the data into.\r
+\r
+   Returns:\r
+\r
+   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+   --*/\r
+{\r
+  CHAR8   *Destination8;\r
+  CHAR8   *Source8;\r
+  UINT32  Length;\r
+\r
+  Destination8  = Buffer;\r
+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+  Length        = *ReadSize;\r
+  while (Length--) {\r
+    *(Destination8++) = *(Source8++);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)\r
+  /*\r
+    InFile is input file for getting alignment\r
+    return the alignment\r
+    */\r
+{\r
+  FILE                           *InFileHandle;\r
+  UINT8                          *PeFileBuffer;\r
+  UINTN                          PeFileSize;\r
+  UINT32                         CurSecHdrSize;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;\r
+  EFI_COMMON_SECTION_HEADER      *CommonHeader;\r
+  EFI_STATUS                     Status;\r
+\r
+  InFileHandle        = NULL;\r
+  PeFileBuffer        = NULL;\r
+  *Alignment          = 0;\r
+\r
+  memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
+  InFileHandle = fopen(LongFilePath(InFile), "rb");\r
+  if (InFileHandle == NULL){\r
+    Error (NULL, 0, 0001, "Error opening file", InFile);\r
+    return EFI_ABORTED;\r
+  }\r
+  PeFileSize = _filelength (fileno(InFileHandle));\r
+  PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+  if (PeFileBuffer == NULL) {\r
+    fclose (InFileHandle);\r
+    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated  of %s", InFileHandle);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);\r
+  fclose (InFileHandle);\r
+  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;\r
+  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);\r
+  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);\r
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;\r
+  Status               = PeCoffLoaderGetImageInfo(&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);\r
+    return Status;\r
+   }\r
+  *Alignment = ImageContext.SectionAlignment;\r
+  // Free the allocated memory resource\r
+  if (PeFileBuffer != NULL) {\r
+    free (PeFileBuffer);\r
+    PeFileBuffer = NULL;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 int\r
 main (\r
   int  argc,\r
@@ -1269,11 +1375,14 @@ Returns:
         }\r
         memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
       }\r
-      \r
-      Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
-        goto Finish;\r
+      if (stricmp(argv[1], "0") == 0) {\r
+        InputFileAlign[InputFileAlignNum] = 0;\r
+      } else {\r
+        Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
+        if (EFI_ERROR (Status)) {\r
+          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+          goto Finish;\r
+        }\r
       }\r
       argc -= 2;\r
       argv += 2;\r
@@ -1316,6 +1425,16 @@ Returns:
     Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
     goto Finish;\r
   }\r
+  for (Index = 0; Index < InputFileAlignNum; Index++)\r
+  {\r
+    if (InputFileAlign[Index] == 0) {\r
+      Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index]));\r
+      if (EFI_ERROR(Status)) {\r
+        Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);\r
+        goto Finish;\r
+      }\r
+    }\r
+  }\r
 \r
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
 \r