blob: 80176daa26bca27e1785f54c2400f22f02e0a221 [file] [log] [blame]
/*
* Copyright (c) 2023 Intel Corporation
* Copyright (c) 2024 Schneider Electric
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#ifndef ZEPHYR_LLEXT_ELF_H
#define ZEPHYR_LLEXT_ELF_H
#include <stdint.h>
/**
* @file
* @brief Data structures and constants defined in the ELF specification.
*
* Reference documents can be found here: https://refspecs.linuxfoundation.org/elf/
*
* @defgroup llext_elf ELF constants and data types
* @ingroup llext_apis
* @{
*/
#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;
};
/** ELF section types */
#define SHT_NULL 0x0 /**< Unused section */
#define SHT_PROGBITS 0x1 /**< Program data */
#define SHT_SYMTAB 0x2 /**< Symbol table */
#define SHT_STRTAB 0x3 /**< String table */
#define SHT_RELA 0x4 /**< Relocation entries with addends */
#define SHT_NOBITS 0x8 /**< Program data with no file image */
#define SHT_REL 0x9 /**< Relocation entries without addends */
#define SHT_DYNSYM 0xB /**< Dynamic linking symbol table */
#define SHT_INIT_ARRAY 0xe /**< Array of pointers to init functions */
#define SHT_FINI_ARRAY 0xf /**< Array of pointers to termination functions */
#define SHT_PREINIT_ARRAY 0x10 /**< Array of pointers to early init functions */
/** ELF section flags */
#define SHF_WRITE 0x1 /**< Section is writable */
#define SHF_ALLOC 0x2 /**< Section is present in memory */
#define SHF_EXECINSTR 0x4 /**< Section contains executable instructions */
#define SHF_MASKOS 0x0ff00000 /**< OS specific flags */
#define SHF_LLEXT_HAS_RELOCS 0x00100000 /**< Section is a target for relocations */
#define SHF_BASIC_TYPE_MASK (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)
/**
* @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;
/** 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;
/** Value or location of the symbol */
elf64_addr st_value;
/** Size of the symbol */
elf64_xword st_size;
};
/** ELF section numbers */
#define SHN_UNDEF 0 /**< Undefined section */
#define SHN_LORESERVE 0xff00 /**< Start of reserved section numbers */
#define SHN_ABS 0xfff1 /**< Special value for absolute symbols */
#define SHN_COMMON 0xfff2 /**< Common block */
#define SHN_HIRESERVE 0xffff /**< End of reserved section numbers */
/** Symbol table entry types */
#define STT_NOTYPE 0 /**< No type */
#define STT_OBJECT 1 /**< Data or object */
#define STT_FUNC 2 /**< Function */
#define STT_SECTION 3 /**< Section */
#define STT_FILE 4 /**< File name */
#define STT_COMMON 5 /**< Common block */
#define STT_LOOS 10 /**< Start of OS specific */
#define STT_HIOS 12 /**< End of OS specific */
#define STT_LOPROC 13 /**< Start of processor specific */
#define STT_HIPROC 15 /**< End of processor specific */
/** Symbol table entry bindings */
#define STB_LOCAL 0 /**< Local symbol */
#define STB_GLOBAL 1 /**< Global symbol */
#define STB_WEAK 2 /**< Weak symbol */
#define STB_LOOS 10 /**< Start of OS specific */
#define STB_HIOS 12 /**< End of OS specific */
#define STB_LOPROC 13 /**< Start of processor specific */
#define STB_HIPROC 15 /**< End of processor specific */
/**
* @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.
*
* This structure stores information describing a relocation to be performed.
* Additional information about the relocation is stored at the location
* pointed to by @ref r_offset.
*/
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;
};
/**
* @brief Relocation entry for 32-bit ELFs with addend.
*
* This structure stores information describing a relocation to be performed.
*/
struct elf32_rela {
/** Offset in the section to perform a relocation */
elf32_addr r_offset;
/** Information about the relocation, related symbol and type */
elf32_word r_info;
/** Offset to be applied to the symbol address */
elf32_sword 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.
*
* This structure stores information describing a relocation to be performed.
* Additional information about the relocation is stored at the location
* pointed to by @ref r_offset.
*/
struct elf64_rel {
/** Offset in the section to perform a relocation */
elf64_addr r_offset;
/** Information about the relocation, related symbol and type */
elf64_xword r_info;
};
/**
* @brief Relocation entry for 64-bit ELFs with addend.
*
* This structure stores information describing a relocation to be performed.
*/
struct elf64_rela {
/** Offset in the section to perform a relocation */
elf64_addr r_offset;
/** Information about the relocation, related symbol and type */
elf64_xword r_info;
/** Offset to be applied to the symbol address */
elf64_sxword 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)
/**
* Dynamic features currently not used by LLEXT
* @cond ignore
*/
/**
* @brief Program header(32-bit)
*/
struct elf32_phdr {
elf32_word p_type; /**< Type of segment */
elf32_off p_offset; /**< Offset in file */
elf32_addr p_vaddr; /**< Virtual address in memory */
elf32_addr p_paddr; /**< Physical address (usually reserved) */
elf32_word p_filesz; /**< Size of segment in file */
elf32_word p_memsz; /**< Size of segment in memory */
elf32_word p_flags; /**< Segment flags */
elf32_word p_align; /**< Alignment of segment */
};
/**
* @brief Program header(64-bit)
*/
struct elf64_phdr {
elf64_word p_type; /**< Type of segment */
elf64_off p_offset; /**< Offset in file */
elf64_addr p_vaddr; /**< Virtual address in memory */
elf64_addr p_paddr; /**< Physical address (usually reserved) */
elf64_xword p_filesz; /**< Size of segment in file */
elf64_xword p_memsz; /**< Size of segment in memory */
elf64_word p_flags; /**< Segment flags */
elf64_xword p_align; /**< Alignment of segment */
};
/**
* @brief Program segment type
*/
#define PT_LOAD 1
/**
* @brief Dynamic section entry(32-bit)
*/
struct elf32_dyn {
elf32_sword d_tag; /**< Entry tag */
union {
elf32_word d_val; /**< Integer value */
elf32_addr d_ptr; /**< Address value */
} d_un;
};
/**
* @brief Dynamic section entry(64-bit)
*/
struct elf64_dyn {
elf64_sxword d_tag; /**< Entry tag */
union {
elf64_xword d_val; /**< Integer value */
elf64_addr d_ptr; /**< Address value */
} d_un;
};
/** @endcond */
#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;
/** Machine sized relocation struct with addend */
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;
/** Machine sized relocation struct with addend */
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 */