Support for building and running external apps (#112)

This commit is contained in:
Ken Van Hoeylandt
2024-12-08 16:46:19 +01:00
committed by GitHub
parent 42e843b463
commit 415442e410
74 changed files with 2901 additions and 126 deletions
+41
View File
@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "private/elf_types.h"
#include "elf_symbol.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_ELFSYM_EXPORT(_sym) { #_sym, (void*)&_sym }
#define ESP_ELFSYM_END { NULL, NULL }
/** @brief Function symbol description */
struct esp_elfsym {
const char *name; /*!< Function name */
const void *sym; /*!< Function pointer */
};
/**
* @brief Find symbol address by name.
*
* @param sym_name - Symbol name
*
* @return Symbol address if success or 0 if failed.
*/
uintptr_t elf_find_sym(const char *sym_name);
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
void elf_set_custom_symbols(const struct esp_elfsym* symbols);
#endif
#ifdef __cplusplus
}
#endif
+94
View File
@@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "private/elf_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Map symbol's address of ELF to physic space.
*
* @param elf - ELF object pointer
* @param sym - ELF symbol address
*
* @return Mapped physic address.
*/
uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym);
/**
* @brief Initialize ELF object.
*
* @param elf - ELF object pointer
*
* @return ESP_OK if sucess or other if failed.
*/
int esp_elf_init(esp_elf_t *elf);
/**
* @brief Decode and relocate ELF data.
*
* @param elf - ELF object pointer
* @param pbuf - ELF data buffer
*
* @return ESP_OK if sucess or other if failed.
*/
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf);
/**
* @brief Request running relocated ELF function.
*
* @param elf - ELF object pointer
* @param opt - Request options
* @param argc - Arguments number
* @param argv - Arguments value array
*
* @return ESP_OK if sucess or other if failed.
*/
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[]);
/**
* @brief Deinitialize ELF object.
*
* @param elf - ELF object pointer
*
* @return None
*/
void esp_elf_deinit(esp_elf_t *elf);
/**
* @brief Print header description information of ELF.
*
* @param pbuf - ELF data buffer
*
* @return None
*/
void esp_elf_print_hdr(const uint8_t *pbuf);
/**
* @brief Print section header description information of ELF.
*
* @param pbuf - ELF data buffer
*
* @return None
*/
void esp_elf_print_shdr(const uint8_t *pbuf);
/**
* @brief Print section information of ELF.
*
* @param pbuf - ELF data buffer
*
* @return None
*/
void esp_elf_print_sec(esp_elf_t *elf);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "private/elf_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ELF_ALIGN_SIZE
#define ELF_ALIGN_SIZE 4
#endif
#define ELF_ALIGN(_a) (((_a) + (ELF_ALIGN_SIZE - 1)) & \
(~(ELF_ALIGN_SIZE - 1)))
/**
* @brief Allocate block of memory.
*
* @param n - Memory size in byte
* @param exec - True: memory can run executable code; False: memory can R/W data
*
* @return Memory pointer if success or NULL if failed.
*/
void *esp_elf_malloc(uint32_t n, bool exec);
/**
* @brief Free block of memory.
*
* @param ptr - memory block pointer allocated by "esp_elf_malloc"
*
* @return None
*/
void esp_elf_free(void *ptr);
/**
* @brief Relocates target architecture symbol of ELF
*
* @param elf - ELF object pointer
* @param rela - Relocated symbol data
* @param sym - ELF symbol table
* @param addr - Jumping target address
*
* @return ESP_OK if sucess or other if failed.
*/
int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
const elf32_sym_t *sym, uint32_t addr);
/**
* @brief Remap symbol from ".data" to ".text" section.
*
* @param elf - ELF object pointer
* @param sym - ELF symbol table
*
* @return Remapped symbol value
*/
#ifdef CONFIG_ELF_LOADER_CACHE_OFFSET
uintptr_t elf_remap_text(esp_elf_t *elf, uintptr_t sym);
#endif
/**
* @brief Flush data from cache to external RAM.
*
* @param None
*
* @return None
*/
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
void esp_elf_arch_flush(void);
#endif
/**
* @brief Initialize MMU hardware remapping function.
*
* @param elf - ELF object pointer
*
* @return 0 if success or a negative value if failed.
*/
#ifdef CONFIG_ELF_LOADER_SET_MMU
int esp_elf_arch_init_mmu(esp_elf_t *elf);
#endif
/**
* @brief De-initialize MMU hardware remapping function.
*
* @param elf - ELF object pointer
*
* @return None
*/
#ifdef CONFIG_ELF_LOADER_SET_MMU
void esp_elf_arch_deinit_mmu(esp_elf_t *elf);
#endif
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,205 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EI_NIDENT 16 /*!< Magic number and other information length */
/** @brief Section Type */
#define SHT_NULL 0 /*!< invalid section header */
#define SHT_PROGBITS 1 /*!< some useful section like .text, .data .got, .plt .rodata .interp and so on */
#define SHT_SYMTAB 2 /*!< symbol table */
#define SHT_STRTAB 3 /*!< string table */
#define SHT_RELA 4 /*!< relocation table */
#define SHT_HASH 5 /*!< HASH table */
#define SHT_SYNAMIC 6 /*!< dynamic symbol table */
#define SHT_NOTE 7 /*!< note information */
#define SHT_NOBITS 8 /*!< .bss */
#define SHT_REL 9 /*!< relocation table */
#define SHT_SHKIB 10 /*!< reserved but has unspecified semantics. */
#define SHT_SYNSYM 11 /*!< dynamic symbol */
#define SHT_LOPROC 0x70000000 /*!< reserved for processor-specific semantics */
#define SHT_LOUSER 0x7fffffff /*!< lower bound of the range of indexes reserved for application programs */
#define SHT_HIUSER 0xffffffff /*!< upper bound of the range of indexes reserved for application programs. */
/** @brief Section Attribute Flags */
#define SHF_WRITE 1 /*!< writable when task runs */
#define SHF_ALLOC 2 /*!< allocated when task runs */
#define SHF_EXECINSTR 4 /*!< machine code */
#define SHF_MASKPROG 0xf0000000 /*!< reserved for processor-specific semantics */
/** @brief Symbol Types */
#define STT_NOTYPE 0 /*!< symbol type is unspecified */
#define STT_OBJECT 1 /*!< data object */
#define STT_FUNC 2 /*!< code object */
#define STT_SECTION 3 /*!< symbol identifies an ELF section */
#define STT_FILE 4 /*!< symbol's name is file name */
#define STT_COMMON 5 /*!< common data object */
#define STT_TLS 6 /*!< thread-local data object */
#define STT_NUM 7 /*!< defined types in generic range */
#define STT_LOOS 10 /*!< Low OS specific range */
#define STT_HIOS 12 /*!< High OS specific range */
#define STT_LOPROC 13 /*!< processor specific range */
#define STT_HIPROC 15 /*!< processor specific link range */
/** @brief Section names */
#define ELF_BSS ".bss" /*!< uninitialized data */
#define ELF_DATA ".data" /*!< initialized data */
#define ELF_DEBUG ".debug" /*!< debug */
#define ELF_DYNAMIC ".dynamic" /*!< dynamic linking information */
#define ELF_DYNSTR ".dynstr" /*!< dynamic string table */
#define ELF_DYNSYM ".dynsym" /*!< dynamic symbol table */
#define ELF_FINI ".fini" /*!< termination code */
#define ELF_GOT ".got" /*!< global offset table */
#define ELF_HASH ".hash" /*!< symbol hash table */
#define ELF_INIT ".init" /*!< initialization code */
#define ELF_REL_DATA ".rel.data" /*!< relocation data */
#define ELF_REL_FINI ".rel.fini" /*!< relocation termination code */
#define ELF_REL_INIT ".rel.init" /*!< relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /*!< relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /*!< relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /*!< relocation code */
#define ELF_RODATA ".rodata" /*!< read-only data */
#define ELF_SHSTRTAB ".shstrtab" /*!< section header string table */
#define ELF_STRTAB ".strtab" /*!< string table */
#define ELF_SYMTAB ".symtab" /*!< symbol table */
#define ELF_TEXT ".text" /*!< code */
#define ELF_DATA_REL_RO ".data.rel.ro" /*!< dynamic read-only data */
/** @brief ELF section and symbol operation */
#define ELF_SEC_TEXT 0
#define ELF_SEC_BSS 1
#define ELF_SEC_DATA 2
#define ELF_SEC_RODATA 3
#define ELF_SEC_DRLRO 4
#define ELF_SECS 5
#define ELF_ST_BIND(_i) ((_i) >> 4)
#define ELF_ST_TYPE(_i) ((_i) & 0xf)
#define ELF_ST_INFO(_b, _t) (((_b)<<4) + ((_t) & 0xf))
#define ELF_R_SYM(_i) ((_i) >> 8)
#define ELF_R_TYPE(_i) ((unsigned char)(_i))
#define ELF_R_INFO(_s, _t) (((_s) << 8) + (unsigned char)(_t))
#define ELF_SEC_MAP(_elf, _sec, _addr) \
((_elf)->sec[(_sec)].addr - \
(_elf)->sec[(_sec)].v_addr + \
(_addr))
typedef unsigned int Elf32_Addr;
typedef unsigned int Elf32_Off;
typedef unsigned int Elf32_Word;
typedef unsigned short Elf32_Half;
typedef int Elf32_Sword;
/** @brief ELF Header */
typedef struct elf32_hdr {
unsigned char ident[EI_NIDENT]; /*!< ELF Identification */
Elf32_Half type; /*!< object file type */
Elf32_Half machine; /*!< machine */
Elf32_Word version; /*!< object file version */
Elf32_Addr entry; /*!< virtual entry point */
Elf32_Off phoff; /*!< program header table offset */
Elf32_Off shoff; /*!< section header table offset */
Elf32_Word flags; /*!< processor-specific flags */
Elf32_Half ehsize; /*!< ELF header size */
Elf32_Half phentsize; /*!< program header entry size */
Elf32_Half phnum; /*!< number of program header entries */
Elf32_Half shentsize; /*!< section header entry size */
Elf32_Half shnum; /*!< number of section header entries */
Elf32_Half shstrndx; /*!< section header table's "section header string table" entry offset */
} elf32_hdr_t;
/** @brief Section Header */
typedef struct elf32_shdr {
Elf32_Word name; /*!< section index and it is offset in section .shstrtab */
Elf32_Word type; /*!< type */
Elf32_Word flags; /*!< flags */
Elf32_Addr addr; /*!< start address when map to task space */
Elf32_Off offset; /*!< offset address from file start address */
Elf32_Word size; /*!< size */
Elf32_Word link; /*!< link to another section */
Elf32_Word info; /*!< additional section information */
Elf32_Word addralign; /*!< address align */
Elf32_Word entsize; /*!< index table size */
} elf32_shdr_t;
/** @brief Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word name; /*!< name - index into string table */
Elf32_Addr value; /*!< symbol value */
Elf32_Word size; /*!< symbol size */
unsigned char info; /*!< type and binding */
unsigned char other; /*!< 0 - no defined meaning */
Elf32_Half shndx; /*!< section header index */
} elf32_sym_t;
/** @brief Relocation entry with implicit addend */
typedef struct elf32_rel {
Elf32_Addr offset; /*!< offset of relocation */
Elf32_Word info; /*!< symbol table index and type */
} elf32_rel_t;
/** @brief Relocation entry with explicit addend */
typedef struct elf32_rela {
Elf32_Addr offset; /*!< offset of relocation */
Elf32_Word info; /*!< symbol table index and type */
Elf32_Sword addend; /*!< Added information */
} elf32_rela_t;
/** @brief ELF section object */
typedef struct esp_elf_sec {
uintptr_t v_addr; /*!< symbol virtual address */
off_t offset; /*!< offset in ELF */
uintptr_t addr; /*!< section physic address in memory */
size_t size; /*!< section size */
} esp_elf_sec_t;
/** @brief ELF object */
typedef struct esp_elf {
unsigned char *ptext; /*!< instruction buffer pointer */
unsigned char *pdata; /*!< data buffer pointer */
esp_elf_sec_t sec[ELF_SECS]; /*!< ".bss", "data", "rodata", ".text" */
int (*entry)(int argc, char *argv[]); /*!< Entry pointer of ELF */
#ifdef CONFIG_ELF_LOADER_SET_MMU
uint32_t text_off; /* .text symbol offset */
uint32_t mmu_off; /* MMU unit offset */
uint32_t mmu_num; /* MMU unit total number */
#endif
} esp_elf_t;
#ifdef __cplusplus
}
#endif