int main ( IN int Argc, IN char **Argv ) { COMPILER_RUN_STATUS Status; SetPrintLevel(WARNING_LOG_LEVEL); CVfrCompiler Compiler(Argc, Argv); Compiler.PreProcess(); Compiler.Compile(); Compiler.AdjustBin(); Compiler.GenBinary(); Compiler.GenCFile(); Compiler.GenRecordListFile (); Status = Compiler.RunStatus (); if ((Status == STATUS_DEAD) || (Status == STATUS_FAILED)) { return 2; } if (gCBuffer.Buffer != NULL) { delete gCBuffer.Buffer; } if (gRBuffer.Buffer != NULL) { delete gRBuffer.Buffer; } return GetUtilityStatus (); }
int main ( int Argc, char *Argv[] ) /*++ Routine Description: Call the routine to parse the command-line options, then process the file. Arguments: Standard C main() argc and argv. Returns: 0 if successful nonzero otherwise --*/ { STATUS Status; // // Set the utility name for error reporting purposes // SetUtilityName (UTILITY_NAME); // // Process the command-line arguments // Status = ProcessArgs (Argc, Argv); if (Status != STATUS_SUCCESS) { return Status; } // // Switch based on args // if (mGlobals.Mode & MODE_CREATE_HII_RESOURCE_FILE) { CreateResourceScript (mGlobals.ResourceFileName, &mGlobals.Guid, mGlobals.PackageFile); } if (mGlobals.Mode & MODE_CREATE_HII_PACKAGE_LIST) { CreatePackageList (mGlobals.PackageListFileName, &mGlobals.Guid, mGlobals.PackageFile); } FreeGlobals (); return GetUtilityStatus (); }
static STATUS ProcessFile ( INT8 *InFileName, INT8 *OutFileName ) /*++ Routine Description: Process a PE32 EFI file. Arguments: InFileName - the file name pointer to the input file OutFileName - the file name pointer to the output file Returns: STATUS_SUCCESS - the process has been finished successfully STATUS_ERROR - error occured during the processing --*/ { STATUS Status; FILE *InFptr; FILE *OutFptr; UINT16 MachineType; UINT16 SubSystem; EFI_TE_IMAGE_HEADER TEImageHeader; UINT32 PESigOffset; EFI_IMAGE_FILE_HEADER FileHeader; EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; UINT32 BytesStripped; UINT32 FileSize; UINT8 *Buffer; long SaveFilePosition; InFptr = NULL; OutFptr = NULL; Buffer = NULL; Status = STATUS_ERROR; // // Try to open the input file // if ((InFptr = fopen (InFileName, "rb")) == NULL) { Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); return STATUS_ERROR; } // // Double-check the file to make sure it's what we expect it to be // if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { goto Finish; } // // Initialize our new header // memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER)); // // Seek to the end to get the file size // fseek (InFptr, 0, SEEK_END); FileSize = ftell (InFptr); fseek (InFptr, 0, SEEK_SET); // // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit // offset (from the start of the file) to the PE signature, which always // follows the MSDOS stub. The PE signature is immediately followed by the // COFF file header. // // if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); goto Finish; } if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); goto Finish; } if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); goto Finish; } // // We should now be at the COFF file header. Read it in and verify it's // of an image type we support. // if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { Error (NULL, 0, 0, InFileName, "failed to read file header from image"); goto Finish; } if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) { Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); goto Finish; } // // Calculate the total number of bytes we're going to strip off. The '4' is for the // PE signature PE\0\0. Then sanity check the size. // BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader; if (BytesStripped >= FileSize) { Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size"); goto Finish; } if (BytesStripped &~0xFFFF) { Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL); goto Finish; } TEImageHeader.StrippedSize = (UINT16) BytesStripped; // // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ // SaveFilePosition = ftell (InFptr); if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); goto Finish; } if (OptionalHeader32.SectionAlignment != OptionalHeader32.FileAlignment) { Error (NULL, 0, 0, InFileName, "Section alignment is not same to file alignment."); goto Finish; } if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Fill in our new header with required data directory entries // TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint; // // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); // // We're going to pack the subsystem into 1 byte. Make sure it fits // if (OptionalHeader32.Subsystem &~0xFF) { Error ( NULL, 0, 0, InFileName, NULL, "image subsystem 0x%X cannot be packed into 1 byte", (UINT32) OptionalHeader32.Subsystem ); goto Finish; } TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem; TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase); if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; } if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; } } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { // // Rewind and re-read the optional header // fseek (InFptr, SaveFilePosition, SEEK_SET); if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file"); goto Finish; } TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint; // // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); // // We're going to pack the subsystem into 1 byte. Make sure it fits // if (OptionalHeader64.Subsystem &~0xFF) { Error ( NULL, 0, 0, InFileName, NULL, "image subsystem 0x%X cannot be packed into 1 byte", (UINT32) OptionalHeader64.Subsystem ); goto Finish; } TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem; TEImageHeader.BaseOfCode = OptionalHeader64.BaseOfCode; TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase); if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; } if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; } } else { Error ( NULL, 0, 0, InFileName, "unsupported magic number 0x%X found in optional header", (UINT32) OptionalHeader32.Magic ); goto Finish; } // // Fill in the remainder of our new image header // TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE; TEImageHeader.Machine = FileHeader.Machine; // // We're going to pack the number of sections into a single byte. Make sure it fits. // if (FileHeader.NumberOfSections &~0xFF) { Error ( NULL, 0, 0, InFileName, NULL, "image's number of sections 0x%X cannot be packed into 1 byte", (UINT32) FileHeader.NumberOfSections ); goto Finish; } TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections; // // Now open our output file // if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); goto Finish; } // // Write the TE header // if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) { Error (NULL, 0, 0, "failed to write image header to output file", NULL); goto Finish; } // // Position into the input file, read the part we're not stripping, and // write it out. // fseek (InFptr, BytesStripped, SEEK_SET); Buffer = (UINT8 *) malloc (FileSize - BytesStripped); if (Buffer == NULL) { Error (NULL, 0, 0, "application error", "failed to allocate memory"); goto Finish; } if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) { Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file"); goto Finish; } if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) { Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file"); goto Finish; } Status = STATUS_SUCCESS; Finish: if (InFptr != NULL) { fclose (InFptr); } // // Close the output file. If there was an error, delete the output file so // that a subsequent build will rebuild it. // if (OutFptr != NULL) { fclose (OutFptr); if (GetUtilityStatus () == STATUS_ERROR) { remove (OutFileName); } } // // Free up our buffer // if (Buffer != NULL) { free (Buffer); } return Status; }
int main ( int Argc, char *Argv[] ) /*++ Routine Description: Arguments: Argc - standard C main() argument count Argv - standard C main() argument list Returns: 0 success non-zero otherwise --*/ // GC_TODO: ] - add argument and description to function comment { INT8 *Ext; UINT32 Status; SetUtilityName (UTILITY_NAME); // // Parse the command line arguments // if (ParseCommandLine (Argc, Argv)) { return STATUS_ERROR; } // // If dumping an image, then do that and quit // if (mOptions.Dump) { DumpImage (mOptions.InFileName); goto Finish; } // // Determine the output filename. Either what they specified on // the command line, or the first input filename with a different extension. // if (!mOptions.OutFileName[0]) { strcpy (mOptions.OutFileName, mOptions.InFileName); // // Find the last . on the line and replace the filename extension with // the default // for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); Ext-- ) ; // // If dot here, then insert extension here, otherwise append // if (*Ext != '.') { Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); } strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); } // // Make sure we don't have the same filename for input and output files // if (_stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); goto Finish; } // // Process the file // ProcessFile (mOptions.InFileName, mOptions.OutFileName); Finish: Status = GetUtilityStatus (); return Status; }
int main ( int Argc, char *Argv[] ) /*++ Routine Description: Call the routine to parse the command-line options, then process each file to build dependencies. Arguments: Argc - Standard C main() argc. Argv - Standard C main() argv. Returns: 0 if successful nonzero otherwise --*/ { STRING_LIST *File; STRING_LIST ProcessedFiles; STRING_LIST *TempList; STATUS Status; INT8 *Cptr; INT8 TargetFileName[MAX_PATH]; SetUtilityName (UTILITY_NAME); // // Process the command-line arguments // Status = ProcessArgs (Argc, Argv); if (Status != STATUS_SUCCESS) { return STATUS_ERROR; } // // Go through the list of source files and process each. // memset (&ProcessedFiles, 0, sizeof (STRING_LIST)); File = mGlobals.SourceFiles; while (File != NULL) { // // Clear out our list of processed files // TempList = ProcessedFiles.Next; while (ProcessedFiles.Next != NULL) { TempList = ProcessedFiles.Next->Next; free (ProcessedFiles.Next->Str); free (ProcessedFiles.Next); ProcessedFiles.Next = TempList; } // // Replace filename extension with ".obj" if they did not // specifically specify the target file // if (mGlobals.TargetFileName[0] == 0) { strcpy (TargetFileName, File->Str); // // Find the .extension // for (Cptr = TargetFileName + strlen (TargetFileName) - 1; (*Cptr != '\\') && (Cptr > TargetFileName) && (*Cptr != '.'); Cptr-- ) ; if (Cptr == TargetFileName) { Error (NULL, 0, 0, File->Str, "could not locate extension in filename"); goto Finish; } // // Tack on the ".obj" // strcpy (Cptr, ".obj"); } else { // // Copy the target filename they specified // strcpy (TargetFileName, mGlobals.TargetFileName); } if (mGlobals.IsCl) { Status = ProcessClOutput (TargetFileName, File->Str, &ProcessedFiles); } else { Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles, SearchCurrentDir); } if (Status != STATUS_SUCCESS) { goto Finish; } File = File->Next; } Finish: // // Free up memory // FreeLists (); // // Free up our processed files list // TempList = ProcessedFiles.Next; while (ProcessedFiles.Next != NULL) { TempList = ProcessedFiles.Next->Next; free (ProcessedFiles.Next->Str); free (ProcessedFiles.Next); ProcessedFiles.Next = TempList; } // // Close our temp output file // if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) { fclose (mGlobals.OutFptr); } if (mGlobals.NeverFail) { return STATUS_SUCCESS; } if (mGlobals.OutFileName != NULL) { if (GetUtilityStatus () == STATUS_ERROR) { // // If any errors, then delete our temp output // Also try to delete target file to improve the incremental build // remove (mGlobals.TmpFileName); remove (TargetFileName); } else { // // Otherwise, rename temp file to output file // remove (mGlobals.OutFileName); rename (mGlobals.TmpFileName, mGlobals.OutFileName); } } return GetUtilityStatus (); }
EFI_STATUS main ( IN INTN argc, IN CHAR8 **argv ) /*++ Routine Description: This utility uses GenFvImage.Lib to build a firmware volume image. Arguments: FvInfFileName The name of an FV image description file. Arguments come in pair in any order. -I FvInfFileName Returns: EFI_SUCCESS No error conditions detected. EFI_INVALID_PARAMETER One or more of the input parameters is invalid. EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable. Most commonly this will be memory allocation or file creation. EFI_LOAD_ERROR GenFvImage.lib could not be loaded. EFI_ABORTED Error executing the GenFvImage lib. --*/ { EFI_STATUS Status; CHAR8 InfFileName[_MAX_PATH]; CHAR8 *InfFileImage; UINTN InfFileSize; UINT8 *FvImage; UINTN FvImageSize; UINT8 Index; CHAR8 FvFileNameBuffer[_MAX_PATH]; CHAR8 *FvFileName; FILE *FvFile; FILE *SymFile; CHAR8 SymFileNameBuffer[_MAX_PATH]; CHAR8 *SymFileName; UINT8 *SymImage; UINTN SymImageSize; CHAR8 *CurrentSymString; FvFileName = FvFileNameBuffer; SymFileName = SymFileNameBuffer; SetUtilityName (UTILITY_NAME); // // Display utility information // PrintUtilityInfo (); // // Verify the correct number of arguments // if (argc != MAX_ARGS) { Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); PrintUsage (); return GetUtilityStatus (); } // // Initialize variables // strcpy (InfFileName, ""); // // Parse the command line arguments // for (Index = 1; Index < MAX_ARGS; Index += 2) { // // Make sure argument pair begin with - or / // if (argv[Index][0] != '-' && argv[Index][0] != '/') { Error (NULL, 0, 0, argv[Index], "argument pair must begin with \"-\" or \"/\""); PrintUsage (); return GetUtilityStatus (); } // // Make sure argument specifier is only one letter // if (argv[Index][2] != 0) { Error (NULL, 0, 0, argv[Index], "unrecognized argument"); PrintUsage (); return GetUtilityStatus (); } // // Determine argument to read // switch (argv[Index][1]) { case 'I': case 'i': if (strlen (InfFileName) == 0) { strcpy (InfFileName, argv[Index + 1]); } else { Error (NULL, 0, 0, argv[Index + 1], "FvInfFileName may only be specified once"); PrintUsage (); return GetUtilityStatus (); } break; default: Error (NULL, 0, 0, argv[Index], "unrecognized argument"); PrintUsage (); return GetUtilityStatus (); break; } } // // Read the INF file image // Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize); if (EFI_ERROR (Status)) { return STATUS_ERROR; } // // Call the GenFvImage lib // Status = GenerateFvImage ( InfFileImage, InfFileSize, &FvImage, &FvImageSize, &FvFileName, &SymImage, &SymImageSize, &SymFileName ); if (EFI_ERROR (Status)) { switch (Status) { case EFI_INVALID_PARAMETER: Error (NULL, 0, 0, "invalid parameter passed to GenFvImage Lib", NULL); return GetUtilityStatus (); break; case EFI_ABORTED: Error (NULL, 0, 0, "error detected while creating the file image", NULL); return GetUtilityStatus (); break; case EFI_OUT_OF_RESOURCES: Error (NULL, 0, 0, "GenFvImage Lib could not allocate required resources", NULL); return GetUtilityStatus (); break; case EFI_VOLUME_CORRUPTED: Error (NULL, 0, 0, "no base address was specified, but the FV.INF included a PEI or BSF file", NULL); return GetUtilityStatus (); break; case EFI_LOAD_ERROR: Error (NULL, 0, 0, "could not load FV image generation library", NULL); return GetUtilityStatus (); break; default: Error (NULL, 0, 0, "GenFvImage Lib returned unknown status", "status returned = 0x%X", Status); return GetUtilityStatus (); break; } } // // Write file // FvFile = fopen (FvFileName, "wb"); if (FvFile == NULL) { Error (NULL, 0, 0, FvFileName, "could not open output file"); free (FvImage); free (SymImage); return GetUtilityStatus (); } if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) { Error (NULL, 0, 0, FvFileName, "failed to write to output file"); free (FvImage); free (SymImage); fclose (FvFile); return GetUtilityStatus (); } fclose (FvFile); free (FvImage); // // Write symbol file // if (strcmp (SymFileName, "")) { SymFile = fopen (SymFileName, "wt"); if (SymFile == NULL) { Error (NULL, 0, 0, SymFileName, "could not open output symbol file"); free (SymImage); return GetUtilityStatus (); } fprintf (SymFile, "TEXTSYM format | V1.0\n"); CurrentSymString = SymImage; while (((UINTN) CurrentSymString - (UINTN) SymImage) < SymImageSize) { fprintf (SymFile, "%s", CurrentSymString); CurrentSymString = (CHAR8 *) (((UINTN) CurrentSymString) + strlen (CurrentSymString) + 1); } fclose (SymFile); } free (SymImage); return GetUtilityStatus (); }