summaryrefslogtreecommitdiffstats
path: root/ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c')
-rw-r--r--ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c340
1 files changed, 0 insertions, 340 deletions
diff --git a/ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c b/ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c
deleted file mode 100644
index 6bb0d22de2..0000000000
--- a/ArmPlatformPkg/Library/ArmShellCmdRunAxf/ElfLoader.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/** @file
-*
-* Copyright (c) 2014, ARM Limited. All rights reserved.
-*
-* This program and the accompanying materials
-* are licensed and made available under the terms and conditions of the BSD License
-* which accompanies this distribution. The full text of the license may be found at
-* http://opensource.org/licenses/bsd-license.php
-*
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-
-#include "ArmShellCmdRunAxf.h"
-#include "ElfLoader.h"
-#include "elf_common.h"
-#include "elf32.h"
-#include "elf64.h"
-
-
-// Put the functions the #ifdef. We only use the appropriate one for the platform.
-// This prevents 'defined but not used' compiler warning.
-#ifdef MDE_CPU_ARM
-STATIC
-BOOLEAN
-IsArmElf (
- IN CONST VOID *Buf
- )
-{
- Elf32_Ehdr *Hdr = (Elf32_Ehdr*)Buf;
-
- if (Hdr->e_ident[EI_CLASS] != ELFCLASS32) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_32), gRunAxfHiiHandle);
- return FALSE;
- }
-
- if (Hdr->e_machine != EM_ARM) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_32), gRunAxfHiiHandle);
- return FALSE;
- }
-
- // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA])
-
- return TRUE;
-}
-#elif defined(MDE_CPU_AARCH64)
-STATIC
-BOOLEAN
-IsAarch64Elf (
- IN CONST VOID *Buf
- )
-{
- Elf64_Ehdr *Hdr = (Elf64_Ehdr*)Buf;
-
- if (Hdr->e_ident[EI_CLASS] != ELFCLASS64) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS_64), gRunAxfHiiHandle);
- return FALSE;
- }
-
- if (Hdr->e_machine != EM_AARCH64) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGMACH_64), gRunAxfHiiHandle);
- return FALSE;
- }
-
- // We don't currently check endianness of ELF data (hdr->e_ident[EI_DATA])
-
- return TRUE;
-}
-#endif // MDE_CPU_ARM , MDE_CPU_AARCH64
-
-
-/**
- Support checking 32 and 64bit as the header could be valid, we might just
- not support loading it.
-**/
-STATIC
-EFI_STATUS
-ElfCheckHeader (
- IN CONST VOID *Buf
- )
-{
- Elf32_Ehdr *Hdr32 = (Elf32_Ehdr*)Buf;
-
- if (!IS_ELF (*Hdr32)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFMAGIC), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Hdr32->e_type != ET_EXEC) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOTEXEC), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Hdr32->e_ident[EI_CLASS] == ELFCLASS32) {
- if ((Hdr32->e_phoff == 0) || (Hdr32->e_phentsize == 0) || (Hdr32->e_phnum == 0)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Hdr32->e_flags != 0) {
- DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n"));
- }
-
- DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr32->e_entry));
- DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr32->e_phoff));
- DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr32->e_phentsize));
- DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr32->e_phnum));
- } else if (Hdr32->e_ident[EI_CLASS] == ELFCLASS64) {
- Elf64_Ehdr *Hdr64 = (Elf64_Ehdr*)Buf;
-
- if ((Hdr64->e_phoff == 0) || (Hdr64->e_phentsize == 0) || (Hdr64->e_phnum == 0)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOPROG), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Hdr64->e_flags != 0) {
- DEBUG ((EFI_D_INFO, "Warning: Wrong processor-specific flags, expected 0.\n"));
- }
-
- DEBUG ((EFI_D_INFO, "Entry point addr: 0x%lx\n", Hdr64->e_entry));
- DEBUG ((EFI_D_INFO, "Start of program headers: 0x%lx\n", Hdr64->e_phoff));
- DEBUG ((EFI_D_INFO, "Size of 1 program header: %d\n", Hdr64->e_phentsize));
- DEBUG ((EFI_D_INFO, "Number of program headers: %d\n", Hdr64->e_phnum));
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFWRONGCLASS), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Load an ELF segment into memory.
-
- This function assumes the ELF file is valid.
- This function is meant to be called for PT_LOAD type segments only.
-**/
-STATIC
-EFI_STATUS
-ElfLoadSegment (
- IN CONST VOID *ElfImage,
- IN CONST VOID *PHdr,
- IN LIST_ENTRY *LoadList
- )
-{
- VOID *FileSegment;
- VOID *MemSegment;
- UINTN ExtraZeroes;
- UINTN ExtraZeroesCount;
- RUNAXF_LOAD_LIST *LoadNode;
-
-#ifdef MDE_CPU_ARM
- Elf32_Phdr *ProgramHdr;
- ProgramHdr = (Elf32_Phdr *)PHdr;
-#elif defined(MDE_CPU_AARCH64)
- Elf64_Phdr *ProgramHdr;
- ProgramHdr = (Elf64_Phdr *)PHdr;
-#endif
-
- ASSERT (ElfImage != NULL);
- ASSERT (ProgramHdr != NULL);
-
- FileSegment = (VOID *)((UINTN)ElfImage + ProgramHdr->p_offset);
- MemSegment = (VOID *)ProgramHdr->p_vaddr;
-
- // If the segment's memory size p_memsz is larger than the file size p_filesz,
- // the "extra" bytes are defined to hold the value 0 and to follow the
- // segment's initialised area.
- // This is typically the case for the .bss segment.
- // The file size may not be larger than the memory size.
- if (ProgramHdr->p_filesz > ProgramHdr->p_memsz) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADFORMAT), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- // Load the segment in memory.
- if (ProgramHdr->p_filesz != 0) {
- DEBUG ((EFI_D_INFO, "Loading segment from 0x%lx to 0x%lx (size = %ld)\n",
- FileSegment, MemSegment, ProgramHdr->p_filesz));
-
- LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
- if (LoadNode == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- LoadNode->MemOffset = (UINTN)MemSegment;
- LoadNode->FileOffset = (UINTN)FileSegment;
- LoadNode->Length = (UINTN)ProgramHdr->p_filesz;
- InsertTailList (LoadList, &LoadNode->Link);
- }
-
- ExtraZeroes = ((UINTN)MemSegment + ProgramHdr->p_filesz);
- ExtraZeroesCount = ProgramHdr->p_memsz - ProgramHdr->p_filesz;
- DEBUG ((EFI_D_INFO, "Completing segment with %d zero bytes.\n", ExtraZeroesCount));
- if (ExtraZeroesCount > 0) {
- // Extra Node to add the Zeroes.
- LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
- if (LoadNode == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- LoadNode->MemOffset = (UINTN)ExtraZeroes;
- LoadNode->Zeroes = TRUE;
- LoadNode->Length = ExtraZeroesCount;
- InsertTailList (LoadList, &LoadNode->Link);
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Check that the ELF File Header is valid and Machine type supported.
-
- Not all information is checked in the ELF header, only the stuff that
- matters to us in our simplified ELF loader.
-
- @param[in] ElfImage Address of the ELF file to check.
-
- @retval EFI_SUCCESS on success.
- @retval EFI_INVALID_PARAMETER if the header is invalid.
- @retval EFI_UNSUPPORTED if the file type/platform is not supported.
-**/
-EFI_STATUS
-ElfCheckFile (
- IN CONST VOID *ElfImage
- )
-{
- EFI_STATUS Status;
-
- ASSERT (ElfImage != NULL);
-
- // Check that the ELF header is valid.
- Status = ElfCheckHeader (ElfImage);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFBADHEADER), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
-#ifdef MDE_CPU_ARM
- if (IsArmElf (ElfImage)) {
- return EFI_SUCCESS;
- }
-#elif defined(MDE_CPU_AARCH64)
- if (IsAarch64Elf (ElfImage)) {
- return EFI_SUCCESS;
- }
-#endif
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_BAD_ARCH), gRunAxfHiiHandle);
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Load a ELF file.
-
- @param[in] ElfImage Address of the ELF file in memory.
-
- @param[out] EntryPoint Will be filled with the ELF entry point address.
-
- @param[out] ImageSize Will be filled with the ELF size in memory. This will
- effectively be equal to the sum of the segments sizes.
-
- This functon assumes the header is valid and supported as checked with
- ElfCheckFile().
-
- @retval EFI_SUCCESS on success.
- @retval EFI_INVALID_PARAMETER if the ELF file is invalid.
-**/
-EFI_STATUS
-ElfLoadFile (
- IN CONST VOID *ElfImage,
- OUT VOID **EntryPoint,
- OUT LIST_ENTRY *LoadList
- )
-{
- EFI_STATUS Status;
- UINT8 *ProgramHdr;
- UINTN Index;
- UINTN ImageSize;
-
-#ifdef MDE_CPU_ARM
- Elf32_Ehdr *ElfHdr;
- Elf32_Phdr *ProgramHdrPtr;
-
- ElfHdr = (Elf32_Ehdr*)ElfImage;
-#elif defined(MDE_CPU_AARCH64)
- Elf64_Ehdr *ElfHdr;
- Elf64_Phdr *ProgramHdrPtr;
-
- ElfHdr = (Elf64_Ehdr*)ElfImage;
-#endif
-
- ASSERT (ElfImage != NULL);
- ASSERT (EntryPoint != NULL);
- ASSERT (LoadList != NULL);
-
- ProgramHdr = (UINT8*)ElfImage + ElfHdr->e_phoff;
- DEBUG ((EFI_D_INFO, "ELF program header entry : 0x%lx\n", ProgramHdr));
-
- ImageSize = 0;
-
- // Load every loadable ELF segment into memory.
- for (Index = 0; Index < ElfHdr->e_phnum; ++Index) {
-
-#ifdef MDE_CPU_ARM
- ProgramHdrPtr = (Elf32_Phdr*)ProgramHdr;
-#elif defined(MDE_CPU_AARCH64)
- ProgramHdrPtr = (Elf64_Phdr*)ProgramHdr;
-#endif
-
- // Only consider PT_LOAD type segments, ignore others.
- if (ProgramHdrPtr->p_type == PT_LOAD) {
- Status = ElfLoadSegment (ElfImage, (VOID *)ProgramHdrPtr, LoadList);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFFAILSEG), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
- ImageSize += ProgramHdrPtr->p_memsz;
- }
- ProgramHdr += ElfHdr->e_phentsize;
- }
-
- if (ImageSize == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_RUNAXF_ELFNOSEG), gRunAxfHiiHandle);
- return EFI_INVALID_PARAMETER;
- }
-
- // Return the entry point specified in the ELF header.
- *EntryPoint = (void*)ElfHdr->e_entry;
-
- return EFI_SUCCESS;
-}