--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004 - 2005, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PeCoffLoader.c\r
+\r
+Abstract:\r
+\r
+ Tiano PE/COFF loader \r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+#include <IndustryStandard/PeImage.h>\r
+#include "PeCoffLib.h"\r
+\r
+typedef union {\r
+ VOID *Header; \r
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
+} EFI_IMAGE_OPTIONAL_HEADER_POINTER;\r
+\r
+STATIC\r
+RETURN_STATUS\r
+PeCoffLoaderGetPeHeader (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_IMAGE_NT_HEADERS **PeHdr,\r
+ OUT EFI_TE_IMAGE_HEADER **TeHdr\r
+ );\r
+\r
+STATIC\r
+RETURN_STATUS\r
+PeCoffLoaderCheckImageType (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
+ IN EFI_TE_IMAGE_HEADER *TeHdr\r
+ );\r
+\r
+STATIC\r
+void *\r
+PeCoffLoaderImageAddress (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN UINTN Address\r
+ );\r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateIa32Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateX64Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateIpfImage (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
+STATIC\r
+RETURN_STATUS\r
+PeCoffLoaderGetPeHeader (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_IMAGE_NT_HEADERS **PeHdr,\r
+ OUT EFI_TE_IMAGE_HEADER **TeHdr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Retrieves the PE or TE Header from a PE/COFF or TE image\r
+\r
+Arguments:\r
+\r
+ ImageContext - The context of the image being loaded\r
+\r
+ PeHdr - The buffer in which to return the PE header\r
+ \r
+ TeHdr - The buffer in which to return the TE header\r
+\r
+Returns:\r
+\r
+ RETURN_SUCCESS if the PE or TE Header is read, \r
+ Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.\r
+\r
+--*/\r
+{\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_DOS_HEADER DosHdr;\r
+ UINTN Size;\r
+\r
+ ImageContext->IsTeImage = FALSE;\r
+ //\r
+ // Read the DOS image headers\r
+ //\r
+ Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ 0,\r
+ &Size,\r
+ &DosHdr\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+\r
+ ImageContext->PeCoffHeaderOffset = 0;\r
+ if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+ //\r
+ // DOS image header is present, so read the PE header after the DOS image header\r
+ //\r
+ ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;\r
+ }\r
+ //\r
+ // Get the PE/COFF Header pointer\r
+ //\r
+ *PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);\r
+ if ((*PeHdr)->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ //\r
+ // Check the PE/COFF Header Signature. If not, then try to get a TE header\r
+ //\r
+ *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr; \r
+ if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+ ImageContext->IsTeImage = TRUE;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+STATIC\r
+RETURN_STATUS\r
+PeCoffLoaderCheckImageType (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
+ IN EFI_TE_IMAGE_HEADER *TeHdr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Checks the PE or TE header of a PE/COFF or TE image to determine if it supported\r
+\r
+Arguments:\r
+\r
+ ImageContext - The context of the image being loaded\r
+\r
+ PeHdr - The buffer in which to return the PE header\r
+ \r
+ TeHdr - The buffer in which to return the TE header\r
+\r
+Returns:\r
+\r
+ RETURN_SUCCESS if the PE/COFF or TE image is supported\r
+ RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.\r
+\r
+--*/\r
+{\r
+ //\r
+ // See if the machine type is supported. \r
+ // We support a native machine type (IA-32/Itanium-based)\r
+ //\r
+ if (ImageContext->IsTeImage == FALSE) {\r
+ ImageContext->Machine = PeHdr->FileHeader.Machine;\r
+ } else {\r
+ ImageContext->Machine = TeHdr->Machine;\r
+ }\r
+ \r
+ if (ImageContext->Machine != EFI_IMAGE_MACHINE_IA32 && \\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_IA64 && \\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_X64) {\r
+ //\r
+ // upsupported PeImage machine type \r
+ // \r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // See if the image type is supported. We support EFI Applications,\r
+ // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers.\r
+ //\r
+ if (ImageContext->IsTeImage == FALSE) {\r
+ ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;\r
+ } else {\r
+ ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);\r
+ }\r
+\r
+ if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \\r
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \\r
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \\r
+ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) {\r
+ //\r
+ // upsupported PeImage subsystem type \r
+ // \r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderGetImageInfo (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Retrieves information on a PE/COFF image\r
+\r
+Arguments:\r
+\r
+ This - Calling context\r
+ ImageContext - The context of the image being loaded\r
+\r
+Returns:\r
+\r
+ RETURN_SUCCESS - The information on the PE/COFF image was collected.\r
+ RETURN_INVALID_PARAMETER - ImageContext is NULL.\r
+ RETURN_UNSUPPORTED - The PE/COFF image is not supported.\r
+ Otherwise - The error status from reading the PE/COFF image using the\r
+ ImageContext->ImageRead() function\r
+\r
+--*/\r
+{\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_TE_IMAGE_HEADER *TeHdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
+ UINTN Size;\r
+ UINTN Index;\r
+ UINTN DebugDirectoryEntryRva;\r
+ UINTN DebugDirectoryEntryFileOffset;\r
+ UINTN SectionHeaderOffset;\r
+ EFI_IMAGE_SECTION_HEADER SectionHeader;\r
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;\r
+\r
+ PeHdr = NULL;\r
+ TeHdr = NULL;\r
+ DebugDirectoryEntry = NULL;\r
+ DebugDirectoryEntryRva = 0;\r
+\r
+ if (NULL == ImageContext) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Assume success\r
+ //\r
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+\r
+ Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Verify machine type\r
+ //\r
+ Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+\r
+ //\r
+ // Retrieve the base address of the image\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase;\r
+ } else {\r
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase;\r
+ }\r
+ } else {\r
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
+ }\r
+ //\r
+ // Initialize the alternate destination address to 0 indicating that it\r
+ // should not be used.\r
+ //\r
+ ImageContext->DestinationAddress = 0;\r
+\r
+ //\r
+ // Initialize the codeview pointer.\r
+ //\r
+ ImageContext->CodeView = NULL;\r
+ ImageContext->PdbPointer = NULL;\r
+\r
+ //\r
+ // Three cases with regards to relocations:\r
+ // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable\r
+ // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable\r
+ // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but\r
+ // has no base relocs to apply\r
+ // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.\r
+ //\r
+ // Look at the file header to determine if relocations have been stripped, and\r
+ // save this info in the image context for later use.\r
+ //\r
+ if ((!(ImageContext->IsTeImage)) && ((PeHdr->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
+ ImageContext->RelocationsStripped = TRUE;\r
+ } else {\r
+ ImageContext->RelocationsStripped = FALSE;\r
+ }\r
+\r
+ if (!(ImageContext->IsTeImage)) {\r
+\r
+ if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+ ImageContext->ImageSize = (UINT64) OptionHeader.Optional32->SizeOfImage;\r
+ ImageContext->SectionAlignment = OptionHeader.Optional32->SectionAlignment;\r
+ ImageContext->SizeOfHeaders = OptionHeader.Optional32->SizeOfHeaders;\r
+ \r
+ //\r
+ // Modify ImageSize to contain .PDB file name if required and initialize\r
+ // PdbRVA field...\r
+ //\r
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+ }\r
+ } else {\r
+ ImageContext->ImageSize = (UINT64) OptionHeader.Optional64->SizeOfImage;\r
+ ImageContext->SectionAlignment = OptionHeader.Optional64->SectionAlignment;\r
+ ImageContext->SizeOfHeaders = OptionHeader.Optional64->SizeOfHeaders;\r
+ \r
+ //\r
+ // Modify ImageSize to contain .PDB file name if required and initialize\r
+ // PdbRVA field...\r
+ //\r
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+ }\r
+ }\r
+ \r
+ if (DebugDirectoryEntryRva != 0) {\r
+ //\r
+ // Determine the file offset of the debug directory... This means we walk\r
+ // the sections to find which section contains the RVA of the debug\r
+ // directory\r
+ //\r
+ DebugDirectoryEntryFileOffset = 0;\r
+\r
+ SectionHeaderOffset = (UINTN)(\r
+ ImageContext->PeCoffHeaderOffset +\r
+ sizeof (UINT32) + \r
+ sizeof (EFI_IMAGE_FILE_HEADER) + \r
+ PeHdr->FileHeader.SizeOfOptionalHeader\r
+ );\r
+\r
+ for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++) {\r
+ //\r
+ // Read section header from file\r
+ //\r
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ SectionHeaderOffset,\r
+ &Size,\r
+ &SectionHeader\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+\r
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
+ DebugDirectoryEntryFileOffset =\r
+ DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;\r
+ break;\r
+ }\r
+\r
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ }\r
+\r
+ if (DebugDirectoryEntryFileOffset != 0) { \r
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {\r
+ //\r
+ // Read next debug directory entry\r
+ //\r
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); \r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ DebugDirectoryEntryFileOffset + Index,\r
+ &Size,\r
+ &DebugEntry\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+\r
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);\r
+ if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {\r
+ ImageContext->ImageSize += DebugEntry.SizeOfData;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } else {\r
+ ImageContext->ImageSize = 0;\r
+ ImageContext->SectionAlignment = 4096;\r
+ ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize;\r
+\r
+ DebugDirectoryEntry = &TeHdr->DataDirectory[1];\r
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+ SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));\r
+\r
+ DebugDirectoryEntryFileOffset = 0;\r
+\r
+ for (Index = 0; Index < TeHdr->NumberOfSections;) {\r
+ //\r
+ // Read section header from file\r
+ //\r
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ SectionHeaderOffset,\r
+ &Size,\r
+ &SectionHeader\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+\r
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
+ DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -\r
+ SectionHeader.VirtualAddress +\r
+ SectionHeader.PointerToRawData +\r
+ sizeof (EFI_TE_IMAGE_HEADER) -\r
+ TeHdr->StrippedSize;\r
+\r
+ //\r
+ // File offset of the debug directory was found, if this is not the last\r
+ // section, then skip to the last section for calculating the image size.\r
+ //\r
+ if (Index < (UINTN) TeHdr->NumberOfSections - 1) {\r
+ SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ Index = TeHdr->NumberOfSections - 1;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // In Te image header there is not a field to describe the ImageSize.\r
+ // Actually, the ImageSize equals the RVA plus the VirtualSize of \r
+ // the last section mapped into memory (Must be rounded up to \r
+ // a mulitple of Section Alignment). Per the PE/COFF specification, the\r
+ // section headers in the Section Table must appear in order of the RVA\r
+ // values for the corresponding sections. So the ImageSize can be determined\r
+ // by the RVA and the VirtualSize of the last section header in the\r
+ // Section Table.\r
+ //\r
+ if ((++Index) == (UINTN) TeHdr->NumberOfSections) {\r
+ ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +\r
+ ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);\r
+ }\r
+\r
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ }\r
+\r
+ if (DebugDirectoryEntryFileOffset != 0) {\r
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {\r
+ //\r
+ // Read next debug directory entry\r
+ //\r
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ DebugDirectoryEntryFileOffset,\r
+ &Size,\r
+ &DebugEntry\r
+ );\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+\r
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);\r
+ return RETURN_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID *\r
+PeCoffLoaderImageAddress (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN UINTN Address\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Converts an image address to the loaded address\r
+\r
+Arguments:\r
+\r
+ ImageContext - The context of the image being loaded\r
+\r
+ Address - The address to be converted to the loaded address\r
+\r
+Returns:\r
+\r
+ NULL if the address can not be converted, otherwise, the converted address\r
+\r
+--*/\r
+{\r
+ if (Address >= ImageContext->ImageSize) {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
+ return NULL;\r
+ }\r
+\r
+ return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address);\r
+}\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderRelocateImage (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Relocates a PE/COFF image in memory\r
+\r
+Arguments:\r
+\r
+ This - Calling context\r
+\r
+ ImageContext - Contains information on the loaded image to relocate\r
+\r
+Returns:\r
+\r
+ RETURN_SUCCESS if the PE/COFF image was relocated\r
+ RETURN_LOAD_ERROR if the image is not a valid PE/COFF image\r
+ RETURN_UNSUPPORTED not support\r
+\r
+--*/\r
+{\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_TE_IMAGE_HEADER *TeHdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
+ UINT64 Adjust;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
+ UINT16 *Reloc;\r
+ UINT16 *RelocEnd;\r
+ CHAR8 *Fixup;\r
+ CHAR8 *FixupBase;\r
+ UINT16 *F16;\r
+ UINT32 *F32;\r
+ CHAR8 *FixupData;\r
+ PHYSICAL_ADDRESS BaseAddress;\r
+ UINT16 MachineType;\r
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;\r
+\r
+ PeHdr = NULL;\r
+ TeHdr = NULL;\r
+ //\r
+ // Assume success\r
+ //\r
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+\r
+ //\r
+ // If there are no relocation entries, then we are done\r
+ //\r
+ if (ImageContext->RelocationsStripped) {\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If the destination address is not 0, use that rather than the\r
+ // image address as the relocation target.\r
+ //\r
+ if (ImageContext->DestinationAddress) {\r
+ BaseAddress = ImageContext->DestinationAddress;\r
+ } else {\r
+ BaseAddress = ImageContext->ImageAddress;\r
+ }\r
+\r
+ if (!(ImageContext->IsTeImage)) {\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + \r
+ ImageContext->PeCoffHeaderOffset);\r
+ OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+ if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+ Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase;\r
+ OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress;\r
+ MachineType = ImageContext->Machine;\r
+ //\r
+ // Find the relocation block\r
+ //\r
+ // Per the PE/COFF spec, you can't assume that a given data directory\r
+ // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+ // the optional header to verify a desired directory entry is there.\r
+ //\r
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ RelocDir = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+ RelocBaseEnd = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ RelocDir->VirtualAddress + RelocDir->Size - 1\r
+ );\r
+ } else {\r
+ //\r
+ // Set base and end to bypass processing below.\r
+ //\r
+ RelocBase = RelocBaseEnd = 0;\r
+ }\r
+ } else {\r
+ Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase;\r
+ OptionHeader.Optional64->ImageBase = BaseAddress;\r
+ MachineType = ImageContext->Machine;\r
+ //\r
+ // Find the relocation block\r
+ //\r
+ // Per the PE/COFF spec, you can't assume that a given data directory\r
+ // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+ // the optional header to verify a desired directory entry is there.\r
+ //\r
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ RelocDir = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+ RelocBaseEnd = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ RelocDir->VirtualAddress + RelocDir->Size - 1\r
+ );\r
+ } else {\r
+ //\r
+ // Set base and end to bypass processing below.\r
+ //\r
+ RelocBase = RelocBaseEnd = 0;\r
+ }\r
+ }\r
+ } else {\r
+ TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
+ Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase);\r
+ TeHdr->ImageBase = (UINT64) (BaseAddress);\r
+ MachineType = TeHdr->Machine;\r
+ \r
+ //\r
+ // Find the relocation block\r
+ //\r
+ RelocDir = &TeHdr->DataDirectory[0];\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
+ ImageContext->ImageAddress + \r
+ RelocDir->VirtualAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER) - \r
+ TeHdr->StrippedSize\r
+ );\r
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
+ }\r
+ \r
+ //\r
+ // Run the relocation information and apply the fixups\r
+ //\r
+ FixupData = ImageContext->FixupData;\r
+ while (RelocBase < RelocBaseEnd) {\r
+\r
+ Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
+ RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+ if (!(ImageContext->IsTeImage)) {\r
+ FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+ } else {\r
+ FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
+ RelocBase->VirtualAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER) - \r
+ TeHdr->StrippedSize\r
+ );\r
+ }\r
+\r
+ if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||\r
+ (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + \r
+ (UINTN)ImageContext->ImageSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
+ //\r
+ // Run this relocation record\r
+ //\r
+ while (Reloc < RelocEnd) {\r
+\r
+ Fixup = FixupBase + (*Reloc & 0xFFF);\r
+ switch ((*Reloc) >> 12) {\r
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGH:\r
+ F16 = (UINT16 *) Fixup;\r
+ *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16)));\r
+ if (FixupData != NULL) {\r
+ *(UINT16 *) FixupData = *F16;\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ }\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_LOW:\r
+ F16 = (UINT16 *) Fixup;\r
+ *F16 = (UINT16) (*F16 + (UINT16) Adjust);\r
+ if (FixupData != NULL) {\r
+ *(UINT16 *) FixupData = *F16;\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ }\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGHLOW:\r
+ F32 = (UINT32 *) Fixup;\r
+ *F32 = *F32 + (UINT32) Adjust;\r
+ if (FixupData != NULL) {\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
+ *(UINT32 *) FixupData = *F32;\r
+ FixupData = FixupData + sizeof (UINT32);\r
+ }\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGHADJ:\r
+ //\r
+ // Return the same EFI_UNSUPPORTED return code as\r
+ // PeCoffLoaderRelocateImageEx() returns if it does not recognize\r
+ // the relocation type.\r
+ //\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_UNSUPPORTED;\r
+\r
+ default:\r
+ switch (MachineType) {\r
+ case EFI_IMAGE_MACHINE_IA32:\r
+ Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust);\r
+ break;\r
+ case EFI_IMAGE_MACHINE_X64:\r
+ Status = PeCoffLoaderRelocateX64Image (Reloc, Fixup, &FixupData, Adjust);\r
+ break;\r
+ case EFI_IMAGE_MACHINE_IA64:\r
+ Status = PeCoffLoaderRelocateIpfImage (Reloc, Fixup, &FixupData, Adjust);\r
+ break;\r
+ default:\r
+ Status = RETURN_UNSUPPORTED;\r
+ break;\r
+ }\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Next relocation record\r
+ //\r
+ Reloc += 1;\r
+ }\r
+\r
+ //\r
+ // Next reloc block\r
+ //\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderLoadImage (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Loads a PE/COFF image into memory\r
+\r
+Arguments:\r
+\r
+ This - Calling context\r
+\r
+ ImageContext - Contains information on image to load into memory\r
+\r
+Returns:\r
+\r
+ RETURN_SUCCESS if the PE/COFF image was loaded\r
+ RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer\r
+ RETURN_LOAD_ERROR if the image is a runtime driver with no relocations\r
+ RETURN_INVALID_PARAMETER if the image address is invalid\r
+\r
+--*/\r
+{\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_TE_IMAGE_HEADER *TeHdr;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;\r
+ EFI_IMAGE_SECTION_HEADER *FirstSection;\r
+ EFI_IMAGE_SECTION_HEADER *Section;\r
+ UINTN NumberOfSections;\r
+ UINTN Index;\r
+ CHAR8 *Base;\r
+ CHAR8 *End;\r
+ CHAR8 *MaxEnd;\r
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
+ UINTN Size;\r
+ UINT32 TempDebugEntryRva;\r
+ EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;\r
+\r
+ PeHdr = NULL;\r
+ TeHdr = NULL;\r
+ //\r
+ // Assume success\r
+ //\r
+ ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+\r
+ //\r
+ // Copy the provided context info into our local version, get what we\r
+ // can from the original image, and then use that to make sure everything\r
+ // is legit.\r
+ //\r
+ CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
+\r
+ Status = PeCoffLoaderGetImageInfo (&CheckContext);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Make sure there is enough allocated space for the image being loaded\r
+ //\r
+ if (ImageContext->ImageSize < CheckContext.ImageSize) {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ //\r
+ // If there's no relocations, then make sure it's not a runtime driver,\r
+ // and that it's being loaded at the linked address.\r
+ //\r
+ if (CheckContext.RelocationsStripped) {\r
+ //\r
+ // If the image does not contain relocations and it is a runtime driver\r
+ // then return an error.\r
+ //\r
+ if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+ //\r
+ // If the image does not contain relocations, and the requested load address\r
+ // is not the linked address, then return an error.\r
+ //\r
+ if (CheckContext.ImageAddress != ImageContext->ImageAddress) {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Make sure the allocated space has the proper section alignment\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Read the entire PE/COFF or TE header into memory\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ 0,\r
+ &ImageContext->SizeOfHeaders,\r
+ (VOID *) (UINTN) ImageContext->ImageAddress\r
+ );\r
+\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)\r
+ ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
+\r
+ OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+ \r
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN)ImageContext->ImageAddress +\r
+ ImageContext->PeCoffHeaderOffset +\r
+ sizeof(UINT32) + \r
+ sizeof(EFI_IMAGE_FILE_HEADER) + \r
+ PeHdr->FileHeader.SizeOfOptionalHeader\r
+ );\r
+ NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections);\r
+ } else {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ 0,\r
+ &ImageContext->SizeOfHeaders,\r
+ (void *) (UINTN) ImageContext->ImageAddress\r
+ );\r
+\r
+ TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
+\r
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN)ImageContext->ImageAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER)\r
+ );\r
+ NumberOfSections = (UINTN) (TeHdr->NumberOfSections);\r
+\r
+ }\r
+\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
+ //\r
+ // Load each section of the image\r
+ //\r
+ Section = FirstSection;\r
+ for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {\r
+\r
+ //\r
+ // Compute sections address\r
+ //\r
+ Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);\r
+ End = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
+ );\r
+ if (ImageContext->IsTeImage) {\r
+ Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
+ End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
+ }\r
+\r
+ if (End > MaxEnd) {\r
+ MaxEnd = End;\r
+ }\r
+ //\r
+ // If the base start or end address resolved to 0, then fail.\r
+ //\r
+ if ((Base == NULL) || (End == NULL)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
+ //\r
+ // Read the section\r
+ //\r
+ Size = (UINTN) Section->Misc.VirtualSize;\r
+ if ((Size == 0) || (Size > Section->SizeOfRawData)) {\r
+ Size = (UINTN) Section->SizeOfRawData;\r
+ }\r
+\r
+ if (Section->SizeOfRawData) {\r
+ if (!(ImageContext->IsTeImage)) {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ Section->PointerToRawData,\r
+ &Size,\r
+ Base\r
+ );\r
+ } else {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,\r
+ &Size,\r
+ Base\r
+ );\r
+ }\r
+\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If raw size is less then virt size, zero fill the remaining\r
+ //\r
+\r
+ if (Size < Section->Misc.VirtualSize) {\r
+ ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);\r
+ }\r
+\r
+ //\r
+ // Next Section\r
+ //\r
+ Section += 1;\r
+ }\r
+\r
+ //\r
+ // Get image's entry point\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ PeHdr->OptionalHeader.AddressOfEntryPoint\r
+ );\r
+ } else {\r
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (\r
+ (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)TeHdr->AddressOfEntryPoint +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+ (UINTN) TeHdr->StrippedSize\r
+ );\r
+ }\r
+\r
+ //\r
+ // Determine the size of the fixup data\r
+ //\r
+ // Per the PE/COFF spec, you can't assume that a given data directory\r
+ // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+ // the optional header to verify a desired directory entry is there.\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+ if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+ &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+ } else {\r
+ ImageContext->FixupDataSize = 0;\r
+ }\r
+ } else {\r
+ if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+ &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+ } else {\r
+ ImageContext->FixupDataSize = 0;\r
+ }\r
+ }\r
+ } else {\r
+ DirectoryEntry = &TeHdr->DataDirectory[0];\r
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+ }\r
+ //\r
+ // Consumer must allocate a buffer for the relocation fixup log.\r
+ // Only used for runtime drivers.\r
+ //\r
+ ImageContext->FixupData = NULL;\r
+\r
+ //\r
+ // Load the Codeview info if present\r
+ //\r
+ if (ImageContext->DebugDirectoryEntryRva != 0) {\r
+ if (!(ImageContext->IsTeImage)) {\r
+ DebugEntry = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ ImageContext->DebugDirectoryEntryRva\r
+ );\r
+ } else {\r
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
+ ImageContext->ImageAddress +\r
+ ImageContext->DebugDirectoryEntryRva +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ TeHdr->StrippedSize\r
+ );\r
+ }\r
+\r
+ if (DebugEntry != NULL) {\r
+ TempDebugEntryRva = DebugEntry->RVA;\r
+ if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
+ Section--;\r
+ if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
+ TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
+ } else {\r
+ TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
+ }\r
+ }\r
+\r
+ if (TempDebugEntryRva != 0) {\r
+ if (!(ImageContext->IsTeImage)) {\r
+ ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);\r
+ } else {\r
+ ImageContext->CodeView = (VOID *)(\r
+ (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)TempDebugEntryRva +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+ (UINTN) TeHdr->StrippedSize\r
+ );\r
+ }\r
+\r
+ if (ImageContext->CodeView == NULL) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
+ if (DebugEntry->RVA == 0) {\r
+ Size = DebugEntry->SizeOfData;\r
+ if (!(ImageContext->IsTeImage)) {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ DebugEntry->FileOffset,\r
+ &Size,\r
+ ImageContext->CodeView\r
+ );\r
+ } else {\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,\r
+ &Size,\r
+ ImageContext->CodeView\r
+ );\r
+ //\r
+ // Should we apply fix up to this field according to the size difference between PE and TE?\r
+ // Because now we maintain TE header fields unfixed, this field will also remain as they are\r
+ // in original PE image.\r
+ //\r
+ }\r
+\r
+ if (RETURN_ERROR (Status)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
+ DebugEntry->RVA = TempDebugEntryRva;\r
+ }\r
+\r
+ switch (*(UINT32 *) ImageContext->CodeView) {\r
+ case CODEVIEW_SIGNATURE_NB10:\r
+ ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+ break;\r
+\r
+ case CODEVIEW_SIGNATURE_RSDS:\r
+ ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
\r
LIBNAME = Common\r
\r
-OBJECTS = CommonLib.obj Decompress.obj EfiUtilityMsgs.obj MyAlloc.obj SimpleFileParsing.obj Crc32.obj EfiCompress.obj FvLib.obj ParseInf.obj TianoCompress.obj\r
+OBJECTS = CommonLib.obj Decompress.obj EfiUtilityMsgs.obj MyAlloc.obj SimpleFileParsing.obj Crc32.obj EfiCompress.obj FvLib.obj ParseInf.obj TianoCompress.obj PeCoffLoaderEx.obj BasePeCoff.obj \r
\r
!INCLUDE ..\MSmakefile.lib\r
\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ PeCoffLoaderEx.c\r
+\r
+Abstract:\r
+\r
+ IA32, X64 and IPF Specific relocation fixups\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+#include <IndustryStandard/PeImage.h>\r
+#include "PeCoffLib.h"\r
+\r
+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
+ Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
+\r
+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \\r
+ *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \\r
+ ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)\r
+\r
+#define IMM64_IMM7B_INST_WORD_X 3 \r
+#define IMM64_IMM7B_SIZE_X 7 \r
+#define IMM64_IMM7B_INST_WORD_POS_X 4 \r
+#define IMM64_IMM7B_VAL_POS_X 0 \r
+\r
+#define IMM64_IMM9D_INST_WORD_X 3 \r
+#define IMM64_IMM9D_SIZE_X 9 \r
+#define IMM64_IMM9D_INST_WORD_POS_X 18 \r
+#define IMM64_IMM9D_VAL_POS_X 7 \r
+\r
+#define IMM64_IMM5C_INST_WORD_X 3 \r
+#define IMM64_IMM5C_SIZE_X 5 \r
+#define IMM64_IMM5C_INST_WORD_POS_X 13 \r
+#define IMM64_IMM5C_VAL_POS_X 16 \r
+\r
+#define IMM64_IC_INST_WORD_X 3 \r
+#define IMM64_IC_SIZE_X 1 \r
+#define IMM64_IC_INST_WORD_POS_X 12 \r
+#define IMM64_IC_VAL_POS_X 21 \r
+\r
+#define IMM64_IMM41a_INST_WORD_X 1 \r
+#define IMM64_IMM41a_SIZE_X 10 \r
+#define IMM64_IMM41a_INST_WORD_POS_X 14 \r
+#define IMM64_IMM41a_VAL_POS_X 22 \r
+\r
+#define IMM64_IMM41b_INST_WORD_X 1 \r
+#define IMM64_IMM41b_SIZE_X 8 \r
+#define IMM64_IMM41b_INST_WORD_POS_X 24 \r
+#define IMM64_IMM41b_VAL_POS_X 32 \r
+\r
+#define IMM64_IMM41c_INST_WORD_X 2 \r
+#define IMM64_IMM41c_SIZE_X 23 \r
+#define IMM64_IMM41c_INST_WORD_POS_X 0 \r
+#define IMM64_IMM41c_VAL_POS_X 40 \r
+\r
+#define IMM64_SIGN_INST_WORD_X 3 \r
+#define IMM64_SIGN_SIZE_X 1 \r
+#define IMM64_SIGN_INST_WORD_POS_X 27 \r
+#define IMM64_SIGN_VAL_POS_X 63 \r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateIa32Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs an IA-32 specific relocation fixup\r
+\r
+Arguments:\r
+\r
+ Reloc - Pointer to the relocation record\r
+\r
+ Fixup - Pointer to the address to fix up\r
+\r
+ FixupData - Pointer to a buffer to log the fixups\r
+\r
+ Adjust - The offset to adjust the fixup\r
+\r
+Returns:\r
+\r
+ EFI_UNSUPPORTED - Unsupported now\r
+\r
+--*/\r
+{\r
+ return RETURN_UNSUPPORTED;\r
+}\r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateIpfImage (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup, \r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs an Itanium-based specific relocation fixup\r
+\r
+Arguments:\r
+\r
+ Reloc - Pointer to the relocation record\r
+\r
+ Fixup - Pointer to the address to fix up\r
+\r
+ FixupData - Pointer to a buffer to log the fixups\r
+\r
+ Adjust - The offset to adjust the fixup\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+--*/\r
+{\r
+ UINT64 *F64;\r
+ UINT64 FixupVal;\r
+\r
+ switch ((*Reloc) >> 12) {\r
+\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *F64 = *F64 + (UINT64) Adjust;\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
+ *(UINT64 *)(*FixupData) = *F64;\r
+ *FixupData = *FixupData + sizeof(UINT64);\r
+ }\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
+\r
+ //\r
+ // Align it to bundle address before fixing up the\r
+ // 64-bit immediate value of the movl instruction.\r
+ //\r
+\r
+ Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));\r
+ FixupVal = (UINT64)0;\r
+ \r
+ // \r
+ // Extract the lower 32 bits of IMM64 from bundle\r
+ //\r
+ EXT_IMM64(FixupVal,\r
+ (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64(FixupVal,\r
+ (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64(FixupVal,\r
+ (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64(FixupVal,\r
+ (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64(FixupVal,\r
+ (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+ \r
+ // \r
+ // Update 64-bit address\r
+ //\r
+ FixupVal += Adjust;\r
+\r
+ // \r
+ // Insert IMM64 into bundle\r
+ //\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),\r
+ IMM64_IMM41b_SIZE_X,\r
+ IMM64_IMM41b_INST_WORD_POS_X,\r
+ IMM64_IMM41b_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),\r
+ IMM64_IMM41c_SIZE_X,\r
+ IMM64_IMM41c_INST_WORD_POS_X,\r
+ IMM64_IMM41c_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64(FixupVal,\r
+ ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),\r
+ IMM64_SIGN_SIZE_X,\r
+ IMM64_SIGN_INST_WORD_POS_X,\r
+ IMM64_SIGN_VAL_POS_X\r
+ );\r
+\r
+ F64 = (UINT64 *) Fixup;\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
+ *(UINT64 *)(*FixupData) = *F64;\r
+ *FixupData = *FixupData + sizeof(UINT64);\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateX64Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup, \r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+/**\r
+ Performs an x64 specific relocation fixup\r
+\r
+ @param Reloc Pointer to the relocation record\r
+ @param Fixup Pointer to the address to fix up\r
+ @param FixupData Pointer to a buffer to log the fixups\r
+ @param Adjust The offset to adjust the fixup\r
+ \r
+ @retval RETURN_SUCCESS Success to perform relocation\r
+ @retval RETURN_UNSUPPORTED Unsupported.\r
+**/\r
+{\r
+ UINT64 *F64;\r
+\r
+ switch ((*Reloc) >> 12) {\r
+\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *F64 = *F64 + (UINT64) Adjust;\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
+ *(UINT64 *)(*FixupData) = *F64;\r
+ *FixupData = *FixupData + sizeof(UINT64);\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
APPNAME = EfiRom
-LIBS = Common.lib String.lib
+LIBS = Common.lib
OBJECTS = EfiRom.obj
#include <Common/PiFirmwareFile.h>\r
#include <Common/PiFirmwareVolume.h>\r
#include <Guid/PiFirmwareFileSystem.h>\r
-\r
#include <IndustryStandard/PeImage.h>\r
-#include <Library/PeCoffLib.h>\r
\r
#include "CommonLib.h"\r
#include "ParseInf.h"\r
+#include "PeCoffLib.h"\r
\r
//\r
// Private data declarations\r
APPNAME = GenFv
-LIBS = Common.lib PeCoffLoader.lib RpcRT4.lib
+LIBS = Common.lib RpcRT4.lib
OBJECTS = GenFv.obj GenFvInternalLib.obj
goto Finish;\r
}\r
\r
- \r
//\r
// One input file\r
//\r
EFI_COMMON_SECTION_HEADER CommonSect;\r
UINT32 InputLength;\r
UINT8 *FileBuffer;\r
- BOOLEAN AllocatedFlag;\r
EFI_STATUS Status;\r
\r
fprintf (stdout, "GenSec tool start.\n"); \r
SectGuidAttribute = 0;\r
FileBuffer = NULL;\r
InputLength = 0;\r
- AllocatedFlag = FALSE;\r
Status = STATUS_SUCCESS;\r
\r
\r
if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
//\r
// The input file are required for those section type.\r
- // The file are from stdin.\r
//\r
if (InputFileNum == 0) {\r
Error (NULL, 0, 0, NULL, "No input files is specified.");\r
}\r
\r
Finish:\r
- if (AllocatedFlag == TRUE) {\r
- for (Index = 0; Index < InputFileNum; Index ++) {\r
- free (InputFileName[Index]);\r
- }\r
- }\r
-\r
if (InputFileName != NULL) {\r
free (InputFileName);\r
}\r
APPNAME = GenVtf
-LIBS = Common.lib String.lib
+LIBS = Common.lib
OBJECTS = GenVtf.obj
+++ /dev/null
-/** @file\r
- EFI image format for PE32+. Please note some data structures are different\r
- for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64\r
-\r
- @bug Fix text - doc as defined in MSFT EFI specification.\r
-\r
- Copyright (c) 2006, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
- Module Name: EfiImage.h\r
-\r
-**/\r
-\r
-#ifndef __EFI_IMAGE_H__\r
-#define __EFI_IMAGE_H__\r
-\r
-//\r
-// PE32+ Subsystem type for EFI images\r
-//\r
-#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10\r
-#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11\r
-#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12\r
-#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13\r
-\r
-//\r
-// BugBug: Need to get a real answer for this problem. This is not in the\r
-// PE specification.\r
-//\r
-// A SAL runtime driver does not get fixed up when a transition to\r
-// virtual mode is made. In all other cases it should be treated\r
-// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image\r
-//\r
-#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13\r
-\r
-//\r
-// PE32+ Machine type for EFI images\r
-//\r
-#define IMAGE_FILE_MACHINE_I386 0x014c\r
-#define IMAGE_FILE_MACHINE_IA64 0x0200\r
-#define IMAGE_FILE_MACHINE_EBC 0x0EBC\r
-#define IMAGE_FILE_MACHINE_X64 0x8664\r
-//\r
-// Support old names for backward compatible\r
-//\r
-#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 \r
-#define EFI_IMAGE_MACHINE_IA64 IMAGE_FILE_MACHINE_IA64 \r
-#define EFI_IMAGE_MACHINE_IPF IMAGE_FILE_MACHINE_IA64 \r
-#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC \r
-#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64\r
-\r
-#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ\r
-#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE\r
-#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE\r
-#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00\r
-#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED\r
-\r
-///\r
-/// PE images can start with an optional DOS header, so if an image is run\r
-/// under DOS it can print an error message.\r
-///\r
-typedef struct {\r
- UINT16 e_magic; // Magic number\r
- UINT16 e_cblp; // Bytes on last page of file\r
- UINT16 e_cp; // Pages in file\r
- UINT16 e_crlc; // Relocations\r
- UINT16 e_cparhdr; // Size of header in paragraphs\r
- UINT16 e_minalloc; // Minimum extra paragraphs needed\r
- UINT16 e_maxalloc; // Maximum extra paragraphs needed\r
- UINT16 e_ss; // Initial (relative) SS value\r
- UINT16 e_sp; // Initial SP value\r
- UINT16 e_csum; // Checksum\r
- UINT16 e_ip; // Initial IP value\r
- UINT16 e_cs; // Initial (relative) CS value\r
- UINT16 e_lfarlc; // File address of relocation table\r
- UINT16 e_ovno; // Overlay number\r
- UINT16 e_res[4]; // Reserved words\r
- UINT16 e_oemid; // OEM identifier (for e_oeminfo)\r
- UINT16 e_oeminfo; // OEM information; e_oemid specific\r
- UINT16 e_res2[10]; // Reserved words\r
- UINT32 e_lfanew; // File address of new exe header\r
-} EFI_IMAGE_DOS_HEADER;\r
-\r
-///\r
-/// File header format.\r
-///\r
-typedef struct {\r
- UINT16 Machine;\r
- UINT16 NumberOfSections;\r
- UINT32 TimeDateStamp;\r
- UINT32 PointerToSymbolTable;\r
- UINT32 NumberOfSymbols;\r
- UINT16 SizeOfOptionalHeader;\r
- UINT16 Characteristics;\r
-} EFI_IMAGE_FILE_HEADER;\r
-\r
-#define EFI_IMAGE_SIZEOF_FILE_HEADER 20\r
-\r
-#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.\r
-#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).\r
-#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.\r
-#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.\r
-#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.\r
-#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.\r
-#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file\r
-#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File.\r
-#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL.\r
-#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.\r
-#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0\r
-#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.\r
-#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian\r
-#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian\r
-#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP*\r
-#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian\r
-#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine\r
-//\r
-// * Other names and brands may be claimed as the property of others.\r
-//\r
-\r
-///\r
-/// Directory format.\r
-///\r
-typedef struct {\r
- UINT32 VirtualAddress;\r
- UINT32 Size;\r
-} EFI_IMAGE_DATA_DIRECTORY;\r
-\r
-#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16\r
-\r
-typedef struct {\r
- UINT16 Magic;\r
- UINT8 MajorLinkerVersion;\r
- UINT8 MinorLinkerVersion;\r
- UINT32 SizeOfCode;\r
- UINT32 SizeOfInitializedData;\r
- UINT32 SizeOfUninitializedData;\r
- UINT32 AddressOfEntryPoint;\r
- UINT32 BaseOfCode;\r
- UINT32 BaseOfData;\r
- UINT32 BaseOfBss;\r
- UINT32 GprMask;\r
- UINT32 CprMask[4];\r
- UINT32 GpValue;\r
-} EFI_IMAGE_ROM_OPTIONAL_HEADER;\r
-\r
-#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107\r
-#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)\r
-\r
-typedef struct {\r
- EFI_IMAGE_FILE_HEADER FileHeader;\r
- EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;\r
-} EFI_IMAGE_ROM_HEADERS;\r
-\r
-///\r
-/// @attention\r
-/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64\r
-/// are for use ONLY by tools. All proper EFI code MUST use\r
-/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!\r
-///\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b\r
-\r
-typedef struct {\r
- //\r
- // Standard fields.\r
- //\r
- UINT16 Magic;\r
- UINT8 MajorLinkerVersion;\r
- UINT8 MinorLinkerVersion;\r
- UINT32 SizeOfCode;\r
- UINT32 SizeOfInitializedData;\r
- UINT32 SizeOfUninitializedData;\r
- UINT32 AddressOfEntryPoint;\r
- UINT32 BaseOfCode;\r
- UINT32 BaseOfData;\r
- //\r
- // NT additional fields.\r
- //\r
- UINT32 ImageBase;\r
- UINT32 SectionAlignment;\r
- UINT32 FileAlignment;\r
- UINT16 MajorOperatingSystemVersion;\r
- UINT16 MinorOperatingSystemVersion;\r
- UINT16 MajorImageVersion;\r
- UINT16 MinorImageVersion;\r
- UINT16 MajorSubsystemVersion;\r
- UINT16 MinorSubsystemVersion;\r
- UINT32 Win32VersionValue;\r
- UINT32 SizeOfImage;\r
- UINT32 SizeOfHeaders;\r
- UINT32 CheckSum;\r
- UINT16 Subsystem;\r
- UINT16 DllCharacteristics;\r
- UINT32 SizeOfStackReserve;\r
- UINT32 SizeOfStackCommit;\r
- UINT32 SizeOfHeapReserve;\r
- UINT32 SizeOfHeapCommit;\r
- UINT32 LoaderFlags;\r
- UINT32 NumberOfRvaAndSizes;\r
- EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];\r
-} EFI_IMAGE_OPTIONAL_HEADER32;\r
-\r
-///\r
-/// @attention\r
-/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64\r
-/// are for use ONLY by tools. All proper EFI code MUST use\r
-/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!\r
-///\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b\r
-\r
-typedef struct {\r
- //\r
- // Standard fields.\r
- //\r
- UINT16 Magic;\r
- UINT8 MajorLinkerVersion;\r
- UINT8 MinorLinkerVersion;\r
- UINT32 SizeOfCode;\r
- UINT32 SizeOfInitializedData;\r
- UINT32 SizeOfUninitializedData;\r
- UINT32 AddressOfEntryPoint;\r
- UINT32 BaseOfCode;\r
- //\r
- // NT additional fields.\r
- //\r
- UINT64 ImageBase;\r
- UINT32 SectionAlignment;\r
- UINT32 FileAlignment;\r
- UINT16 MajorOperatingSystemVersion;\r
- UINT16 MinorOperatingSystemVersion;\r
- UINT16 MajorImageVersion;\r
- UINT16 MinorImageVersion;\r
- UINT16 MajorSubsystemVersion;\r
- UINT16 MinorSubsystemVersion;\r
- UINT32 Win32VersionValue;\r
- UINT32 SizeOfImage;\r
- UINT32 SizeOfHeaders;\r
- UINT32 CheckSum;\r
- UINT16 Subsystem;\r
- UINT16 DllCharacteristics;\r
- UINT64 SizeOfStackReserve;\r
- UINT64 SizeOfStackCommit;\r
- UINT64 SizeOfHeapReserve;\r
- UINT64 SizeOfHeapCommit;\r
- UINT32 LoaderFlags;\r
- UINT32 NumberOfRvaAndSizes;\r
- EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];\r
-} EFI_IMAGE_OPTIONAL_HEADER64;\r
-\r
-///\r
-/// @attention\r
-/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY\r
-/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!\r
-///\r
-typedef struct {\r
- UINT32 Signature;\r
- EFI_IMAGE_FILE_HEADER FileHeader;\r
- EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;\r
-} EFI_IMAGE_NT_HEADERS32;\r
-\r
-#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- EFI_IMAGE_FILE_HEADER FileHeader;\r
- EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;\r
-} EFI_IMAGE_NT_HEADERS64;\r
-\r
-#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)\r
-\r
-//\r
-// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the\r
-// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for\r
-// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code.\r
-//\r
-#if defined (MDE_CPU_IA32)\r
-\r
-typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
-#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
- (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
-\r
-#elif defined (MDE_CPU_IPF)\r
-\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
-#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
- (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
-\r
-#elif defined (MDE_CPU_X64)\r
-\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
-#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
- (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
-\r
-#elif defined (MDE_CPU_EBC)\r
-\r
-//\r
-// This is just to make sure you can cross compile with the EBC compiiler.\r
-// It does not make sense to have a PE loader coded in EBC. You need to \r
-// understand the basic \r
-//\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
-#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)\r
-\r
-#else\r
-#error Unknown Processor Type\r
-#endif\r
-\r
-\r
-#define EFI_IMAGE_FIRST_SECTION(ntheader) \\r
- ( \\r
- (EFI_IMAGE_SECTION_HEADER *) \\r
- ( \\r
- (UINT32) ntheader + \\r
- FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \\r
- ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \\r
- ) \\r
- )\r
-\r
-//\r
-// Subsystem Values\r
-//\r
-#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0\r
-#define EFI_IMAGE_SUBSYSTEM_NATIVE 1\r
-#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2\r
-#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.\r
-#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5\r
-#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7\r
-\r
-//\r
-// Directory Entries\r
-//\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9\r
-#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10\r
-\r
-//\r
-// Section header format.\r
-//\r
-#define EFI_IMAGE_SIZEOF_SHORT_NAME 8\r
-\r
-typedef struct {\r
- UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];\r
- union {\r
- UINT32 PhysicalAddress;\r
- UINT32 VirtualSize;\r
- } Misc;\r
- UINT32 VirtualAddress;\r
- UINT32 SizeOfRawData;\r
- UINT32 PointerToRawData;\r
- UINT32 PointerToRelocations;\r
- UINT32 PointerToLinenumbers;\r
- UINT16 NumberOfRelocations;\r
- UINT16 NumberOfLinenumbers;\r
- UINT32 Characteristics;\r
-} EFI_IMAGE_SECTION_HEADER;\r
-\r
-#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40\r
-\r
-#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.\r
-#define EFI_IMAGE_SCN_CNT_CODE 0x00000020\r
-#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040\r
-#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080\r
-\r
-#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.\r
-#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.\r
-#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.\r
-#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000\r
-\r
-#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000\r
-#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000\r
-#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000\r
-#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000\r
-#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000\r
-#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000\r
-#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000\r
-\r
-#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000\r
-#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000\r
-#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000\r
-#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000\r
-#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000\r
-#define EFI_IMAGE_SCN_MEM_READ 0x40000000\r
-#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000\r
-\r
-///\r
-/// Symbol format.\r
-///\r
-#define EFI_IMAGE_SIZEOF_SYMBOL 18\r
-\r
-//\r
-// Section values.\r
-//\r
-// Symbols have a section number of the section in which they are\r
-// defined. Otherwise, section numbers have the following meanings:\r
-//\r
-#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common.\r
-#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value.\r
-#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item.\r
-//\r
-// Type (fundamental) values.\r
-//\r
-#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type.\r
-#define EFI_IMAGE_SYM_TYPE_VOID 1 //\r
-#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character.\r
-#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer.\r
-#define EFI_IMAGE_SYM_TYPE_INT 4\r
-#define EFI_IMAGE_SYM_TYPE_LONG 5\r
-#define EFI_IMAGE_SYM_TYPE_FLOAT 6\r
-#define EFI_IMAGE_SYM_TYPE_DOUBLE 7\r
-#define EFI_IMAGE_SYM_TYPE_STRUCT 8\r
-#define EFI_IMAGE_SYM_TYPE_UNION 9\r
-#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration.\r
-#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration.\r
-#define EFI_IMAGE_SYM_TYPE_BYTE 12\r
-#define EFI_IMAGE_SYM_TYPE_WORD 13\r
-#define EFI_IMAGE_SYM_TYPE_UINT 14\r
-#define EFI_IMAGE_SYM_TYPE_DWORD 15\r
-\r
-//\r
-// Type (derived) values.\r
-//\r
-#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type.\r
-#define EFI_IMAGE_SYM_DTYPE_POINTER 1\r
-#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2\r
-#define EFI_IMAGE_SYM_DTYPE_ARRAY 3\r
-\r
-//\r
-// Storage classes.\r
-//\r
-#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1\r
-#define EFI_IMAGE_SYM_CLASS_NULL 0\r
-#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1\r
-#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2\r
-#define EFI_IMAGE_SYM_CLASS_STATIC 3\r
-#define EFI_IMAGE_SYM_CLASS_REGISTER 4\r
-#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5\r
-#define EFI_IMAGE_SYM_CLASS_LABEL 6\r
-#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7\r
-#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8\r
-#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9\r
-#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10\r
-#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11\r
-#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12\r
-#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13\r
-#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14\r
-#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15\r
-#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16\r
-#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17\r
-#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18\r
-#define EFI_IMAGE_SYM_CLASS_BLOCK 100\r
-#define EFI_IMAGE_SYM_CLASS_FUNCTION 101\r
-#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102\r
-#define EFI_IMAGE_SYM_CLASS_FILE 103\r
-#define EFI_IMAGE_SYM_CLASS_SECTION 104\r
-#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105\r
-\r
-//\r
-// type packing constants\r
-//\r
-#define EFI_IMAGE_N_BTMASK 017\r
-#define EFI_IMAGE_N_TMASK 060\r
-#define EFI_IMAGE_N_TMASK1 0300\r
-#define EFI_IMAGE_N_TMASK2 0360\r
-#define EFI_IMAGE_N_BTSHFT 4\r
-#define EFI_IMAGE_N_TSHIFT 2\r
-\r
-//\r
-// Communal selection types.\r
-//\r
-#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1\r
-#define EFI_IMAGE_COMDAT_SELECT_ANY 2\r
-#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3\r
-#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4\r
-#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5\r
-\r
-#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1\r
-#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2\r
-#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3\r
-\r
-///\r
-/// Relocation format.\r
-///\r
-typedef struct {\r
- UINT32 VirtualAddress;\r
- UINT32 SymbolTableIndex;\r
- UINT16 Type;\r
-} EFI_IMAGE_RELOCATION;\r
-\r
-#define EFI_IMAGE_SIZEOF_RELOCATION 10\r
-\r
-//\r
-// I386 relocation types.\r
-//\r
-#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary\r
-#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included\r
-#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address\r
-#define EFI_IMAGE_REL_I386_SECTION 012\r
-#define EFI_IMAGE_REL_I386_SECREL 013\r
-#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address\r
-\r
-///\r
-/// Based relocation format.\r
-///\r
-typedef struct {\r
- UINT32 VirtualAddress;\r
- UINT32 SizeOfBlock;\r
-} EFI_IMAGE_BASE_RELOCATION;\r
-\r
-#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8\r
-\r
-//\r
-// Based relocation types.\r
-//\r
-#define EFI_IMAGE_REL_BASED_ABSOLUTE 0\r
-#define EFI_IMAGE_REL_BASED_HIGH 1\r
-#define EFI_IMAGE_REL_BASED_LOW 2\r
-#define EFI_IMAGE_REL_BASED_HIGHLOW 3\r
-#define EFI_IMAGE_REL_BASED_HIGHADJ 4\r
-#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5\r
-#define EFI_IMAGE_REL_BASED_IA64_IMM64 9\r
-#define EFI_IMAGE_REL_BASED_DIR64 10\r
-\r
-///\r
-/// Line number format.\r
-///\r
-typedef struct {\r
- union {\r
- UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.\r
- UINT32 VirtualAddress; // Virtual address of line number.\r
- } Type;\r
- UINT16 Linenumber; // Line number.\r
-} EFI_IMAGE_LINENUMBER;\r
-\r
-#define EFI_IMAGE_SIZEOF_LINENUMBER 6\r
-\r
-//\r
-// Archive format.\r
-//\r
-#define EFI_IMAGE_ARCHIVE_START_SIZE 8\r
-#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"\r
-#define EFI_IMAGE_ARCHIVE_END "`\n"\r
-#define EFI_IMAGE_ARCHIVE_PAD "\n"\r
-#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "\r
-#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "\r
-\r
-typedef struct {\r
- UINT8 Name[16]; // File member name - `/' terminated.\r
- UINT8 Date[12]; // File member date - decimal.\r
- UINT8 UserID[6]; // File member user id - decimal.\r
- UINT8 GroupID[6]; // File member group id - decimal.\r
- UINT8 Mode[8]; // File member mode - octal.\r
- UINT8 Size[10]; // File member size - decimal.\r
- UINT8 EndHeader[2]; // String to end header.\r
-} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;\r
-\r
-#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60\r
-\r
-//\r
-// DLL support.\r
-//\r
-\r
-///\r
-/// DLL Export Format\r
-///\r
-typedef struct {\r
- UINT32 Characteristics;\r
- UINT32 TimeDateStamp;\r
- UINT16 MajorVersion;\r
- UINT16 MinorVersion;\r
- UINT32 Name;\r
- UINT32 Base;\r
- UINT32 NumberOfFunctions;\r
- UINT32 NumberOfNames;\r
- UINT32 AddressOfFunctions;\r
- UINT32 AddressOfNames;\r
- UINT32 AddressOfNameOrdinals;\r
-} EFI_IMAGE_EXPORT_DIRECTORY;\r
-\r
-///\r
-/// DLL support.\r
-/// Import Format\r
-///\r
-typedef struct {\r
- UINT16 Hint;\r
- UINT8 Name[1];\r
-} EFI_IMAGE_IMPORT_BY_NAME;\r
-\r
-typedef struct {\r
- union {\r
- UINT32 Function;\r
- UINT32 Ordinal;\r
- EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;\r
- } u1;\r
-} EFI_IMAGE_THUNK_DATA;\r
-\r
-#define EFI_IMAGE_ORDINAL_FLAG 0x80000000\r
-#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)\r
-#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)\r
-\r
-typedef struct {\r
- UINT32 Characteristics;\r
- UINT32 TimeDateStamp;\r
- UINT32 ForwarderChain;\r
- UINT32 Name;\r
- EFI_IMAGE_THUNK_DATA *FirstThunk;\r
-} EFI_IMAGE_IMPORT_DESCRIPTOR;\r
-\r
-///\r
-/// Debug Format\r
-///\r
-#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2\r
-\r
-typedef struct {\r
- UINT32 Characteristics;\r
- UINT32 TimeDateStamp;\r
- UINT16 MajorVersion;\r
- UINT16 MinorVersion;\r
- UINT32 Type;\r
- UINT32 SizeOfData;\r
- UINT32 RVA;\r
- UINT32 FileOffset;\r
-} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;\r
-\r
-#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"\r
-typedef struct {\r
- UINT32 Signature; // "NB10"\r
- UINT32 Unknown;\r
- UINT32 Unknown2;\r
- UINT32 Unknown3;\r
- //\r
- // Filename of .PDB goes here\r
- //\r
-} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;\r
-\r
-#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS"\r
-typedef struct {\r
- UINT32 Signature; // "RSDS"\r
- UINT32 Unknown;\r
- UINT32 Unknown2;\r
- UINT32 Unknown3;\r
- UINT32 Unknown4;\r
- UINT32 Unknown5;\r
- //\r
- // Filename of .PDB goes here\r
- //\r
-} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;\r
-\r
-//\r
-// .pdata entries for X64\r
-//\r
-typedef struct {\r
- UINT32 FunctionStartAddress;\r
- UINT32 FunctionEndAddress;\r
- UINT32 UnwindInfoAddress;\r
-} RUNTIME_FUNCTION;\r
-\r
-typedef struct {\r
- UINT8 Version:3;\r
- UINT8 Flags:5;\r
- UINT8 SizeOfProlog;\r
- UINT8 CountOfUnwindCodes;\r
- UINT8 FrameRegister:4;\r
- UINT8 FrameRegisterOffset:4;\r
-} UNWIND_INFO;\r
-\r
-///\r
-/// Header format for TE images\r
-///\r
-typedef struct {\r
- UINT16 Signature; // signature for TE format = "VZ"\r
- UINT16 Machine; // from the original file header\r
- UINT8 NumberOfSections; // from the original file header\r
- UINT8 Subsystem; // from original optional header\r
- UINT16 StrippedSize; // how many bytes we removed from the header\r
- UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header\r
- UINT32 BaseOfCode; // from original image -- required for ITP debug\r
- UINT64 ImageBase; // from original file header\r
- EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory\r
-} EFI_TE_IMAGE_HEADER;\r
-\r
-#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ"\r
-\r
-//\r
-// Data directory indexes in our TE image header\r
-//\r
-#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0\r
-#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
- Library that provides print services\r
-\r
- Copyright (c) 2006, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
- Module Name: PrintLib.h\r
-\r
-**/\r
-\r
-#ifndef __PRINT_LIB_H__\r
-#define __PRINT_LIB_H__\r
-\r
-//\r
-// Print primitives\r
-//\r
-#define LEFT_JUSTIFY 0x01\r
-#define COMMA_TYPE 0x08\r
-#define PREFIX_ZERO 0x20\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on \r
- a Null-terminated Unicode format string and a VA_LIST argument list\r
- \r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize. \r
- The Unicode string is produced by parsing the format string specified by FormatString. \r
- Arguments are pulled from the variable argument list specified by Marker based on the \r
- contents of the format string. \r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- @param Marker VA_LIST marker for the variable argument list.\r
- \r
- @return return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-UnicodeVSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- IN VA_LIST Marker\r
- );\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated \r
- Unicode format string and variable argument list.\r
- \r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the format string.\r
- The length of the produced output buffer is returned. \r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-UnicodeSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
- ASCII format string and a VA_LIST argument list\r
- \r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list specified by Marker based on the \r
- contents of the format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- @param Marker VA_LIST marker for the variable argument list.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-UnicodeVSPrintAsciiFormat (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- IN VA_LIST Marker\r
- );\r
-\r
-/**\r
- Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated \r
- ASCII format string and variable argument list.\r
- \r
- Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The Unicode string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the \r
- format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- Unicode string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-UnicodeSPrintAsciiFormat (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
- ASCII format string and a VA_LIST argument list.\r
- \r
- Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The ASCII string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list specified by Marker based on \r
- the contents of the format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- ASCII string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- @param Marker VA_LIST marker for the variable argument list.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiVSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- IN VA_LIST Marker\r
- );\r
-\r
-/**\r
- Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
- ASCII format string and variable argument list.\r
- \r
- Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The ASCII string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the \r
- format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- ASCII string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
- ASCII format string and a VA_LIST argument list.\r
- \r
- Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The ASCII string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list specified by Marker based on \r
- the contents of the format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- ASCII string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- @param Marker VA_LIST marker for the variable argument list.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiVSPrintUnicodeFormat (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- IN VA_LIST Marker\r
- );\r
-\r
-/**\r
- Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
- ASCII format string and variable argument list.\r
- \r
- Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
- and BufferSize.\r
- The ASCII string is produced by parsing the format string specified by FormatString.\r
- Arguments are pulled from the variable argument list based on the contents of the \r
- format string.\r
- The length of the produced output buffer is returned.\r
- If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
-\r
- If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT().\r
- If BufferSize is not 0 and FormatString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
- PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
- contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT().\r
-\r
- @param StartOfBuffer APointer to the output buffer for the produced Null-terminated \r
- ASCII string.\r
- @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
- @param FormatString Null-terminated Unicode format string.\r
- \r
- @return Length of the produced output buffer.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiSPrintUnicodeFormat (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- );\r
-\r
-/**\r
- Converts a decimal value to a Null-terminated Unicode string.\r
- \r
- Converts the decimal number specified by Value to a Null-terminated Unicode \r
- string specified by Buffer containing at most Width characters.\r
- If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
- The total number of characters placed in Buffer is returned.\r
- If the conversion contains more than Width characters, then only the first\r
- Width characters are returned, and the total number of characters \r
- required to perform the conversion is returned.\r
- Additional conversion parameters are specified in Flags. \r
- The Flags bit LEFT_JUSTIFY is always ignored.\r
- All conversions are left justified in Buffer.\r
- If Width is 0, PREFIX_ZERO is ignored in Flags.\r
- If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas\r
- are inserted every 3rd digit starting from the right.\r
- If Value is < 0, then the fist character in Buffer is a '-'.\r
- If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, \r
- then Buffer is padded with '0' characters so the combination of the optional '-' \r
- sign character, '0' characters, digit characters for Value, and the Null-terminator\r
- add up to Width characters.\r
-\r
- If Buffer is NULL, then ASSERT().\r
- If unsupported bits are set in Flags, then ASSERT().\r
- If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()\r
-\r
- @param Buffer Pointer to the output buffer for the produced Null-terminated\r
- Unicode string.\r
- @param Flags The bitmask of flags that specify left justification, zero pad, and commas.\r
- @param Value The 64-bit signed value to convert to a string.\r
- @param Width The maximum number of Unicode characters to place in Buffer.\r
- \r
- @return Total number of characters required to perform the conversion.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-UnicodeValueToString (\r
- IN OUT CHAR16 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width\r
- );\r
-\r
-/**\r
- Converts a decimal value to a Null-terminated ASCII string.\r
- \r
- Converts the decimal number specified by Value to a Null-terminated ASCII string \r
- specified by Buffer containing at most Width characters.\r
- If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
- The total number of characters placed in Buffer is returned.\r
- If the conversion contains more than Width characters, then only the first Width\r
- characters are returned, and the total number of characters required to perform\r
- the conversion is returned.\r
- Additional conversion parameters are specified in Flags. \r
- The Flags bit LEFT_JUSTIFY is always ignored.\r
- All conversions are left justified in Buffer.\r
- If Width is 0, PREFIX_ZERO is ignored in Flags.\r
- If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas \r
- are inserted every 3rd digit starting from the right.\r
- If Value is < 0, then the fist character in Buffer is a '-'.\r
- If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer\r
- is padded with '0' characters so the combination of the optional '-'\r
- sign character, '0' characters, digit characters for Value, and the \r
- Null-terminator add up to Width characters.\r
-\r
- If Buffer is NULL, then ASSERT().\r
- If unsupported bits are set in Flags, then ASSERT().\r
- If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()\r
-\r
- @param Buffer Pointer to the output buffer for the produced Null-terminated\r
- ASCII string.\r
- @param Flags The bitmask of flags that specify left justification, zero pad, and commas.\r
- @param Value The 64-bit signed value to convert to a string.\r
- @param Width The maximum number of ASCII characters to place in Buffer.\r
- \r
- @return Total number of characters required to perform the conversion.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width\r
- );\r
-\r
-#endif\r
!INCLUDE MSmakefile.common
-LIBRARIES = Common PeCoffLoader String
-APPLICATIONS = GenFw GenSec GenFv GenFfs GenVtf EfiRom TianoCompress Split
+LIBRARIES = Common
+APPLICATIONS = GenFw GenSec GenFv GenFfs GenVtf EfiRom TianoCompress Split GenBootSector
all: libs apps install
+++ /dev/null
-ARCH ?= IA32
-MAKEROOT ?= ..
-
-# VPATH = ..
-
-LIBNAME = String
-
-OBJECTS = PrintLib.o PrintLibInternal.o String.o
-
-include $(MAKEROOT)/lib.makefile
+++ /dev/null
-!INCLUDE ..\MSmakefile.common\r
-\r
-LIBNAME = String\r
-\r
-OBJECTS = PrintLib.obj PrintLibInternal.obj String.obj\r
-\r
-!INCLUDE ..\MSmakefile.lib\r
-\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- PrintLib.c\r
-\r
-Abstract:\r
-\r
- Print Library.\r
-\r
---*/\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Library/PrintLib.h>\r
-\r
-#include "CommonLib.h"\r
-#include "PrintLibInternal.h"\r
-\r
-typedef struct {\r
- RETURN_STATUS Status;\r
- CHAR8 *String;\r
-} STATUS_LOOKUP_TABLE_ENTRY;\r
-\r
-static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString[] = {\r
- { RETURN_SUCCESS, "Success" },\r
- { RETURN_LOAD_ERROR, "Load Error" },\r
- { RETURN_INVALID_PARAMETER, "Invalid Parameter" },\r
- { RETURN_UNSUPPORTED, "Unsupported" },\r
- { RETURN_BAD_BUFFER_SIZE, "Bad Buffer Size" },\r
- { RETURN_BUFFER_TOO_SMALL, "Buffer Too Small" },\r
- { RETURN_NOT_READY, "Not Ready" },\r
- { RETURN_DEVICE_ERROR, "Device Error" },\r
- { RETURN_WRITE_PROTECTED, "Write Protected" },\r
- { RETURN_OUT_OF_RESOURCES, "Out of Resources" },\r
- { RETURN_VOLUME_CORRUPTED, "Volume Corrupt" },\r
- { RETURN_VOLUME_FULL, "Volume Full" },\r
- { RETURN_NO_MEDIA, "No Media" },\r
- { RETURN_MEDIA_CHANGED, "Media changed" },\r
- { RETURN_NOT_FOUND, "Not Found" },\r
- { RETURN_ACCESS_DENIED, "Access Denied" },\r
- { RETURN_NO_RESPONSE, "No Response" },\r
- { RETURN_NO_MAPPING, "No mapping" },\r
- { RETURN_TIMEOUT, "Time out" },\r
- { RETURN_NOT_STARTED, "Not started" },\r
- { RETURN_ALREADY_STARTED, "Already started" },\r
- { RETURN_ABORTED, "Aborted" },\r
- { RETURN_ICMP_ERROR, "ICMP Error" },\r
- { RETURN_TFTP_ERROR, "TFTP Error" },\r
- { RETURN_PROTOCOL_ERROR, "Protocol Error" },\r
- { RETURN_WARN_UNKNOWN_GLYPH, "Warning Unknown Glyph" },\r
- { RETURN_WARN_DELETE_FAILURE, "Warning Delete Failure" },\r
- { RETURN_WARN_WRITE_FAILURE, "Warning Write Failure" },\r
- { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" },\r
- { 0, NULL }\r
-};\r
-\r
-\r
-/**\r
- VSPrint function to process format and place the results in Buffer. Since a\r
- VA_LIST is used this rountine allows the nesting of Vararg routines. Thus\r
- this is the main print working routine\r
-\r
- @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into.\r
-\r
- @param BufferSize Maximum number of characters to put into buffer. Zero means\r
- no limit.\r
-\r
- @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
-\r
- @param FormatString Unicode format string see file header for more details.\r
-\r
- @param Marker Vararg list consumed by processing Format.\r
-\r
- @return Number of characters printed.\r
-\r
-**/\r
-UINTN\r
-BasePrintLibVSPrint (\r
- OUT CHAR8 *Buffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *Format,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- CHAR8 *OriginalBuffer;\r
- CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
- UINTN BytesPerOutputCharacter;\r
- UINTN BytesPerFormatCharacter;\r
- UINTN FormatMask;\r
- UINTN FormatCharacter;\r
- UINTN Width;\r
- UINTN Precision;\r
- INT64 Value;\r
- CHAR8 *ArgumentString;\r
- UINTN Character;\r
- GUID *TmpGuid;\r
- TIME *TmpTime;\r
- UINTN Count;\r
- UINTN ArgumentMask;\r
- INTN BytesPerArgumentCharacter;\r
- UINTN ArgumentCharacter;\r
- BOOLEAN Done;\r
- UINTN Index;\r
- CHAR8 Prefix;\r
- BOOLEAN ZeroPad;\r
- BOOLEAN Comma;\r
- UINTN Digits;\r
- UINTN Radix;\r
- RETURN_STATUS Status;\r
-\r
- OriginalBuffer = Buffer;\r
-\r
- if ((Flags & OUTPUT_UNICODE) != 0) {\r
- BytesPerOutputCharacter = 2;\r
- } else {\r
- BytesPerOutputCharacter = 1;\r
- }\r
- if ((Flags & FORMAT_UNICODE) != 0) {\r
- BytesPerFormatCharacter = 2;\r
- FormatMask = 0xffff;\r
- } else {\r
- BytesPerFormatCharacter = 1;\r
- FormatMask = 0xff;\r
- }\r
-\r
- //\r
- // Reserve space for the Null terminator.\r
- // If BufferSize is 0, this will set BufferSize to the max unsigned value\r
- //\r
- BufferSize--;\r
-\r
- //\r
- // Get the first character from the format string\r
- //\r
- FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
-\r
- //\r
- // Loop until the end of the format string is reached or the output buffer is full\r
- //\r
- while (FormatCharacter != 0 && BufferSize > 0) {\r
- //\r
- // Clear all the flag bits except those that may have been passed in\r
- //\r
- Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);\r
-\r
- //\r
- // Set the default width to zero, and the default precision to 1\r
- //\r
- Width = 0;\r
- Precision = 1;\r
- Prefix = 0;\r
- Comma = FALSE;\r
- ZeroPad = FALSE;\r
- Count = 0;\r
- Digits = 0;\r
-\r
- switch (FormatCharacter) {\r
- case '%':\r
- //\r
- // Parse Flags and Width\r
- //\r
- for (Done = FALSE; !Done; ) {\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
- switch (FormatCharacter) {\r
- case '.':\r
- Flags |= PRECISION;\r
- break;\r
- case '-':\r
- Flags |= LEFT_JUSTIFY;\r
- break;\r
- case '+':\r
- Flags |= PREFIX_SIGN;\r
- break;\r
- case ' ':\r
- Flags |= PREFIX_BLANK;\r
- break;\r
- case ',':\r
- Flags |= COMMA_TYPE;\r
- break;\r
- case 'L':\r
- case 'l':\r
- Flags |= LONG_TYPE;\r
- break;\r
- case '*':\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PAD_TO_WIDTH;\r
- Width = VA_ARG (Marker, UINTN);\r
- } else {\r
- Precision = VA_ARG (Marker, UINTN);\r
- }\r
- break;\r
- case '0':\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PREFIX_ZERO;\r
- }\r
- case '1':\r
- case '2':\r
- case '3':\r
- case '4':\r
- case '5':\r
- case '6':\r
- case '7':\r
- case '8':\r
- case '9':\r
- for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){\r
- Count = (Count * 10) + FormatCharacter - '0';\r
- Format += BytesPerFormatCharacter;\r
- FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
- }\r
- Format -= BytesPerFormatCharacter;\r
- if ((Flags & PRECISION) == 0) {\r
- Flags |= PAD_TO_WIDTH;\r
- Width = Count;\r
- } else {\r
- Precision = Count;\r
- }\r
- break;\r
- default:\r
- Done = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Limit the maximum field width to the remaining characters in the output buffer\r
- //\r
- if (Width > BufferSize) {\r
- Width = BufferSize;\r
- }\r
-\r
- //\r
- // Handle each argument type\r
- //\r
- switch (FormatCharacter) {\r
- case 'X':\r
- Flags |= PREFIX_ZERO;\r
- //\r
- // break skiped on purpose\r
- //\r
- case 'x':\r
- Flags |= RADIX_HEX;\r
- //\r
- // break skiped on purpose\r
- //\r
- case 'd':\r
- if ((Flags & LONG_TYPE) == 0) {\r
- Value = (VA_ARG (Marker, INTN));\r
- } else {\r
- Value = VA_ARG (Marker, INT64);\r
- }\r
- if ((Flags & PREFIX_BLANK) != 0) {\r
- Prefix = ' ';\r
- }\r
- if ((Flags & PREFIX_SIGN) != 0) {\r
- Prefix = '+';\r
- }\r
- if ((Flags & COMMA_TYPE) != 0) {\r
- Comma = TRUE;\r
- }\r
- if ((Flags & RADIX_HEX) == 0) {\r
- Radix = 10;\r
- if (Comma) {\r
- Flags &= (~PREFIX_ZERO);\r
- Precision = 1;\r
- }\r
- if (Value < 0) {\r
- Flags |= PREFIX_SIGN;\r
- Prefix = '-';\r
- Value = -Value;\r
- }\r
- } else {\r
- Radix = 16;\r
- Comma = FALSE;\r
- if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
- Value = (UINTN)Value;\r
- }\r
- }\r
- //\r
- // Convert Value to a reversed string\r
- //\r
- Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
- if (Value == 0 && Precision == 0) {\r
- Count = 0;\r
- }\r
- ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
- Digits = 3 - (Count % 3);\r
- if (Comma && Count != 0) {\r
- Count += ((Count - 1) / 3);\r
- }\r
- if (Prefix != 0) {\r
- Count++;\r
- }\r
- Flags |= ARGUMENT_REVERSED;\r
- ZeroPad = TRUE;\r
- if ((Flags & PREFIX_ZERO) != 0) {\r
- if ((Flags & PAD_TO_WIDTH) != 0) {\r
- if ((Flags & PRECISION) == 0) {\r
- Precision = Width;\r
- }\r
- }\r
- }\r
- break;\r
-\r
- case 's':\r
- case 'S':\r
- Flags |= ARGUMENT_UNICODE;\r
- //\r
- // break skipped on purpose\r
- //\r
- case 'a':\r
- ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);\r
- if (ArgumentString == NULL) {\r
- Flags &= (~ARGUMENT_UNICODE);\r
- ArgumentString = "<null string>";\r
- }\r
- break;\r
-\r
- case 'c':\r
- Character = VA_ARG (Marker, UINTN) & 0xffff;\r
- ArgumentString = (CHAR8 *)&Character;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
-\r
- case 'g':\r
- TmpGuid = VA_ARG (Marker, GUID *);\r
- if (TmpGuid == NULL) {\r
- ArgumentString = "<null guid>";\r
- } else {\r
- BasePrintLibSPrint (\r
- ValueBuffer,\r
- 0,\r
- 0,\r
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
- TmpGuid->Data1,\r
- TmpGuid->Data2,\r
- TmpGuid->Data3,\r
- TmpGuid->Data4[0],\r
- TmpGuid->Data4[1],\r
- TmpGuid->Data4[2],\r
- TmpGuid->Data4[3],\r
- TmpGuid->Data4[4],\r
- TmpGuid->Data4[5],\r
- TmpGuid->Data4[6],\r
- TmpGuid->Data4[7]\r
- );\r
- ArgumentString = ValueBuffer;\r
- }\r
- break;\r
-\r
- case 't':\r
- TmpTime = VA_ARG (Marker, TIME *);\r
- if (TmpTime == NULL) {\r
- ArgumentString = "<null time>";\r
- } else {\r
- BasePrintLibSPrint (\r
- ValueBuffer,\r
- 0,\r
- 0,\r
- "%02d/%02d/%04d %02d:%02d",\r
- TmpTime->Month,\r
- TmpTime->Day,\r
- TmpTime->Year,\r
- TmpTime->Hour,\r
- TmpTime->Minute\r
- );\r
- ArgumentString = ValueBuffer;\r
- }\r
- break;\r
-\r
- case 'r':\r
- Status = VA_ARG (Marker, RETURN_STATUS);\r
- ArgumentString = ValueBuffer;\r
- for (Index = 0; StatusString[Index].String != NULL; Index++) {\r
- if (Status == StatusString[Index].Status) {\r
- ArgumentString = StatusString[Index].String;\r
- }\r
- }\r
- if (ArgumentString == ValueBuffer) {\r
- BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status);\r
- }\r
- break;\r
-\r
- case '%':\r
- default:\r
- //\r
- // if the type is '%' or unknown, then print it to the screen\r
- //\r
- ArgumentString = (CHAR8 *)&FormatCharacter;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
- }\r
- break;\r
- case '\n':\r
- ArgumentString = "\n";\r
- \r
- break;\r
- default:\r
- ArgumentString = (CHAR8 *)&FormatCharacter;\r
- Flags |= ARGUMENT_UNICODE;\r
- break;\r
- }\r
-\r
- //\r
- // Retrieve the ArgumentString attriubutes\r
- //\r
- if ((Flags & ARGUMENT_UNICODE) != 0) {\r
- ArgumentMask = 0xffff;\r
- BytesPerArgumentCharacter = 2;\r
- } else {\r
- ArgumentMask = 0xff;\r
- BytesPerArgumentCharacter = 1;\r
- }\r
- if ((Flags & ARGUMENT_REVERSED) != 0) {\r
- BytesPerArgumentCharacter = -BytesPerArgumentCharacter;\r
- } else {\r
- //\r
- // Compute the number of characters in ArgumentString and store it in Count\r
- // ArgumentString is either null-terminated, or it contains Precision characters\r
- //\r
- for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
- ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
- if (ArgumentCharacter == 0) {\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Limit the length of the string to append to the remaining characters in the output buffer\r
- //\r
- if (Count > BufferSize) {\r
- Count = BufferSize;\r
- }\r
- if (Precision < Count) {\r
- Precision = Count;\r
- }\r
-\r
- //\r
- // Pad before the string\r
- //\r
- if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
- }\r
-\r
- if (ZeroPad) {\r
- if (Prefix != 0) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
- }\r
- Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter);\r
- } else {\r
- Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter);\r
- if (Prefix != 0) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
- }\r
- }\r
-\r
- //\r
- // Output the Prefix character if it is present\r
- //\r
- Index = 0;\r
- if (Prefix) {\r
- Index++;\r
- }\r
-\r
- //\r
- // Copy the string into the output buffer performing the required type conversions\r
- //\r
- while (Index < Count) {\r
- ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
-\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter);\r
- ArgumentString += BytesPerArgumentCharacter;\r
- Index++;\r
- if (Comma) {\r
- Digits++;\r
- if (Digits == 3) {\r
- Digits = 0;\r
- Index++;\r
- if (Index < Count) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter);\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Pad after the string\r
- //\r
- if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
- }\r
-\r
- //\r
- // Reduce the number of characters\r
- //\r
- BufferSize -= Count;\r
-\r
- //\r
- // Get the next character from the format string\r
- //\r
- Format += BytesPerFormatCharacter;\r
-\r
- //\r
- // Get the next character from the format string\r
- //\r
- FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
- }\r
-\r
- //\r
- // Null terminate the Unicode or ASCII string\r
- //\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter);\r
-\r
- return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);\r
-}\r
-\r
-UINTN\r
-BasePrintLibSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-UnicodeVSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-UnicodeSPrint (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-UnicodeVSPrintAsciiFormat (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-UnicodeSPrintAsciiFormat (\r
- OUT CHAR16 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsciiVSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsciiSPrint (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsciiVSPrintUnicodeFormat (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- IN VA_LIST Marker\r
- )\r
-{\r
- return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsciiSPrintUnicodeFormat (\r
- OUT CHAR8 *StartOfBuffer,\r
- IN UINTN BufferSize,\r
- IN CONST CHAR16 *FormatString,\r
- ...\r
- )\r
-{\r
- VA_LIST Marker;\r
-\r
- VA_START (Marker, FormatString);\r
- return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-UnicodeValueToString (\r
- IN OUT CHAR16 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width\r
- )\r
-{\r
- return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);\r
-}\r
-\r
-UINTN\r
-EFIAPI\r
-AsciiValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width\r
- )\r
-{\r
- return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1);\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- PrintLibInternal.c\r
-\r
-Abstract:\r
-\r
- Print Library worker functions.\r
-\r
---*/\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Library/PrintLib.h>\r
-\r
-#include "CommonLib.h"\r
-#include "PrintLibInternal.h"\r
-\r
-static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
-\r
-CHAR8 *\r
-BasePrintLibFillBuffer (\r
- CHAR8 *Buffer,\r
- INTN Length,\r
- UINTN Character,\r
- INTN Increment\r
- )\r
-{\r
- INTN Index;\r
-\r
- for (Index = 0; Index < Length; Index++) {\r
- *Buffer = (CHAR8) Character;\r
- *(Buffer + 1) = (CHAR8) (Character >> 8);\r
- Buffer += Increment;\r
- }\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Print worker function that prints a Value as a decimal number in Buffer.\r
-\r
- @param Buffer Location to place the Unicode or ASCII string of Value.\r
-\r
- @param Value Value to convert to a Decimal or Hexidecimal string in Buffer.\r
-\r
- @param Flags Flags to use in printing string, see file header for details.\r
-\r
- @param Precision Minimum number of digits to return in the ASCII string\r
-\r
- @return Number of characters printed.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-BasePrintLibValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN INT64 Value,\r
- IN UINTN Radix\r
- )\r
-{\r
- UINTN Digits;\r
- UINT32 Remainder;\r
-\r
- //\r
- // Loop to convert one digit at a time in reverse order\r
- //\r
- *(Buffer++) = 0;\r
- Digits = 0;\r
- do {\r
- // Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);\r
- Remainder = (UINT64)Value % (UINT32)Radix;\r
- Value = (UINT64)Value / (UINT32)Radix;\r
- *(Buffer++) = mHexStr[Remainder];\r
- Digits++;\r
- } while (Value != 0);\r
- return Digits;\r
-}\r
-\r
-UINTN\r
-BasePrintLibConvertValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width,\r
- IN UINTN Increment\r
- )\r
-{\r
- CHAR8 *OriginalBuffer;\r
- CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
- UINTN Count;\r
- UINTN Digits;\r
- UINTN Index;\r
-\r
- OriginalBuffer = Buffer;\r
-\r
- if (Width == 0 || (Flags & COMMA_TYPE) != 0) {\r
- Flags &= (~PREFIX_ZERO);\r
- }\r
-\r
- if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) {\r
- Width = MAXIMUM_VALUE_CHARACTERS - 1;\r
- }\r
-\r
- if (Value < 0) {\r
- Value = -Value;\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment);\r
- }\r
-\r
- Count = BasePrintLibValueToString (ValueBuffer, Value, 10);\r
-\r
- if ((Flags & PREFIX_ZERO) != 0) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment);\r
- }\r
-\r
- Digits = 3 - (Count % 3);\r
- for (Index = 0; Index < Count; Index++) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment);\r
- if ((Flags & COMMA_TYPE) != 0) {\r
- Digits++;\r
- if (Digits == 3) {\r
- Digits = 0;\r
- if ((Index + 1) < Count) {\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment);\r
- }\r
- }\r
- }\r
- }\r
-\r
- Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment);\r
-\r
- return ((Buffer - OriginalBuffer) / Increment);\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- PrintLibInternal.h\r
-\r
-Abstract:\r
-\r
- Print Library.\r
-\r
---*/\r
-\r
-\r
-\r
-//\r
-// Print primitives\r
-//\r
-//#define LEFT_JUSTIFY 0x01\r
-#define PREFIX_SIGN 0x02\r
-#define PREFIX_BLANK 0x04\r
-//#define COMMA_TYPE 0x08\r
-#define LONG_TYPE 0x10\r
-//#define PREFIX_ZERO 0x20\r
-#define OUTPUT_UNICODE 0x40\r
-#define RADIX_HEX 0x80\r
-#define FORMAT_UNICODE 0x100\r
-#define PAD_TO_WIDTH 0x200\r
-#define ARGUMENT_UNICODE 0x400\r
-#define PRECISION 0x800\r
-#define ARGUMENT_REVERSED 0x1000\r
-\r
-///\r
-/// Define the maximum number of characters that are required to encode\r
-/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator.\r
-/// Maximum Length Decimal String = 28 "-9,223,372,036,854,775,808"\r
-/// Maximum Length Hexidecimal String = 17 "FFFFFFFFFFFFFFFF"\r
-/// Maximum Length GUID = 37 "00000000-0000-0000-0000-000000000000"\r
-/// Maximum Length TIME = 18 "12/12/2006 12:12"\r
-///\r
-#define MAXIMUM_VALUE_CHARACTERS 38\r
-\r
-//\r
-//\r
-//\r
-typedef struct {\r
- UINT16 Year;\r
- UINT8 Month;\r
- UINT8 Day;\r
- UINT8 Hour;\r
- UINT8 Minute;\r
- UINT8 Second;\r
- UINT8 Pad1;\r
- UINT32 Nanosecond;\r
- INT16 TimeZone;\r
- UINT8 Daylight;\r
- UINT8 Pad2;\r
-} TIME;\r
-\r
-UINTN\r
-BasePrintLibSPrint (\r
- OUT CHAR8 *Buffer,\r
- IN UINTN BufferSize,\r
- IN UINTN Flags,\r
- IN CONST CHAR8 *FormatString,\r
- ...\r
- );\r
-\r
-CHAR8 *\r
-BasePrintLibFillBuffer (\r
- CHAR8 *Buffer,\r
- INTN Length,\r
- UINTN Character,\r
- INTN Increment\r
- );\r
-\r
-UINTN\r
-EFIAPI\r
-BasePrintLibValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN INT64 Value,\r
- IN UINTN Radix\r
- );\r
-\r
-UINTN\r
-BasePrintLibConvertValueToString (\r
- IN OUT CHAR8 *Buffer,\r
- IN UINTN Flags,\r
- IN INT64 Value,\r
- IN UINTN Width,\r
- IN UINTN Increment\r
- );\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-\r
-Module Name:\r
-\r
- String.c\r
-\r
-Abstract:\r
-\r
- Unicode and ASCII string primatives.\r
-\r
---*/\r
-\r
-#include <assert.h>\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-\r
-#include <string.h>\r
-\r
-#include "CommonLib.h"\r
-\r
-/**\r
- Returns the length of a Null-terminated Unicode string.\r
-\r
- This function returns the number of Unicode characters in the Null-terminated\r
- Unicode string specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
-\r
- @param String Pointer to a Null-terminated Unicode string.\r
-\r
- @return The length of String.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-StrLen (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- UINTN Length;\r
-\r
- ASSERT (String != NULL);\r
-\r
- for (Length = 0; *String != L'\0'; String++, Length++) {\r
- ;\r
- }\r
- return Length;\r
-}\r
-\r
-/**\r
- Returns the length of a Null-terminated ASCII string.\r
-\r
- This function returns the number of ASCII characters in the Null-terminated\r
- ASCII string specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
-\r
- @param String Pointer to a Null-terminated ASCII string.\r
-\r
- @return The length of String.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiStrLen (\r
- IN CONST CHAR8 *String\r
- )\r
-{\r
- UINTN Length;\r
-\r
- ASSERT (String != NULL);\r
-\r
- for (Length = 0; *String != '\0'; String++, Length++) {\r
- ;\r
- }\r
- return Length;\r
-}\r
-\r
-/**\r
- Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
- string and returns the new Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
-\r
- @return Destiantion\r
-\r
-**/\r
-CHAR16 *\r
-EFIAPI\r
-StrCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) > StrLen (Source));\r
-\r
- ReturnValue = Destination;\r
- while (*Source) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Copies one Null-terminated Unicode string with a maximum length to another\r
- Null-terminated Unicode string with a maximum length and returns the new\r
- Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. At most, Length Unicode\r
- characters are copied from Source to Destination. If Length is 0, then\r
- Destination is returned unmodified. If Length is greater that the number of\r
- Unicode characters in Source, then Destination is padded with Null Unicode\r
- characters. If Source and Destination overlap, then the results are\r
- undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to copy.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR16 *\r
-EFIAPI\r
-StrnCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source,\r
- IN UINTN Length\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- if (Length == 0) {\r
- return Destination;\r
- }\r
-\r
- //\r
- // Destination cannot be NULL if Length is not zero\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- // Q: Does Source have to be NULL-terminated?\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) >= Length);\r
-\r
- ReturnValue = Destination;\r
-\r
- while ((*Source != L'\0') && (Length > 0)) {\r
- *(Destination++) = *(Source++);\r
- Length--;\r
- }\r
-\r
- memset (Destination, 0, Length * sizeof (*Destination));\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Returns the size of a Null-terminated Unicode string in bytes, including the\r
- Null terminator.\r
-\r
- This function returns the size, in bytes, of the Null-terminated Unicode\r
- string specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
-\r
- @param String Pointer to a Null-terminated Unicode string.\r
-\r
- @return The size of String.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-StrSize (\r
- IN CONST CHAR16 *String\r
- )\r
-{\r
- return (StrLen (String) + 1) * sizeof (*String);\r
-}\r
-\r
-/**\r
- Compares two Null-terminated Unicode strings, and returns the difference\r
- between the first mismatched Unicode characters.\r
-\r
- This function compares the Null-terminated Unicode string FirstString to the\r
- Null-terminated Unicode string SecondString. If FirstString is identical to\r
- SecondString, then 0 is returned. Otherwise, the value returned is the first\r
- mismatched Unicode character in SecondString subtracted from the first\r
- mismatched Unicode character in FirstString.\r
-\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
-\r
- @param FirstString Pointer to a Null-terminated Unicode string.\r
- @param SecondString Pointer to a Null-terminated Unicode string.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-StrCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString\r
- )\r
-{\r
- //\r
- // ASSERT both strings should never be zero\r
- //\r
- ASSERT (StrSize (FirstString) != 0);\r
- ASSERT (StrSize (SecondString) != 0);\r
-\r
- while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
- FirstString++;\r
- SecondString++;\r
- }\r
- return *FirstString - *SecondString;\r
-}\r
-\r
-/**\r
- Compares two Null-terminated Unicode strings with maximum lengths, and\r
- returns the difference between the first mismatched Unicode characters.\r
-\r
- This function compares the Null-terminated Unicode string FirstString to the\r
- Null-terminated Unicode string SecondString. At most, Length Unicode\r
- characters will be compared. If Length is 0, then 0 is returned. If\r
- FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
- value returned is the first mismatched Unicode character in SecondString\r
- subtracted from the first mismatched Unicode character in FirstString.\r
-\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
-\r
- @param FirstString Pointer to a Null-terminated Unicode string.\r
- @param SecondString Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to compare.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-StrnCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString,\r
- IN UINTN Length\r
- )\r
-{\r
- if (Length == 0) {\r
- return 0;\r
- }\r
-\r
- //\r
- // ASSERT both strings should never be zero\r
- //\r
- ASSERT (StrSize (FirstString) != 0);\r
- ASSERT (StrSize (SecondString) != 0);\r
-\r
- while ((*FirstString != L'\0') &&\r
- (*FirstString == *SecondString) &&\r
- (Length > 1)) {\r
- FirstString++;\r
- SecondString++;\r
- Length--;\r
- }\r
-\r
- return *FirstString - *SecondString;\r
-}\r
-\r
-/**\r
- Concatenates one Null-terminated Unicode string to another Null-terminated\r
- Unicode string, and returns the concatenated Unicode string.\r
-\r
- This function concatenates two Null-terminated Unicode strings. The contents\r
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination. The Null-terminated concatenated\r
- Unicode String is returned. If Source and Destination overlap, then the\r
- results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR16 *\r
-EFIAPI\r
-StrCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- StrCpy (Destination + StrLen (Destination), Source);\r
-\r
- //\r
- // Size of the resulting string should never be zero.\r
- //\r
- ASSERT (StrSize (Destination) != 0);\r
- return Destination;\r
-}\r
-\r
-/**\r
- Concatenates one Null-terminated Unicode string with a maximum length to the\r
- end of another Null-terminated Unicode string, and returns the concatenated\r
- Unicode string.\r
-\r
- This function concatenates two Null-terminated Unicode strings. The contents\r
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination, and Destination is returned. At\r
- most, Length Unicode characters are concatenated from Source to the end of\r
- Destination, and Destination is always Null-terminated. If Length is 0, then\r
- Destination is returned unmodified. If Source and Destination overlap, then\r
- the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to concatenate from\r
- Source.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR16 *\r
-EFIAPI\r
-StrnCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source,\r
- IN UINTN Length\r
- )\r
-{\r
- StrnCpy (Destination + StrLen (Destination), Source, Length);\r
-\r
- //\r
- // Size of the resulting string should never be zero.\r
- //\r
- ASSERT (StrSize (Destination) != 0);\r
- return Destination;\r
-}\r
-\r
-/**\r
- Copies one Null-terminated ASCII string to another Null-terminated ASCII\r
- string and returns the new ASCII string.\r
-\r
- This function copies the contents of the ASCII string Source to the ASCII\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-AsciiStrCpy (\r
- OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source\r
- )\r
-{\r
- CHAR8 *ReturnValue;\r
-\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));\r
-\r
- ReturnValue = Destination;\r
- while (*Source) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Copies one Null-terminated ASCII string with a maximum length to another\r
- Null-terminated ASCII string with a maximum length and returns the new ASCII\r
- string.\r
-\r
- This function copies the contents of the ASCII string Source to the ASCII\r
- string Destination, and returns Destination. At most, Length ASCII characters\r
- are copied from Source to Destination. If Length is 0, then Destination is\r
- returned unmodified. If Length is greater that the number of ASCII characters\r
- in Source, then Destination is padded with Null ASCII characters. If Source\r
- and Destination overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
- @param Length Maximum number of ASCII characters to copy.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-AsciiStrnCpy (\r
- OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source,\r
- IN UINTN Length\r
- )\r
-{\r
- CHAR8 *ReturnValue;\r
-\r
- if (Length == 0) {\r
- return Destination;\r
- }\r
-\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) >= Length);\r
-\r
- ReturnValue = Destination;\r
-\r
- while (*Source && Length > 0) {\r
- *(Destination++) = *(Source++);\r
- Length--;\r
- }\r
-\r
- // ZeroMem (Destination, Length * sizeof (*Destination));\r
- memset (Destination, 0, Length * sizeof (*Destination));\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Returns the size of a Null-terminated ASCII string in bytes, including the\r
- Null terminator.\r
-\r
- This function returns the size, in bytes, of the Null-terminated ASCII string\r
- specified by String.\r
-\r
- If String is NULL, then ASSERT().\r
-\r
- @param String Pointer to a Null-terminated ASCII string.\r
-\r
- @return The size of String.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsciiStrSize (\r
- IN CONST CHAR8 *String\r
- )\r
-{\r
- return (AsciiStrLen (String) + 1) * sizeof (*String);\r
-}\r
-\r
-/**\r
- Compares two Null-terminated ASCII strings, and returns the difference\r
- between the first mismatched ASCII characters.\r
-\r
- This function compares the Null-terminated ASCII string FirstString to the\r
- Null-terminated ASCII string SecondString. If FirstString is identical to\r
- SecondString, then 0 is returned. Otherwise, the value returned is the first\r
- mismatched ASCII character in SecondString subtracted from the first\r
- mismatched ASCII character in FirstString.\r
-\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
-\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-AsciiStrCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString\r
- )\r
-{\r
- //\r
- // ASSERT both strings should never be zero\r
- //\r
- ASSERT (AsciiStrSize (FirstString));\r
- ASSERT (AsciiStrSize (SecondString));\r
-\r
- while ((*FirstString != '\0') && (*FirstString == *SecondString)) {\r
- FirstString++;\r
- SecondString++;\r
- }\r
-\r
- return *FirstString - *SecondString;\r
-}\r
-\r
-STATIC\r
-CHAR8\r
-EFIAPI\r
-AsciiToUpper (\r
- IN CHAR8 Chr\r
- )\r
-{\r
- return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;\r
-}\r
-\r
-/**\r
- Performs a case insensitive comparison of two Null-terminated ASCII strings,\r
- and returns the difference between the first mismatched ASCII characters.\r
-\r
- This function performs a case insensitive comparison of the Null-terminated\r
- ASCII string FirstString to the Null-terminated ASCII string SecondString. If\r
- FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
- value returned is the first mismatched lower case ASCII character in\r
- SecondString subtracted from the first mismatched lower case ASCII character\r
- in FirstString.\r
-\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
-\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\r
-\r
- @retval 0 FirstString is identical to SecondString using case insensitive\r
- comparisons.\r
- @retval !=0 FirstString is not identical to SecondString using case\r
- insensitive comparisons.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-AsciiStriCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString\r
- )\r
-{\r
- //\r
- // ASSERT both strings should never be zero\r
- //\r
- ASSERT (AsciiStrSize (FirstString));\r
- ASSERT (AsciiStrSize (SecondString));\r
-\r
- while ((*FirstString != '\0') &&\r
- (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) {\r
- FirstString++;\r
- SecondString++;\r
- }\r
-\r
- return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);\r
-}\r
-\r
-/**\r
- Compares two Null-terminated ASCII strings with maximum lengths, and returns\r
- the difference between the first mismatched ASCII characters.\r
-\r
- This function compares the Null-terminated ASCII string FirstString to the\r
- Null-terminated ASCII string SecondString. At most, Length ASCII characters\r
- will be compared. If Length is 0, then 0 is returned. If FirstString is\r
- identical to SecondString, then 0 is returned. Otherwise, the value returned\r
- is the first mismatched ASCII character in SecondString subtracted from the\r
- first mismatched ASCII character in FirstString.\r
-\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
-\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\r
-\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-AsciiStrnCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString,\r
- IN UINTN Length\r
- )\r
-{\r
- //\r
- // ASSERT both strings should never be zero\r
- //\r
- ASSERT (AsciiStrSize (FirstString));\r
- ASSERT (AsciiStrSize (SecondString));\r
-\r
- while ((*FirstString != '\0') &&\r
- (*FirstString == *SecondString) &&\r
- (Length > 1)) {\r
- FirstString++;\r
- SecondString++;\r
- Length--;\r
- }\r
- return *FirstString - *SecondString;\r
-}\r
-\r
-/**\r
- Concatenates one Null-terminated ASCII string to another Null-terminated\r
- ASCII string, and returns the concatenated ASCII string.\r
-\r
- This function concatenates two Null-terminated ASCII strings. The contents of\r
- Null-terminated ASCII string Source are concatenated to the end of Null-\r
- terminated ASCII string Destination. The Null-terminated concatenated ASCII\r
- String is returned.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-AsciiStrCat (\r
- IN OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source\r
- )\r
-{\r
- AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);\r
-\r
- //\r
- // Size of the resulting string should never be zero.\r
- //\r
- ASSERT (AsciiStrSize (Destination) != 0);\r
- return Destination;\r
-}\r
-\r
-/**\r
- Concatenates one Null-terminated ASCII string with a maximum length to the\r
- end of another Null-terminated ASCII string, and returns the concatenated\r
- ASCII string.\r
-\r
- This function concatenates two Null-terminated ASCII strings. The contents\r
- of Null-terminated ASCII string Source are concatenated to the end of Null-\r
- terminated ASCII string Destination, and Destination is returned. At most,\r
- Length ASCII characters are concatenated from Source to the end of\r
- Destination, and Destination is always Null-terminated. If Length is 0, then\r
- Destination is returned unmodified. If Source and Destination overlap, then\r
- the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
- @param Length Maximum number of ASCII characters to concatenate from\r
- Source.\r
-\r
- @return Destination\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-AsciiStrnCat (\r
- IN OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source,\r
- IN UINTN Length\r
- )\r
-{\r
- AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);\r
-\r
- //\r
- // Size of the resulting string should never be zero.\r
- //\r
- ASSERT (AsciiStrSize (Destination) != 0);\r
- return Destination;\r
-}\r
APPNAME = TianoCompress
-LIBS = Common.lib String.lib
+LIBS = Common.lib
OBJECTS = TianoCompress.obj