* Copyright (c) 2014, Mentor Graphics Corporation
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ELF_LOADER_H_
#define ELF_LOADER_H_
#include <openamp/remoteproc.h>
#include <openamp/remoteproc_loader.h>
#if defined __cplusplus
extern "C" {
#endif
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Half;
typedef uint64_t Elf64_Off;
typedef int32_t Elf64_Sword;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOOS 0xfe00
#define ET_HIOS 0xfeff
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
#define EM_ARM 40
#define EV_CURRENT 1
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_PAD 9
#define EI_NIDENT 16
* EI_MAG0 to EI_MAG3 - A file's first 4 bytes hold amagic number, identifying
* the file as an ELF object file
*/
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
* EI_CLASS - The next byte, e_ident[EI_CLASS], identifies the file's class, or
* capacity.
*/
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
* EI_DATA - Byte e_ident[EI_DATA] specifies the data encoding of the
* remote_proc-specific data in the object file. The following encodings are
* currently defined.
*/
#define ELFDATANONE 0
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define ELFOSABI_NONE 0
typedef struct elf32_phdr {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef struct elf64_phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7
#define PT_LOOS 0x60000000
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
typedef struct {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MASKPROC 0xf0000000
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
} Elf64_Rel;
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
typedef struct elf64_rela {
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Sxword r_addend;
} Elf64_Rela;
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
typedef struct elf64_sym {
Elf64_Word st_name;
unsigned char st_info;
unsigned char st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
#define R_ARM_GLOB_DAT 21
#define R_ARM_JUMP_SLOT 22
#define R_ARM_RELATIVE 23
#define R_ARM_ABS32 2
struct elf32_info {
Elf32_Ehdr ehdr;
int load_state;
Elf32_Phdr *phdrs;
Elf32_Shdr *shdrs;
void *shstrtab;
};
struct elf64_info {
Elf64_Ehdr ehdr;
int load_state;
Elf64_Phdr *phdrs;
Elf64_Shdr *shdrs;
void *shstrtab;
};
#define ELF_STATE_INIT 0x0L
#define ELF_STATE_WAIT_FOR_PHDRS 0x100L
#define ELF_STATE_WAIT_FOR_SHDRS 0x200L
#define ELF_STATE_WAIT_FOR_SHSTRTAB 0x400L
#define ELF_STATE_HDRS_COMPLETE 0x800L
#define ELF_STATE_MASK 0xFF00L
#define ELF_NEXT_SEGMENT_MASK 0x00FFL
extern const struct loader_ops elf_ops;
* @internal
*
* @brief Check if it is an ELF file
*
* It will check if the input image header is an ELF header.
*
* @param img_data Firmware private data which will be passed to user
* defined loader operations
* @param len Firmware header length
*
* @return 0 for success or negative value for failure.
*/
int elf_identify(const void *img_data, size_t len);
* @internal
*
* @brief Load ELF headers
*
* It will get the ELF header, the program header, and the section header.
*
* @param img_data Image data
* @param offset Input image data offset to the start of image
* file
* @param len Input image data length
* @param img_info Pointer to store image information data
* @param last_load_state Last state return by this function
* @param noffset Pointer to next offset required by loading ELF
* header
* @param nlen Pointer to next data length required by loading
* ELF header
*
* @return ELF loading header state, or negative value for failure
*/
int elf_load_header(const void *img_data, size_t offset, size_t len,
void **img_info, int last_load_state,
size_t *noffset, size_t *nlen);
* @internal
*
* @brief Load ELF data
*
* It will parse the ELF image and return the target device address,
* offset to the start of the ELF image of the data to load and the
* length of the data to load.
*
* @param rproc Pointer to remoteproc instance
* @param img_data Image data which will passed to the function.
* it can be NULL, if image data doesn't need to
* be handled by the load function. E.g. binary
* data which was loaded to the target memory.
* @param offset Last loaded image data offset to the start of
* image file
* @param len Last loaded image data length
* @param img_info Pointer to store image information data
* @param last_load_state The returned state of the last function call.
* @param da Target device address, if the data to load is
* not for target memory the da will be set to
* ANY.
* @param noffset Pointer to next offset required by loading ELF
* header
* @param nlen Pointer to next data length required by loading
* ELF header
* @param padding Value to pad it is possible that a size of a
* segment in memory is larger than what it is in
* the ELF image. e.g. a segment can have stack
* section .bss. It doesn't need to copy image
* file space, in this case, it will be packed
* with 0.
* @param nmemsize Pointer to next data target memory size. The
* size of a segment in the target memory can be
* larger than the its size in the image file.
*
* @return 0 for success, otherwise negative value for failure
*/
int elf_load(struct remoteproc *rproc, const void *img_data,
size_t offset, size_t len,
void **img_info, int last_load_state,
metal_phys_addr_t *da,
size_t *noffset, size_t *nlen,
unsigned char *padding, size_t *nmemsize);
* @internal
*
* @brief Release ELF image information
*
* It will release ELF image information data.
*
* @param img_info Pointer to ELF image information
*/
void elf_release(void *img_info);
* @internal
*
* @brief Get entry point
*
* It will return entry point specified in the ELF file.
*
* @param img_info Pointer to ELF image information
*
* @return Entry address
*/
metal_phys_addr_t elf_get_entry(void *img_info);
* @internal
*
* @brief Locate the resource table information
*
* It will return the length of the resource table, and the device address of
* the resource table.
*
* @param img_info Pointer to ELF image information
* @param da Pointer to the device address
* @param offset Pointer to the offset to in the ELF image of the
* resource table section.
* @param size Pointer to the size of the resource table section.
*
* @return 0 if successfully locate the resource table, negative value for
* failure.
*/
int elf_locate_rsc_table(void *img_info, metal_phys_addr_t *da,
size_t *offset, size_t *size);
#if defined __cplusplus
}
#endif
#endif