Awesome
elfloader
For contributing list see CONTRIBUTORS.md
ARMv7M ELF loader
The goal of this project is provide a loader for ELF file format for ARMv7-M (thumb-2) architecture (Aka Cortex-M, Cortex-R in Thumb2 mode) over bare-metal or RTOS enviroment.
This loader not required MMU or special OS support (only aligned memory alloc) and run with minimun memory overhead (only required parts of files is loaded in memory).
This is developed using gcc arm embedded compiler from GCC arm embedded (arm-none-eabi) but is successful tested with linaro arm-linux-gnueabihf in freestangin mode.
ELF creation
For correct handling, The code must be compiled with certain characteristics:
- No common section is allowed. All non-init data is in bss (CC -fno-common)
- Only word relocation is allowed. (CC -mword-relocation) This is not realy
true, some compilers produce R_ARM_THB_CALL/JMP relocation and ignore
word-relocation flags, therefore, the loader handling only two relocation:
- R_ARM_ABS32 Emmited on every data access and some jmp (weak/extern)
- R_ARM_THB_JMP/CALL Emmited on some short jumps (CC -mlong-call flag not fix it)
- Relocatable ELF is required (LD -r option)
- No start library (LD -nostartfiles)
Additionally, following memory sections are recognized: .sdram_data, .sdram_rodata, .sdram_bss.
An example of application is found in the app folder
Usage
The API is simple, first call to #load_elf to obtain an execution context.
extern int load_elf(const char *path, const ELFEnv_t *env, ELFExec_t **exec);
This function take a path to a file, and ELFEnv_t is a struct containing:
typedef struct {
const ELFSymbol_t *exported;
size_t exported_size;
} ELFEnv_t;
exported
: Array of symbols to resolve in executable.ELFSymbol_t
is a struct containsconst char *name
for C-String symbol name andvoid *ptr
pointer to memory related to symbol (entry point of function, variable address, etc)size
: Size of exported symbol array in elements number
Then, #jumpTo and #get_func calls can be made:
extern int jumpTo(ELFExec_t *exec);
to execute code at the entry point of the ELF.
Use
extern void * get_func(ELFExec_t *exec, const char *func_name);
to obtain a function pointer corresponding to a (mangled) symbol name.
And
extern void * get_obj(ELFExec_t *exec, const char *obj_name);
to obtain a pointer corresponding to a global variable.
Finally, the execution context can be cleaned up:
extern int unload_elf(ELFExec_t *exec);
Loader config
File handling macros
LOADER_FD_T
File descriptor typeLOADER_OPEN_FOR_RD(path)
Function to open file for readLOADER_FD_VALID(fd)
Validity evaluation of file descriptorLOADER_READ(fd, buffer, size)
Function to read buffer from fdLOADER_CLOSE(fd)
Function to close file descriptorLOADER_SEEK_FROM_START(fd, off)
Seek function over fdLOADER_TELL(fd)
Tell position of fd cursor
Memory manager/access
LOADER_ALIGN_ALLOC(size, align, perm)
Aligned malloc function macroLOADER_ALIGN_ALLOC_SDRAM(size, align, perm)
Aligned malloc function macro (for .sdram_* sections)LOADER_FREE(ptr)
Free memory functionLOADER_CLEAR(ptr, size)
Memory clearance (to 0) functionLOADER_STREQ(s1, s2)
String compare function (return !=0 if s1==s2)
Code execution
LOADER_JUMP_TO(entry)
Macro for jump to "entry" pointer (entry_t)
Debug/message
DBG(...)
printf style macro for debugERR(msg)
puts style macro used on severe errorMSG(msg)
puts style macro used on info/warning