#define FW_MERGE_IMAGE 8\r
#define FW_RELOC_STRIPEED_IMAGE 9\r
#define FW_HII_PACKAGE_LIST_RCIMAGE 10\r
+#define FW_HII_PACKAGE_LIST_BINIMAGE 11\r
\r
#define DUMP_TE_HEADER 0x11\r
\r
fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
File will be created to store the ouput content.\n");\r
fprintf (stdout, " -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\\r
- Create Efi Image. EFI_FILETYPE is one of BASE, SEC,\n\\r
+ Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\\r
PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\\r
- DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER, \n\\r
- DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER, \n\\r
+ SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\\r
+ DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\\r
PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\\r
APPLICATION, SAL_RT_DRIVER to support all module types\n\\r
It can only be used together with --keepexceptiontable,\n\\r
except for -o, -r option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
input action option will override the previous one.\n");;\r
- fprintf (stdout, " -l, --stripped Relocation info stripped from the input PE or TE image.\n\\r
+ fprintf (stdout, " -l, --stripped Strip off the relocation info from PE or TE image.\n\\r
It can't be combined with other action options\n\\r
except for -o, -r option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
If more input files are specified,\n\\r
the last input file will be as the output file.\n");\r
fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\\r
- HiiListPackageGuidGuid is from the module guid.\n\\r
+ Guid is used to specify hii package list guid.\n\\r
Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\\r
If not specified, the first Form FormSet guid is used.\n");\r
fprintf (stdout, " --hiipackage Combine all input binary hii pacakges into \n\\r
except for -o option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
input action option will override the previous one.\n");\r
+ fprintf (stdout, " --hiibinpackage Combine all input binary hii pacakges into \n\\r
+ a single package list as the binary resource section.\n\\r
+ It can't be combined with other action options\n\\r
+ except for -o option. It is a action option.\n\\r
+ If it is combined with other action options, the later\n\\r
+ input action option will override the previous one.\n");\r
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
UINT32 HiiRsrcOffset;\r
UINT32 RelocOffset;\r
\r
-//\r
-// HiiBinData\r
-//\r
-UINT8* HiiBinData = NULL;\r
-UINT32 HiiBinSize = 0;\r
-\r
EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;\r
UINT16 *CoffEntryRel;\r
\r
}\r
\r
VOID\r
-GetBinaryHiiData (\r
- CHAR8 *RcString,\r
- UINT32 Size,\r
+SetHiiResourceHeader (\r
+ UINT8 *HiiBinData,\r
UINT32 OffsetToFile\r
)\r
{\r
- unsigned Data16;\r
- UINT32 HiiBinOffset;\r
UINT32 Index;\r
EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
\r
- Index = 0;\r
- while (Index < Size && *RcString != '\0' && *RcString != '{') {\r
- RcString ++;\r
- Index ++;\r
- }\r
- \r
- if (*RcString == '\0' || Index == Size) {\r
- return;\r
- }\r
- \r
- //\r
- // Skip '{' character\r
- // Skip space and ',' character\r
- //\r
- RcString ++;\r
- Index ++;\r
- while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
- RcString ++;\r
- Index ++;\r
- }\r
-\r
- //\r
- // '}' end character\r
- //\r
- if (*RcString == '}' || Index == Size) {\r
- return;\r
- }\r
-\r
- HiiBinOffset = 0;\r
- HiiBinSize = 0x1000;\r
- HiiBinData = (UINT8 *) malloc (HiiBinSize);\r
- if (HiiBinData == NULL) {\r
- return;\r
- }\r
- memset (HiiBinData, 0, HiiBinSize);\r
//\r
// Fill Resource section entry\r
//\r
- ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
- ResourceDirectory->NumberOfNamedEntries = 1;\r
-\r
- ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
- ResourceDirectoryEntry->u1.s.NameIsString = 1;\r
- ResourceDirectoryEntry->u1.s.NameOffset = HiiBinOffset;\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+ for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) {\r
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);\r
\r
- ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + HiiBinOffset);\r
- ResourceDirectoryString->Length = 3;\r
- ResourceDirectoryString->String[0] =L'H';\r
- ResourceDirectoryString->String[1] =L'I';\r
- ResourceDirectoryString->String[2] =L'I';\r
- HiiBinOffset = HiiBinOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ if (ResourceDirectoryString->Length == 3 &&\r
+ ResourceDirectoryString->String[0] == L'H' &&\r
+ ResourceDirectoryString->String[1] == L'I' &&\r
+ ResourceDirectoryString->String[2] == L'I') {\r
+ //\r
+ // Resource Type "HII" found\r
+ //\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Name\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
\r
- ResourceDirectoryEntry->u2.OffsetToData = HiiBinOffset;\r
- ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
- ResourceDataEntry->OffsetToData = OffsetToFile + HiiBinOffset;\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Language\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+ }\r
+ }\r
\r
- while (sscanf (RcString, "0x%X", &Data16) != EOF) {\r
- //\r
- // Convert the string data to the binary data.\r
- //\r
- *(UINT16 *)(HiiBinData + HiiBinOffset) = (UINT16) Data16;\r
- HiiBinOffset += 2;\r
- //\r
- // Jump to the next data.\r
- //\r
- RcString = RcString + 2 + 4;\r
- Index = Index + 2 + 4;\r
- //\r
- // Skip space and ',' character\r
- //\r
- while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
- RcString ++;\r
- Index ++;\r
- }\r
- //\r
- // '}' end character\r
- //\r
- if (*RcString == '}'|| Index == Size) {\r
- break;\r
- }\r
- //\r
- // Check BinBuffer size\r
- //\r
- if (HiiBinOffset >= HiiBinSize) {\r
- HiiBinSize += 0x1000;\r
- HiiBinData = (UINT8 *) realloc (HiiBinData, HiiBinSize);\r
- //\r
- // Memory allocation is failure.\r
- //\r
- if (HiiBinData == NULL) {\r
- HiiBinSize = 0;\r
- break;\r
+ //\r
+ // Now it ought to be resource Data and update its OffsetToData value \r
+ //\r
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);\r
+ ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile;\r
+ break;\r
+ }\r
}\r
}\r
- }\r
-\r
- if (HiiBinData != NULL) {\r
- HiiBinSize = HiiBinOffset;\r
- ResourceDataEntry->Size = HiiBinSize + OffsetToFile - ResourceDataEntry->OffsetToData;\r
+ ResourceDirectoryEntry++;\r
}\r
\r
return;\r
Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
}\r
}\r
- GetBinaryHiiData ((CHAR8*)Ehdr + shdr->sh_offset, shdr->sh_size, HiiRsrcOffset);\r
- if (HiiBinSize != 0) {\r
- CoffOffset += HiiBinSize;\r
+ if (shdr->sh_size != 0) {\r
+ CoffSectionsOffset[i] = CoffOffset;\r
+ CoffOffset += shdr->sh_size;\r
CoffOffset = CoffAlign(CoffOffset);\r
+ SetHiiResourceHeader ((UINT8*) Ehdr + shdr->sh_offset, HiiRsrcOffset);\r
}\r
break;\r
}\r
EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
| EFI_IMAGE_SCN_MEM_READ);\r
\r
- NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiBinSize;\r
+ NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = RelocOffset - HiiRsrcOffset;\r
NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = HiiRsrcOffset;\r
-\r
- memcpy(CoffFile + HiiRsrcOffset, HiiBinData, HiiBinSize);\r
- free (HiiBinData);\r
- HiiBinData = NULL;\r
- HiiBinSize = 0;\r
} else {\r
// Don't make a section of size 0. \r
NtHdr->Pe32.FileHeader.NumberOfSections--;\r
//\r
WriteSections(IsTextShdr);\r
WriteSections(IsDataShdr);\r
+ WriteSections(IsHiiRsrcShdr);\r
VerboseMsg ("Write and relocate sections.");\r
\r
//\r
}\r
}\r
\r
+\r
+EFI_IMAGE_OPTIONAL_HEADER_UNION *\r
+GetPeCoffHeader (\r
+ void *Data\r
+ )\r
+{\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
+\r
+ //\r
+ // Read the dos & pe hdrs of the image\r
+ //\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Data;\r
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+ // NO DOS header, check for PE/COFF header\r
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data);\r
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ return NULL;\r
+ }\r
+ } else {\r
+\r
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew);\r
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ return NULL;\r
+ }\r
+ }\r
+ \r
+ return PeHdr;\r
+}\r
+\r
+void\r
+PeCoffConvertImageToXip (\r
+ UINT8 **FileBuffer,\r
+ UINT32 *FileLength\r
+ )\r
+{\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NewPeHdr;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
+ UINTN TotalNecessaryFileSize;\r
+ UINTN SectionSize;\r
+ UINT8 *XipFile;\r
+ UINT32 XipLength;\r
+ UINTN Index;\r
+ UINTN FirstSectionOffset;\r
+ BOOLEAN ConversionNeeded;\r
+\r
+ PeHdr = GetPeCoffHeader ((void *) *FileBuffer);\r
+ if (PeHdr == NULL) {\r
+ return;\r
+ }\r
+ \r
+ if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) {\r
+ //\r
+ // The only reason to expand zero fill sections is to make them compatible with XIP images.\r
+ // If SectionAlignment is not equal to FileAlginment then it is not an XIP type image.\r
+ //\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Calculate size of XIP file, and determine if the conversion is needed.\r
+ //\r
+ ConversionNeeded = FALSE;\r
+ XipLength = 0;\r
+ FirstSectionOffset = *FileLength;\r
+ TotalNecessaryFileSize = 0;\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);\r
+ TotalNecessaryFileSize += SectionSize;\r
+ if (SectionSize > 0) {\r
+ FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress);\r
+ XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize);\r
+ if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) {\r
+ ConversionNeeded = TRUE;\r
+ }\r
+ }\r
+ if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) {\r
+ ConversionNeeded = TRUE;\r
+ }\r
+ }\r
+\r
+ if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
+ //\r
+ // If one of the sections should be loaded to an offset overlapping with\r
+ // the executable header, then it cannot be made into an XIP image.\r
+ //\r
+ VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");\r
+ VerboseMsg ("of section data with the executable header.");\r
+ return;\r
+ }\r
+\r
+ if (FirstSectionOffset == *FileLength) {\r
+ //\r
+ // If we never found a section with a non-zero size, then we\r
+ // skip the conversion.\r
+ //\r
+ return;\r
+ }\r
+\r
+ TotalNecessaryFileSize += FirstSectionOffset;\r
+\r
+ if (!ConversionNeeded) {\r
+ return;\r
+ }\r
+\r
+ if (XipLength > (2 * TotalNecessaryFileSize)) {\r
+ VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");\r
+ VerboseMsg ("The image linking process may have left unused memory ranges.");\r
+ }\r
+\r
+ if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) {\r
+ //\r
+ // This field is obsolete and should be zero\r
+ //\r
+ PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
+ }\r
+\r
+ //\r
+ // Allocate the extra space that we need to grow the image\r
+ //\r
+ XipFile = malloc (XipLength);\r
+ memset (XipFile, 0, XipLength);\r
+\r
+ //\r
+ // Copy the file headers\r
+ //\r
+ memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders);\r
+\r
+ NewPeHdr = GetPeCoffHeader ((void *)XipFile);\r
+ if (NewPeHdr == NULL) {\r
+ free (XipFile);\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Copy the section data over to the appropriate XIP offsets\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ if (SectionHeader->SizeOfRawData > 0) {\r
+ memcpy (\r
+ XipFile + SectionHeader->VirtualAddress,\r
+ *FileBuffer + SectionHeader->PointerToRawData,\r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ }\r
+ SectionHeader->SizeOfRawData = SectionHeader->Misc.VirtualSize;\r
+ SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;\r
+ }\r
+\r
+ free (*FileBuffer);\r
+ *FileLength = XipLength;\r
+ *FileBuffer = XipFile;\r
+}\r
+\r
+UINT8 *\r
+CreateHiiResouceSectionHeader (\r
+ UINT32 *pSectionHeaderSize, \r
+ UINT32 HiiDataSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create COFF resource section header\r
+\r
+Arguments:\r
+\r
+ pSectionHeaderSize - Pointer to section header size.\r
+ HiiDataSize - Size of the total HII data in section.\r
+\r
+Returns:\r
+ The created section header buffer.\r
+\r
+--*/\r
+{\r
+ UINT32 HiiSectionHeaderSize;\r
+ UINT32 HiiSectionOffset;\r
+ UINT8 *HiiSectionHeader;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LanguageResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
+\r
+ //\r
+ // Calculate the total size for the resource header (include Type, Name and Language)\r
+ // then allocate memory for the resource header.\r
+ //\r
+ HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)) \r
+ + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16)) \r
+ + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+ HiiSectionHeader = malloc (HiiSectionHeaderSize);\r
+ memset (HiiSectionHeader, 0, HiiSectionHeaderSize);\r
+\r
+ HiiSectionOffset = 0;\r
+ //\r
+ // Create Type entry \r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ TypeResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ TypeResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
+ TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+ //\r
+ // Create Name entry\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ NameResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ NameResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
+ NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+ //\r
+ // Create Language entry\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ LanguageResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ //\r
+ // Create string entry for Type\r
+ //\r
+ TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'H';\r
+ ResourceDirectoryString->String[1] = L'I';\r
+ ResourceDirectoryString->String[2] = L'I';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create string entry for Name\r
+ //\r
+ NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'E';\r
+ ResourceDirectoryString->String[1] = L'F';\r
+ ResourceDirectoryString->String[2] = L'I';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create string entry for Language\r
+ //\r
+ LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'B';\r
+ ResourceDirectoryString->String[1] = L'I';\r
+ ResourceDirectoryString->String[2] = L'N';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create Leaf data\r
+ //\r
+ LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset;\r
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+ ResourceDataEntry->OffsetToData = HiiSectionOffset;\r
+ ResourceDataEntry->Size = HiiDataSize;\r
+\r
+ *pSectionHeaderSize = HiiSectionHeaderSize;\r
+ return HiiSectionHeader;\r
+}\r
+\r
int\r
main (\r
int argc,\r
EFI_IFR_FORM_SET IfrFormSet;\r
UINT8 NumberOfFormPacakge;\r
EFI_HII_PACKAGE_HEADER EndPackage;\r
+ UINT32 HiiSectionHeaderSize;\r
+ UINT8 *HiiSectionHeader;\r
\r
SetUtilityName (UTILITY_NAME);\r
\r
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
EndPackage.Type = EFI_HII_PACKAGE_END;\r
memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));\r
+ HiiSectionHeaderSize = 0;\r
+ HiiSectionHeader = NULL;\r
\r
if (argc == 1) {\r
Error (NULL, 0, 1001, "Missing options", "No input options.");\r
continue;\r
}\r
\r
+ if (stricmp (argv[0], "--hiibinpackage") == 0) {\r
+ OutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+\r
if (argv[0][0] == '-') {\r
Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
goto Finish;\r
goto Finish;\r
}\r
\r
+ if ((OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) {\r
+ Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");\r
+ goto Finish;\r
+ }\r
+\r
//\r
// Input image file\r
//\r
case FW_HII_PACKAGE_LIST_RCIMAGE:\r
VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
break;\r
+ case FW_HII_PACKAGE_LIST_BINIMAGE:\r
+ VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge list file.");\r
+ break;\r
default:\r
break;\r
}\r
}\r
\r
//\r
- // Combine multi binary HII package files to a single text package list RC file.\r
+ // Combine multi binary HII package files.\r
//\r
- if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+ if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
//\r
// Get hii package list lenght\r
//\r
HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
}\r
memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
+\r
//\r
- // write the hii package into the text package list rc file.\r
+ // write the hii package into the binary package list file with the resource section header\r
//\r
- for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
- fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
+ if (OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
+ //\r
+ // Create the resource section header\r
+ //\r
+ HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);\r
+ //\r
+ // Wrtie section header and HiiData into File.\r
+ //\r
+ fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut);\r
+ fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut);\r
+ //\r
+ // Free allocated resources.\r
+ //\r
+ free (HiiSectionHeader);\r
+ free (HiiPackageListBuffer);\r
+ //\r
+ // Done successfully\r
+ //\r
+ goto Finish;\r
}\r
- fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
\r
- HiiPackageDataPointer = HiiPackageListBuffer;\r
- for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
+ //\r
+ // write the hii package into the text package list rc file.\r
+ //\r
+ if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+ for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
+ fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
+ }\r
+ fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
+\r
+ HiiPackageDataPointer = HiiPackageListBuffer;\r
+ for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
+ if (Index % 16 == 0) {\r
+ fprintf (fpOut, "\n ");\r
+ }\r
+ fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
+ HiiPackageDataPointer += 2;\r
+ }\r
+ \r
if (Index % 16 == 0) {\r
fprintf (fpOut, "\n ");\r
}\r
- fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
- HiiPackageDataPointer += 2;\r
- }\r
- \r
- if (Index % 16 == 0) {\r
- fprintf (fpOut, "\n ");\r
- }\r
- if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
- fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
- }\r
- if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
- fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+ if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
+ }\r
+ if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+ }\r
+ free (HiiPackageListBuffer);\r
+ //\r
+ // Done successfully\r
+ //\r
+ goto Finish;\r
}\r
- free (HiiPackageListBuffer);\r
- //\r
- // Done successfully\r
- //\r
- goto Finish;\r
}\r
\r
//\r
stricmp (ModuleType, "DXE_DRIVER") == 0 ||\r
stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||\r
stricmp (ModuleType, "UEFI_DRIVER") == 0 ||\r
- stricmp (ModuleType, "SMM_DRIVER") == 0 ||\r
stricmp (ModuleType, "SMM_CORE") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
VerboseMsg ("Convert the input ELF Image to Pe Image");\r
ConvertElf(&FileBuffer, &FileLength);\r
}\r
+ \r
+ //\r
+ // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP\r
+ // XIP == eXecute In Place\r
+ //\r
+ PeCoffConvertImageToXip (&FileBuffer, &FileLength);\r
\r
//\r
// Remove reloc section from PE or TE image\r
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
}\r
}\r
- \r
+\r
+ //\r
+ // Fill HII section data\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
+ if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) {\r
+ //\r
+ // Update resource section header offset\r
+ //\r
+ SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);\r
+ //\r
+ // Update resource section name\r
+ //\r
+ strcpy((char *) SectionHeader[Index].Name, ".rsrc");\r
+ //\r
+ // Update resource data directory.\r
+ //\r
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
//\r
// Zero ExceptionTable Xdata\r
//\r
//\r
// strip space\r
//\r
- for (cptr = Line; *cptr && isspace(*cptr); cptr++) {\r
+ for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) {\r
}\r
\r
// Skip Blank Lines and Comment Lines\r
// DD XXXXXXXXX\r
// DD XXXXXXXXX\r
//\r
- if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {\r
+ if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) {\r
//\r
// Skip blanks and look for a hex digit\r
//\r
cptr += 3;\r
- for (; *cptr && isspace(*cptr); cptr++) {\r
+ for (; *cptr && isspace((int)*cptr); cptr++) {\r
}\r
- if (isxdigit (*cptr)) {\r
+ if (isxdigit ((int)*cptr)) {\r
if (sscanf (cptr, "%X", &ScannedData) != 1) {\r
return STATUS_ERROR;\r
}\r