From OSDev Wiki
Jump to: navigation, search

The process of dynamic linking is conceptually difficult to understand, but practically very simple. I'm assuming that you want to link ELF shared objects. The general sequence of events is to load the library as normal, load it into memory and patch the GOT. To be precise, you need to:

  • Load the ELF object
  • Look for the DYNAMIC section and process the values therein
    • You'll want the hash table, global offset table, relocation tables (including the PLT) and dependencies
    • Don't forget that these values are relative to the start of the file
  • Get the symbol tables, by using the hash table
    • Hashing is fairly simple, but you'll have to get the value at the hash table pointer to find out how many symbols are in the dynamic symbol table
    • Again, hashing is optional, but you might as well make use of it for fast lookups
  • Write two values to the GOT
    • Integer one is a unique value (I use C++, so use the location of my shared object class in memory)
    • Integer two is the location of a dynamic resolution method
  • Process the relocations
    • There doesn't seem to be any need to put in code for every relocation type, I've only come across types 6, 7 and 8
    • Don't forget that any symbol values need to be absolute; the symbols in the dynamic symbol table are usually relative
  • Load all the loadable segments into memory
  • Do a special set of relocations on the PLT relocation entries.
    • Go through every entry, and make the location at [relocationEntry->Offset + executableBase] absolute instead of relative

That sets everything up for dynamic linking. The dynamic resolution method is

call resolveDynamicSymbol
pop ecx
pop ecx
jmp eax

Your resolveDynamicSymbol method just passes through to the relevant C or C++ method, which does the following

  • Treats the passed integer as an offset (not an index) into the PLT relocation table to get a relocation entry
  • Get the symbol from the dynamic symbol table
    • This is probably an assumption, but seems to work for most libraries
  • Get the symbol name from the dynamic string table
    • As above
  • Look through every loaded object that the shared object depends upon, trying to find the symbol name in their dynamic symbol tables
  • If you find a match, write [symbolFound->Value + dependency->Base] to the memory location [relocationEntry->Offset + executableBase] and exit the loop
  • Return the value that you've just written

This is just a rough guide; I couldn't find many resources about this when I was writing my linker, so there's probably some assumptions there. Also, please note that this is just one half of the code. If you want to implement dynamic linking in the kernel (as I did) then you need to patch the kernel's GOT to do pretty much the same thing. The only difference is that you get the value from the Multiboot header

Personal tools