Updated elf_loader library to latest from GitHub (#234)

This commit is contained in:
Ken Van Hoeylandt
2025-02-22 23:57:45 +01:00
committed by GitHub
parent 6d1d08944b
commit bd2786b122
45 changed files with 641 additions and 483 deletions
@@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <assert.h>
#include <sys/errno.h>
#include "esp_elf.h"
#include "esp_log.h"
#include "private/elf_platform.h"
/** @brief RISC-V relocations defined by the ABIs */
#define R_RISCV_NONE 0
#define R_RISCV_32 1
#define R_RISCV_64 2
#define R_RISCV_RELATIVE 3
#define R_RISCV_COPY 4
#define R_RISCV_JUMP_SLOT 5
#define R_RISCV_TLS_DTPMOD32 6
#define R_RISCV_TLS_DTPMOD64 7
#define R_RISCV_TLS_DTPREL32 8
#define R_RISCV_TLS_DTPREL64 9
#define R_RISCV_TLS_TPREL32 10
#define R_RISCV_TLS_TPREL64 11
#define R_RISCV_TLS_DESC 12
#define R_RISCV_BRANCH 16
#define R_RISCV_JAL 17
#define R_RISCV_CALL 18
#define R_RISCV_CALL_PLT 19
#define R_RISCV_GOT_HI20 20
#define R_RISCV_TLS_GOT_HI20 21
#define R_RISCV_TLS_GD_HI20 22
#define R_RISCV_PCREL_HI20 23
#define R_RISCV_PCREL_LO12_I 24
#define R_RISCV_PCREL_LO12_S 25
#define R_RISCV_HI20 26
#define R_RISCV_LO12_I 27
#define R_RISCV_LO12_S 28
#define R_RISCV_TPREL_HI20 29
#define R_RISCV_TPREL_LO12_I 30
#define R_RISCV_TPREL_LO12_S 31
#define R_RISCV_TPREL_ADD 32
#define R_RISCV_ADD8 33
#define R_RISCV_ADD16 34
#define R_RISCV_ADD32 35
#define R_RISCV_ADD64 36
#define R_RISCV_SUB8 37
#define R_RISCV_SUB16 38
#define R_RISCV_SUB32 39
#define R_RISCV_SUB64 40
#define R_RISCV_GNU_VTINHERIT 41
#define R_RISCV_GNU_VTENTRY 42
#define R_RISCV_ALIGN 43
#define R_RISCV_RVC_BRANCH 44
#define R_RISCV_RVC_JUMP 45
#define R_RISCV_RVC_LUI 46
#define R_RISCV_RELAX 51
#define R_RISCV_SUB6 52
#define R_RISCV_SET6 53
#define R_RISCV_SET8 54
#define R_RISCV_SET16 55
#define R_RISCV_SET32 56
#define R_RISCV_32_PCREL 57
#define R_RISCV_IRELATIVE 58
#define R_RISCV_PLT32 59
static const char *TAG = "elf_arch";
/**
* @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 success 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)
{
uint32_t *where;
assert(elf && rela);
where = (uint32_t *)((uint8_t *)elf->psegment + rela->offset + elf->svaddr);
ESP_LOGD(TAG, "type: %d, where=%p addr=0x%x offset=0x%x",
ELF_R_TYPE(rela->info), where, (int)elf->psegment, (int)rela->offset);
/* Do relocation based on relocation type */
switch (ELF_R_TYPE(rela->info)) {
case R_RISCV_NONE:
break;
case R_RISCV_32:
*where = addr + rela->addend;
break;
case R_RISCV_RELATIVE:
*where = (Elf32_Addr)((uint8_t *)elf->psegment - elf->svaddr + rela->addend);
break;
case R_RISCV_JUMP_SLOT:
*where = addr;
break;
default:
ESP_LOGE(TAG, "info=%d is not supported\n", ELF_R_TYPE(rela->info));
return -EINVAL;
}
return 0;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -69,8 +69,8 @@ static const char *TAG = "elf_arch";
* @param rela - Relocated symbol data
* @param sym - ELF symbol table
* @param addr - Jumping target address
*
* @return ESP_OK if sucess or other if failed.
*
* @return ESP_OK if success 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)
@@ -82,7 +82,8 @@ int esp_elf_arch_relocate(esp_elf_t *elf, const elf32_rela_t *rela,
where = (uint32_t *)esp_elf_map_sym(elf, rela->offset);
ESP_LOGD(TAG, "where=%p addr=%x offset=%x\n", where, (int)addr, (int)rela->offset);
ESP_LOGD(TAG, "type: %d, where=%p addr=0x%x offset=0x%x\n",
ELF_R_TYPE(rela->info), where, (int)addr, (int)rela->offset);
switch (ELF_R_TYPE(rela->info)) {
case R_XTENSA_RELATIVE:
+305 -115
View File
@@ -1,149 +1,111 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/param.h>
#include "esp_log.h"
#include "soc/soc_caps.h"
#include "elf_symbol.h"
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#include "hal/cache_ll.h"
#endif
#include "private/elf_symbol.h"
#include "private/elf_platform.h"
#define stype(_s, _t) ((_s)->type == (_t))
#define sflags(_s, _f) (((_s)->flags & (_f)) == (_f))
#define ADDR_OFFSET (0x400)
static const char *TAG = "ELF";
/**
* @brief Map symbol's address of ELF to physic space.
*
* @param elf - ELF object pointer
* @param sym - ELF symbol address
*
* @return ESP_OK if sucess or other if failed.
*/
uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym)
{
for (int i = 0; i < ELF_SECS; i++) {
if ((sym >= elf->sec[i].v_addr) &&
(sym < (elf->sec[i].v_addr + elf->sec[i].size))) {
return sym - elf->sec[i].v_addr + elf->sec[i].addr;
}
}
return 0;
}
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
/**
* @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)
{
ESP_LOGI(TAG, "ELF loader version: %d.%d.%d", ELF_LOADER_VER_MAJOR, ELF_LOADER_VER_MINOR, ELF_LOADER_VER_PATCH);
if (!elf) {
return -EINVAL;
}
memset(elf, 0, sizeof(esp_elf_t));
return 0;
}
/**
* @brief Decode and relocate ELF data.
* @brief Load ELF section.
*
* @param elf - ELF object pointer
* @param pbuf - ELF data buffer
*
* @return ESP_OK if sucess or other if failed.
*
* @return ESP_OK if success or other if failed.
*/
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
static int esp_elf_load_section(esp_elf_t *elf, const uint8_t *pbuf)
{
uint32_t entry;
uint32_t size;
const elf32_hdr_t *phdr;
const elf32_shdr_t *pshdr;
const char *shstrab;
if (!elf || !pbuf) {
return -EINVAL;
}
phdr = (const elf32_hdr_t *)pbuf;
pshdr = (const elf32_shdr_t *)(pbuf + phdr->shoff);
shstrab = (const char *)pbuf + pshdr[phdr->shstrndx].offset;
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
const elf32_shdr_t *shdr = (const elf32_shdr_t *)(pbuf + ehdr->shoff);
const char *shstrab = (const char *)pbuf + shdr[ehdr->shstrndx].offset;
/* Calculate ELF image size */
for (uint32_t i = 0; i < phdr->shnum; i++) {
const char *name = shstrab + pshdr[i].name;
for (uint32_t i = 0; i < ehdr->shnum; i++) {
const char *name = shstrab + shdr[i].name;
if (stype(&pshdr[i], SHT_PROGBITS) && sflags(&pshdr[i], SHF_ALLOC)) {
if (sflags(&pshdr[i], SHF_EXECINSTR) && !strcmp(ELF_TEXT, name)) {
if (stype(&shdr[i], SHT_PROGBITS) && sflags(&shdr[i], SHF_ALLOC)) {
if (sflags(&shdr[i], SHF_EXECINSTR) && !strcmp(ELF_TEXT, name)) {
ESP_LOGD(TAG, ".text sec addr=0x%08x size=0x%08x offset=0x%08x",
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
shdr[i].addr, shdr[i].size, shdr[i].offset);
elf->sec[ELF_SEC_TEXT].v_addr = pshdr[i].addr;
elf->sec[ELF_SEC_TEXT].size = ELF_ALIGN(pshdr[i].size);
elf->sec[ELF_SEC_TEXT].offset = pshdr[i].offset;
elf->sec[ELF_SEC_TEXT].v_addr = shdr[i].addr;
elf->sec[ELF_SEC_TEXT].size = ELF_ALIGN(shdr[i].size, 4);
elf->sec[ELF_SEC_TEXT].offset = shdr[i].offset;
ESP_LOGD(TAG, ".text offset is 0x%lx size is 0x%x",
elf->sec[ELF_SEC_TEXT].offset,
elf->sec[ELF_SEC_TEXT].size);
} else if (sflags(&pshdr[i], SHF_WRITE) && !strcmp(ELF_DATA, name)) {
} else if (sflags(&shdr[i], SHF_WRITE) && !strcmp(ELF_DATA, name)) {
ESP_LOGD(TAG, ".data sec addr=0x%08x size=0x%08x offset=0x%08x",
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
shdr[i].addr, shdr[i].size, shdr[i].offset);
elf->sec[ELF_SEC_DATA].v_addr = pshdr[i].addr;
elf->sec[ELF_SEC_DATA].size = pshdr[i].size;
elf->sec[ELF_SEC_DATA].offset = pshdr[i].offset;
elf->sec[ELF_SEC_DATA].v_addr = shdr[i].addr;
elf->sec[ELF_SEC_DATA].size = shdr[i].size;
elf->sec[ELF_SEC_DATA].offset = shdr[i].offset;
ESP_LOGD(TAG, ".data offset is 0x%lx size is 0x%x",
elf->sec[ELF_SEC_DATA].offset,
elf->sec[ELF_SEC_DATA].size);
} else if (!strcmp(ELF_RODATA, name)) {
ESP_LOGD(TAG, ".rodata sec addr=0x%08x size=0x%08x offset=0x%08x",
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
shdr[i].addr, shdr[i].size, shdr[i].offset);
elf->sec[ELF_SEC_RODATA].v_addr = pshdr[i].addr;
elf->sec[ELF_SEC_RODATA].size = pshdr[i].size;
elf->sec[ELF_SEC_RODATA].offset = pshdr[i].offset;
elf->sec[ELF_SEC_RODATA].v_addr = shdr[i].addr;
elf->sec[ELF_SEC_RODATA].size = shdr[i].size;
elf->sec[ELF_SEC_RODATA].offset = shdr[i].offset;
ESP_LOGD(TAG, ".rodata offset is 0x%lx size is 0x%x",
elf->sec[ELF_SEC_RODATA].offset,
elf->sec[ELF_SEC_RODATA].size);
} else if (!strcmp(ELF_DATA_REL_RO, name)) {
ESP_LOGD(TAG, ".data.rel.ro sec addr=0x%08x size=0x%08x offset=0x%08x",
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
shdr[i].addr, shdr[i].size, shdr[i].offset);
elf->sec[ELF_SEC_DRLRO].v_addr = pshdr[i].addr;
elf->sec[ELF_SEC_DRLRO].size = pshdr[i].size;
elf->sec[ELF_SEC_DRLRO].offset = pshdr[i].offset;
elf->sec[ELF_SEC_DRLRO].v_addr = shdr[i].addr;
elf->sec[ELF_SEC_DRLRO].size = shdr[i].size;
elf->sec[ELF_SEC_DRLRO].offset = shdr[i].offset;
ESP_LOGD(TAG, ".data.rel.ro offset is 0x%lx size is 0x%x",
elf->sec[ELF_SEC_DRLRO].offset,
elf->sec[ELF_SEC_DRLRO].size);
}
} else if (stype(&pshdr[i], SHT_NOBITS) &&
sflags(&pshdr[i], SHF_ALLOC | SHF_WRITE) &&
} else if (stype(&shdr[i], SHT_NOBITS) &&
sflags(&shdr[i], SHF_ALLOC | SHF_WRITE) &&
!strcmp(ELF_BSS, name)) {
ESP_LOGD(TAG, ".bss sec addr=0x%08x size=0x%08x offset=0x%08x",
pshdr[i].addr, pshdr[i].size, pshdr[i].offset);
shdr[i].addr, shdr[i].size, shdr[i].offset);
elf->sec[ELF_SEC_BSS].v_addr = pshdr[i].addr;
elf->sec[ELF_SEC_BSS].size = pshdr[i].size;
elf->sec[ELF_SEC_BSS].offset = pshdr[i].offset;
elf->sec[ELF_SEC_BSS].v_addr = shdr[i].addr;
elf->sec[ELF_SEC_BSS].size = shdr[i].size;
elf->sec[ELF_SEC_BSS].offset = shdr[i].offset;
ESP_LOGD(TAG, ".bss offset is 0x%lx size is 0x%x",
elf->sec[ELF_SEC_BSS].offset,
@@ -174,7 +136,7 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
}
}
/* Dump ".text" from ELF to excutable space memory */
/* Dump ".text" from ELF to executable space memory */
elf->sec[ELF_SEC_TEXT].addr = (Elf32_Addr)elf->ptext;
memcpy(elf->ptext, pbuf + elf->sec[ELF_SEC_TEXT].offset,
@@ -183,6 +145,7 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
#ifdef CONFIG_ELF_LOADER_SET_MMU
if (esp_elf_arch_init_mmu(elf)) {
esp_elf_free(elf->ptext);
esp_elf_free(elf->pdata);
return -EIO;
}
#endif
@@ -231,8 +194,8 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
/* Set ELF entry */
entry = phdr->entry + elf->sec[ELF_SEC_TEXT].addr -
elf->sec[ELF_SEC_TEXT].v_addr;
entry = ehdr->entry + elf->sec[ELF_SEC_TEXT].addr -
elf->sec[ELF_SEC_TEXT].v_addr;
#ifdef CONFIG_ELF_LOADER_CACHE_OFFSET
elf->entry = (void *)elf_remap_text(elf, (uintptr_t)entry);
@@ -240,21 +203,203 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
elf->entry = (void *)entry;
#endif
return 0;
}
#else
/**
* @brief Load ELF segment.
*
* @param elf - ELF object pointer
* @param pbuf - ELF data buffer
*
* @return ESP_OK if success or other if failed.
*/
static int esp_elf_load_segment(esp_elf_t *elf, const uint8_t *pbuf)
{
uint32_t size;
bool first_segment = false;
Elf32_Addr vaddr_s = 0;
Elf32_Addr vaddr_e = 0;
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
const elf32_phdr_t *phdr = (const elf32_phdr_t *)(pbuf + ehdr->phoff);
for (int i = 0; i < ehdr->phnum; i++) {
if (phdr[i].type != PT_LOAD) {
continue;
}
if (phdr[i].memsz < phdr[i].filesz) {
ESP_LOGE(TAG, "Invalid segment[%d], memsz: %d, filesz: %d",
i, phdr[i].memsz, phdr[i].filesz);
return -EINVAL;
}
if (first_segment == true) {
vaddr_s = phdr[i].vaddr;
vaddr_e = phdr[i].vaddr + phdr[i].memsz;
first_segment = true;
if (vaddr_e < vaddr_s) {
ESP_LOGE(TAG, "Invalid segment[%d], vaddr: 0x%x, memsz: %d",
i, phdr[i].vaddr, phdr[i].memsz);
return -EINVAL;
}
} else {
if (phdr[i].vaddr < vaddr_e) {
ESP_LOGE(TAG, "Invalid segment[%d], should not overlap, vaddr: 0x%x, vaddr_e: 0x%x\n",
i, phdr[i].vaddr, vaddr_e);
return -EINVAL;
}
if (phdr[i].vaddr > vaddr_e + ADDR_OFFSET) {
ESP_LOGI(TAG, "Too much padding before segment[%d], padding: %d",
i, phdr[i].vaddr - vaddr_e);
}
vaddr_e = phdr[i].vaddr + phdr[i].memsz;
if (vaddr_e < phdr[i].vaddr) {
ESP_LOGE(TAG, "Invalid segment[%d], address overflow, vaddr: 0x%x, vaddr_e: 0x%x\n",
i, phdr[i].vaddr, vaddr_e);
return -EINVAL;
}
}
ESP_LOGD(TAG, "LOAD segment[%d], vaddr: 0x%x, memsize: 0x%08x",
i, phdr[i].vaddr, phdr[i].memsz);
}
size = vaddr_e - vaddr_s;
if (size == 0) {
return -EINVAL;
}
elf->svaddr = vaddr_s;
elf->psegment = esp_elf_malloc(size, true);
if (!elf->psegment) {
return -ENOMEM;
}
memset(elf->psegment, 0, size);
/* Dump "PT_LOAD" from ELF to memory space */
for (int i = 0; i < ehdr->phnum; i++) {
if (phdr[i].type == PT_LOAD) {
memcpy(elf->psegment + phdr[i].vaddr - vaddr_s,
(uint8_t *)pbuf + phdr[i].offset, phdr[i].filesz);
ESP_LOGD(TAG, "Copy segment[%d], mem_addr: 0x%x, vaddr: 0x%x, size: 0x%08x",
i, (int)((uint8_t *)elf->psegment + phdr[i].vaddr - vaddr_s),
phdr[i].vaddr, phdr[i].filesz);
}
}
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
cache_ll_writeback_all(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
#endif
elf->entry = (void *)((uint8_t *)elf->psegment + ehdr->entry - vaddr_s);
return 0;
}
#endif
/**
* @brief Map symbol's address of ELF to physic space.
*
* @param elf - ELF object pointer
* @param sym - ELF symbol address
*
* @return ESP_OK if success or other if failed.
*/
uintptr_t esp_elf_map_sym(esp_elf_t *elf, uintptr_t sym)
{
for (int i = 0; i < ELF_SECS; i++) {
if ((sym >= elf->sec[i].v_addr) &&
(sym < (elf->sec[i].v_addr + elf->sec[i].size))) {
return sym - elf->sec[i].v_addr + elf->sec[i].addr;
}
}
return 0;
}
/**
* @brief Initialize ELF object.
*
* @param elf - ELF object pointer
*
* @return ESP_OK if success or other if failed.
*/
int esp_elf_init(esp_elf_t *elf)
{
ESP_LOGI(TAG, "ELF loader version: %d.%d.%d", ELF_LOADER_VER_MAJOR, ELF_LOADER_VER_MINOR, ELF_LOADER_VER_PATCH);
if (!elf) {
return -EINVAL;
}
memset(elf, 0, sizeof(esp_elf_t));
return 0;
}
/**
* @brief Decode and relocate ELF data.
*
* @param elf - ELF object pointer
* @param pbuf - ELF data buffer
*
* @return ESP_OK if success or other if failed.
*/
int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
{
int ret;
const elf32_hdr_t *ehdr;
const elf32_shdr_t *shdr;
const char *shstrab;
if (!elf || !pbuf) {
return -EINVAL;
}
ehdr = (const elf32_hdr_t *)pbuf;
shdr = (const elf32_shdr_t *)(pbuf + ehdr->shoff);
shstrab = (const char *)pbuf + shdr[ehdr->shstrndx].offset;
/* Load section or segment to memory space */
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
ret = esp_elf_load_section(elf, pbuf);
#else
ret = esp_elf_load_segment(elf, pbuf);
#endif
if (ret) {
ESP_LOGE(TAG, "Error to load elf file, ret=%d", ret);
return ret;
}
ESP_LOGI(TAG, "elf->entry=%p\n", elf->entry);
/* Relocation section data */
for (uint32_t i = 0; i < phdr->shnum; i++) {
if (stype(&pshdr[i], SHT_RELA)) {
for (uint32_t i = 0; i < ehdr->shnum; i++) {
if (stype(&shdr[i], SHT_RELA)) {
uint32_t nr_reloc;
const elf32_rela_t *rela;
const elf32_sym_t *symtab;
const char *strtab;
nr_reloc = pshdr[i].size / sizeof(elf32_rela_t);
rela = (const elf32_rela_t *)(pbuf + pshdr[i].offset);
symtab = (const elf32_sym_t *)(pbuf + pshdr[pshdr[i].link].offset);
strtab = (const char *)(pbuf + pshdr[pshdr[pshdr[i].link].link].offset);
nr_reloc = shdr[i].size / sizeof(elf32_rela_t);
rela = (const elf32_rela_t *)(pbuf + shdr[i].offset);
symtab = (const elf32_sym_t *)(pbuf + shdr[shdr[i].link].offset);
strtab = (const char *)(pbuf + shdr[shdr[shdr[i].link].link].offset);
ESP_LOGD(TAG, "Section %s has %d symbol tables", shstrab + pshdr[i].name, (int)nr_reloc);
ESP_LOGD(TAG, "Section %s has %d symbol tables", shstrab + shdr[i].name, (int)nr_reloc);
for (int i = 0; i < nr_reloc; i++) {
int type;
@@ -265,8 +410,8 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
const elf32_sym_t *sym = &symtab[ELF_R_SYM(rela_buf.info)];
type = ELF_R_TYPE(rela->info);
if (type == STT_COMMON) {
type = ELF_R_TYPE(rela_buf.info);
if (type == STT_COMMON || type == STT_OBJECT || type == STT_SECTION) {
const char *comm_name = strtab + sym->name;
if (comm_name[0]) {
@@ -274,8 +419,12 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
if (!addr) {
ESP_LOGE(TAG, "Can't find common %s", strtab + sym->name);
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
esp_elf_free(elf->pdata);
esp_elf_free(elf->ptext);
#else
esp_elf_free(elf->psegment);
#endif
return -ENOSYS;
}
@@ -292,8 +441,12 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
if (!addr) {
ESP_LOGE(TAG, "Can't find symbol %s", func_name);
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
esp_elf_free(elf->pdata);
esp_elf_free(elf->ptext);
#else
esp_elf_free(elf->psegment);
#endif
return -ENOSYS;
}
@@ -319,11 +472,15 @@ int esp_elf_relocate(esp_elf_t *elf, const uint8_t *pbuf)
* @param opt - Request options
* @param argc - Arguments number
* @param argv - Arguments value array
*
* @return ESP_OK if sucess or other if failed.
*
* @return ESP_OK if success or other if failed.
*/
int esp_elf_request(esp_elf_t *elf, int opt, int argc, char *argv[])
{
if (!elf || !(elf->entry)) {
return -EINVAL;
}
elf->entry(argc, argv);
return 0;
@@ -333,11 +490,12 @@ 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)
{
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
if (elf->pdata) {
esp_elf_free(elf->pdata);
elf->pdata = NULL;
@@ -347,6 +505,12 @@ void esp_elf_deinit(esp_elf_t *elf)
esp_elf_free(elf->ptext);
elf->ptext = NULL;
}
#else
if (elf->psegment) {
esp_elf_free(elf->ptext);
elf->ptext = NULL;
}
#endif
#ifdef CONFIG_ELF_LOADER_SET_MMU
esp_elf_arch_deinit_mmu(elf);
@@ -357,10 +521,10 @@ 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)
void esp_elf_print_ehdr(const uint8_t *pbuf)
{
const char *s_bits, *s_endian;
const elf32_hdr_t *hdr = (const elf32_hdr_t *)pbuf;
@@ -411,30 +575,56 @@ void esp_elf_print_hdr(const uint8_t *pbuf)
ESP_LOGI(TAG, "%-40s %d", "Section header string table i:", hdr->shstrndx);
}
/**
* @brief Print program header description information of ELF.
*
* @param pbuf - ELF data buffer
*
* @return None
*/
void esp_elf_print_phdr(const uint8_t *pbuf)
{
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
const elf32_phdr_t *phdr = (const elf32_phdr_t *)((size_t)pbuf + ehdr->phoff);
for (int i = 0; i < ehdr->phnum; i++) {
ESP_LOGI(TAG, "%-40s %d", "type:", phdr->type);
ESP_LOGI(TAG, "%-40s 0x%x", "offset:", phdr->offset);
ESP_LOGI(TAG, "%-40s 0x%x", "vaddr", phdr->vaddr);
ESP_LOGI(TAG, "%-40s 0x%x", "paddr:", phdr->paddr);
ESP_LOGI(TAG, "%-40s %d", "filesz", phdr->filesz);
ESP_LOGI(TAG, "%-40s %d", "memsz", phdr->memsz);
ESP_LOGI(TAG, "%-40s %d", "flags", phdr->flags);
ESP_LOGI(TAG, "%-40s 0x%x", "align", phdr->align);
phdr = (const elf32_phdr_t *)((size_t)phdr + sizeof(elf32_phdr_t));
}
}
/**
* @brief Print section header description information of ELF.
*
* @param pbuf - ELF data buffer
*
*
* @return None
*/
void esp_elf_print_shdr(const uint8_t *pbuf)
{
const elf32_hdr_t *phdr = (const elf32_hdr_t *)pbuf;
const elf32_shdr_t *pshdr = (const elf32_shdr_t *)((size_t)pbuf + phdr->shoff);
const elf32_hdr_t *ehdr = (const elf32_hdr_t *)pbuf;
const elf32_shdr_t *shdr = (const elf32_shdr_t *)((size_t)pbuf + ehdr->shoff);
for (int i = 0; i < phdr->shnum; i++) {
ESP_LOGI(TAG, "%-40s %d", "name:", pshdr->name);
ESP_LOGI(TAG, "%-40s %d", "type:", pshdr->type);
ESP_LOGI(TAG, "%-40s 0x%x", "flags:", pshdr->flags);
ESP_LOGI(TAG, "%-40s %x", "addr", pshdr->addr);
ESP_LOGI(TAG, "%-40s %x", "offset:", pshdr->offset);
ESP_LOGI(TAG, "%-40s %d", "size", pshdr->size);
ESP_LOGI(TAG, "%-40s 0x%x", "link", pshdr->link);
ESP_LOGI(TAG, "%-40s %d", "addralign", pshdr->addralign);
ESP_LOGI(TAG, "%-40s %d", "entsize", pshdr->entsize);
for (int i = 0; i < ehdr->shnum; i++) {
ESP_LOGI(TAG, "%-40s %d", "name:", shdr->name);
ESP_LOGI(TAG, "%-40s %d", "type:", shdr->type);
ESP_LOGI(TAG, "%-40s 0x%x", "flags:", shdr->flags);
ESP_LOGI(TAG, "%-40s %x", "addr", shdr->addr);
ESP_LOGI(TAG, "%-40s %x", "offset:", shdr->offset);
ESP_LOGI(TAG, "%-40s %d", "size", shdr->size);
ESP_LOGI(TAG, "%-40s 0x%x", "link", shdr->link);
ESP_LOGI(TAG, "%-40s %d", "addralign", shdr->addralign);
ESP_LOGI(TAG, "%-40s %d", "entsize", shdr->entsize);
pshdr = (const elf32_shdr_t *)((size_t)pshdr + sizeof(elf32_shdr_t));
shdr = (const elf32_shdr_t *)((size_t)shdr + sizeof(elf32_shdr_t));
}
}
@@ -442,7 +632,7 @@ 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)
+21 -9
View File
@@ -23,15 +23,28 @@
*
* @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)
{
uint32_t caps;
#if CONFIG_ELF_LOADER_BUS_ADDRESS_MIRROR
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
uint32_t caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
#else
uint32_t caps = exec ? MALLOC_CAP_EXEC : MALLOC_CAP_8BIT;
caps = exec ? MALLOC_CAP_EXEC : MALLOC_CAP_8BIT;
#endif
#else
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
caps = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
#else
caps = MALLOC_CAP_8BIT;
#endif
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
caps |= MALLOC_CAP_CACHE_ALIGNED;
#endif
#endif
return heap_caps_malloc(n, caps);
@@ -41,7 +54,7 @@ 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)
@@ -50,11 +63,11 @@ void esp_elf_free(void *ptr)
}
/**
* @brief Remap symbol from ".data" to ".text" section.
* @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
@@ -64,7 +77,7 @@ uintptr_t elf_remap_text(esp_elf_t *elf, uintptr_t sym)
esp_elf_sec_t *sec = &elf->sec[ELF_SEC_TEXT];
if ((sym >= sec->addr) &&
(sym < (sec->addr + sec->size))) {
(sym < (sec->addr + sec->size))) {
#ifdef CONFIG_ELF_LOADER_SET_MMU
mapped_sym = sym + elf->text_off;
#else
@@ -82,7 +95,7 @@ uintptr_t elf_remap_text(esp_elf_t *elf, uintptr_t sym)
* @brief Flush data from cache to external RAM.
*
* @param None
*
*
* @return None
*/
#ifdef CONFIG_ELF_LOADER_LOAD_PSRAM
@@ -105,4 +118,3 @@ void IRAM_ATTR esp_elf_arch_flush(void)
spi_flash_enable_interrupts_caches_and_other_cpu();
}
#endif
+31 -24
View File
@@ -19,14 +19,20 @@
#include "rom/ets_sys.h"
#include "elf_symbol.h"
#include "private/elf_symbol.h"
extern int __ltdf2(double a, double b);
extern unsigned int __fixunsdfsi(double a);
extern int __gtdf2(double a, double b);
extern double __floatunsidf(unsigned int i);
extern double __divdf3(double a, double b);
extern int __ltdf2 (double a, double b);
extern unsigned int __fixunsdfsi (double a);
extern int __gtdf2 (double a, double b);
extern double __floatunsidf (unsigned int i);
extern double __divdf3 (double a, double b);
// Tactility custom -->
static const struct esp_elfsym* custom_symbols = NULL;
void elf_set_custom_symbols(const struct esp_elfsym* symbols) {
custom_symbols = symbols;
}
// <-- Tactility custom
/** @brief Libc public functions symbols look-up table */
@@ -150,19 +156,11 @@ static const struct esp_elfsym g_esp_espidf_elfsyms[] = {
ESP_ELFSYM_END
};
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
static const struct esp_elfsym* custom_symbols = NULL;
void elf_set_custom_symbols(const struct esp_elfsym* symbols) {
custom_symbols = symbols;
}
#endif
/**
* @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)
@@ -198,19 +196,28 @@ uintptr_t elf_find_sym(const char *sym_name)
#endif
#ifdef CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS
syms = custom_symbols;
if (syms != NULL) {
while (syms->name) {
if (!strcmp(syms->name, sym_name)) {
return (uintptr_t)syms->sym;
}
extern const struct esp_elfsym g_customer_elfsyms[];
syms++;
syms = g_customer_elfsyms;
while (syms->name) {
if (!strcmp(syms->name, sym_name)) {
return (uintptr_t)syms->sym;
}
}
syms++;
}
#endif
// Tactility custom -->
syms = custom_symbols;
while (syms->name) {
if (!strcmp(syms->name, sym_name)) {
return (uintptr_t)syms->sym;
}
syms++;
}
// <-- Tactility custom
return 0;
}
@@ -16,7 +16,7 @@
#include "soc/mmu.h"
#include "private/elf_platform.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#define PSRAM_VADDR_START 0x3f800000
#else
#define PSRAM_VADDR_START (DRAM0_CACHE_ADDRESS_HIGH - esp_spiram_get_size())
@@ -26,6 +26,12 @@
#define MMU_UNIT_SIZE 0x10000
#define MMU_REG ((volatile uint32_t *)DR_REG_MMU_TABLE)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
#define IRAM0_ADDRESS_LOW SOC_IRAM0_ADDRESS_LOW
#define IRAM0_ADDRESS_HIGH SOC_IRAM0_ADDRESS_HIGH
#define MMU_ACCESS_SPIRAM SOC_MMU_ACCESS_SPIRAM
#endif
#define ESP_MMU_IBUS_BASE IRAM0_ADDRESS_LOW
#define ESP_MMU_IBUS_MAX ((IRAM0_ADDRESS_HIGH - IRAM0_ADDRESS_LOW) / \
MMU_UNIT_SIZE)