How exactly does a program (executable image) and library (pre-compiled image) “link” together

binarybindingimagelinkingstatic-linking

I know very well of the difference of static versus dynamic linking. What I want to know is, when linking statically (with a library like Winmm.lib on Windows), how does the linker "link" the pre-compiled format with the just compiled binary of the executable?

It does not have to pertain to any specific platform, OS, etc. I just want to know the process of which the linking takes place, and how that static "linking" binds an executable binary together that, when executed, forms a branch with the necessary system calls, routines, and low-level API access.

Basically, how does the compiled file get "put together" statically with the pre-compiled data, especially if they're coded differently?

I mean I know the library "exposes" routines, but where is the certainty that the called routines always work, and how can this be assured in a linking process?

EXAMPLE: I compile "Hello world.exe", and it is statically linked, and launched from the OS loader. Does something within the binary that the program itself linked with have all the necessary "instructions", "magic number", "checksum", etc. to perform the correct procedures, or the does the OS loader, on the fly, find what's needed to access, i.e. system calls, type of program header, other magic numbers, etc.?

I just want to thoroughly understand my linker's job, and how that linking makes the bonafide binary that the OS can handle, and get to my screen, as opposed to just plain instructions that the OS can't "branch" to any other process with.

Best Answer

A library is basically a collection of object files. An object file is basically a list of function names and signatures, together with the machine code instructions. When statically linking, when the linker sees a function call, it finds its name and signature in the object files, copies the machine code instructions to the exe, and changes the function call to point to the place it copied it to.

Dynamic loaders perform a similar task for dynamic libraries. They load the libraries into memory, look at the function calls the application is making, and change them to point to the library's executable instructions in memory.