#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
- (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
*(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
\r
\r
VOID\r
-WriteRelocations(\r
+WriteRelocations (\r
VOID\r
)\r
{\r
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
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
case DT_RELENT:\r
RelElementSize = Dyn->d_un.d_val;\r
break;\r
+\r
+ default:\r
+ break;\r
}\r
Dyn++;\r
}\r
\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
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
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
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
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
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
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
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