/** @file
  ELF library

  Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "ElfLibInternal.h"

/**
  Return the section header specified by Index.

  @param ImageBase      The image base.
  @param Index          The section index.

  @return Pointer to the section header.
**/
Elf64_Shdr *
GetElf64SectionByIndex (
  IN  UINT8                 *ImageBase,
  IN  UINT32                Index
  )
{
  Elf64_Ehdr        *Ehdr;

  Ehdr  = (Elf64_Ehdr *)ImageBase;
  if (Index >= Ehdr->e_shnum) {
    return NULL;
  }

  return (Elf64_Shdr *)(ImageBase + Ehdr->e_shoff + Index * Ehdr->e_shentsize);
}

/**
  Return the segment header specified by Index.

  @param ImageBase      The image base.
  @param Index          The segment index.

  @return Pointer to the segment header.
**/
Elf64_Phdr *
GetElf64SegmentByIndex (
  IN  UINT8                 *ImageBase,
  IN  UINT32                Index
  )
{
  Elf64_Ehdr        *Ehdr;

  Ehdr  = (Elf64_Ehdr *)ImageBase;
  if (Index >= Ehdr->e_phnum) {
    return NULL;
  }

  return (Elf64_Phdr *)(ImageBase + Ehdr->e_phoff + Index * Ehdr->e_phentsize);
}

/**
  Return the section header specified by the range.

  @param ImageBase      The image base.
  @param Offset         The section offset.
  @param Size           The section size.

  @return Pointer to the section header.
**/
Elf64_Shdr *
GetElf64SectionByRange (
  IN  UINT8                 *ImageBase,
  IN  UINT64                Offset,
  IN  UINT64                Size
  )
{
  UINT32                    Index;
  Elf64_Ehdr                *Ehdr;
  Elf64_Shdr                *Shdr;

  Ehdr = (Elf64_Ehdr *)ImageBase;

  Shdr = (Elf64_Shdr *) (ImageBase + Ehdr->e_shoff);
  for (Index = 0; Index < Ehdr->e_shnum; Index++) {
    if ((Shdr->sh_offset == Offset) && (Shdr->sh_size == Size)) {
      return Shdr;
    }
    Shdr = ELF_NEXT_ENTRY (Elf64_Shdr, Shdr, Ehdr->e_shentsize);
  }
  return NULL;
}

