eld
eld is a minimal dynamic loader for ELF shared objects.
Building
mkdir eld
cd eld
git clone ... src
mkdir build
cd build
cmake ../src/ -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE="Debug" \
-DCMAKE_C_COMPILER="$INSTALL_PATH/bin/clang" \
-DCMAKE_C_FLAGS="-target or1k-elf" \
-DOR1K_SIM_PATH="$INSTALL_PATH/bin/or32-elf-sim" \
-DCMAKE_INSTALL_PREFIX="$INSTALL_PATH/or1k-elf"
make
Components
libeld.a
This is the core dynamic loading library. It exposes the classical dlopen,
dlclose and dlsym functions. They work pretty much as expected, except for
the fact that the file name provided to dlopen must be a pointer to the buffer
of memory where the ELF to load is located.
To try it out, create a C file, name it libyour.c and make it a shared
library:
int your() {
return 99;
}
$ clang -target or1k-elf libyour.c -shared -o libyour.so
Convert the ELF shell object (.so file) in a C array with xxd:
$ xxd -i libyour.so > libyour.so.h
$ cat libyour.so.h
unsigned char libmy_so[] = {
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
...
Then include it in your main C file (main.c) and call dlopen on the
generated array:
#include
#include
#include "dl.h"
#include "libyour.so.h"
typedef int (*myfunc_ptr)();
int main() {
void *handle = NULL;
handle = dlopen((char *) libyour_so, 0);
if (!handle) {
printf("Couldn't load the dynamic library\n");
return EXIT_FAILURE;
}
myfunc_ptr your = dlsym(handle, "your");
if (!your) {
printf("Couldn't find the symbol \"your\"\n");
return EXIT_FAILURE;
}
printf("your() == %d\n", your());
return EXIT_SUCCESS;
}