Diving into ELF
While it was very fun, here are some things I didn’t like:
Getting the filepath
I had a instruction pointer, and I wanted to open the
corresponding ELF file on disk. If the corresponding ELF-file is some
shared library, both dl_iterate_phdr and
dladdr can be used to do that. But if the corresponding
ELF-file is the main program (i.e. /proc/self/exe), there
is a problem:
dl_iterate_phdrsetsdlpi_nameto an empty string for the main program. Weird, and problematic for my case, but at least somewhat documented in the manpage and easy to find during testing.dladdrsetsdli_fnametoargv[0]for the main program. But if your program is calledfooand is somewhere in$PATH, then runningfooworks, butopen("foo", ...)does not. Tricky to find during testing, because everything works if you run it using an absolute or relative path. Also it’s not documented.
This left me with three choices:
- Use
dl_iterate_phdrand fallback to/proc/self/exeifdlpi_nameis an empty string. - Use
dladdrand fallback to/proc/self/exeifdlpi_nameis not an absolute path. - Use
/proc/self/maps.
I chose the latter because I don’t like fallbacks. But unfortunately
there was no way around writing a parser for the text-format of
/proc/self/maps.
Reading elf files
Coherent naming is important in software. Unfortunately, the elf manpage
uses both section name string table section and
section header string table section to refer to the same
thing.
The bigger problem is that there are 3 address spaces that are relevant:
- Virtual Addresses (i.e. what
printf("%p\n", ptr)will print) - Positions in the elf file (i.e. what
xxd libfoo.soshows) - Virtual Adresses minus
info->dlpi_addr(i.e. whatobjdump -d libfoo.soshows)
I absolutely do not like the fact that there seems to be no proper
term for the third address space. The elf manpage
is calling it vaddr, virtual address and the
dladdr1
manpage is calling it address in the ELF file.