This is a good introduction to a topic that very little is generally written about, and is practically useful to few people outside operating systems and compilers - and compilers usually use someone else's linker, although they still need to know about relocations, fixups, external linkage schemes etc to generate workable machine code.
If you squint a bit, there's a continuum between image-based languages like Smalltalk and Lisp (optionally), where allocations persist across restarts, and linkers, where the memory "allocation" happens at compile time and is only used at runtime, through to smart linkers, which closely resemble the marking and compacting phases of a simple garbage collector. The compiler needs to advertise its roots, pointers and pointed to targets to the linker so that relocations can work. Even fixups, the micro language that the linker needs to evaluate when resolving symbols, has analogies with restoring an image - any non-persistable references need to be restored.