]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/BasePeCoff.c
Sync EDKII BaseTools to BaseTools project r1988
[mirror_edk2.git] / BaseTools / Source / C / Common / BasePeCoff.c
index 72b6a52f890c162744b9f4bbbaf527598774c083..4a3f92fb159d0ea7be97cd3d5fa1afba5408215c 100644 (file)
@@ -2,8 +2,8 @@
 \r
   Functions to get info and load PE/COFF image.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+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
@@ -71,6 +71,14 @@ PeCoffLoaderRelocateIpfImage (
   IN UINT64      Adjust\r
   );\r
 \r
+RETURN_STATUS\r
+PeCoffLoaderRelocateArmImage (\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
@@ -621,15 +629,10 @@ Returns:
   }\r
 \r
   //\r
-  // If the destination address is not 0, use that rather than the\r
-  // image address as the relocation target.\r
+  // Use DestinationAddress field of ImageContext as the relocation address even if it is 0.\r
   //\r
-  if (ImageContext->DestinationAddress) {\r
-    BaseAddress = ImageContext->DestinationAddress;\r
-  } else {\r
-    BaseAddress = ImageContext->ImageAddress;\r
-  }\r
-\r
+  BaseAddress = ImageContext->DestinationAddress;\r
+  \r
   if (!(ImageContext->IsTeImage)) {\r
     PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress + \r
                                             ImageContext->PeCoffHeaderOffset);\r
@@ -777,9 +780,11 @@ Returns:
       default:\r
         switch (MachineType) {\r
         case EFI_IMAGE_MACHINE_IA32:\r
-        case EFI_IMAGE_MACHINE_ARMT:\r
           Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust);\r
           break;\r
+        case EFI_IMAGE_MACHINE_ARMT:\r
+          Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);\r
+          break;\r
         case EFI_IMAGE_MACHINE_X64:\r
           Status = PeCoffLoaderRelocateX64Image (Reloc, Fixup, &FixupData, Adjust);\r
           break;\r
@@ -856,6 +861,7 @@ Returns:
 \r
   PeHdr = NULL;\r
   TeHdr = NULL;\r
+  OptionHeader.Header = NULL;\r
   //\r
   // Assume success\r
   //\r
@@ -1172,6 +1178,9 @@ Returns:
           ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
           break;\r
 \r
+        case CODEVIEW_SIGNATURE_MTOC:\r
+          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);\r
+\r
         default:\r
           break;\r
         }\r
@@ -1252,11 +1261,11 @@ PeCoffLoaderGetPdbPointer (
       //\r
       // Get the DebugEntry offset in the raw data image.\r
       //\r
-           SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1);\r
-           Index = Hdr.Te->NumberOfSections;\r
+      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1);\r
+      Index = Hdr.Te->NumberOfSections;\r
       for (Index1 = 0; Index1 < Index; Index1 ++) {\r
-       if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && \r
-                (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
+        if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && \r
+           (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
           DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +\r
                         DirectoryEntry->VirtualAddress - \r
                         SectionHeader [Index1].VirtualAddress + \r
@@ -1324,8 +1333,8 @@ PeCoffLoaderGetPdbPointer (
       // Get the DebugEntry offset in the raw data image.\r
       //\r
       for (Index1 = 0; Index1 < Index; Index1 ++) {\r
-       if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && \r
-                (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
+        if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && \r
+           (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
           DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (\r
                        (UINTN) Pe32Data + \r
                        DirectoryEntry->VirtualAddress - \r
@@ -1349,32 +1358,35 @@ PeCoffLoaderGetPdbPointer (
   for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
     if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) {\r
       if (DebugEntry->SizeOfData > 0) {\r
-             //\r
-             // Get the DebugEntry offset in the raw data image.\r
-             //\r
-             for (Index1 = 0; Index1 < Index; Index1 ++) {\r
-               if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) && \r
-                        (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
-                 CodeViewEntryPointer = (VOID *) (\r
-                                        ((UINTN)Pe32Data) + \r
-                                        (UINTN) DebugEntry->RVA - \r
-                                        SectionHeader[Index1].VirtualAddress + \r
-                                        SectionHeader[Index1].PointerToRawData + \r
-                                        (UINTN)TEImageAdjust);\r
-                 break;\r
-               }\r
-             }\r
-             if (Index1 >= Index) {\r
-               //\r
-               // Can't find CodeViewEntryPointer in raw PE/COFF image.\r
-               //\r
-               continue;\r
-             }\r
+        //\r
+        // Get the DebugEntry offset in the raw data image.\r
+        //\r
+        CodeViewEntryPointer = NULL;\r
+        for (Index1 = 0; Index1 < Index; Index1 ++) {\r
+          if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) && \r
+             (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {\r
+            CodeViewEntryPointer = (VOID *) (\r
+                                   ((UINTN)Pe32Data) + \r
+                                   (UINTN) DebugEntry->RVA - \r
+                                   SectionHeader[Index1].VirtualAddress + \r
+                                   SectionHeader[Index1].PointerToRawData + \r
+                                   (UINTN)TEImageAdjust);\r
+            break;\r
+          }\r
+        }\r
+        if (Index1 >= Index) {\r
+          //\r
+          // Can't find CodeViewEntryPointer in raw PE/COFF image.\r
+          //\r
+          continue;\r
+        }\r
         switch (* (UINT32 *) CodeViewEntryPointer) {\r
         case CODEVIEW_SIGNATURE_NB10:\r
           return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));\r
         case CODEVIEW_SIGNATURE_RSDS:\r
           return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));\r
+        case CODEVIEW_SIGNATURE_MTOC:\r
+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));\r
         default:\r
           break;\r
         }\r
@@ -1384,3 +1396,50 @@ PeCoffLoaderGetPdbPointer (
 \r
   return NULL;\r
 }\r
+\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderGetEntryPoint (\r
+  IN  VOID  *Pe32Data,\r
+  OUT VOID  **EntryPoint,\r
+  OUT VOID  **BaseOfImage\r
+  )\r
+{\r
+  EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
+\r
+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\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
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+  } else {\r
+    //\r
+    // DOS image header is not present, so PE header is at the image base.\r
+    //\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+  }\r
+\r
+  //\r
+  // Calculate the entry point relative to the start of the image.\r
+  // AddressOfEntryPoint is common for PE32 & PE32+\r
+  //\r
+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+    *BaseOfImage = (VOID *)(UINTN)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
+    *EntryPoint = (VOID *)((UINTN)*BaseOfImage + (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);\r
+    return RETURN_SUCCESS;\r
+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+    *EntryPoint = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint;\r
+    if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+      *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.ImageBase;\r
+    } else {\r
+      *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
+    }\r
+    *EntryPoint = (VOID *)(UINTN)((UINTN)*EntryPoint + (UINTN)*BaseOfImage);\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  return RETURN_UNSUPPORTED;\r
+}\r