diff --git a/os/sb/host/sbelf_old.c b/os/sb/host/sbelf_old.c deleted file mode 100644 index 360861445..000000000 --- a/os/sb/host/sbelf_old.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, - 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation version 3 of the License. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file sb/host/sbelf.c - * @brief ARM SandBox ELF loader code. - * - * @addtogroup ARM_SANDBOX_ELF - * @{ - */ - -#include - -#include "ch.h" -#include "sb.h" - -#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module local definitions. */ -/*===========================================================================*/ - -/* Relevant section types.*/ -#define SHT_PROGBITS 1U -#define SHT_SYMTAB 2U -#define SHT_NOBITS 8U -#define SHT_REL 9U - -/* Relevant section flags.*/ -#define SHF_WRITE (1U << 0) -#define SHF_ALLOC (1U << 1) -#define SHF_EXECINSTR (1U << 2) -#define SHF_INFO_LINK (1U << 6) - -/* Special section indices.*/ -#define SHN_UNDEF 0U - -/* Supported relocation types.*/ -#define R_ARM_ABS32 2U -#define R_ARM_THM_PC22 10U -#define R_ARM_THM_JUMP24 30U - -#define ELF32_R_SYM(v) ((v) >> 8) -#define ELF32_R_TYPE(v) ((v) & 0xFFU) - -/*===========================================================================*/ -/* Module exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local types. */ -/*===========================================================================*/ - -/** - * @brief Type of a section number. - */ -typedef unsigned elf_secnum_t; - -/** - * @brief Type of a symbol number. - */ -typedef unsigned elf_symnum_t; - -/** - * @brief Type of a loadable section info structure. - */ -typedef struct { - elf_secnum_t section; - uint32_t address; - size_t bits_size; - vfs_offset_t bits_off; - size_t rel_size; - vfs_offset_t rel_off; -} elf_loadable_info_t; - -/** - * @brief Type of an ELF loader context. - */ -typedef struct elf_load_context { - vfs_file_node_c *fnp; - const memory_area_t *map; - uint8_t *next; - - uint32_t entry; - elf_secnum_t sections_num; - vfs_offset_t sections_off; - elf_symnum_t symbols_num; - vfs_offset_t symbols_off; - elf_loadable_info_t loadable_code; - elf_loadable_info_t loadable_const; - elf_loadable_info_t loadable_data; -#if 0 -// vfs_offset_t strings_off; -#endif -} elf_load_context_t; - -/** - * @brief Type of an ELF32 header. - */ -typedef struct { - unsigned char e_ident[16]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint32_t e_entry; - uint32_t e_phoff; - uint32_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -} elf32_header_t; - -typedef struct { - uint32_t sh_name; - uint32_t sh_type; - uint32_t sh_flags; - uint32_t sh_addr; - uint32_t sh_offset; - uint32_t sh_size; - uint32_t sh_link; - uint32_t sh_info; - uint32_t sh_addralign; - uint32_t sh_entsize; -} elf32_section_header_t; - -typedef struct { - uint32_t r_offset; - uint32_t r_info; -} elf32_rel_t; - -typedef struct { - uint32_t st_name; - uint32_t st_value; - uint32_t st_size; - uint8_t st_info; - uint8_t st_other; - uint16_t st_shndx; -} elf32_symbol_t; - -/*===========================================================================*/ -/* Module local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module local functions. */ -/*===========================================================================*/ - -#if 0 -static msg_t read_section_name(elf_load_context_t *ctxp, - elf32_section_header_t *shp, - char *buf, size_t buflen) { - msg_t ret; - - if (shp->sh_name == 0U) { - *buf = '\0'; - return CH_RET_SUCCESS; - } - - ret = vfsSetFilePosition(ctxp->fnp, - ctxp->stringsoff + (vfs_offset_t)shp->sh_name, - VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)buf, buflen); - CH_RETURN_ON_ERROR(ret); - - return CH_RET_SUCCESS; -} -#endif - -static msg_t read_section_header(elf_load_context_t *ctxp, - elf32_section_header_t *shp, - elf_secnum_t index) { - msg_t ret; - - ret = vfsSetFilePosition(ctxp->fnp, - ctxp->sections_off + ((vfs_offset_t)index * - (vfs_offset_t)sizeof (elf32_section_header_t)), - VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - return vfsReadFile(ctxp->fnp, (void *)shp, sizeof (elf32_section_header_t)); -} - -static msg_t allocate_section(elf_load_context_t *ctxp, - elf32_section_header_t *shp) { - uint8_t *load_address; - - /* Checking if the section can fit into the destination memory area.*/ - load_address = ctxp->map->base + shp->sh_addr; - if (!chMemIsSpaceWithinX(ctxp->map, - (const void *)load_address, - (size_t)shp->sh_size)) { - return CH_RET_ENOMEM; - } - - return CH_RET_SUCCESS; -} - -static elf_loadable_info_t *find_loaded_section(elf_load_context_t *ctxp, - elf_secnum_t sn) { - - if (sn == ctxp->loadable_code.section) { - /* Executable code section.*/ - return &ctxp->loadable_code; - } - if (sn == ctxp->loadable_data.section) { - /* Writable data section.*/ - return &ctxp->loadable_data; - } - if (sn == ctxp->loadable_const.section) { - /* Constants data section.*/ - return &ctxp->loadable_const; - } - - return NULL; -} - -#if 0 -static msg_t reloc_jump(uint32_t relocation_address, - uint32_t destination_address) { - - uint32_t ins = (((uint32_t *)relocation_address)[0] << 16) | - (((uint32_t *)relocation_address)[1] << 0); - uint32_t s = (ins >> 26) & 1U; - uint32_t j1 = (ins >> 13) & 1U; - uint32_t j2 = (ins >> 11) & 1U; - uint32_t off = (s << 24) | - ((~(j1 ^ s) & 1U) << 23) | - ((~(j2 ^ s) & 1U) << 22) | - ((ins & 0x03FF0000U) >> 4) | - ((ins & 0x000007FFU) << 1); -} -#endif - -static msg_t reloc_entry(elf_load_context_t *ctxp, - elf_loadable_info_t *lip, - elf32_rel_t *rp) { - vfs_offset_t symoff; - elf_symnum_t symnum; - uint32_t relocation_address; - elf_loadable_info_t *symbol_lip; - elf32_symbol_t symbol; - msg_t ret; - - /* Checking for a symbol number overflow.*/ - symnum = (elf_symnum_t)ELF32_R_SYM(rp->r_info); - if (symnum > ctxp->symbols_num) { - return CH_RET_ENOEXEC; - } - - /* Moving file pointer to the symbol then reading it.*/ - symoff = ctxp->symbols_off + ((vfs_offset_t)symnum * - (vfs_offset_t)sizeof (elf32_symbol_t)); - ret = vfsSetFilePosition(ctxp->fnp, symoff, VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)&symbol, sizeof (elf32_symbol_t)); - CH_RETURN_ON_ERROR(ret); - - /* Undefined symbols are not handled, this is a loader not a linker.*/ - if (symbol.st_shndx == SHN_UNDEF) { - return CH_RET_ENOEXEC; - } - - /* Symbols must be associated to an already loaded section.*/ - symbol_lip = find_loaded_section(ctxp, (elf_symnum_t)symbol.st_shndx); - if (symbol_lip == NULL) { - return CH_RET_ENOEXEC; - } - - /* Relocation point address.*/ - relocation_address = (uint32_t)ctxp->map->base + - lip->address + - rp->r_offset; - if (!chMemIsSpaceWithinX(ctxp->map, - (const void *)relocation_address, - sizeof (uint32_t))) { - return CH_RET_ENOMEM; - } - - /* Handling the various relocation point types.*/ - switch (ELF32_R_TYPE(rp->r_info)) { - case R_ARM_ABS32: - *((uint32_t *)relocation_address) += (uint32_t)ctxp->map->base + - symbol_lip->address + - symbol.st_value; - break; - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP24: -// return reloc_jump(relocation_address, symbol_lip->address); - /* TODO */ - break; - default: - return CH_RET_ENOEXEC; - } - - return CH_RET_SUCCESS; -} - -static msg_t reloc_section(elf_load_context_t *ctxp, - elf_loadable_info_t *lip) { - elf32_rel_t *rbuf; - size_t size, done_size, remaining_size; - msg_t ret; - - rbuf = (elf32_rel_t *)(void *)vfs_buffer_take(); - - /* Reading the relocation section data.*/ - remaining_size = lip->rel_size; - done_size = 0U; - while (remaining_size > 0U) { - unsigned i, n; - - /* Reading relocation data using buffers in order to not make continuous - calls to the FS which could be unbuffered.*/ - if (remaining_size > VFS_BUFFERS_SIZE) { - size = VFS_BUFFERS_SIZE; - } - else { - size = remaining_size; - } - - /* Reading a buffer-worth of relocation data.*/ - ret = vfsSetFilePosition(ctxp->fnp, - lip->rel_off + (vfs_offset_t)done_size, - VFS_SEEK_SET); - CH_BREAK_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)rbuf, size); - CH_BREAK_ON_ERROR(ret); - - /* Number of relocation entries in the buffer.*/ - n = (unsigned)ret / (unsigned)sizeof (elf32_rel_t); - for (i = 0U; i < n; i++) { - ret = reloc_entry(ctxp, lip, &rbuf[i]); - CH_BREAK_ON_ERROR(ret); - } - CH_BREAK_ON_ERROR(ret); - - remaining_size -= size; - done_size += size; - } - - vfs_buffer_release((char *)rbuf); - - return ret; -} - -static msg_t load_relocate_section(elf_load_context_t *ctxp, - elf_loadable_info_t *lip) { - uint8_t *load_address; - msg_t ret; - - if (lip->rel_size > 0U) { - - /* Checking if the section can fit into the destination memory area.*/ - load_address = ctxp->map->base + lip->address; - if (!chMemIsSpaceWithinX(ctxp->map, - (const void *)load_address, - lip->bits_size)) { - return CH_RET_ENOMEM; - } - - /* Loading the section data into the final memory area.*/ - if (lip->bits_size > 0U) { - ret = vfsSetFilePosition(ctxp->fnp, lip->bits_off, VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)load_address, lip->bits_size); - CH_RETURN_ON_ERROR(ret); - } - - ret = reloc_section(ctxp, lip); - CH_RETURN_ON_ERROR(ret); - } - - return CH_RET_SUCCESS; -} - -static msg_t init_elf_context(elf_load_context_t *ctxp, - vfs_file_node_c *fnp, - const memory_area_t *map) { - static uint8_t elf32_header[16] = { - 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - elf32_header_t h; - msg_t ret; - - /* Context fully cleared.*/ - memset((void *)ctxp, 0, sizeof (elf_load_context_t)); - - /* Initializing the fixed part of the context.*/ - ctxp->fnp = fnp; - ctxp->map = map; - ctxp->next = map->base; - - /* Reading the main ELF header.*/ - ret = vfsSetFilePosition(ctxp->fnp, (vfs_offset_t)0, VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)&h, sizeof (elf32_header_t)); - CH_RETURN_ON_ERROR(ret); - - /* Checking for the expected header.*/ - if (memcmp(h.e_ident, elf32_header, 16) != 0) { - return CH_RET_ENOEXEC; - } - - /* TODO more consistency checks.*/ - - /* Storing info required later.*/ - ctxp->entry = h.e_entry; - ctxp->sections_num = (unsigned)h.e_shnum; - ctxp->sections_off = (vfs_offset_t)h.e_shoff; - - return CH_RET_SUCCESS; -} - -/*===========================================================================*/ -/* Module exported functions. */ -/*===========================================================================*/ - -msg_t sbElfLoad(vfs_file_node_c *fnp, const memory_area_t *map) { - msg_t ret; - - do { - elf_load_context_t ctx; - elf_loadable_info_t *lip; - elf_secnum_t i; - - ret = init_elf_context(&ctx, fnp, map); - CH_BREAK_ON_ERROR(ret); - - /* Discovery phase, scanning section headers and gathering data.*/ - for (i = 0U; i < ctx.sections_num; i++) { - elf32_section_header_t sh; - - /* Reading the header.*/ - ret = read_section_header(&ctx, &sh, i); - CH_BREAK_ON_ERROR(ret); - - /* Empty sections are not processed.*/ - if (sh.sh_size == 0U) { - continue; - } - - /* Deciding what to do with the section depending on type.*/ - switch (sh.sh_type) { - case SHT_PROGBITS: - /* Loadable section type, we allow for one executable, one data and - one constants sections.*/ - if ((sh.sh_flags & SHF_ALLOC) != 0U) { - - if ((sh.sh_flags & SHF_EXECINSTR) != 0U) { - /* Executable code section.*/ - lip = &ctx.loadable_code; - } - else if ((sh.sh_flags & SHF_WRITE) != 0U) { - /* Writable data section.*/ - lip = &ctx.loadable_data; - } - else { - /* Constants data section.*/ - lip = &ctx.loadable_const; - } - - /* Multiple sections of same kind.*/ - if (lip->section != 0U) { - return CH_RET_ENOEXEC; - } - - lip->section = i; - lip->address = sh.sh_addr; - lip->bits_size = (size_t)sh.sh_size; - lip->bits_off = (vfs_offset_t)sh.sh_offset; - - } - break; - - case SHT_NOBITS: - /* Uninitialized data section, we can have more than one, just checking - address ranges.*/ - if ((sh.sh_flags & SHF_ALLOC) != 0U) { - ret = allocate_section(&ctx, &sh); - CH_RETURN_ON_ERROR(ret); - } - break; - - case SHT_REL: - if ((sh.sh_flags & SHF_INFO_LINK) != 0U) { - - lip = find_loaded_section(&ctx, (elf_secnum_t)sh.sh_info); - if (lip == NULL) { - /* Ignoring other relocation sections.*/ - break; - } - - /* Multiple relocation sections associated to the same section.*/ - if (lip->rel_size != 0U) { - return CH_RET_ENOEXEC; - } - - lip->rel_size = sh.sh_size; - lip->rel_off = (vfs_offset_t)sh.sh_offset; - } - break; - - case SHT_SYMTAB: - /* Symbols section, this is required for relocation.*/ - - if (ctx.symbols_num != 0U) { - /* Multiple symbol sections.*/ - return CH_RET_ENOEXEC; - } - - ctx.symbols_num = (elf_symnum_t)sh.sh_size / - (elf_symnum_t)sizeof (elf32_symbol_t); - ctx.symbols_off = (vfs_offset_t)sh.sh_offset; - break; - - default: - /* Ignoring other section types.*/ - break; - } - } - - /* Loading phase.*/ - ret = load_relocate_section(&ctx, &ctx.loadable_code); - CH_RETURN_ON_ERROR(ret); - ret = load_relocate_section(&ctx, &ctx.loadable_data); - CH_RETURN_ON_ERROR(ret); - ret = load_relocate_section(&ctx, &ctx.loadable_const); - CH_RETURN_ON_ERROR(ret); - } while (false); - - return ret; -} - -msg_t sbElfLoadFile(vfs_driver_c *drvp, - const char *path, - const memory_area_t *map) { - vfs_file_node_c *fnp; - msg_t ret; - - ret = vfsDrvOpenFile(drvp, path, VO_RDONLY, &fnp); - CH_RETURN_ON_ERROR(ret); - - do { - ret = sbElfLoad(fnp, map); - CH_BREAK_ON_ERROR(ret); - - } while (false); - - vfsClose((vfs_node_c *)fnp); - - return ret; -} - -#endif /* SB_CFG_ENABLE_VFS == TRUE */ - -/** @} */ diff --git a/os/sb/host/sbelf_old.h b/os/sb/host/sbelf_old.h deleted file mode 100644 index 62ca61c9e..000000000 --- a/os/sb/host/sbelf_old.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, - 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. - - This file is part of ChibiOS. - - ChibiOS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation version 3 of the License. - - ChibiOS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file sb/host/sbloader.h - * @brief ARM SandBox ELF loader macros and structures. - * - * @addtogroup sbhost.h - * @{ - */ - -#ifndef SBELF_H -#define SBELF_H - -#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - msg_t sbElfLoad(vfs_file_node_c *fnp, - const memory_area_t *map); - msg_t sbElfLoadFile(vfs_driver_c *drvp, - const char *path, - const memory_area_t *map); -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -#endif /* SB_CFG_ENABLE_VFS == TRUE */ - -#endif /* SBELF_H */ - -/** @} */