Search code examples
linkerd

Is it possible to produce working binary without linker?


As far as I know compiler convert source code to machine code. But this code do not have any OS-related sections and linker add them to file.

But is it's possible to make some executable without linker?


Solution

  • Let's first make a statement that is to be considered true, compilers do not generate machine code that can be immediately executed (JIT's do, but lets ignore that).

    Instead they generate files (object, static, dynamic, executable) which describe what they contains as well as groups of symbols. Symbols can be global variables or functions.

    But symbols just like the file itself contain metadata. This metadata is very important. See the machine code stored in a symbol is the raw instructions for the target architecture but it does not know where memory is stored.

    While modern CPU's give each process its own address space, a symbol may not land and probably won't land in the same address twice. In very recent times this is a security measure, but in past its so that dynamic linking works correctly.

    So when the OS loads up an executable or shared library it can place it wherever it wants and by doing so make it not repeatable. Otherwise we'd all have to start caring and saying "this file contains 100% of the code I intend to execute". Usually on load the raw binary in the symbol table get transformed by patching it with the symbol locations in RAM. Making everything just work.

    In summary the compiler emits files that allow for dynamic patching of assembly prior to execution. If it didn't, we would be living in a very restrictive and problematic world.

    Linkers even have scripts to change how they operate. They are a very complex and delicate piece of software required to make our programs work.

    Have a read of the PE-COFF and ELF standards if you want to get an idea of just how complex those formats really are.