- https://arxiv.org/abs/2011.13127
- https://sillycross.github.io/2023/05/12/2023-05-12/
- python/cpython#113465
- https://www.youtube.com/watch?v=kMO3Ju0QCDo
- https://www.youtube.com/watch?v=HxSHIpEQRjs
- https://scot.tg/2024/12/22/worked-example-of-copy-and-patch-compilation/
For now it requirese exactly LLVM 16 (I don't know why)
- Create stencils
./build_stencils.sh - Compile
main_jittarget in CMake - In separate release build compile the
main_interptarget - Run both executables and compare the times.
Plik elf dzieli się na segmenty lub sekcje.
Segmenty to jednostki, które są ładowane do pamięci w trakcie działania programu. Mogą zawierać kilka sekcji. Informacje o nich znajdują się w nagłówku program headers,
znajdują się w plikach wykonywalnych (typ. Executable).
Dane używane przez narzędzia do organizowania danych w pliku.
Sekcja .text – zawiera kod wykonywalny programu.
Sekcja .data – zawiera zainicjowane dane globalne.
Sekcja .bss – zawiera niezainicjowane dane globalne (miejsca w pamięci, które będą zainicjowane wartością zero).
Sekcja .rodata – zawiera dane stałe (np. łańcuchy znaków, które są tylko do odczytu).
Sekcja .symtab – zawiera tabelę symboli, używaną do mapowania nazw na adresy pamięci.
Sekcja .strtab – zawiera łańcuchy znaków, takie jak nazwy symboli.
Sekcja jest oznaczana przez typ. Nas obchodzą dwa typy:
SH_PROGBITS – sekcja zawierająca dane programu.
SH_RELA - sekcja zawierająca tablicę relokacji.
Symbole to nazwy, które są używane w programie. Mogą to być funkcje i zmienne.
W sekcji .symtab znajduje się tabela symboli, która mapuje nazwy na adresy pamięci.
Value symbolu to adres w pamięci lub offset w pliku.
ELF - executable and linkable symbols - info for linker about functions and variables that are visible from outside
Symbols can be anything in the module or global scope: functions, global variables, static variables. We also have to keep static variables (works like private variables) to move them around in the final executable file, to find them home.
Info about relocation resides in: .rela.text .rela.data
R_X86_64_64 - relocation, absolute address should be put there
objdump -dx to show code relocation
readelf -s to show symbol table
program header table - mapping of segments and where segments are to memory addresses section header table - info about where sections are - not relevant for running the code, only for the linter
readelf -a
Segments: 02 - .interp - how to use dyamic loader, .text, .rodata 03 - .data,
ELF header - entry point address
nasm -o hello_world.o hello_world.asm
ld -o hello_world.out hello_world.oFeature to add position independence to executables to enable ASLR on them and make them more secure.
Ubuntu toolchain is now configured to generate PIE executables by default, which leads the Linux
kernel to place the executable on a different address every time.
gcc -fpie vs gcc -fno-pie.
Pie is a functionality to enable ASLR.
It is on by default on linux, but can be disabled on system level.
Gdb disables it by default, but can be enabled.
The one with no-pie gives us absolute addresses in symbol table.
Type: EXEC (Executable file)
vs.
Type: DYN (Position-Independent Executable file)
Symbol table on pie gives us an offset.
65: 0000000000001135 23 FUNC GLOBAL DEFAULT 14 main
By turning ASLR off (with either randomize_va_space or set disable-randomization off), GDB always gives main the address: 0x5555555547a9, so we deduce that the -pie address is composed from:
0x555555554000 + random offset + symbol offset (79a)
https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld/51308031#51308031 https://stackoverflow.com/questions/3322911/what-do-linkercs-do https://stackoverflow.com/questions/65554551/why-gcc-generates-a-plt-when-it-is-apparently-not-needed https://stackoverflow.com/questions/64424692/how-does-the-address-of-r-x86-64-plt32-computed/69544175#69544175