28 if (Index >= Ehdr->e_shnum) {
32 return (
Elf64_Shdr *)(ImageBase + Ehdr->e_shoff + Index * Ehdr->e_shentsize);
52 if (Index >= Ehdr->e_phnum) {
56 return (
Elf64_Phdr *)(ImageBase + Ehdr->e_phoff + Index * Ehdr->e_phentsize);
81 Shdr = (
Elf64_Shdr *)(ImageBase + Ehdr->e_shoff);
82 for (Index = 0; Index < Ehdr->e_shnum; Index++) {
83 if ((Shdr->sh_offset == Offset) && (Shdr->sh_size == Size)) {
87 Shdr = ELF_NEXT_ENTRY (
Elf64_Shdr, Shdr, Ehdr->e_shentsize);
109 IN UINT64 RelaEntrySize,
112 IN BOOLEAN DynamicLinking
120 ;
MultU64x64 (RelaEntrySize, Index) < RelaSize
121 ; Index++, Rela = ELF_NEXT_ENTRY (
Elf64_Rela, Rela, RelaEntrySize)
127 Ptr = (UINT64 *)(
UINTN)(Rela->r_offset + Delta);
128 Type = ELF64_R_TYPE (Rela->r_info);
133 case R_X86_64_GOTPCREL:
134 case R_X86_64_GOTPCRELX:
135 case R_X86_64_REX_GOTPCRELX:
139 if (DynamicLinking) {
143 DEBUG ((DEBUG_INFO,
"Unsupported relocation type %02X\n", Type));
155 DEBUG ((DEBUG_INFO,
"Unsupported relocation type %02X\n", Type));
159 case R_X86_64_RELATIVE:
160 if (DynamicLinking) {
179 if (RelaType == SHT_RELA) {
180 *Ptr = Delta + Rela->r_addend;
191 DEBUG ((DEBUG_INFO,
"Unsupported relocation type %02X\n", Type));
198 DEBUG ((DEBUG_INFO,
"Unsupported relocation type %02X\n", Type));
226 UINT64 RelaEntrySize;
238 for (Index = 0; Index < ElfCt->PhNum; Index++) {
240 ASSERT (Phdr !=
NULL);
241 if (Phdr->p_type == PT_DYNAMIC) {
253 ASSERT (DynShdr !=
NULL);
254 if (DynShdr ==
NULL) {
255 return EFI_UNSUPPORTED;
258 ASSERT (DynShdr->sh_type == SHT_DYNAMIC);
259 ASSERT (DynShdr->sh_entsize >= sizeof (*Dyn));
264 RelaAddress = MAX_UINT64;
269 for ( Index = 0, Dyn = (
Elf64_Dyn *)(ElfCt->FileBase + DynShdr->sh_offset)
271 ; Index++, Dyn = ELF_NEXT_ENTRY (
Elf64_Dyn, Dyn, DynShdr->sh_entsize)
274 switch (Dyn->d_tag) {
284 RelaAddress = Dyn->d_un.d_ptr;
285 RelaType = (Dyn->d_tag == DT_RELA) ? SHT_RELA : SHT_REL;
289 RelaCount = Dyn->d_un.d_val;
293 RelaEntrySize = Dyn->d_un.d_val;
297 RelaSize = Dyn->d_un.d_val;
304 if (RelaAddress == MAX_UINT64) {
305 ASSERT (RelaCount == 0);
306 ASSERT (RelaEntrySize == 0);
307 ASSERT (RelaSize == 0);
318 for (Index = 0; Index < ElfCt->ShNum; Index++) {
320 ASSERT (RelShdr !=
NULL);
321 if ((RelShdr->sh_addr == RelaAddress) && (RelShdr->sh_size == RelaSize)) {
328 if (RelShdr ==
NULL) {
329 return EFI_UNSUPPORTED;
332 ASSERT (RelShdr->sh_type == RelaType);
333 ASSERT (RelShdr->sh_entsize == RelaEntrySize);
339 (
Elf64_Rela *)(ElfCt->FileBase + RelShdr->sh_offset),
343 (
UINTN)ElfCt->ImageAddress - (
UINTN)ElfCt->PreferredImageAddress,
370 if (Ehdr->e_machine != EM_X86_64) {
371 return EFI_UNSUPPORTED;
374 Delta = (
UINTN)ElfCt->ImageAddress - (
UINTN)ElfCt->PreferredImageAddress;
375 ElfCt->EntryPoint = (
UINTN)(Ehdr->e_entry + Delta);
380 if (Ehdr->e_type == ET_DYN) {
381 DEBUG ((DEBUG_INFO,
"DYN ELF: Relocate using dynamic sections...\n"));
396 DEBUG ((DEBUG_INFO,
"EXEC ELF: Fix actual/preferred base address delta ...\n"));
397 for ( Index = 0, RelShdr = (
Elf64_Shdr *)(ElfCt->FileBase + Ehdr->e_shoff)
398 ; Index < Ehdr->e_shnum
399 ; Index++, RelShdr = ELF_NEXT_ENTRY (
Elf64_Shdr, RelShdr, Ehdr->e_shentsize)
402 if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {
407 if ((Shdr->sh_flags & SHF_ALLOC) == SHF_ALLOC) {
412 (
Elf64_Rela *)((UINT8 *)Ehdr + RelShdr->sh_offset),
448 ASSERT (ElfCt !=
NULL);
455 for ( Index = 0, Phdr = (
Elf64_Phdr *)(ElfCt->FileBase + Ehdr->e_phoff)
456 ; Index < Ehdr->e_phnum
457 ; Index++, Phdr = ELF_NEXT_ENTRY (
Elf64_Phdr, Phdr, Ehdr->e_phentsize)
463 if ((Phdr->p_type != PT_LOAD) ||
464 (Phdr->p_memsz == 0))
473 Delta = (
UINTN)Phdr->p_paddr - (
UINTN)ElfCt->PreferredImageAddress;
474 CopyMem (ElfCt->ImageAddress + Delta, ElfCt->FileBase + (
UINTN)Phdr->p_offset, (
UINTN)Phdr->p_filesz);
475 ZeroMem (ElfCt->ImageAddress + Delta + (
UINTN)Phdr->p_filesz, (
UINTN)(Phdr->p_memsz - Phdr->p_filesz));
481 if (ElfCt->ImageAddress != ElfCt->PreferredImageAddress) {
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS ProcessRelocation64(IN Elf64_Rela *Rela, IN UINT64 RelaSize, IN UINT64 RelaEntrySize, IN UINT64 RelaType, IN INT64 Delta, IN BOOLEAN DynamicLinking)
Elf64_Shdr * GetElf64SectionByRange(IN UINT8 *ImageBase, IN UINT64 Offset, IN UINT64 Size)
EFI_STATUS RelocateElf64Sections(IN ELF_IMAGE_CONTEXT *ElfCt)
Elf64_Shdr * GetElf64SectionByIndex(IN UINT8 *ImageBase, IN UINT32 Index)
EFI_STATUS LoadElf64Image(IN ELF_IMAGE_CONTEXT *ElfCt)
Elf64_Phdr * GetElf64SegmentByIndex(IN UINT8 *ImageBase, IN UINT32 Index)
EFI_STATUS RelocateElf64Dynamic(IN ELF_IMAGE_CONTEXT *ElfCt)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)