-VOID\r
-ScanSections(\r
- VOID\r
- )\r
-{\r
- UINT32 i;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- UINT32 CoffEntry;\r
-\r
- CoffEntry = 0;\r
- CoffOffset = 0;\r
-\r
- //\r
- // Coff file start with a DOS header.\r
- //\r
- CoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;\r
- NtHdrOffset = CoffOffset;\r
- switch (Ehdr->e_machine) {\r
- case EM_386:\r
- case EM_ARM:\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
- break;\r
- case EM_X86_64:\r
- case EM_IA_64:\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
- break;\r
- default:\r
- VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
- break;\r
- }\r
-\r
- TableOffset = CoffOffset;\r
- CoffOffset += CoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);\r
-\r
- //\r
- // First text sections.\r
- //\r
- CoffOffset = CoffAlign(CoffOffset);\r
- TextOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsTextShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- \r
- /* Relocate entry. */\r
- if ((Ehdr->e_entry >= shdr->sh_addr) &&\r
- (Ehdr->e_entry < shdr->sh_addr + shdr->sh_size)) {\r
- CoffEntry = CoffOffset + Ehdr->e_entry - shdr->sh_addr;\r
- }\r
- CoffSectionsOffset[i] = CoffOffset;\r
- CoffOffset += shdr->sh_size;\r
- }\r
- }\r
-\r
- if (Ehdr->e_machine != EM_ARM) {\r
- CoffOffset = CoffAlign(CoffOffset);\r
- }\r
-\r
- //\r
- // Then data sections.\r
- //\r
- DataOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsDataShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- CoffSectionsOffset[i] = CoffOffset;\r
- CoffOffset += shdr->sh_size;\r
- }\r
- }\r
- CoffOffset = CoffAlign(CoffOffset);\r
-\r
- //\r
- // The HII resource sections.\r
- //\r
- HiiRsrcOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsHiiRsrcShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- if (shdr->sh_size != 0) {\r
- CoffSectionsOffset[i] = CoffOffset;\r
- CoffOffset += shdr->sh_size;\r
- CoffOffset = CoffAlign(CoffOffset);\r
- SetHiiResourceHeader ((UINT8*) Ehdr + shdr->sh_offset, HiiRsrcOffset);\r
- }\r
- break;\r
- }\r
- }\r
-\r
- RelocOffset = CoffOffset;\r
-\r
- //\r
- // Allocate base Coff file. Will be expanded later for relocations.\r
- //\r
- CoffFile = (UINT8 *)malloc(CoffOffset);\r
- memset(CoffFile, 0, CoffOffset);\r
-\r
- //\r
- // Fill headers.\r
- //\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *)CoffFile;\r
- DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
- DosHdr->e_lfanew = NtHdrOffset;\r
-\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(CoffFile + NtHdrOffset);\r
-\r
- NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;\r
-\r
- switch (Ehdr->e_machine) {\r
- case EM_386:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- break;\r
- case EM_X86_64:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- break;\r
- case EM_IA_64:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- break;\r
- case EM_ARM:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- break;\r
- default:\r
- VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- }\r
-\r
- NtHdr->Pe32.FileHeader.NumberOfSections = CoffNbrSections;\r
- NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);\r
- NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;\r
- NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);\r
- NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE\r
- | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED\r
- | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED\r
- | EFI_IMAGE_FILE_32BIT_MACHINE;\r
-\r
- NtHdr->Pe32.OptionalHeader.SizeOfCode = DataOffset - TextOffset;\r
- NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = RelocOffset - DataOffset;\r
- NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0;\r
- NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
-\r
- NtHdr->Pe32.OptionalHeader.BaseOfCode = TextOffset;\r
-\r
- NtHdr->Pe32.OptionalHeader.BaseOfData = DataOffset;\r
- NtHdr->Pe32.OptionalHeader.ImageBase = 0;\r
- NtHdr->Pe32.OptionalHeader.SectionAlignment = CoffAlignment;\r
- NtHdr->Pe32.OptionalHeader.FileAlignment = CoffAlignment;\r
- NtHdr->Pe32.OptionalHeader.SizeOfImage = 0;\r
-\r
- NtHdr->Pe32.OptionalHeader.SizeOfHeaders = TextOffset;\r
- NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
-\r
- //\r
- // Section headers.\r
- //\r
- if ((DataOffset - TextOffset) > 0) {\r
- CreateSectionHeader (".text", TextOffset, DataOffset - TextOffset,\r
- EFI_IMAGE_SCN_CNT_CODE\r
- | EFI_IMAGE_SCN_MEM_EXECUTE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- }\r
-\r
- if ((HiiRsrcOffset - DataOffset) > 0) {\r
- CreateSectionHeader (".data", DataOffset, HiiRsrcOffset - DataOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_WRITE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- }\r
-\r
- if ((RelocOffset - HiiRsrcOffset) > 0) {\r
- CreateSectionHeader (".rsrc", HiiRsrcOffset, RelocOffset - HiiRsrcOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_READ);\r
-\r
- NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = RelocOffset - HiiRsrcOffset;\r
- NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = HiiRsrcOffset;\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- }\r
-\r
-}\r
-\r
-VOID\r
-WriteSections(\r
- int (*Filter)(Elf_Shdr *)\r
- )\r
-{\r
- UINT32 Idx;\r
- Elf_Shdr *SecShdr;\r
- UINT32 SecOffset;\r
-\r
- //\r
- // First: copy sections.\r
- //\r
- for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
- Elf_Shdr *Shdr = GetShdrByIndex(Idx);\r
- if ((*Filter)(Shdr)) {\r
- switch (Shdr->sh_type) {\r
- case SHT_PROGBITS:\r
- /* Copy. */\r
- memcpy(CoffFile + CoffSectionsOffset[Idx],\r
- (UINT8*)Ehdr + Shdr->sh_offset,\r
- Shdr->sh_size);\r
- break;\r
- \r
- case SHT_NOBITS:\r
- memset(CoffFile + CoffSectionsOffset[Idx], 0, Shdr->sh_size);\r
- break;\r
- \r
- default:\r
- //\r
- // Ignore for unkown section type.\r
- //\r
- VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type);\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Second: apply relocations.\r
- //\r
- for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
- Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\r
- if (RelShdr->sh_type != SHT_REL)\r
- continue;\r
- SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
- SecOffset = CoffSectionsOffset[RelShdr->sh_info];\r
- if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {\r
- UINT32 RelIdx;\r
- Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);\r
- UINT8 *Symtab = (UINT8*)Ehdr + SymtabShdr->sh_offset;\r
-\r
- for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
- Elf_Rel *Rel = (Elf_Rel *)((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
- Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
- Elf_Shdr *SymShdr;\r
- UINT8 *Targ;\r
-\r
- if (Sym->st_shndx == SHN_UNDEF\r
- || Sym->st_shndx == SHN_ABS\r
- || Sym->st_shndx > Ehdr->e_shnum) {\r
- Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName);\r
- }\r
- SymShdr = GetShdrByIndex(Sym->st_shndx);\r
-\r
- //\r
- // Note: r_offset in a memory address.\r
- // Convert it to a pointer in the coff file.\r
- //\r
- Targ = CoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);\r
-\r
- if (Ehdr->e_machine == EM_386) {\r
- switch (ELF_R_TYPE(Rel->r_info)) {\r
- case R_386_NONE:\r
- break;\r
- case R_386_32:\r
- //\r
- // Absolute relocation.\r
- //\r
- *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr\r
- + CoffSectionsOffset[Sym->st_shndx];\r
- break;\r
- case R_386_PC32:\r
- //\r
- // Relative relocation: Symbol - Ip + Addend\r
- //\r
- *(UINT32 *)Targ = *(UINT32 *)Targ\r
- + (CoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)\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
- }\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
- break;\r
- case R_ARM_ABS32:\r
- case R_ARM_RABS32:\r
- //\r
- // Absolute relocation.\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
- }\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-VOID\r
-CoffAddFixupEntry(\r
- UINT16 Val\r
- )\r
-{\r
- *CoffEntryRel = Val;\r
- CoffEntryRel++;\r
- CoffBaseRel->SizeOfBlock += 2;\r
- CoffOffset += 2;\r
-}\r
-\r
-VOID\r
-CoffAddFixup(\r
- UINT32 Offset,\r
- UINT8 Type\r
- )\r
-{\r
- if (CoffBaseRel == NULL\r
- || CoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {\r
- if (CoffBaseRel != NULL) {\r
- //\r
- // Add a null entry (is it required ?)\r
- //\r
- CoffAddFixupEntry (0);\r
- //\r
- // Pad for alignment.\r
- //\r
- if (CoffOffset % 4 != 0)\r
- CoffAddFixupEntry (0);\r
- }\r
-\r
- CoffFile = realloc\r
- (CoffFile,\r
- CoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
- memset(CoffFile + CoffOffset, 0,\r
- sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
-\r
- CoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(CoffFile + CoffOffset);\r
- CoffBaseRel->VirtualAddress = Offset & ~0xfff;\r
- CoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);\r
-\r
- CoffEntryRel = (UINT16 *)(CoffBaseRel + 1);\r
- CoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);\r
- }\r
-\r
- //\r
- // Fill the entry.\r
- //\r
- CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));\r
-}\r
-\r
-\r
-Elf_Phdr *\r
-GetPhdrByIndex (\r
- UINT32 num\r
- )\r
-{\r
- if (num >= Ehdr->e_phnum) {\r
- return NULL;\r
- }\r
- \r
- return (Elf32_Phdr *)((UINT8*)gPhdrBase + num * Ehdr->e_phentsize);\r
-}\r
-\r
-\r
-VOID\r
-WriteRelocations(\r
- VOID\r
- )\r
-{\r
- UINT32 Index;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *Dir;\r
- BOOLEAN FoundRelocations;\r
- Elf_Dyn *Dyn;\r
- Elf_Rel *Rel;\r
- UINTN RelElementSize;\r
- UINTN RelSize;\r
- UINTN RelOffset;\r
- UINTN K;\r
- UINT8 *Targ;\r
- Elf32_Phdr *DynamicSegment;\r
- Elf32_Phdr *TargetSegment;\r
-\r
- for (Index = 0, FoundRelocations = FALSE; Index < Ehdr->e_shnum; Index++) {\r
- Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
- if (RelShdr->sh_type == SHT_REL) {\r
- Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
- if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {\r
- UINT32 RelIdx;\r
- FoundRelocations = TRUE;\r
- for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
- Elf_Rel *Rel = (Elf_Rel *)\r
- ((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
- \r
- if (Ehdr->e_machine == EM_386) { \r
- switch (ELF_R_TYPE(Rel->r_info)) {\r
- case R_386_NONE:\r
- case R_386_PC32:\r
- break;\r
- case R_386_32:\r
- CoffAddFixup(CoffSectionsOffset[RelShdr->sh_info]\r
- + (Rel->r_offset - SecShdr->sh_addr),\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
- }\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_PC24:\r
- case R_ARM_XPC25:\r
- break;\r
- case R_ARM_ABS32:\r
- case R_ARM_RABS32:\r
- CoffAddFixup (\r
- CoffSectionsOffset[RelShdr->sh_info]\r
- + (Rel->r_offset - SecShdr->sh_addr),\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
- } 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
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (!FoundRelocations && (Ehdr->e_machine == EM_ARM)) {\r
- /* Try again, but look for PT_DYNAMIC instead of SHT_REL */\r
-\r
- for (Index = 0; Index < Ehdr->e_phnum; Index++) {\r
- RelElementSize = 0;\r
- RelSize = 0;\r
- RelOffset = 0;\r
-\r
- DynamicSegment = GetPhdrByIndex (Index);\r
-\r
- if (DynamicSegment->p_type == PT_DYNAMIC) {\r
- Dyn = (Elf32_Dyn *) ((UINT8 *)Ehdr + DynamicSegment->p_offset);\r
-\r
- while (Dyn->d_tag != DT_NULL) {\r
- switch (Dyn->d_tag) {\r
- case DT_REL:\r
- RelOffset = Dyn->d_un.d_val;\r
- break;\r
-\r
- case DT_RELSZ:\r
- RelSize = Dyn->d_un.d_val;\r
- break;\r
-\r
- case DT_RELENT:\r
- RelElementSize = Dyn->d_un.d_val;\r
- break;\r
- }\r
- Dyn++;\r
- }\r
- if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) {\r
- Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName);\r
- }\r
-\r
- for (K = 0; K < RelSize; K += RelElementSize) {\r
-\r
- Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + DynamicSegment->p_offset + RelOffset + K);\r
-\r
- switch (ELF32_R_TYPE (Rel->r_info)) {\r
- case R_ARM_RBASE:\r
- break;\r
- case R_ARM_RABS32:\r
- TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1);\r
-\r
- // Note: r_offset in a memory address. Convert it to a pointer in the coff file.\r
- Targ = CoffFile + CoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr;\r
-\r
- *(UINT32 *)Targ = *(UINT32 *)Targ + CoffSectionsOffset [ELF32_R_SYM( Rel->r_info )];\r
-\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
- }\r
- }\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Pad by adding empty entries.\r
- //\r
- while (CoffOffset & (CoffAlignment - 1)) {\r
- CoffAddFixupEntry(0);\r
- }\r
-\r
-\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
- Dir->Size = CoffOffset - RelocOffset;\r
- if (Dir->Size == 0) {\r
- // If no relocations, null out the directory entry and don't add the .reloc section\r
- Dir->VirtualAddress = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- } else {\r
- Dir->VirtualAddress = RelocOffset;\r
- CreateSectionHeader (".reloc", RelocOffset, CoffOffset - RelocOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- }\r
-\r
-}\r
-\r
-VOID\r
-WriteDebug(\r
- VOID\r
- )\r
-{\r
- UINT32 Len;\r
- UINT32 DebugOffset;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *DataDir;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
- EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
-\r
- Len = strlen(mInImageName) + 1;\r
- DebugOffset = CoffOffset;\r
-\r
- CoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
- + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
- + Len;\r
- CoffOffset = CoffAlign(CoffOffset);\r
-\r
- CoffFile = realloc(CoffFile, CoffOffset);\r
- memset(CoffFile + DebugOffset, 0, CoffOffset - DebugOffset);\r
-\r
- Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(CoffFile + DebugOffset);\r
- Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
- Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
- Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
- Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-\r
- Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
- Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
- strcpy ((char *)(Nb10 + 1), mInImageName);\r
-\r
-\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
- DataDir->VirtualAddress = DebugOffset;\r
- DataDir->Size = CoffOffset - DebugOffset;\r
- if (DataDir->Size == 0) {\r
- // If no debug, null out the directory entry and don't add the .debug section\r
- DataDir->VirtualAddress = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- } else {\r
- DataDir->VirtualAddress = DebugOffset;\r
- CreateSectionHeader (".debug", DebugOffset, CoffOffset - DebugOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
-\r
- }\r
-}\r
-\r
-VOID\r
-ConvertElf (\r
- UINT8 **FileBuffer,\r
- UINT32 *FileLength\r
- )\r
-{\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
-\r
- //\r
- // Check header, read section table.\r
- //\r
- Ehdr = (Elf32_Ehdr*)*FileBuffer;\r
- if (!CheckElfHeader())\r
- return;\r
-\r
- VerboseMsg ("Check Efl Image Header");\r
- //\r
- // Compute sections new address.\r
- //\r
- \r
- ScanSections();\r
-\r
- VerboseMsg ("Compute sections new address.");\r
-\r
- //\r
- // Write and relocate sections.\r
- //\r
- WriteSections(IsTextShdr);\r
- WriteSections(IsDataShdr);\r
- WriteSections(IsHiiRsrcShdr);\r
- VerboseMsg ("Write and relocate sections.");\r
-\r
- //\r
- // Translate and write relocations.\r
- //\r
- WriteRelocations();\r
- VerboseMsg ("Translate and write relocations.");\r
-\r
- //\r
- // Write debug info.\r
- //\r
- WriteDebug();\r
- VerboseMsg ("Write debug info.");\r
-\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- NtHdr->Pe32.OptionalHeader.SizeOfImage = CoffOffset;\r
-\r
- //\r
- // Replace.\r
- //\r
- free(*FileBuffer);\r
- *FileBuffer = CoffFile;\r
- *FileLength = CoffOffset;\r
-\r
- //\r
- // Free memory space\r
- //\r
- if (CoffSectionsOffset != NULL) {\r
- free (CoffSectionsOffset);\r
- }\r
-}\r
-\r
-\r