summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFreeArtMan <dos21h@gmail.com>2022-08-17 14:10:46 +0100
committerFreeArtMan <dos21h@gmail.com>2022-08-17 14:10:46 +0100
commitee15fc203cb3a2bc029d0d3f14daf3a648b38ebb (patch)
tree203e9730cd8afcf850d2b1bde9610a4ef9bdedc1
parentc830b365f52bdd8dcaab604614658ce70d158055 (diff)
downloadmd-content-ee15fc203cb3a2bc029d0d3f14daf3a648b38ebb.tar.gz
md-content-ee15fc203cb3a2bc029d0d3f14daf3a648b38ebb.zip
Linking chapter
-rw-r--r--md/notes/undefined_c/titles.md178
1 files changed, 173 insertions, 5 deletions
diff --git a/md/notes/undefined_c/titles.md b/md/notes/undefined_c/titles.md
index 513b533..60e14a4 100644
--- a/md/notes/undefined_c/titles.md
+++ b/md/notes/undefined_c/titles.md
@@ -764,16 +764,182 @@ int main(void) {
}
```
-
-## Base usage
+## Advanced topics
### Kernel module
-### Write plugins
+Linux kernel, macos kernel and *BSD's kernels written in C,
+so there is possibility to write kernel modules in C for some of those.
+
+Example will not match some specific things to local distribution.
+
+```c
+
+```
-## Advanced cases
+http://main.lv/writeup/kernel_hello_world.md
### Linking
+
+Linking is one of the most interesting parts of compiling of C code. When object file is created
+it contains functions and variables that can be of different type. And linking tries to resolve
+all of those. So there is possible to have fun with linking and content of object files.
+
+
+First example is piece of C code that can be compiled to object file, but it will not able to
+resolve to executable.
+```
+gcc -c link_elf.c
+```
+```c
+int main() {
+ fun1();
+ fun2();
+}
+```
+So we can see that fun1 and fun2 are marked as undefined in object file. If we try compile it will not able to find those.
+So lets create one more object file
+```
+$ readelf -a link_elf.o
+
+Symbol table '.symtab' contains 6 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS link_elf.c
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
+ 3: 0000000000000000 31 FUNC GLOBAL DEFAULT 1 main
+ 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND fun1
+ 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND fun2
+
+```
+__link_fun1.c__
+```c
+void fun1() {
+ printf("Hello fun1\n");
+}
+void fun2() {
+ printf("Hello fun2\n");
+}
+```
+
+So now we have object file with funtions that are defined. and we see that its now have undefine pritnf/puts function there.
+
+```
+readelf -a link_fun1.o
+Symbol table '.symtab' contains 7 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS link_fun1.c
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .rodata
+ 4: 0000000000000000 22 FUNC GLOBAL DEFAULT 1 fun1
+ 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
+ 6: 0000000000000016 22 FUNC GLOBAL DEFAULT 1 fun2
+
+```
+
+we can merge both of those files together
+```shell
+gcc -o link_elf link_elf.o link_fun1.o
+```
+The function in object files dont have any idea about input output types. That why anything can be linked that just match name
+lets rewrite code like this
+
+```c
+int fun1(int i) {
+ printf("Hello fun1\n");
+}
+int fun2(int i) {
+ printf("Hello fun2\n");
+}
+```
+And this links without issue. Theat this as 2 sets that are merge together only few thins know when linking things.
+Return type, and function arguments arent exposed when object file is created.
+
+Functions can have aliases.
+
+__link_fun2.c__
+```c
+static void fun2() {
+ printf("hello 2\n");
+} __attribute__ ((alias("fun1")));
+```
+
+Now function is local.
+
+```
+Symbol table '.symtab' contains 6 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS link_fun2.c
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .rodata
+ 4: 0000000000000000 22 FUNC LOCAL DEFAULT 1 fun2
+ 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
+```
+
+Lets compile all object to executable. And the function fun2 isnt used in this case,
+
+
+
+```
+$ gcc link_fun1.o link_fun2.o link_elf.o -o link_elf
+$ ./link_elf
+Hello fun1
+Hello fun2
+
+```
+
+
+
+lets witch aliasing between 2 functions **fun2**
+
+
+```
+link_fun1.o
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS link_fun1.c
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .rodata
+ 4: 000000000000001d 29 FUNC LOCAL DEFAULT 1 fun2
+ 5: 0000000000000000 29 FUNC GLOBAL DEFAULT 1 fun1
+ 6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
+
+link_fun2.o
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS link_fun2.c
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .rodata
+ 4: 0000000000000000 22 FUNC GLOBAL DEFAULT 1 fun2
+ 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
+
+```
+
+```
+$ gcc link_fun1.o link_fun2.o link_elf.o -o link_elf
+$ ./link_elf
+Hello fun1
+hello 2
+```
+
+So all of this plays role in linking object files.
+There is more interesting utilit called ld its doing things on lower level then gcc.
+
+```
+$ ldd ./link_elf
+ linux-vdso.so.1 (0x00007ffd8f5d0000)
+ libc.so.6 => /usr/lib/libc.so.6 (0x00007f96c0e00000)
+ /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f96c10d2000)
+```
+
+We havent specified those options when we compiled executable, lets use **ld** for that.
+
+```
+ld -dynamic-linker /lib/ld-linux.so.2 link_elf.o link_fun1.o link_fun2.o -o link_elf
+```
+
+
+
### Extern
### Attributes
### Creating shared library
@@ -788,9 +954,10 @@ int main(void) {
### Canary
### Atomic
### Multithreading
+### Write plugins
-## Embedding
+## Embedding C
### Embed in C++
### Embed in Go
@@ -816,6 +983,7 @@ int main(void) {
### SDL2
### GTK
### OpenGL
+### Shaders
### Generate image