]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/GenSec: Support EFI_SECTION_FREEFORM_SUBTYPE_GUID sections
authorKonstantin Aladyshev <aladyshev22@gmail.com>
Wed, 20 Jul 2022 14:08:12 +0000 (22:08 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 6 Aug 2022 15:12:28 +0000 (15:12 +0000)
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
BaseTools/Source/C/GenSec/GenSec.c

index 35a1ac64eae96740f2a170d18d3cbba7f25b4bdc..d86cc197cc261a0aa4b959722056c6fd8eba4713 100644 (file)
@@ -988,6 +988,155 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+GenSectionSubtypeGuidSection (\r
+  CHAR8    **InputFileName,\r
+  UINT32   *InputFileAlign,\r
+  UINT32   InputFileNum,\r
+  EFI_GUID *SubTypeGuid,\r
+  UINT8    **OutFileBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Generate a section of type EFI_SECTION_FREEFORM_SUBTYPE_GUID\r
+  The function won't validate the input file contents.\r
+  The utility will add section header to the file.\r
+\r
+Arguments:\r
+\r
+  InputFileName - Name of the input file.\r
+\r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
+  InputFileNum - Number of input files. Should be 1 for this section.\r
+\r
+  SubTypeGuid - Specify vendor guid value.\r
+\r
+  OutFileBuffer   - Buffer pointer to Output file contents\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS on successful return\r
+  EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
+  EFI_ABORTED if unable to open input file.\r
+  EFI_OUT_OF_RESOURCES  No resource to complete the operation.\r
+\r
+--*/\r
+{\r
+  UINT32                TotalLength;\r
+  UINT32                InputLength;\r
+  UINT32                Offset;\r
+  UINT8                 *FileBuffer;\r
+  EFI_STATUS            Status;\r
+  EFI_FREEFORM_SUBTYPE_GUID_SECTION  *SubtypeGuidSect;\r
+  EFI_FREEFORM_SUBTYPE_GUID_SECTION2  *SubtypeGuidSect2;\r
+\r
+\r
+  InputLength = 0;\r
+  Offset      = 0;\r
+  FileBuffer  = NULL;\r
+  TotalLength = 0;\r
+\r
+  if (InputFileNum > 1) {\r
+    Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");\r
+    return STATUS_ERROR;\r
+  } else if (InputFileNum < 1) {\r
+    Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // read all input file contents into a buffer\r
+  // first get the size of all file contents\r
+  //\r
+  Status = GetSectionContents (\r
+            InputFileName,\r
+            InputFileAlign,\r
+            InputFileNum,\r
+            FileBuffer,\r
+            &InputLength\r
+            );\r
+\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Offset = sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION);\r
+    if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+      Offset = sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION2);\r
+    }\r
+    TotalLength = InputLength + Offset;\r
+\r
+    FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
+    if (FileBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // read all input file contents into a buffer\r
+    //\r
+    Status = GetSectionContents (\r
+              InputFileName,\r
+              InputFileAlign,\r
+              InputFileNum,\r
+              FileBuffer + Offset,\r
+              &InputLength\r
+              );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    if (FileBuffer != NULL) {\r
+      free (FileBuffer);\r
+    }\r
+    Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);\r
+    return Status;\r
+  }\r
+\r
+  if (InputLength == 0) {\r
+    if (FileBuffer != NULL) {\r
+      free (FileBuffer);\r
+    }\r
+    Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // InputLength != 0, but FileBuffer == NULL means out of resources.\r
+  //\r
+  if (FileBuffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Now data is in FileBuffer + Offset\r
+  //\r
+  if (TotalLength >= MAX_SECTION_SIZE) {\r
+    SubtypeGuidSect2 = (EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *) FileBuffer;\r
+    SubtypeGuidSect2->CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+    SubtypeGuidSect2->CommonHeader.Size[0]  = (UINT8) 0xff;\r
+    SubtypeGuidSect2->CommonHeader.Size[1]  = (UINT8) 0xff;\r
+    SubtypeGuidSect2->CommonHeader.Size[2]  = (UINT8) 0xff;\r
+    SubtypeGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION2);\r
+    memcpy (&(SubtypeGuidSect2->SubTypeGuid), SubTypeGuid, sizeof (EFI_GUID));\r
+  } else {\r
+    SubtypeGuidSect = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) FileBuffer;\r
+    SubtypeGuidSect->CommonHeader.Type     = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
+    SubtypeGuidSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+    SubtypeGuidSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+    SubtypeGuidSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+    memcpy (&(SubtypeGuidSect->SubTypeGuid), SubTypeGuid, sizeof (EFI_GUID));\r
+  }\r
+\r
+  VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
+\r
+  //\r
+  // Set OutFileBuffer\r
+  //\r
+  *OutFileBuffer = FileBuffer;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 EFI_STATUS\r
 FfsRebaseImageRead (\r
     IN      VOID    *FileHandle,\r
@@ -1591,14 +1740,22 @@ Returns:
   }\r
 \r
   //\r
-  // GuidValue is only required by Guided section.\r
+  // GuidValue is only required by Guided section and SubtypeGuid section.\r
   //\r
-  if ((SectType != EFI_SECTION_GUID_DEFINED) &&\r
+  if ((SectType != EFI_SECTION_GUID_DEFINED) && (SectType != EFI_SECTION_FREEFORM_SUBTYPE_GUID) &&\r
     (SectionName != NULL) &&\r
     (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
     fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
   }\r
 \r
+  //\r
+  // Check whether there is GUID for the SubtypeGuid section\r
+  //\r
+  if ((SectType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) && (CompareGuid (&VendorGuid, &mZeroGuid) == 0)) {\r
+    Error (NULL, 0, 1001, "Missing options", "GUID");\r
+    goto Finish;\r
+  }\r
+\r
   //\r
   // Check whether there is input file\r
   //\r
@@ -1667,6 +1824,16 @@ Returns:
               );\r
     break;\r
 \r
+  case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
+    Status = GenSectionSubtypeGuidSection (\r
+              InputFileName,\r
+              InputFileAlign,\r
+              InputFileNum,\r
+              &VendorGuid,\r
+              &OutFileBuffer\r
+              );\r
+    break;\r
+\r
   case EFI_SECTION_VERSION:\r
     Index           = sizeof (EFI_COMMON_SECTION_HEADER);\r
     //\r