From 4532dd92433cf2b2f491d497e4abb4dd11fa1d48 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 6 Jan 2022 08:01:46 +0000 Subject: [PATCH] More loader code, not finished yet. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15318 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/sb/host/sbelf.c | 156 ++++++++++++++++++++++++++++++++++++++++----- os/sb/host/sbelf.h | 3 +- 2 files changed, 142 insertions(+), 17 deletions(-) diff --git a/os/sb/host/sbelf.c b/os/sb/host/sbelf.c index 2c8723327..f62a9ee78 100644 --- a/os/sb/host/sbelf.c +++ b/os/sb/host/sbelf.c @@ -36,6 +36,16 @@ /* Module local definitions. */ /*===========================================================================*/ +/* Relevant section types.*/ +#define SHT_PROGBITS 1U +#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) + /*===========================================================================*/ /* Module exported variables. */ /*===========================================================================*/ @@ -56,6 +66,7 @@ typedef struct elf_load_context { uint16_t shnum; vfs_offset_t shoff; vfs_offset_t stringsoff; + uint64_t loaded; } elf_load_context_t; /** @@ -95,12 +106,65 @@ typedef struct { /* 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, + unsigned index) { + msg_t ret; + + ret = vfsSetFilePosition(ctxp->fnp, + ctxp->shoff + ((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 load_section(elf_load_context_t *ctxp, + elf32_section_header_t *shp) { + + (void)ctxp; + (void)shp; + + return CH_RET_SUCCESS; +} + +static msg_t reloc_section(elf_load_context_t *ctxp, + elf32_section_header_t *shp) { + + (void)ctxp; + (void)shp; + + return CH_RET_SUCCESS; +} + static msg_t init_elf_context(elf_load_context_t *ctxp, + elf32_section_header_t *shp, vfs_file_node_c *fnp, memory_area_t *map) { static uint8_t elf32_header[16] = { @@ -108,9 +172,10 @@ static msg_t init_elf_context(elf_load_context_t *ctxp, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; elf32_header_t h; - elf32_section_header_t sh; msg_t ret; + memset((void *)ctxp, 0, sizeof (elf_load_context_t)); + /* Initializing the fixed part of the context.*/ ctxp->fnp = fnp; ctxp->map = map; @@ -129,20 +194,14 @@ static msg_t init_elf_context(elf_load_context_t *ctxp, /* TODO more consistency checks.*/ - /* Reading the header of the section containing the section names.*/ - ret = vfsSetFilePosition(ctxp->fnp, - (vfs_offset_t)(h.e_shoff + - (h.e_shstrndx * sizeof (elf32_section_header_t))), - VFS_SEEK_SET); - CH_RETURN_ON_ERROR(ret); - ret = vfsReadFile(ctxp->fnp, (void *)&sh, sizeof (elf32_section_header_t)); - CH_RETURN_ON_ERROR(ret); - /* Storing info required later.*/ ctxp->entry = h.e_entry; ctxp->shnum = h.e_shnum; ctxp->shoff = (vfs_offset_t)h.e_shoff; - ctxp->stringsoff = (vfs_offset_t)sh.sh_offset; + + /* Reading the header of the section containing the section names.*/ + ret = read_section_header(ctxp, shp, (unsigned)h.e_shstrndx); + ctxp->stringsoff = (vfs_offset_t)shp->sh_offset; return CH_RET_SUCCESS; } @@ -151,23 +210,88 @@ static msg_t init_elf_context(elf_load_context_t *ctxp, /* Module exported functions. */ /*===========================================================================*/ -msg_t sbElfLoad(vfs_driver_c *drvp, const char *path, memory_area_t *map) { +msg_t sbElfLoad(vfs_file_node_c *fnp, memory_area_t *map) { + elf_load_context_t ctx; + elf32_section_header_t sh; + unsigned i; + msg_t ret; + + do { + ret = init_elf_context(&ctx, &sh, fnp, map); + CH_BREAK_ON_ERROR(ret); + + /* Iterating through sections.*/ + for (i = 0U; i < (unsigned)ctx.shnum; i++) { +// char name[8]; + + ret = read_section_header(&ctx, &sh, i); + CH_BREAK_ON_ERROR(ret); + +#if 0 + ret = read_section_name(&ctx, &sh, name, sizeof name); + CH_BREAK_ON_ERROR(ret); + + /* Handling the various sections.*/ + if (strcmp(name, ".text") == (size_t)0) { + ret = load_section(&ctx, &sh, i); + } + else if (strcmp(name, ".rodata") == (size_t)0) { + ret = load_section(&ctx, &sh, i); + } + else if (strcmp(name, ".data") == (size_t)0) { + ret = load_section(&ctx, &sh, i); + } + else if (strcmp(name, ".bss") == (size_t)0) { + + } +#endif + + /* Sections to be loaded.*/ + if ((sh.sh_type == SHT_PROGBITS) && ((sh.sh_flags & SHF_ALLOC) != 0U)) { + + /* Loading sections with index greater than 63 is not supported.*/ + if (i >= 64U) { + return CH_RET_ENOMEM; + } + + ret = load_section(&ctx, &sh); + CH_RETURN_ON_ERROR(ret); + + ctx.loaded |= (1ULL << i); + } + + /* Sections to be relocated, must refer to a loaded section.*/ + if ((sh.sh_type == SHT_REL) && + ((sh.sh_flags & SHF_INFO_LINK) != 0U) && + ((ctx.loaded & (1ULL << sh.sh_info)) != 0ULL)) { + + ret = reloc_section(&ctx, &sh); + CH_RETURN_ON_ERROR(ret); + + } + } + + } while (false); + + return ret; +} + +msg_t sbElfLoadFile(vfs_driver_c *drvp, const char *path, memory_area_t *map) { vfs_file_node_c *fnp; msg_t ret; - elf_load_context_t ctx; ret = vfsDrvOpenFile(drvp, path, VO_RDONLY, &fnp); CH_RETURN_ON_ERROR(ret); do { - ret = init_elf_context(&ctx, fnp, map); + ret = sbElfLoad(fnp, map); CH_BREAK_ON_ERROR(ret); } while (false); vfsClose((vfs_node_c *)fnp); - return CH_RET_SUCCESS; + return ret; } #endif /* SB_CFG_ENABLE_VFS == TRUE */ diff --git a/os/sb/host/sbelf.h b/os/sb/host/sbelf.h index 79f96ba8a..773b07f11 100644 --- a/os/sb/host/sbelf.h +++ b/os/sb/host/sbelf.h @@ -57,7 +57,8 @@ #ifdef __cplusplus extern "C" { #endif - msg_t sbElfLoad(vfs_driver_c *drvp, const char *path, memory_area_t *map); + msg_t sbElfLoad(vfs_file_node_c *fnp, memory_area_t *map); + msg_t sbElfLoadFile(vfs_driver_c *drvp, const char *path, memory_area_t *map); #ifdef __cplusplus } #endif