A dynamic linker murder mystery

I write a ton of articles about rust. And in those articles, the main focus is about writing Rust code that compiles. Once it compiles, well, we're basically in the clear! Especially if it compiles to a single executable, that's made up entirely of Rust code.

Dynamic symbol resolution

Let's pick up where we left off: we had just taught elk to load not only an executable, but also its dependencies, and then their dependencies as well.

Up until now, we've been loading a single ELF file, and there wasn't much structure to how we did it: everyhing just kinda happened in main, in no particular order.

The simplest shared library

In our last article, we managed to load and execute a PIE (position-independent executable) compiled from the following code:

X86 Assembly; in samples/hello-pie.asm

global _start

section .text

_start: mov rdi, 1      ; stdout fd
lea rsi, [rel msg]
mov rdx, 9      ; 8 chars + newline
mov rax, 1      ; write syscall
syscall

xor rdi, rdi    ; return code 0
mov rax, 60     ; exit syscall
syscall

section .data

msg:    db "hi there", 10

ELF relocations

The last article, Position-independent code, was a mess. But who could blame us? We looked at the world, and found it to be a chaotic and seemingly nonsensical place. So, in order to blend in, we had to let go of a little bit of sanity.

Done scrolling? Go back to the homepage.