]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
Sync EDKII BaseTools to BaseTools project r1928
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index d42c88e23d9f193baef5e6b7d3871b4d8406016b..4d6081478079c8261cdeade83eeae31fd2781fd2 100644 (file)
@@ -24,6 +24,8 @@ Abstract:
 #ifndef __GNUC__\r
 #include <windows.h>\r
 #include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
 #endif\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -1034,14 +1036,20 @@ WriteSections(
               - (SecOffset - SecShdr->sh_addr);\r
             break;\r
           default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
+            Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
           }\r
         } else if (Ehdr->e_machine == EM_ARM) {\r
           switch (ELF32_R_TYPE(Rel->r_info)) {\r
           case R_ARM_RBASE:   // No relocation - no action required\r
-          case R_ARM_PC24:    // PC-relative relocations don't require modification\r
-          case R_ARM_XPC25:   // PC-relative relocations don't require modification\r
+          \r
+          // Thease are all PC-relative relocations and don't require modification\r
+          case R_ARM_PC24:    \r
+          case R_ARM_XPC25:   \r
+          case R_ARM_THM_PC22:\r
+          case R_ARM_THM_JUMP19:\r
+          case R_ARM_CALL:\r
             break;\r
+\r
           case R_ARM_ABS32:\r
           case R_ARM_RABS32:\r
             //\r
@@ -1050,7 +1058,7 @@ WriteSections(
             *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + CoffSectionsOffset[Sym->st_shndx];\r
             break;\r
           default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
+            Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
           }\r
         }\r
       }\r
@@ -1124,7 +1132,7 @@ GetPhdrByIndex (
 \r
 \r
 VOID\r
-WriteRelocations(\r
+WriteRelocations (\r
   VOID\r
   )\r
 {\r
@@ -1164,13 +1172,18 @@ WriteRelocations(
               EFI_IMAGE_REL_BASED_HIGHLOW);\r
               break;\r
             default:\r
-              Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
+              Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
             }\r
           } else if (Ehdr->e_machine == EM_ARM) {\r
             switch (ELF32_R_TYPE(Rel->r_info)) {\r
-            case R_ARM_RBASE:\r
+            case R_ARM_RBASE: // No relocation - no action required\r
+          \r
+            // Thease are all PC-relative relocations and don't require modification\r
             case R_ARM_PC24:\r
             case R_ARM_XPC25:\r
+            case R_ARM_THM_PC22:\r
+            case R_ARM_THM_JUMP19:\r
+            case R_ARM_CALL:\r
               break;\r
             case R_ARM_ABS32:\r
             case R_ARM_RABS32:\r
@@ -1180,8 +1193,9 @@ WriteRelocations(
                 EFI_IMAGE_REL_BASED_HIGHLOW\r
                 );\r
               break;\r
-            default:\r
-              Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
+\r
+           default:\r
+              Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
             }\r
           } else {\r
             Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) Ehdr->e_machine);\r
@@ -1217,6 +1231,9 @@ WriteRelocations(
             case  DT_RELENT:\r
               RelElementSize = Dyn->d_un.d_val;\r
               break;\r
+\r
+            default:\r
+              break;\r
           }\r
           Dyn++;\r
         }\r
@@ -1226,7 +1243,13 @@ WriteRelocations(
 \r
         for (K = 0; K < RelSize; K += RelElementSize) {\r
 \r
-          Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + DynamicSegment->p_offset + RelOffset + K);\r
+          if (DynamicSegment->p_paddr == 0) {\r
+            // This seems to be how it works on armcc???? Have the email in to find out?\r
+            Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + DynamicSegment->p_offset + RelOffset + K);\r
+          } else {\r
+            // This is how it reads in the ELF specification\r
+            Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + RelOffset + K);\r
+          }\r
 \r
           switch (ELF32_R_TYPE (Rel->r_info)) {\r
           case  R_ARM_RBASE:\r
@@ -1242,7 +1265,8 @@ WriteRelocations(
             CoffAddFixup (CoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW);\r
             break;\r
           default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type.", mInImageName);\r
+            Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info));\r
+            break;\r
           }\r
         }\r
         break;\r
@@ -1993,6 +2017,9 @@ Returns:
   FILE                             *ReportFile;\r
   CHAR8                            *ReportFileName;\r
   UINTN                            FileLen;\r
+  time_t                           InputFileTime;\r
+  time_t                           OutputFileTime;\r
+  struct stat                      Stat_Buf;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -2038,6 +2065,8 @@ Returns:
   HiiSectionHeader       = NULL;\r
   NewBaseAddress         = 0;\r
   NegativeAddr           = FALSE;\r
+  InputFileTime          = 0;\r
+  OutputFileTime         = 0;\r
 \r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No input options.");\r
@@ -2434,6 +2463,14 @@ Returns:
   if (OutImageName != NULL) {\r
     fpOut = fopen (OutImageName, "rb");\r
     if (fpOut != NULL) {\r
+      //\r
+      // Get Output file time stamp\r
+      //\r
+      fstat(fileno (fpOut), &Stat_Buf);\r
+      OutputFileTime = Stat_Buf.st_mtime;\r
+      //\r
+      // Get Output file data\r
+      //\r
       OutputFileLength = _filelength (fileno (fpOut));\r
       OutputFileBuffer = malloc (OutputFileLength);\r
       if (OutputFileBuffer == NULL) {\r
@@ -2460,6 +2497,14 @@ Returns:
     Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
     goto Finish;\r
   }\r
+  //\r
+  // Get Iutput file time stamp\r
+  //\r
+  fstat(fileno (fpIn), &Stat_Buf);\r
+  InputFileTime = Stat_Buf.st_mtime;\r
+  //\r
+  // Get Input file data\r
+  //\r
   InputFileLength = _filelength (fileno (fpIn));\r
   InputFileBuffer = malloc (InputFileLength);\r
   if (InputFileBuffer == NULL) {\r
@@ -3467,6 +3512,27 @@ Returns:
     FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);\r
     memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));\r
     VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));\r
+  } else {\r
+\r
+    //\r
+    // Following codes are to fix the objcopy's issue:\r
+    // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section\r
+    // It cause issue for EFI image which has no ".reloc" sections.\r
+    // Following codes will be removed when objcopy in binutil fix this problem for PE image.\r
+    //\r
+    if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {\r
+      if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+        if (Optional32->ImageBase == 0) {\r
+          PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+        }\r
+      } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+        Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+        if (Optional64->ImageBase == 0) {\r
+          PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+        }\r
+      }\r
+    }\r
   }\r
 \r
 WriteFile:\r
@@ -3487,7 +3553,10 @@ WriteFile:
       VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
     }\r
   } else {\r
-    if ((FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
+    if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
+      //\r
+      // Update File when File is changed or File is old.\r
+      //\r
       fpOut = fopen (OutImageName, "wb");\r
       if (fpOut == NULL) {\r
         Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r