mirror of
https://github.com/0xAX/linux-insides.git
synced 2024-12-22 22:58:08 +00:00
Merge pull request #148 from ianmiell/imiell-nits
Nit-picks and corrections up to "Relocation"
This commit is contained in:
commit
aba4bbf84e
@ -1,17 +1,16 @@
|
||||
Introduction
|
||||
---------------
|
||||
|
||||
During writing of the [linux-insides](http://0xax.gitbooks.io/linux-insides/content/) book I have received and continue to receive many emails with the similar questions related with the [linker](https://en.wikipedia.org/wiki/Linker_%28computing%29) script and a linker related stuff. So've decided to write this post that will cover some aspects related to the linker and linking of object files.
|
||||
|
||||
If we will open page about `Linker` on wikipidia, we will see following definition:
|
||||
During the writing of the [linux-insides](http://0xax.gitbooks.io/linux-insides/content/) book I have received many emails with questions related to the [linker](https://en.wikipedia.org/wiki/Linker_%28computing%29) script and linker-related subjects. So I've decided to write this to cover some aspects of the linker and the linking of object files.
|
||||
|
||||
If we open page the `Linker` page on wikipidia, we will see following definition:
|
||||
|
||||
>In computer science, a linker or link editor is a computer program that takes one or more object files generated by a compiler and combines them into a single executable file, library file, or another object file.
|
||||
|
||||
If you've wrote at least one program on C in your life, you saw files with the `*.o` extension. These files are [object files](https://en.wikipedia.org/wiki/Object_file). Object files are blocks of machine code and data with uncertain addresses of references to data and functions in other object files (or libraries), as well as a list of its own functions and data. The main purpose of the linker is collect/handle code and data of the each object file to the the final executable file or library. In this post we will try to go through all aspects of this process. Let's start.
|
||||
If you've written at least one program on C in your life, you will have seen files with the `*.o` extension. These files are [object files](https://en.wikipedia.org/wiki/Object_file). Object files are blocks of machine code and data with placeholder addresses that reference data and functions in other object files or libraries, as well as a list of its own functions and data. The main purpose of the linker is collect/handle the code and data of each object file, turning it into the the final executable file or library. In this post we will try to go through all aspects of this process. Let's start.
|
||||
|
||||
Linking process
|
||||
----------------
|
||||
---------------
|
||||
|
||||
Let's create simple project with the following structure:
|
||||
|
||||
@ -22,7 +21,7 @@ Let's create simple project with the following structure:
|
||||
*--lib.h
|
||||
```
|
||||
|
||||
And write there for example factorial program. Our `main.c` source code file will contain:
|
||||
And write there our example factorial program. Our `main.c` source code file contains:
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
@ -35,7 +34,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
```
|
||||
|
||||
The `lib.c` will contain:
|
||||
The `lib.c` contains:
|
||||
|
||||
```C
|
||||
int factorial(int base) {
|
||||
@ -65,13 +64,14 @@ int factorial(int base);
|
||||
#endif
|
||||
```
|
||||
|
||||
Now let's compile only `main.c` source code file with the:
|
||||
Now let's compile only the `main.c` source code file with:
|
||||
|
||||
```
|
||||
$ gcc -c main.c
|
||||
```
|
||||
|
||||
If we will look inside with the `nm` util, we will see following output:
|
||||
If we look inside the outputted object file with the `nm` util, we will see the
|
||||
following output:
|
||||
|
||||
```
|
||||
$ nm -A main.o
|
||||
@ -80,13 +80,13 @@ main.o:0000000000000000 T main
|
||||
main.o: U printf
|
||||
```
|
||||
|
||||
The `nm` util allows us to see the list of symbols from the given object file. Look on the its output, it consists from the three columns: the first is the name of the given object file and address of resolved symbols. The second column contains symbol that determines status of the given symbol. In our case the `U` is `undefined` symbol and the `T` is the symbols that placed in the `.text` section. So `nm` util shows us that we have three symbols in the `main.c` source code file:
|
||||
The `nm` util allows us to see the list of symbols from the given object file. It consists of three columns: the first is the name of the given object file and the address of any resolved symbols. The second column contains a character that represents the status of the given symbol. In this case the `U` means `undefined` and the `T` denotes that the symbols are placed in the `.text` section of the object. The `nm` utility shows us here that we have three symbols in the `main.c` source code file:
|
||||
|
||||
* `factorial` - factorial function that defined in the `lib.c` source code file and marked as `undefined` because we compile only `main.c` source code file and it does not know anything about code from the `lib.c` for now;
|
||||
* `main` - main function;
|
||||
* `printf` - function from the [glibc](https://en.wikipedia.org/wiki/GNU_C_Library) library and `main.c` does not anything about it for now too.
|
||||
* `factorial` - the factorial function defined in the `lib.c` source code file. It is marked as `undefined` here because we compiled only the `main.c` source code file, and it does not know anything about code from the `lib.c` file for now;
|
||||
* `main` - the main function;
|
||||
* `printf` - the function from the [glibc](https://en.wikipedia.org/wiki/GNU_C_Library) library. `main.c` does not know anything about it for now either.
|
||||
|
||||
What we can understand from the output of the `nm` for this moment? All is simple. The `main.o` object file contains local symbol `main` by the `0000000000000000` (it will be filled with correct address after the linking) and two unresolved symbols. We can see all of this information in the disassembly output of the `main.o` object file:
|
||||
What can we understand from the output of `nm` so far? The `main.o` object file contains the local symbol `main` at address `0000000000000000` (it will be filled with correct address after is is linked), and two unresolved symbols. We can see all of this information in the disassembly output of the `main.o` object file:
|
||||
|
||||
```
|
||||
$ objdump -S main.o
|
||||
@ -111,7 +111,7 @@ Disassembly of section .text:
|
||||
30: c3 retq
|
||||
```
|
||||
|
||||
Here we are interesting only in the two `callq` operations. The two `callq` operations contain `linker stubs` or in another words function name and offset from it to the next instruction. These stubs will be updated to the real addresses of the functions. We can see these functions names with in the following `objdump` output:
|
||||
Here we are interested only in the two `callq` operations. The two `callq` operations contain `linker stubs`, or the function name and offset from it to the next instruction. These stubs will be updated to the real addresses of the functions. We can see these functions' names with in the following `objdump` output:
|
||||
|
||||
```
|
||||
$ objdump -S -r main.o
|
||||
@ -127,12 +127,12 @@ $ objdump -S -r main.o
|
||||
...
|
||||
```
|
||||
|
||||
The `-r` or `--reloc ` flags of the `objdump` util print the `relocation` entries of the file. Now let's know a little about relocation process.
|
||||
The `-r` or `--reloc ` flags of the `objdump` util print the `relocation` entries of the file. Now let's look in more detail at the relocation process.
|
||||
|
||||
Relocation
|
||||
------------
|
||||
|
||||
Relocation is the process of connecting symbolic references with symbolic definitions. Let's look on the previous snippet from the `objdump` output:
|
||||
Relocation is the process of connecting symbolic references with symbolic definitions. Let's look at the previous snippet from the `objdump` output:
|
||||
|
||||
```
|
||||
14: e8 00 00 00 00 callq 19 <main+0x19>
|
||||
|
@ -3,9 +3,9 @@ linux-insides
|
||||
|
||||
A series of posts about the linux kernel and its insides.
|
||||
|
||||
**The goal is simple** - to share my modest knowledge about the internals of the linux kernel and help people who are interested in the linux kernel internals, and other low-level subject matter.
|
||||
**The goal is simple** - to share my modest knowledge about the internals of the linux kernel and help people who are interested in linux kernel internals, and other low-level subject matter.
|
||||
|
||||
**Questions/Suggestions**: Feel free about any questions or suggestions by pinging me at twitter [@0xAX](https://twitter.com/0xAX), adding [issue](https://github.com/0xAX/linux-internals/issues/new) or just drop me [email](mailto:anotherworldofworld@gmail.com).
|
||||
**Questions/Suggestions**: Feel free about any questions or suggestions by pinging me at twitter [@0xAX](https://twitter.com/0xAX), adding an [issue](https://github.com/0xAX/linux-internals/issues/new) or just drop me an [email](mailto:anotherworldofworld@gmail.com).
|
||||
|
||||
Support
|
||||
-------
|
||||
|
@ -64,3 +64,4 @@ Thank you to all contributors:
|
||||
* [Donny Nadolny](https://github.com/dnadolny)
|
||||
* [Ehsun N](https://github.com/imehsunn)
|
||||
* [Waqar Ahmed](https://github.com/Waqar144)
|
||||
* [Ian Miell](https://github.com/ianmiell)
|
||||
|
Loading…
Reference in New Issue
Block a user