Support for building and running external apps (#112)
This commit is contained in:
committed by
GitHub
parent
42e843b463
commit
415442e410
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user