/**
  Fix up the image based on the relocation entries.

  @param Rela                Relocation entries.
  @param RelaSize            Total size of relocation entries.
  @param RelaEntrySize       Relocation entry size.
  @param RelaType            Type of relocation entry.
  @param Delta               The delta between preferred image base and the actual image base.
  @param DynamicLinking      TRUE when fixing up according to dynamic relocation.

  @retval EFI_SUCCESS   The image fix up is processed successfully.
**/
EFI_STATUS
ProcessRelocation64 (
  IN  Elf64_Rela            *Rela,
  IN  UINT64                RelaSize,
  IN  UINT64                RelaEntrySize,
  IN  UINT64                RelaType,
  IN  INTN                  Delta,
  IN  BOOLEAN               DynamicLinking
  )
{
  UINTN                     Index;
  UINT64                    *Ptr;
  UINT32                    Type;

  for ( Index = 0
      ; MultU64x64 (RelaEntrySize, Index) < RelaSize
      ; Index++, Rela = ELF_NEXT_ENTRY (Elf64_Rela, Rela, RelaEntrySize)
      ) {
    //
    // r_offset is the virtual address of the storage unit affected by the relocation.
    //
    Ptr = (UINT64 *)(UINTN)(Rela->r_offset + Delta);
    Type  = ELF64_R_TYPE(Rela->r_info);
    switch (Type) {
      case R_X86_64_NONE:
      case R_X86_64_PC32:
      case R_X86_64_PLT32:
      case R_X86_64_GOTPCREL:
      case R_X86_64_GOTPCRELX:
      case R_X86_64_REX_GOTPCRELX:
        break;

      case R_X86_64_64:
        if (DynamicLinking) {
          //
          // Dynamic section doesn't contain entries of this type.
          //
          DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type));
          ASSERT (FALSE);
        } else {
          *Ptr += Delta;
        }
        break;

      case R_X86_64_32:
        //
        // Dynamic section doesn't contain entries of this type.
        //
        DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type));
        ASSERT (FALSE);
        break;

      case R_X86_64_RELATIVE:
        if (DynamicLinking) {
          //
          // A: Represents the addend used to compute the value of the relocatable field.
          // B: Represents the base address at which a shared object has been loaded into memory during execution.
          //    Generally, a shared object is built with a 0 base virtual address, but the execution address will be different.
          //
          // B (Base Address) in ELF spec is slightly different:
          //   An executable or shared object file's base address (on platforms that support the concept) is calculated during
          //   execution from three values: the virtual memory load address, the maximum page size, and the lowest virtual address
          //   of a program's loadable segment. To compute the base address, one determines the memory address associated with the
          //   lowest p_vaddr value for a PT_LOAD segment. This address is truncated to the nearest multiple of the maximum page size.
          //   The corresponding p_vaddr value itself is also truncated to the nearest multiple of the maximum page size.
          //
          //   *** The base address is the difference between the truncated memory address and the truncated p_vaddr value. ***
          //
          // Delta in this function is B.
          //
          // Calculation: B + A
          //
          if (RelaType == SHT_RELA) {
            *Ptr = Delta + Rela->r_addend;
          } else {
            //
            // A is stored in the field of relocation for REL type.
            //
            *Ptr = Delta + *Ptr;
          }
        } else {
          //
          // non-Dynamic section doesn't contain entries of this type.
          //
          DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type));
          ASSERT (FALSE);
        }
        break;

      default:
        DEBUG ((DEBUG_INFO, "Unsupported relocation type %02X\n", Type));
    }
  }
  return EFI_SUCCESS;
}

