blob: 6dc3cc4e5c8e6078b4f3c607bd976186e114af7b [file] [log] [blame]
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#ifndef ZEPHYR_LLEXT_ELF_H
#define ZEPHYR_LLEXT_ELF_H
#include <stdint.h>
/**
* @brief ELF types and parsing
*
* Reference documents can be found here https://refspecs.linuxfoundation.org/elf/
*
* @defgroup elf ELF data types and defines
* @ingroup llext
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/** Unsigned program address */
typedef uint32_t elf32_addr;
/** Unsigned medium integer */
typedef uint16_t elf32_half;
/** Unsigned file offset */
typedef uint32_t elf32_off;
/** Signed integer */
typedef int32_t elf32_sword;
/** Unsigned integer */
typedef uint32_t elf32_word;
/** Unsigned program address */
typedef uint64_t elf64_addr;
/** Unsigned medium integer */
typedef uint16_t elf64_half;
/** Unsigned file offset */
typedef uint64_t elf64_off;
/** Signed integer */
typedef int32_t elf64_sword;
/** Unsigned integer */
typedef uint32_t elf64_word;
/** Signed long integer */
typedef int64_t elf64_sxword;
/** Unsigned long integer */
typedef uint64_t elf64_xword;
/**
* @brief ELF identifier block
*
* 4 byte magic (.ELF)
* 1 byte class (Invalid, 32 bit, 64 bit)
* 1 byte endianness (Invalid, LSB, MSB)
* 1 byte version (1)
* 1 byte OS ABI (0 None, 1 HP-UX, 2 NetBSD, 3 Linux)
* 1 byte ABI (0)
* 7 bytes padding
*/
#define EI_NIDENT 16
/**
* @brief ELF Header(32-bit)
*/
struct elf32_ehdr {
/** Magic string identifying ELF binary */
unsigned char e_ident[EI_NIDENT];
/** Type of ELF */
elf32_half e_type;
/** Machine type */
elf32_half e_machine;
/** Object file version */
elf32_word e_version;
/** Virtual address of entry */
elf32_addr e_entry;
/** Program header table offset */
elf32_off e_phoff;
/** Section header table offset */
elf32_off e_shoff;
/** Processor specific flags */
elf32_word e_flags;
/** ELF header size */
elf32_half e_ehsize;
/** Program header count */
elf32_half e_phentsize;
/** Program header count */
elf32_half e_phnum;
/** Section header size */
elf32_half e_shentsize;
/** Section header count */
elf32_half e_shnum;
/** Section header containing section header string table */
elf32_half e_shstrndx;
};
/**
* @brief ELF Header(64-bit)
*/
struct elf64_ehdr {
/** Magic string identifying ELF binary */
unsigned char e_ident[EI_NIDENT];
/** Type of ELF */
elf64_half e_type;
/** Machine type */
elf64_half e_machine;
/** Object file version */
elf64_word e_version;
/** Virtual address of entry */
elf64_addr e_entry;
/** Program header table offset */
elf64_off e_phoff;
/** Section header table offset */
elf64_off e_shoff;
/** Processor specific flags */
elf64_word e_flags;
/** ELF header size */
elf64_half e_ehsize;
/** Program header size */
elf64_half e_phentsize;
/** Program header count */
elf64_half e_phnum;
/** Section header size */
elf64_half e_shentsize;
/** Section header count */
elf64_half e_shnum;
/** Section header containing section header string table */
elf64_half e_shstrndx;
};
/** Relocatable (unlinked) ELF */
#define ET_REL 1
/** Executable (without PIC/PIE) ELF */
#define ET_EXEC 2
/** Dynamic (executable with PIC/PIE or shared lib) ELF */
#define ET_DYN 3
/** Core Dump */
#define ET_CORE 4
/**
* @brief Section Header(32-bit)
*/
struct elf32_shdr {
/** Section header name index in section header string table */
elf32_word sh_name;
/** Section type */
elf32_word sh_type;
/** Section header attributes */
elf32_word sh_flags;
/** Address of section in the image */
elf32_addr sh_addr;
/** Location of section in the ELF binary in bytes */
elf32_off sh_offset;
/** Section size in bytes */
elf32_word sh_size;
/** Section header table link index, depends on section type */
elf32_word sh_link;
/** Section info, depends on section type */
elf32_word sh_info;
/** Section address alignment */
elf32_word sh_addralign;
/** Section contains table of fixed size entries sh_entsize bytes large */
elf32_word sh_entsize;
};
/**
* @brief Section Header(64-bit)
*/
struct elf64_shdr {
/** Section header name index in section header string table */
elf64_word sh_name;
/** Section type */
elf64_word sh_type;
/** Section header attributes */
elf64_xword sh_flags;
/** Address of section in the image */
elf64_addr sh_addr;
/** Location of section in the ELF binary in bytes */
elf64_off sh_offset;
/** Section size in bytes */
elf64_xword sh_size;
/** Section header table link index, depends on section type */
elf64_word sh_link;
/** Section info, depends on section type */
elf64_word sh_info;
/** Section address alignment */
elf64_xword sh_addralign;
/** Section contains table of fixed size entries sh_entsize bytes large */
elf64_xword sh_entsize;
};
#define SHT_PROGBITS 0x1
#define SHT_SYMTAB 0x2
#define SHT_STRTAB 0x3
#define SHT_RELA 0x4
#define SHT_NOBITS 0x8
#define SHT_REL 0x9
#define SHT_DYNSYM 0xB
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
/**
* @brief Symbol table entry(32-bit)
*/
struct elf32_sym {
/** Name of the symbol as an index into the symbol string table */
elf32_word st_name;
/** Value or location of the symbol */
elf32_addr st_value;
/** Size of the symbol */
elf32_word st_size;
/** Symbol binding and type information */
unsigned char st_info;
/** Symbol visibility */
unsigned char st_other;
/** Symbols related section given by section header index */
elf32_half st_shndx;
};
/**
* @brief Symbol table entry(64-bit)
*/
struct elf64_sym {
/** Name of the symbol as an index into the symbol string table */
elf64_word st_name;
/** Value or location of the symbol */
elf64_addr st_value;
/** Size of the symbol */
elf64_xword st_size;
/** Symbol binding and type information */
unsigned char st_info;
/** Symbol visibility */
unsigned char st_other;
/** Symbols related section given by section header index */
elf64_half st_shndx;
};
#define SHN_UNDEF 0
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_LOOS 10
#define STT_HIOS 12
#define STT_LOPROC 13
#define STT_HIPROC 15
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOOS 10
#define STB_HIOS 12
#define STB_LOPROC 13
#define STB_HIPROC 15
/**
* @brief Symbol binding from 32bit st_info
*
* @param i Value of st_info
*/
#define ELF32_ST_BIND(i) ((i) >> 4)
/**
* @brief Symbol type from 32bit st_info
*
* @param i Value of st_info
*/
#define ELF32_ST_TYPE(i) ((i) & 0xf)
/**
* @brief Symbol binding from 32bit st_info
*
* @param i Value of st_info
*/
#define ELF64_ST_BIND(i) ((i) >> 4)
/**
* @brief Symbol type from 32bit st_info
*
* @param i Value of st_info
*/
#define ELF64_ST_TYPE(i) ((i) & 0xf)
/**
* @brief Relocation entry for 32-bit ELFs
*/
struct elf32_rel {
/** Offset in the section to perform a relocation */
elf32_addr r_offset;
/** Information about the relocation, related symbol and type */
elf32_word r_info;
};
struct elf32_rela {
elf32_addr r_offset;
elf32_word r_info;
elf32_word r_addend;
};
/**
* @brief Relocation symbol index from r_info
*
* @param i Value of r_info
*/
#define ELF32_R_SYM(i) ((i) >> 8)
/**
* @brief Relocation type from r_info
*
* @param i Value of r_info
*/
#define ELF32_R_TYPE(i) ((i) & 0xff)
/**
* @brief Relocation entry for 64-bit ELFs
*/
struct elf64_rel {
/** Offset in section to perform a relocation */
elf64_addr r_offset;
/** Information about relocation, related symbol and type */
elf64_xword r_info;
};
struct elf64_rela {
elf64_addr r_offset;
elf64_word r_info;
elf64_word r_addend;
};
/** @brief Relocation symbol from r_info
*
* @param i Value of r_info
*/
#define ELF64_R_SYM(i) ((i) >> 32)
/**
* @brief Relocation type from r_info
*
* @param i Value of r_info
*/
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_386_GOT32 3
#define R_386_PLT32 4
#define R_386_COPY 5
#define R_386_GLOB_DAT 6
#define R_386_JMP_SLOT 7
#define R_386_RELATIVE 8
#define R_386_GOTOFF 9
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_ARM_REL32 3
#define R_ARM_COPY 4
#define R_ARM_CALL 28
#define R_ARM_V4BX 40
#define R_XTENSA_NONE 0
#define R_XTENSA_32 1
#define R_XTENSA_SLOT0_OP 20
/**
* @brief Program header(32-bit)
*/
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;
};
/**
* @brief Program header(64-bit)
*/
struct elf64_phdr {
elf64_word p_type;
elf64_off p_offset;
elf64_addr p_vaddr;
elf64_addr p_paddr;
elf64_xword p_filesz;
elf64_xword p_memsz;
elf64_word p_flags;
elf64_xword p_align;
};
/**
* @brief Program segment type
*/
#define PT_LOAD 1
/**
* @brief Dynamic section entry(32-bit)
*/
struct elf32_dyn {
elf32_sword d_tag;
union {
elf32_word d_val;
elf32_addr d_ptr;
} d_un;
};
/**
* @brief Dynamic section entry(64-bit)
*/
struct elf64_dyn {
elf64_sxword d_tag;
union {
elf64_xword d_val;
elf64_addr d_ptr;
} d_un;
};
#if defined(CONFIG_64BIT) || defined(__DOXYGEN__)
/** Machine sized elf header structure */
typedef struct elf64_ehdr elf_ehdr_t;
/** Machine sized section header structure */
typedef struct elf64_shdr elf_shdr_t;
/** Machine sized program header structure */
typedef struct elf64_phdr elf_phdr_t;
/** Machine sized program address */
typedef elf64_addr elf_addr;
/** Machine sized small integer */
typedef elf64_half elf_half;
/** Machine sized integer */
typedef elf64_xword elf_word;
/** Machine sized relocation struct */
typedef struct elf64_rel elf_rel_t;
typedef struct elf64_rela elf_rela_t;
/** Machine sized symbol struct */
typedef struct elf64_sym elf_sym_t;
/** Machine sized macro alias for obtaining a relocation symbol */
#define ELF_R_SYM ELF64_R_SYM
/** Machine sized macro alias for obtaining a relocation type */
#define ELF_R_TYPE ELF64_R_TYPE
/** Machine sized macro alias for obtaining a symbol bind */
#define ELF_ST_BIND ELF64_ST_BIND
/** Machine sized macro alias for obtaining a symbol type */
#define ELF_ST_TYPE ELF64_ST_TYPE
#else
/** Machine sized elf header structure */
typedef struct elf32_ehdr elf_ehdr_t;
/** Machine sized section header structure */
typedef struct elf32_shdr elf_shdr_t;
/** Machine sized program header structure */
typedef struct elf32_phdr elf_phdr_t;
/** Machine sized program address */
typedef elf32_addr elf_addr;
/** Machine sized small integer */
typedef elf32_half elf_half;
/** Machine sized integer */
typedef elf32_word elf_word;
/** Machine sized relocation struct */
typedef struct elf32_rel elf_rel_t;
typedef struct elf32_rela elf_rela_t;
/** Machine sized symbol struct */
typedef struct elf32_sym elf_sym_t;
/** Machine sized macro alias for obtaining a relocation symbol */
#define ELF_R_SYM ELF32_R_SYM
/** Machine sized macro alias for obtaining a relocation type */
#define ELF_R_TYPE ELF32_R_TYPE
/** Machine sized macro alias for obtaining a symbol bind */
#define ELF_ST_BIND ELF32_ST_BIND
/** Machine sized macro alias for obtaining a symbol type */
#define ELF_ST_TYPE ELF32_ST_TYPE
#endif
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_LLEXT_ELF_H */