How to execute an object file: Part 2
Handling relocations

In the previous post, we learned how to parse an object file and import and execute some functions from it. However, the functions in our toy object file were simple and self-contained: they computed their output solely based on their inputs and didn't have any external code or data dependencies. In this post we will build upon the code from part 1, exploring additional steps needed to handle code with some dependencies.
As an example, we may notice that we can actually rewrite our add10
function using our add5
function:
obj.c:
int add5(int num)
{
return num + 5;
}
int add10(int num)
{
num = add5(num);
return add5(num);
}
Let's recompile the object file and try to use it as a library with our loader
program:
$ gcc -c obj.c
$ ./loader
Executing add5...
add5(42) = 47
Executing add10...
add10(42) = 42
Whoa! Something is not right here. add5
still produces the correct result, but add10
does not . Depending on your environment and code composition, you may even see the loader
program crashing instead of outputting incorrect results. To understand what happened, let's investigate the machine code generated by the compiler. We Continue reading