/**
  Relocate the DYN type image.

  @param ElfCt                Point to image context.

  @retval EFI_SUCCESS      The relocation succeeds.
  @retval EFI_UNSUPPORTED  The image doesn't contain a dynamic section.
**/
EFI_STATUS
RelocateElf64Dynamic (
  IN    ELF_IMAGE_CONTEXT      *ElfCt
  )
{
  UINT32                       Index;
  Elf64_Phdr                   *Phdr;
  Elf64_Shdr                   *DynShdr;
  Elf64_Shdr                   *RelShdr;
  Elf64_Dyn                    *Dyn;
  UINT64                       RelaAddress;
  UINT64                       RelaCount;
  UINT64                       RelaSize;
  UINT64                       RelaEntrySize;
  UINT64                       RelaType;

  //
  // 1. Locate the dynamic section.
  //
  // If an object file participates in dynamic linking, its program header table
  // will have an element of type PT_DYNAMIC.
  // This ``segment'' contains the .dynamic section. A special symbol, _DYNAMIC,
  // labels the section, which contains an array of Elf32_Dyn or Elf64_Dyn.
  //
  DynShdr = NULL;
  for (Index = 0; Index < ElfCt->PhNum; Index++) {
    Phdr = GetElf64SegmentByIndex (ElfCt->FileBase, Index);
    ASSERT (Phdr != NULL);
    if (Phdr->p_type == PT_DYNAMIC) {
      //
      // Verify the existence of the dynamic section.
      //
      DynShdr = GetElf64SectionByRange (ElfCt->FileBase, Phdr->p_offset, Phdr->p_filesz);
      break;
    }
  }

  //
  // It's abnormal a DYN ELF doesn't contain a dynamic section.
  //
  ASSERT (DynShdr != NULL);
  if (DynShdr == NULL) {
    return EFI_UNSUPPORTED;
  }
  ASSERT (DynShdr->sh_type == SHT_DYNAMIC);
  ASSERT (DynShdr->sh_entsize >= sizeof (*Dyn));

  //
  // 2. Locate the relocation section from the dynamic section.
  //
  RelaAddress    = MAX_UINT64;
  RelaSize      = 0;
  RelaCount     = 0;
  RelaEntrySize = 0;
  RelaType      = 0;
  for ( Index = 0, Dyn = (Elf64_Dyn *) (ElfCt->FileBase + DynShdr->sh_offset)
      ; Index < DivU64x64Remainder (DynShdr->sh_size, DynShdr->sh_entsize, NULL)
      ; Index++, Dyn = ELF_NEXT_ENTRY (Elf64_Dyn, Dyn, DynShdr->sh_entsize)
      ) {
    switch (Dyn->d_tag) {
      case DT_RELA:
      case DT_REL:
        //
        // DT_REL represent program virtual addresses.
        // A file's virtual addresses might not match the memory virtual addresses during execution.
        // When interpreting addresses contained in the dynamic structure, the dynamic linker computes actual addresses,
        // based on the original file value and the memory base address.
        // For consistency, files do not contain relocation entries to ``correct'' addresses in the dynamic structure.
        //
        RelaAddress = Dyn->d_un.d_ptr;
        RelaType    = (Dyn->d_tag == DT_RELA) ? SHT_RELA: SHT_REL;
        break;
      case DT_RELACOUNT:
      case DT_RELCOUNT:
        RelaCount = Dyn->d_un.d_val;
        break;
      case DT_RELENT:
      case DT_RELAENT:
        RelaEntrySize = Dyn->d_un.d_val;
        break;
      case DT_RELSZ:
      case DT_RELASZ:
        RelaSize = Dyn->d_un.d_val;
        break;
      default:
        break;
    }
  }

  if (RelaAddress == MAX_UINT64) {
    ASSERT (RelaCount     == 0);
    ASSERT (RelaEntrySize == 0);
    ASSERT (RelaSize      == 0);
    //
    // It's fine that a DYN ELF doesn't contain relocation section.
    //
    return EFI_SUCCESS;
  }

  //
  // Verify the existence of the relocation section.
  //
  RelShdr = NULL;
  for (Index = 0; Index < ElfCt->ShNum; Index++) {
    RelShdr = GetElf64SectionByIndex (ElfCt->FileBase, Index);
    ASSERT (RelShdr != NULL);
    if ((RelShdr->sh_addr == RelaAddress) && (RelShdr->sh_size == RelaSize)) {
      break;
    }
    RelShdr = NULL;
  }

  if (RelShdr == NULL) {
    return EFI_UNSUPPORTED;
  }
  ASSERT (RelShdr->sh_type == RelaType);
  ASSERT (RelShdr->sh_entsize == RelaEntrySize);

  //
  // 3. Process the relocation section.
  //
  ProcessRelocation64 (
    (Elf64_Rela *) (ElfCt->FileBase + RelShdr->sh_offset),
    RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,
    (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddress,
    TRUE
    );
  return EFI_SUCCESS;
}

/**
  Relocate all sections in a ELF image.

  @param[in]  ElfCt               ELF image context pointer.

  @retval EFI_UNSUPPORTED         Relocation is not supported.
  @retval EFI_SUCCESS             ELF image was relocated successfully.
**/
EFI_STATUS
RelocateElf64Sections  (
  IN    ELF_IMAGE_CONTEXT      *ElfCt
  )
{
  EFI_STATUS       Status;
  Elf64_Ehdr       *Ehdr;
  Elf64_Shdr       *RelShdr;
  Elf64_Shdr       *Shdr;
  UINT32           Index;
  UINTN            Delta;

  Ehdr  = (Elf64_Ehdr *)ElfCt->FileBase;
  if (Ehdr->e_machine != EM_X86_64) {
    return EFI_UNSUPPORTED;
  }

  Delta = (UINTN) ElfCt->ImageAddress - (UINTN) ElfCt->PreferredImageAddress;
  ElfCt->EntryPoint = (UINTN)(Ehdr->e_entry + Delta);

  //
  // 1. Relocate dynamic ELF using the relocation section pointed by dynamic section
  //
  if (Ehdr->e_type == ET_DYN) {
    DEBUG ((DEBUG_INFO, "DYN ELF: Relocate using dynamic sections...\n"));
    Status = RelocateElf64Dynamic (ElfCt);
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  //
  // 2. Executable ELF: Fix up the delta between actual image address and preferred image address.
  //
  //  Linker already fixed up EXEC ELF based on the preferred image address.
  //  A ELF loader in modern OS only loads it into the preferred image address.
  //  The below relocation is unneeded in that case.
  //  But the ELF loader in firmware supports to load the image to a different address.
  //  The below relocation is needed in this case.
  //
  DEBUG ((DEBUG_INFO, "EXEC ELF: Fix actual/preferred base address delta ...\n"));
  for ( Index = 0, RelShdr = (Elf64_Shdr *) (ElfCt->FileBase + Ehdr->e_shoff)
      ; Index < Ehdr->e_shnum
      ; Index++,   RelShdr = ELF_NEXT_ENTRY (Elf64_Shdr, RelShdr, Ehdr->e_shentsize)
      ) {
    if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {
      continue;
    }
    Shdr = GetElf64SectionByIndex (ElfCt->FileBase, RelShdr->sh_info);
    if ((Shdr->sh_flags & SHF_ALLOC) == SHF_ALLOC) {
      //
      // Only fix up sections that occupy memory during process execution.
      //
      ProcessRelocation64 (
        (Elf64_Rela *)((UINT8*)Ehdr + RelShdr->sh_offset),
        RelShdr->sh_size, RelShdr->sh_entsize, RelShdr->sh_type,
        Delta, FALSE
        );
    }
  }

  return EFI_SUCCESS;
}

/**
  Load ELF image which has 64-bit architecture.

  Caller should set Context.ImageAddress to a proper value, either pointing to
  a new allocated memory whose size equal to Context.ImageSize, or pointing
  to Context.PreferredImageAddress.

  @param[in]  ElfCt               ELF image context pointer.

  @retval EFI_SUCCESS         ELF binary is loaded successfully.
  @retval Others              Loading ELF binary fails.

**/
EFI_STATUS
LoadElf64Image (
  IN    ELF_IMAGE_CONTEXT    *ElfCt
  )
{
  Elf64_Ehdr    *Ehdr;
  Elf64_Phdr    *Phdr;
  UINT16        Index;
  UINTN         Delta;

  ASSERT (ElfCt != NULL);

  //
  // Per the sprit of ELF, loading to memory only consumes info from program headers.
  //
  Ehdr = (Elf64_Ehdr *)ElfCt->FileBase;

  for ( Index = 0, Phdr = (Elf64_Phdr *)(ElfCt->FileBase + Ehdr->e_phoff)
      ; Index < Ehdr->e_phnum
      ; Index++, Phdr = ELF_NEXT_ENTRY (Elf64_Phdr, Phdr, Ehdr->e_phentsize)
      ) {
    //
    // Skip segments that don't require load (type tells, or size is 0)
    //
    if ((Phdr->p_type != PT_LOAD) ||
        (Phdr->p_memsz == 0)) {
      continue;
    }

    //
    // The memory offset of segment relative to the image base
    // Note: CopyMem() does nothing when the dst equals to src.
    //
    Delta = (UINTN) Phdr->p_paddr - (UINTN) ElfCt->PreferredImageAddress;
    CopyMem (ElfCt->ImageAddress + Delta, ElfCt->FileBase + (UINTN) Phdr->p_offset, (UINTN) Phdr->p_filesz);
    ZeroMem (ElfCt->ImageAddress + Delta + (UINTN) Phdr->p_filesz, (UINTN) (Phdr->p_memsz - Phdr->p_filesz));
  }

  //
  // Relocate when new new image base is not the preferred image base.
  //
  if (ElfCt->ImageAddress != ElfCt->PreferredImageAddress) {
    RelocateElf64Sections (ElfCt);
  }

  return EFI_SUCCESS;
}
