All right, Now let's dive into the fascinating world of the linking phase, which marks the final stage
of the compilation process.
As the name suggests, this phase brings together all the object files and seamlessly merge them into
a unified binary executable.
In modern systems, this phase may also incorporate an additional optimization path known as link time
optimization or enhancing the overall performance of the resulting executable.
And unsurprisingly, the program that performs the linking phase is called a linker or link editor is
typically separate from the compiler, which usually implements all the preceding phases.
As I've already mentioned, object files are relocatable because they are compiled independently from
each other.
As you can see here, preventing the.
That's because the they are preventing the compiler from assuming that an object will end up at any
particular base address.
So these are relocatable and moreover object files may reference functions or variables in other object
files or in libraries that are external to the program.
So before the linking phase, the addresses at which the reference code and data will be placed are
not yet known.
So the object files only contain relocation symbols that specify how functions and variable references
should eventually be resolved.
So in the context of linking references that rely on a relocation symbol are called symbolic references.
When an object file reference is one of its own functions or variables by absolute address, the reference
will also be symbolic.
So the linker job is to take all the object files belonging to a program and merge them into a single
coherent executable, typically intended to be loaded at a particular memory address.
Now here, the arrangement of all modules in the executable is known.
The linker can also resolve more symbolic references as well.
References to the libraries may or may not be completely resolved depending on the type of library.
And static libraries, which on Linux typically have the extension of dot a as here as a dot a.
And are merged into the binary executable.
So allowing any references to them.
To be resolved entirely.
So there are also dynamic which is also called.
The shared libraries which are shared in memory among all programs that run on a system.
In other words, rather than copying the library into every binary that uses it, the dynamic libraries
are loaded into memory only once, and any binary that wants to use the library needs to use this shared
copy.
So during the linking phase, the addresses at which dynamic libraries will reside are not yet known,
so references to them cannot be resolved.
Instead, the linker leaves symbolic references to these libraries even in the final executable, and
these references are not resolved until the binary is actually loaded into memory to be executed.
So most compilers like GCC automatically call the linker at the end of the compilation process to use
the to produce a complete binary executable so you can simply call GCC without any special switches
and compile your application.
My app dot C and that's it.
And here we will now use the file my app dot a.
Or a dot out.
A dot out.
Because this is our output.
While the final file and that's it.
And here.
The first.
Let's actually understand this firstly.
So by default, the executable is called a dot out.
But you can override this by naming, by passing the or parameter or switch to GCC followed by a name
for the output file.
So the file utility now tells us that we are dealing with an Elf 64 bit.
LSB.
I executable rather than a relocatable file.
As you can see here, we have this relocatable file, as you saw.
Also, you saw in the previous lecture and other important information is that the file is dynamically
linked here.
Dynamically length.
So meaning this dynamically linked here, meaning that it uses some libraries that are not merged into
executable but are instead shared among all programs running on the same system.
And finally, we have this interpreter.
This here.
Here.
So.
Um here the interpreter lib64 Linux and x86 64 .0.2 Here in the file output tells you which dynamic
linker will be used to resolve the final dependencies on dynamic libraries when the executable is loaded
into memory to be executed.
So when you run the binary using the dot a dot out command, we are running here.
You can see that it produces the expected output printing the Hello world to us, which confirms that
you have produced a working binary.
But here we have the node script here or stripped here.
But let's what is bit about this binary not being stripped or not stripped.
You will learn that in next lecture.