diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Drivers/CpuDxe/Exception.c index 1487fe8b2e..92faaa33d3 100644 --- a/ArmPkg/Drivers/CpuDxe/Exception.c +++ b/ArmPkg/Drivers/CpuDxe/Exception.c @@ -122,39 +122,6 @@ RegisterDebuggerInterruptHandler ( } -UINT32 -EFIAPI -PeCoffGetSizeOfHeaders ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINTN SizeOfHeaders; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; - } else { - SizeOfHeaders = 0; - } - - return SizeOfHeaders; -} CHAR8 * diff --git a/ArmPkg/Drivers/CpuDxe/Mmu.c b/ArmPkg/Drivers/CpuDxe/Mmu.c index a0977dd110..55e049850f 100644 --- a/ArmPkg/Drivers/CpuDxe/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/Mmu.c @@ -16,10 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "CpuDxe.h" -// -// For debug switch me back to to EFI_D_PAGE when done -// -#define L_EFI_D_PAGE EFI_D_ERROR // // Translation/page table definitions @@ -353,7 +349,7 @@ SyncCacheConfig ( EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; - DEBUG ((L_EFI_D_PAGE, "SyncCacheConfig()\n")); + DEBUG ((EFI_D_PAGE, "SyncCacheConfig()\n")); // This code assumes MMU is enabled and filed with section translations ASSERT (ArmMmuEnabled ()); @@ -483,7 +479,7 @@ UpdatePageEntries ( // Cause a page fault if these ranges are accessed. EntryMask = 0x3; EntryValue = 0; - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting page %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); break; default: @@ -617,7 +613,7 @@ UpdateSectionEntries ( // cannot be implemented UEFI definition unclear for ARM // Cause a page fault if these ranges are accessed. EntryValue = ARM_DESC_TYPE_FAULT; - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): setting section %lx with unsupported attribute %x will page fault on access\n", BaseAddress, Attributes)); break; @@ -680,7 +676,7 @@ ConvertSectionToPages ( volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; volatile ARM_PAGE_TABLE_ENTRY *PageTable; - DEBUG ((L_EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress)); + DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress)); // obtain page table base FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTranslationTableBaseAddress (); @@ -727,10 +723,6 @@ ConvertSectionToPages ( } // flush d-cache so descriptors make it back to uncached memory for subsequent table walks - // TODO: change to use only PageTable base and length - // ArmInvalidateDataCache (); -DEBUG ((EFI_D_ERROR, "InvalidateDataCacheRange (%x, %x)\n", (UINTN)PageTableAddr, EFI_PAGE_SIZE)); - InvalidateDataCacheRange ((VOID *)(UINTN)PageTableAddr, EFI_PAGE_SIZE); // formulate page table entry, Domain=0, NS=0 @@ -756,11 +748,11 @@ SetMemoryAttributes ( if(((BaseAddress & 0xFFFFF) == 0) && ((Length & 0xFFFFF) == 0)) { // is the base and length a multiple of 1 MB? - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU section 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); Status = UpdateSectionEntries (BaseAddress, Length, Attributes, VirtualMask); } else { // base and/or length is not a multiple of 1 MB - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(): MMU page 0x%x length 0x%x to %lx\n", (UINTN)BaseAddress, (UINTN)Length, Attributes)); Status = UpdatePageEntries (BaseAddress, Length, Attributes, VirtualMask); } @@ -807,10 +799,10 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes ) { - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx)\n", BaseAddress, Length, Attributes)); if ( ((BaseAddress & (EFI_PAGE_SIZE-1)) != 0) || ((Length & (EFI_PAGE_SIZE-1)) != 0)){ // minimum granularity is EFI_PAGE_SIZE (4KB on ARM) - DEBUG ((L_EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is EFI_PAGE_SIZE\n", BaseAddress, Length, Attributes)); + DEBUG ((EFI_D_PAGE, "SetMemoryAttributes(%lx, %lx, %lx): minimum ganularity is EFI_PAGE_SIZE\n", BaseAddress, Length, Attributes)); return EFI_UNSUPPORTED; } @@ -843,7 +835,7 @@ CpuConvertPagesToUncachedVirtualAddress ( *Attributes = GcdDescriptor.Attributes; } } -ASSERT (FALSE); + // // Make this address range page fault if accessed. If it is a DMA buffer than this would // be the PCI address. Code should always use the CPU address, and we will or in VirtualMask diff --git a/ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.c b/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c similarity index 56% rename from ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.c rename to ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c index 2e44c629e4..071c510dde 100644 --- a/ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.c +++ b/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.c @@ -10,8 +10,6 @@ http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - **/ #include @@ -21,12 +19,53 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include +#include #include +/** + Append string to debugger script file, create file if needed. + This library can show up in mulitple places so we need to append the file every time we write to it. + For example Sec can use this to load the DXE core, and the DXE core would use this to load all the + other modules. So we have two instances of the library in the system. + + @param Buffer Buffer to write to file. + @param Length Length of Buffer in bytes. +**/ VOID -DeCygwinIfNeeded ( +WriteStringToFile ( + IN VOID *Buffer, + IN UINT32 Length + ) +{ + // Working around and issue with the code that is commented out. For now send it to the console. + // You can copy the console into a file and source the file as a script and you get symbols. + // This gets you all the symbols except for SEC. To get SEC symbols you need to copy the + // debug print in the SEC into the debugger manually + SemihostWriteString (Buffer); +/* + I'm currently having issues with this code crashing the debugger. Seems like it should work. + + UINT32 SemihostHandle; + UINT32 SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_CREATE; + + SemihostFileOpen ("c:\rvi_symbols.inc", SemihostMode, &SemihostHandle); + SemihostFileWrite (SemihostHandle, &Length, Buffer); + SemihostFileClose (SemihostHandle); + */ +} + + +/** + If the build is done on cygwin the paths are cygpaths. + /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert + them to work with RVD commands + + @param Name Path to convert if needed + +**/ +CHAR8 * +DeCygwinPathIfNeeded ( IN CHAR8 *Name ) { @@ -36,7 +75,7 @@ DeCygwinIfNeeded ( Ptr = AsciiStrStr (Name, "/cygdrive/"); if (Ptr == NULL) { - return; + return Name; } Len = AsciiStrLen (Ptr); @@ -56,6 +95,8 @@ DeCygwinIfNeeded ( Ptr[Index] = '\\' ; } } + + return Name; } @@ -77,9 +118,9 @@ PeCoffLoaderRelocateImageExtraAction ( CHAR8 Buffer[256]; AsciiSPrint (Buffer, sizeof(Buffer), "load /a /ni /np %a &0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)); - DeCygwinIfNeeded (&Buffer[16]); + DeCygwinPathIfNeeded (&Buffer[16]); - SerialPortWrite ((UINT8 *) Buffer, AsciiStrLen (Buffer)); + WriteStringToFile (Buffer, AsciiStrSize (Buffer)); } @@ -103,7 +144,7 @@ PeCoffLoaderUnloadImageExtraAction ( CHAR8 Buffer[256]; AsciiSPrint (Buffer, sizeof(Buffer), "unload symbols_only %a", ImageContext->PdbPointer); - DeCygwinIfNeeded (Buffer); + DeCygwinPathIfNeeded (Buffer); - SerialPortWrite ((UINT8 *) Buffer, AsciiStrLen (Buffer)); + WriteStringToFile (Buffer, AsciiStrSize (Buffer)); } diff --git a/ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.inf b/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf similarity index 74% rename from ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.inf rename to ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf index 947fcf4461..50eb57b2a9 100644 --- a/ArmPkg/Library/RviPeCoffExtraActionLib/RviPeCoffExtraActionLib.inf +++ b/ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf @@ -17,13 +17,11 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = RviUnixPeCoffExtraActionLib + BASE_NAME = RvdUnixPeCoffExtraActionLib FILE_GUID = 5EDEB7E7-EA55-4E92-8216-335AC98A3B11 - MODULE_TYPE = DXE_DRIVER + MODULE_TYPE = BASE VERSION_STRING = 1.0 - LIBRARY_CLASS = PeCoffExtraActionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER - EDK_RELEASE_VERSION = 0x00020000 - EFI_SPECIFICATION_VERSION = 0x00020000 + LIBRARY_CLASS = PeCoffExtraActionLib # # The following information is for reference only and not required by the build tools. @@ -32,7 +30,7 @@ # [Sources.common] - RviPeCoffExtraActionLib.c + RvdPeCoffExtraActionLib.c [Packages] MdePkg/MdePkg.dec @@ -40,6 +38,4 @@ [LibraryClasses] DebugLib - HobLib - BaseMemoryLib - SerialLib + SemihostLib diff --git a/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c b/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c index df43f31413..114dfe804d 100644 --- a/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c +++ b/ArmPkg/Library/SemiHostingSerialPortLib/SerialPortLib.c @@ -129,7 +129,7 @@ SerialPortRead ( Check to see if any data is avaiable to be read from the debug device. @retval TRUE At least one byte of data is avaiable to be read - @retval FALS No data is avaiable to be read + @retval FALSE No data is avaiable to be read **/ BOOLEAN diff --git a/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c b/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c index e1a515ef21..31efc0a16e 100644 --- a/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c +++ b/ArmPkg/Library/SemihostLib/Arm/SemihostLib.c @@ -36,8 +36,9 @@ SemihostFileOpen ( SEMIHOST_FILE_OPEN_BLOCK OpenBlock; INT32 Result; - if (FileHandle == NULL) + if (FileHandle == NULL) { return EFI_INVALID_PARAMETER; + } OpenBlock.FileName = FileName; OpenBlock.Mode = Mode; @@ -45,12 +46,9 @@ SemihostFileOpen ( Result = Semihost_SYS_OPEN(&OpenBlock); - if (Result == -1) - { + if (Result == -1) { return EFI_NOT_FOUND; - } - else - { + } else { *FileHandle = Result; return EFI_SUCCESS; } @@ -70,10 +68,11 @@ SemihostFileSeek ( Result = Semihost_SYS_SEEK(&SeekBlock); - if (Result == 0) + if (Result == 0) { return EFI_SUCCESS; - else + } else { return EFI_ABORTED; + } } EFI_STATUS @@ -86,8 +85,9 @@ SemihostFileRead ( SEMIHOST_FILE_READ_WRITE_BLOCK ReadBlock; UINT32 Result; - if ((Length == NULL) || (Buffer == NULL)) - return EFI_INVALID_PARAMETER; + if ((Length == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } ReadBlock.Handle = FileHandle; ReadBlock.Buffer = Buffer; @@ -95,12 +95,9 @@ SemihostFileRead ( Result = Semihost_SYS_READ(&ReadBlock); - if (Result == *Length) - { + if (Result == *Length) { return EFI_ABORTED; - } - else - { + } else { *Length -= Result; return EFI_SUCCESS; } @@ -115,8 +112,9 @@ SemihostFileWrite ( { SEMIHOST_FILE_READ_WRITE_BLOCK WriteBlock; - if ((Length == NULL) || (Buffer == NULL)) + if ((Length == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; + } WriteBlock.Handle = FileHandle; WriteBlock.Buffer = Buffer; @@ -134,10 +132,11 @@ SemihostFileClose ( { INT32 Result = Semihost_SYS_CLOSE(&FileHandle); - if (Result == -1) + if (Result == -1) { return EFI_INVALID_PARAMETER; - else + } else { return EFI_SUCCESS; + } } EFI_STATUS @@ -148,17 +147,15 @@ SemihostFileLength ( { INT32 Result; - if (Length == NULL) + if (Length == NULL) { return EFI_INVALID_PARAMETER; + } Result = Semihost_SYS_FLEN(&FileHandle); - if (Result == -1) - { + if (Result == -1) { return EFI_ABORTED; - } - else - { + } else { *Length = Result; return EFI_SUCCESS; } @@ -177,10 +174,11 @@ SemihostFileRemove ( Result = Semihost_SYS_REMOVE(&RemoveBlock); - if (Result == 0) + if (Result == 0) { return EFI_SUCCESS; - else + } else { return EFI_ABORTED; + } } CHAR8 diff --git a/ArmPkg/Library/SemihostLib/SemihostLib.inf b/ArmPkg/Library/SemihostLib/SemihostLib.inf index d05188c771..c4b5c682d0 100644 --- a/ArmPkg/Library/SemihostLib/SemihostLib.inf +++ b/ArmPkg/Library/SemihostLib/SemihostLib.inf @@ -1,5 +1,5 @@ #/** @file -# Semihosting serail port lib +# Semihosting JTAG lib # # Copyright (c) 2008 - 2010, Apple Inc. # @@ -17,7 +17,7 @@ INF_VERSION = 0x00010005 BASE_NAME = SemihostLib FILE_GUID = C40D08BA-DB7B-4F07-905A-C5FE4B5AF987 - MODULE_TYPE = UEFI_DRIVER + MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = SemihostLib diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc index 928224b101..bed07533e3 100644 --- a/BeagleBoardPkg/BeagleBoardPkg.dsc +++ b/BeagleBoardPkg/BeagleBoardPkg.dsc @@ -59,7 +59,17 @@ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + + # + # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window + # in the debugger will show load and unload commands for symbols. You can cut and paste this + # into the command window to load symbols. We should be able to use a script to do this, but + # the version of RVD I have does not support scipts accessing system memory. + # +# PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + + CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf diff --git a/BeagleBoardPkg/Sec/Sec.c b/BeagleBoardPkg/Sec/Sec.c index 321b35940c..5b4d2946db 100755 --- a/BeagleBoardPkg/Sec/Sec.c +++ b/BeagleBoardPkg/Sec/Sec.c @@ -21,11 +21,23 @@ #include #include #include +#include #include #include +VOID +EFIAPI +_ModuleEntryPoint( + VOID + ); + +CHAR8 * +DeCygwinPathIfNeeded ( + IN CHAR8 *Name + ); + VOID PadConfiguration ( VOID @@ -113,6 +125,53 @@ LzmaDecompressLibConstructor ( VOID ); +/** + If the build is done on cygwin the paths are cygpaths. + /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert + them to work with RVD commands + + This is just code to help print out RVD symbol load command. + If you build with cygwin paths aren't compatible with RVD. + + @param Name Path to convert if needed + +**/ +CHAR8 * +SecDeCygwinPathIfNeeded ( + IN CHAR8 *Name + ) +{ + CHAR8 *Ptr; + UINTN Index; + UINTN Len; + + Ptr = AsciiStrStr (Name, "/cygdrive/"); + if (Ptr == NULL) { + return Name; + } + + Len = AsciiStrLen (Ptr); + + // convert "/cygdrive" to spaces + for (Index = 0; Index < 9; Index++) { + Ptr[Index] = ' '; + } + + // convert /c to c: + Ptr[9] = Ptr[10]; + Ptr[10] = ':'; + + // switch path seperators + for (Index = 11; Index < Len; Index++) { + if (Ptr[Index] == '/') { + Ptr[Index] = '\\' ; + } + } + + return Name; +} + + VOID CEntryPoint ( IN VOID *MemoryBase, @@ -147,7 +206,52 @@ CEntryPoint ( // Start talking UartInit(); - DEBUG((EFI_D_ERROR, "UART Test Line\n")); + DEBUG((EFI_D_ERROR, "UART Enabled\n")); + + DEBUG_CODE_BEGIN (); + // + // On a debug build print out information about the SEC. This is really info about + // the PE/COFF file we are currently running from. Useful for loading symbols in a + // debugger. Remember our image is really part of the FV. + // + RETURN_STATUS Status; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PeCoffImage; + UINT32 Offset; + CHAR8 *FilePath; + + FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_SECURITY_CORE, &VolumeHandle, &FileHandle); + Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &PeCoffImage); + if (EFI_ERROR (Status)) { + // Usually is a TE (PI striped down PE/COFF), but could be a full PE/COFF + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); + } + if (!EFI_ERROR (Status)) { + Offset = PeCoffGetSizeOfHeaders (PeCoffImage); + FilePath = PeCoffLoaderGetPdbPointer (PeCoffImage); + if (FilePath != NULL) { + + // + // In general you should never have to use #ifdef __CC_ARM in the code. It + // is hidden in the away in the MdePkg. But here we would like to print differnt things + // for different toolchains. + // +#ifdef __CC_ARM + // Print out the command for the RVD debugger to load symbols for this image + DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", SecDeCygwinPathIfNeeded (FilePath), PeCoffImage + Offset)); +#elif __GNUC__ + // This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required + DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", FilePath, PeCoffImage + Offset)); +#else + DEBUG ((EFI_D_ERROR, "SEC starts at 0x%08x with an entry point at 0x%08x %a\n", PeCoffImage, _ModuleEntryPoint, FilePath)); +#endif + } + } + + DEBUG_CODE_END (); + + // Start up a free running time so that the timer lib will work TimerInit(); diff --git a/BeagleBoardPkg/Sec/Sec.inf b/BeagleBoardPkg/Sec/Sec.inf index ba4c9048d2..79a5eb4b10 100755 --- a/BeagleBoardPkg/Sec/Sec.inf +++ b/BeagleBoardPkg/Sec/Sec.inf @@ -46,6 +46,7 @@ ExtractGuidedSectionLib LzmaDecompressLib OmapLib + PeCoffGetEntryPointLib [FeaturePcd] gEmbeddedTokenSpaceGuid.PcdCacheEnable diff --git a/MdePkg/Include/Library/PeCoffGetEntryPointLib.h b/MdePkg/Include/Library/PeCoffGetEntryPointLib.h index 237f65cb2e..fe7a6b8e5d 100644 --- a/MdePkg/Include/Library/PeCoffGetEntryPointLib.h +++ b/MdePkg/Include/Library/PeCoffGetEntryPointLib.h @@ -82,4 +82,23 @@ PeCoffLoaderGetPdbPointer ( IN VOID *Pe32Data ); + +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid iamge. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ); + #endif diff --git a/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c index d91f058416..347ff92511 100644 --- a/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c +++ b/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c @@ -268,4 +268,49 @@ PeCoffLoaderGetPdbPointer ( return NULL; } +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid iamge. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } + + return SizeOfHeaders; +} diff --git a/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c index 648c2a08ea..b22bed4d33 100644 --- a/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c +++ b/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c @@ -273,3 +273,50 @@ PeCoffLoaderGetPdbPointer ( return NULL; } + +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid iamge. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } + + return SizeOfHeaders; +} + diff --git a/UnixPkg/Library/EdkUnixPeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/UnixPkg/Library/EdkUnixPeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c index ef0d6c17cb..fb7c15687b 100644 --- a/UnixPkg/Library/EdkUnixPeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c +++ b/UnixPkg/Library/EdkUnixPeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c @@ -253,3 +253,51 @@ PeCoffLoaderGetPdbPointer ( return NULL; } + + +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid iamge. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } + + return SizeOfHeaders; +} +