ELF loader for Ndless
So, a few weeks ago, I posted something about using C++ with the Ndless framework. Unfortunately, while the compiler worked, the end binary kept crashing. I figured that it was because of the C++ vtables having invalid function pointers. The linker wasn’t updating them correctly.
This was the same problem when doing static declarations to pointers. The following code crashes on Ndless.
void foo() {}
int main() {
static void (*var)() = foo;
var();
return 0;
}
The reason is because of the way Ndless links and loads your programs. When you link it on your development machine, it sets a load address and everything is calculated on that. But with Ndless, you can’t load it to a static load address because you don’t know what address you’re going to get from malloc. So, we solve this by relocating.
The startup file that is compiled into Ndless binaries looks up at the Global Offset Table and fills in the correct data at run time. What is run first is PIC which gets its current location and the location of the GOT and patches it so our executable can run correctly.
Unfortunately, when we have statically allocated pointers, they are stored on the .data section of the executable. When it’s turned into a memory image for running on Ndless, all the symbol information telling the linker where each section starts and stops and where all the variables are gone. So, while the GOT may get updated with correct pointers, our statically allocated pointers don’t.
This is a fundamental problem with Ndless’s way of loading things. With this, I started working on a ELF loader a few days ago. An ELF file still contains all the required symbol definitions and the whole lot. That means, our ELF loader can patch everything completely for our program to run.
The code is still in it’s disgusting stage and is in need of a lot of polishing. If you would like to take a look, the code is hosted on Github https://github.com/tangrs/ndless-elfloader