From 95d675b5272d76105e2109a11d8b35f416be8b29 Mon Sep 17 00:00:00 2001 From: qwang12 Date: Thu, 24 Jan 2008 07:29:31 +0000 Subject: 1) Sync EdkCompatibilityPkg with EDK 1.04. The changes includes: 1.1) Bug fixes. (For details, please check Documents & files: Snapshot/Release Notes at https://edk.tianocore.org/servlets/ProjectDocumentList?folderID=43&expandFolder=43&folderID=6) 1.2) Add new UEFI protocol definitions for AbsolutePointer, FormBrowser2, HiiConfigAccess, HiiConfigRouting, HiiDatabase, HiiFont, HiiImage, HiiString, SimpleTextInputEx, DPC protocol. 1.3) Add Smbios 2.5, 2.6 supports. Incompatible changes hilighted: 1) EFI_MANAGED_NETWORK_PROTOCOL_GUID changed. 2) EFI_IP4_IPCONFIG_DATA changed. 2) Add in EdkCompatibilityPkg/EdkCompatibilityPkg.dsc to build all libraries in this package. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4624 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Sample/Tools/Source/GenFfsFile/GenFfsFile.c | 541 ++++++++++++++++----- 1 file changed, 423 insertions(+), 118 deletions(-) (limited to 'EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c') diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c index 188ca77945..2e06570633 100644 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c +++ b/EdkCompatibilityPkg/Sample/Tools/Source/GenFfsFile/GenFfsFile.c @@ -24,6 +24,7 @@ Abstract: #include "EfiFirmwareFileSystem.h" #include "EfiFirmwareVolumeHeader.h" #include "EfiImageFormat.h" +#include "EfiImage.h" #include "ParseInf.h" #include "Compress.h" #include "EfiCustomizedCompress.h" @@ -82,6 +83,39 @@ PrintUsage ( void ); +static +void +AddMacro ( + UINT8 *MacroString + ); + +static +UINT8 * +GetMacroValue ( + UINT8 *MacroName + ); + +static +void +FreeMacros ( + ); + +static +STATUS +ReplaceMacros ( + UINT8 *InputFile, + UINT8 *OutputFile + ); + +// +// Linked list to keep track of all macros +// +typedef struct _MACRO { + struct _MACRO *Next; + UINT8 *Name; + UINT8 *Value; +} MACRO; + // // Keep globals in this structure // @@ -90,10 +124,13 @@ static struct { UINT8 PrimaryPackagePath[_MAX_PATH]; UINT8 OverridePackagePath[_MAX_PATH]; BOOLEAN Verbose; + MACRO *MacroList; } mGlobals; static EFI_GUID mZeroGuid = { 0 }; +static UINT8 MinFfsDataAlignOverride = 0; + static void StripQuotes ( @@ -151,8 +188,9 @@ Returns: --*/ { printf ("Usage:\n"); - printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n"); - printf (" -b \"build directory\":\n "); + printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\"\n"); + printf (" -d \"name=value\" -v\n"); + printf (" -b \"build directory\":\n"); printf (" specifies the full path to the component build directory.\n"); printf (" -p1 \"P1_path\":\n"); printf (" specifies fully qualified file name to the primary package file.\n"); @@ -161,6 +199,10 @@ Returns: printf (" -p2 \"P2_path\":\n"); printf (" specifies fully qualified file name to the override package file.\n"); printf (" This file will normally exist in the build tip. Optional.\n"); + printf (" -d \"name=value\":\n"); + printf (" add a macro definition for package file. Optional.\n"); + printf (" -v :\n"); + printf (" verbose. Optional.\n"); } static @@ -756,54 +798,6 @@ Returns: return ; } -static -INT32 -ProcessEnvironmentVariable ( - IN CHAR8 *Buffer, - OUT CHAR8 *NewBuffer - ) -/*++ - -Routine Description: - - Converts environment variables to values - -Arguments: - - Buffer - Buffer containing Environment Variable String - - NewBuffer - Buffer containing value of environment variable - - -Returns: - - Number of characters from Buffer used - ---*/ -{ - INT32 Index; - INT32 Index2; - CHAR8 VariableBuffer[_MAX_PATH]; - - Index = 2; - Index2 = 0; - - while (Buffer[Index] != ')') { - VariableBuffer[Index - 2] = Buffer[Index++]; - } - - VariableBuffer[Index - 2] = 0; - Index++; - - if (getenv (VariableBuffer) != NULL) { - strcpy (NewBuffer, getenv (VariableBuffer)); - } else { - printf ("Environment variable %s not found!\n", VariableBuffer); - } - - return Index; -} - static void SplitAttributesField ( @@ -880,7 +874,6 @@ GetToolArguments ( UINT32 Index2; UINT32 z; CHAR8 *CharBuffer; - INT32 Index; INT32 ReturnValue; EFI_STATUS Status; @@ -982,17 +975,7 @@ GetToolArguments ( ToolArgumentsArray[argc] = CharBuffer; - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolArgumentsArray[argc], &Buffer[Index]); - } - } else { - strcpy (ToolArgumentsArray[argc], Buffer); - } + strcpy (ToolArgumentsArray[argc], Buffer); argc += 1; ToolArgumentsArray[argc] = NULL; @@ -1010,17 +993,7 @@ GetToolArguments ( ZeroMem (InputFileName, sizeof (_MAX_PATH)); - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (InputFileName, &Buffer[Index]); - } - } else { - strcpy (InputFileName, Buffer); - } + strcpy (InputFileName, Buffer); InputFlag = FALSE; continue; @@ -1037,17 +1010,7 @@ GetToolArguments ( ZeroMem (OutputFileName, sizeof (_MAX_PATH)); - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (OutputFileName, &Buffer[Index]); - } - } else { - strcpy (OutputFileName, Buffer); - } + strcpy (OutputFileName, Buffer); OutputFlag = FALSE; continue; @@ -1139,10 +1102,12 @@ Returns: { EFI_STATUS Status; UINT32 Size; + UINT32 OldSize; + UINT32 Adjust; + UINT16 TeStrippedSize; CHAR8 Buffer[_MAX_PATH]; CHAR8 Type[_MAX_PATH]; CHAR8 FileName[_MAX_PATH]; - CHAR8 NewBuffer[_MAX_PATH]; INT32 Index3; INT32 Index2; UINT32 ReturnValue; @@ -1157,7 +1122,6 @@ Returns: FILE *InputFile; UINT8 Temp; int returnint; - INT32 Index; UINT32 LineNumber; BOOLEAN IsError; EFI_GUID SignGuid; @@ -1200,11 +1164,7 @@ Returns: } StripParens (Buffer); - if (Buffer[0] == '$') { - ProcessEnvironmentVariable (&Buffer[0], Type); - } else { - strcpy (Type, Buffer); - } + strcpy (Type, Buffer); // // build buffer // @@ -1275,19 +1235,7 @@ Returns: } StripParens (Buffer); - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolName, &Buffer[Index]); - } - } else { - strcpy (ToolName, Buffer); - } - + strcpy (ToolName, Buffer); ToolArgumentsArray[0] = ToolName; // @@ -1397,13 +1345,8 @@ Returns: if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) { sprintf (FileName, "%s\\", BuildDirectory); } - + while (Buffer[Index3] != '\n') { - if (Buffer[Index3] == '$') { - Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer); - strcat (FileName, NewBuffer); - } - if (Buffer[Index3] == 0) { break; } else { @@ -1420,6 +1363,7 @@ Returns: goto Done; } + OldSize = Size; fread (&ByteBuffer, sizeof (UINT8), 1, InFile); while (!feof (InFile)) { FileBuffer[Size++] = ByteBuffer; @@ -1429,6 +1373,29 @@ Returns: fclose (InFile); InFile = NULL; + // + // Adjust the TE Section for IPF so that the function entries are 16-byte aligned. + // + if (Size - OldSize >= sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER) && + ((EFI_COMMON_SECTION_HEADER *) &FileBuffer[OldSize])->Type == EFI_SECTION_TE && + ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->Machine == EFI_IMAGE_MACHINE_IA64) { + TeStrippedSize = ((EFI_TE_IMAGE_HEADER *) &FileBuffer[OldSize + 4])->StrippedSize; + Adjust = TeStrippedSize - (OldSize + sizeof (EFI_COMMON_SECTION_HEADER) + sizeof (EFI_TE_IMAGE_HEADER)); + Adjust &= 15; + if (Adjust > 0) { + memmove (&FileBuffer[OldSize + Adjust], &FileBuffer[OldSize], Size - OldSize); + // + // Pad with RAW Section type + // + *(UINT32 *)&FileBuffer[OldSize] = 0x19000000 | Adjust; + Size += Adjust; + // + // Make sure the Data alignment in FFS header is no less than 1 (16-byte aligned) + // + MinFfsDataAlignOverride = 1; + } + } + // // Make sure section ends on a DWORD boundary // @@ -2252,6 +2219,9 @@ here: memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); FileHeader.Type = StringToType (FileType); + if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) { + FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3); + } FileHeader.Attributes = FfsAttrib; // // Now FileSize includes the EFI_FFS_FILE_HEADER @@ -2396,6 +2366,9 @@ here: memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); FileHeader.Type = StringToType (FileType); + if (((FfsAttrib & FFS_ATTRIB_DATA_ALIGNMENT) >> 3) < MinFfsDataAlignOverride) { + FfsAttrib = (FfsAttrib & ~FFS_ATTRIB_DATA_ALIGNMENT) | (MinFfsDataAlignOverride << 3); + } FileHeader.Attributes = FfsAttrib; // // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER @@ -2540,6 +2513,7 @@ Returns: // SetUtilityName (UTILITY_NAME); Status = ProcessCommandLineArgs (argc, argv); + FreeMacros (); if (Status != STATUS_SUCCESS) { return Status; } @@ -2577,6 +2551,11 @@ Returns: --*/ { + STATUS Status; + UINT8 *OriginalPrimaryPackagePath; + UINT8 *OriginalOverridePackagePath; + UINT8 *PackageName; + // // If no args, then print usage instructions and return an error // @@ -2584,7 +2563,9 @@ Returns: PrintUsage (); return STATUS_ERROR; } - + + OriginalPrimaryPackagePath = NULL; + OriginalOverridePackagePath = NULL; memset (&mGlobals, 0, sizeof (mGlobals)); Argc--; Argv++; @@ -2617,12 +2598,12 @@ Returns: return STATUS_ERROR; } - if (mGlobals.PrimaryPackagePath[0]) { + if (OriginalPrimaryPackagePath) { Error (NULL, 0, 0, Argv[0], "option can only be specified once"); return STATUS_ERROR; } - - strcpy (mGlobals.PrimaryPackagePath, Argv[1]); + + OriginalPrimaryPackagePath = Argv[1]; Argc--; Argv++; } else if (_strcmpi (Argv[0], "-p2") == 0) { @@ -2635,12 +2616,12 @@ Returns: return STATUS_ERROR; } - if (mGlobals.OverridePackagePath[0]) { + if (OriginalOverridePackagePath) { Error (NULL, 0, 0, Argv[0], "option can only be specified once"); return STATUS_ERROR; } - - strcpy (mGlobals.OverridePackagePath, Argv[1]); + + OriginalOverridePackagePath = Argv[1]; Argc--; Argv++; } else if (_strcmpi (Argv[0], "-v") == 0) { @@ -2648,6 +2629,19 @@ Returns: // OPTION: -v verbose // mGlobals.Verbose = TRUE; + } else if (_strcmpi (Argv[0], "-d") == 0) { + // + // OPTION: -d name=value + // Make sure there is another argument, then add it to our macro list. + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "option requires the macro definition"); + return STATUS_ERROR; + } + + AddMacro (Argv[1]); + Argc--; + Argv++; } else if (_strcmpi (Argv[0], "-h") == 0) { // // OPTION: -h help @@ -2669,13 +2663,324 @@ Returns: Argv++; Argc--; } + + // + // Must have at least specified the build directory + // + if (!mGlobals.BuildDirectory[0]) { + Error (NULL, 0, 0, "must specify build directory", NULL); + return STATUS_ERROR; + } + // // Must have at least specified the package file name // - if (mGlobals.PrimaryPackagePath[0] == 0) { + if (OriginalPrimaryPackagePath == NULL) { Error (NULL, 0, 0, "must specify primary package file", NULL); return STATUS_ERROR; } + PackageName = OriginalPrimaryPackagePath + strlen (OriginalPrimaryPackagePath); + while ((*PackageName != '\\') && (*PackageName != '/') && + (PackageName != OriginalPrimaryPackagePath)) { + PackageName--; + } + // + // Skip the '\' or '/' + // + if (PackageName != OriginalPrimaryPackagePath) { + PackageName++; + } + sprintf (mGlobals.PrimaryPackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName); + Status = ReplaceMacros (OriginalPrimaryPackagePath, mGlobals.PrimaryPackagePath); + if (Status == STATUS_WARNING) { + // + // No macro replacement, use the previous package file + // + strcpy (mGlobals.PrimaryPackagePath, OriginalPrimaryPackagePath); + } else if (Status != STATUS_SUCCESS) { + return Status; + } + + if (OriginalOverridePackagePath != NULL) { + PackageName = OriginalOverridePackagePath + strlen (OriginalOverridePackagePath); + while ((*PackageName != '\\') && (*PackageName != '/') && + (PackageName != OriginalOverridePackagePath)) { + PackageName--; + } + // + // Skip the '\' or '/' + // + if (PackageName != OriginalOverridePackagePath) { + PackageName++; + } + sprintf (mGlobals.OverridePackagePath, "%s\\%s.new", mGlobals.BuildDirectory, PackageName); + Status = ReplaceMacros (OriginalOverridePackagePath, mGlobals.OverridePackagePath); + if (Status == STATUS_WARNING) { + // + // No macro replacement, use the previous package file + // + strcpy (mGlobals.OverridePackagePath, OriginalOverridePackagePath); + } else if (Status != STATUS_SUCCESS) { + return Status; + } + } + return STATUS_SUCCESS; } + +static +void +AddMacro ( + UINT8 *MacroString + ) +/*++ + +Routine Description: + + Add or override a macro definition. + +Arguments: + + MacroString - macro definition string: name=value + +Returns: + + None + +--*/ +{ + MACRO *Macro; + MACRO *NewMacro; + UINT8 *Value; + + // + // Seperate macro name and value by '\0' + // + for (Value = MacroString; *Value && (*Value != '='); Value++); + + if (*Value == '=') { + *Value = '\0'; + Value ++; + } + + // + // We now have a macro name and value. + // Look for an existing macro and overwrite it. + // + Macro = mGlobals.MacroList; + while (Macro) { + if (_strcmpi (MacroString, Macro->Name) == 0) { + Macro->Value = Value; + return; + } + + Macro = Macro->Next; + } + + // + // Does not exist, create a new one + // + NewMacro = (MACRO *) malloc (sizeof (MACRO)); + memset ((UINT8 *) NewMacro, 0, sizeof (MACRO)); + NewMacro->Name = MacroString; + NewMacro->Value = Value; + + // + // Add it to the head of the list. + // + NewMacro->Next = mGlobals.MacroList; + mGlobals.MacroList = NewMacro; + + return; +} + +static +UINT8 * +GetMacroValue ( + UINT8 *MacroName + ) +/*++ + +Routine Description: + + Look up a macro. + +Arguments: + + MacroName - The name of macro + +Returns: + + Pointer to the value of the macro if found + NULL if the macro is not found + +--*/ +{ + + MACRO *Macro; + UINT8 *Value; + + // + // Scan for macro + // + Macro = mGlobals.MacroList; + while (Macro) { + if (_strcmpi (MacroName, Macro->Name) == 0) { + return Macro->Value; + } + Macro = Macro->Next; + } + + // + // Try environment variable + // + Value = getenv (MacroName); + if (Value == NULL) { + printf ("Environment variable %s not found!\n", MacroName); + } + return Value; +} + +static +void +FreeMacros ( + ) +/*++ + +Routine Description: + + Free the macro list. + +Arguments: + + None + +Returns: + + None + +--*/ +{ + MACRO *Macro; + MACRO *NextMacro; + + Macro = mGlobals.MacroList; + while (Macro) { + NextMacro = Macro->Next; + free (Macro); + Macro = NextMacro; + } + mGlobals.MacroList = NULL; + + return; +} + +static +STATUS +ReplaceMacros ( + UINT8 *InputFile, + UINT8 *OutputFile + ) +/*++ + +Routine Description: + + Replace all the macros in InputFile to create the OutputFile. + +Arguments: + + InputFile - Input package file for macro replacement + OutputFile - Output package file after macro replacement + +Returns: + + STATUS_SUCCESS - Output package file is created successfully after the macro replacement. + STATUS_WARNING - Output package file is not created because of no macro replacement. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + FILE *Fptr; + UINT8 *SaveStart; + UINT8 *FromPtr; + UINT8 *ToPtr; + UINT8 *Value; + UINT8 *FileBuffer; + UINTN FileSize; + + // + // Get the file size, and then read the entire thing into memory. + // Allocate extra space for a terminator character. + // + if ((Fptr = fopen (InputFile, "r")) == NULL) { + Error (NULL, 0, 0, InputFile, "can't open input file"); + return STATUS_ERROR; + } + fseek (Fptr, 0, SEEK_END); + FileSize = ftell (Fptr); + fseek (Fptr, 0, SEEK_SET); + FileBuffer = malloc (FileSize + 1); + if (FileBuffer == NULL) { + fclose (Fptr); + Error (NULL, 0, 0, InputFile, "file buffer memory allocation failure"); + return STATUS_ERROR; + } + fread (FileBuffer, FileSize, 1, Fptr); + FileBuffer[FileSize] = '\0'; + fclose (Fptr); + + // + // Walk the entire file, replacing $(MACRO_NAME). + // + Fptr = NULL; + FromPtr = FileBuffer; + SaveStart = FromPtr; + while (*FromPtr) { + if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) { + FromPtr += 2; + for (ToPtr = FromPtr; *ToPtr && (*ToPtr != ')'); ToPtr++); + if (*ToPtr) { + // + // Find an $(MACRO_NAME), replace it + // + *ToPtr = '\0'; + Value = GetMacroValue (FromPtr); + *(FromPtr-2)= '\0'; + if (Fptr == NULL) { + if ((Fptr = fopen (OutputFile, "w")) == NULL) { + free (FileBuffer); + Error (NULL, 0, 0, OutputFile, "can't open output file"); + return STATUS_ERROR; + } + } + if (Value != NULL) { + fprintf (Fptr, "%s%s", SaveStart, Value); + } else { + fprintf (Fptr, "%s", SaveStart); + } + // + // Continue macro replacement for the remaining string line + // + FromPtr = ToPtr+1; + SaveStart = FromPtr; + continue; + } else { + break; + } + } else { + FromPtr++; + } + } + if (Fptr != NULL) { + fprintf (Fptr, "%s", SaveStart); + } + + free (FileBuffer); + if (Fptr != NULL) { + fclose (Fptr); + return STATUS_SUCCESS; + } else { + return STATUS_WARNING; + } +} -- cgit v1.2.3