gdbelfjitdwarfrelocation

Handling DWARF-5 relocations in a custom ELF loader


I'm building a custom ELF object loader which resolves the library dependencies (DT_NEEDED) and recursively loads those, performs relocations and symbol resolution, calls preinit, etc. ld.so is ignored (DT_INTERP), and my loader attempts to do the things ld.so usually does, not because I think that's a sensible thing to do, but because I'm trying to understand the details of the process well enough to debug a problem I'm having with a JIT compiler that seems to involve PLT issues that I don't understand well enough yet. Perhaps masochistically I've decided to implement a dynamic loader and linker from scratch to learn those details (and check that I actually understand them).

As part of that process I'm attempting to integrate with GDB so that it knows about the new ELF objects I'm loading (no dlopen()). This is easy enough to accomplish with GDB's JIT interface and now GDB sees the symbols in the ELF objects I've loaded, but with the wrong addresses (the addresses are correct, but haven't been relocated to match the base address chosen by mmap given addr=NULL). I don't see any DT_RELA / DT_REL / DT_JMPREL entries corresponding to the debug info. Is there some separate step that needs to be performed to relocate the debug info baked into the ELF?

The debug info is built by gcc with -g and -gdwarf-5 (both show the same result: debug symbols report their un-relocated values in gdb).

If it's relevant I'm using Linux (Ubuntu), x86_64, not linking to libc: -fPIC -gdwarf-5 -nostartfiles -nodefaultlibs.

I've spent some time attempting to google the issue, but sensible programmers don't do this so results are sparse. I did see a suggestion that dwarf-5 uses position-independent symbols somehow, but the results I see don't seem to reflect that.


Solution

  • This is easy enough to accomplish with GDB's JIT interface

    GDB JIT interface is the wrong way to let GDB know that you've loaded a shared library. The right way(s) are described here.

    Is there some separate step that needs to be performed to relocate the debug info baked into the ELF?

    Normally the debug info is not even loaded into memory, so no: the runtime loader doesn't do anything for it.