Skip to content

gerstl/elfloader

 
 

Repository files navigation

elfloader

Original version by Martin Ribelotta martinribelott@gmail.com Forked by Andreas Gerstlauer gerstl@ece.utexas.edu

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.

This fork adds support for both loading of relocatable object files from ELF section information as well as loading of ELF executables (EXEC type) from their program (PT_LOAD) segments, including support for relocation and dynamic linking via corresponding (PT_DYNAMIC) sections. This has been tested with executables generated by Keil uVision 4.7. In addition, support for integration with ValvanoWare library/starter code has been added (enabled by the VALVANOWARE compile option).

ELF creation

For correct handling, executables must be compiled with:

  • Separate load regions/program segments for code and data, i.e. one region containing the RO section and one region containing RW + ZI sections (--split option to ARMLINK).
  • Position-independent code and data (read-only and read-write position independence in Keil via --apcs=/ropi/rwpi options to ARMCC and ARMASM, and --ropi --rwpi options to ARMLINK). Note that this requires the R9 (=SB, static base) register to point to the base of the loaded data (RW+ZI) region when executing the code.
  • Alternatively, the loader should also support relocatable executables (compiled with --relocate option to ARMLINK), but this is untested.
  • Dynamic linking and corresponding relocation of external symbols (IMPORTed via --edit steering file entries to ARMLINK) only works if symbols end up within range. For example, Keil does not seem to generate long branches for calls to dynamically linked functions. Relocation of such calls fails if caller and callee are loaded too far apart (e.g. in RAM vs. ROM).
  • For dynamic linking and relocation, the same restrictions as listed for object file relocation below otherwise apply.

Object code must be compiled with the following 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)

An example of application is found in the app folder

Usage

The API is simple, call to #exec_elf function and enjoying.

extern int exec_elf(const char *path, const ELFEnv_t *env);

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 symbols to resolve in executable
  • size of exported symbol array in elements number

Loader config

  • File handling macros
  • LOADER_FD_T File descriptor type
  • LOADER_OPEN_FOR_RD(path) Function to open file for read
  • LOADER_FD_VALID(fd) Validity evaluation of file descriptor
  • LOADER_READ(fd, buffer, size) Function to read buffer from fd
  • LOADER_CLOSE(fd) Function to close file descriptor
  • LOADER_SEEK_FROM_START(fd, off) Seek function over fd
  • LOADER_TELL(fd) Tell position of fd cursor
  • Memory manager/access
  • LOADER_ALIGN_ALLOC(size, align, perm) Aligned malloc function macro
  • LOADER_FREE(ptr) Free memory function
  • LOADER_CLEAR(ptr, size) Memory clearance (to 0) function
  • LOADER_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 debug
  • ERR(msg) puts style macro used on severe error
  • MSG(msg) puts style macro used on info/warning

About

ARMv7M ELF loader supporting Keil executables

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 98.3%
  • Assembly 1.3%
  • Makefile 0.4%