# Ćwiczenia 9, grupa śr. 17-19, 19 kwietnia 2023
###### tags: `ASK23` `ćwiczenia` `pwit`
## Deklaracje
Gotowość rozwiązania zadania należy wyrazić poprzez postawienie X w odpowiedniej kolumnie! Jeśli pożądasz zreferować dane zadanie (co najwyżej jedno!) w trakcie dyskusji oznacz je znakiem ==X== na żółtym tle.
**UWAGA: Tabelkę wolno edytować tylko wtedy, gdy jest na zielonym tle!**
:::danger
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| ----------------------:| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Mikołaj Balwicki | | | | | | | | | | |
| Kamila Goszcz | | | | X | | | | | X | |
| Mateusz Materek | X | X | X | X | X | | | | X | |
| Mikołaj Łabędzki | | | | | | | | | | |
:::
:::info
**Uwaga:** Po rozwiązaniu zadania należy zmienić kolor nagłówka na zielony.
:::
## Zadanie 1
:::success
Autor: Mateusz Materek
:::

```
U printf zewnętrzny, rodata(?)
U buf zewnętrzny, rodata(?)
D bufp0 globalny, .data
b sum lokalny, .bss
t incr lokalny, .text
b count lokalny, .bss
T swap globalny, .text
```
Wykorzystanie (CS:APP, p. 672):

## Zadanie 2
:::success
Autor: Mateusz Materek
:::

.shstrtab -> This section holds section names.
.strtab -> This section holds strings, most commonly the strings that represent the names associated with symbol table entries
```
typedef struct {
Elf64_Word st_name; //an index into the object file's symbol string table, which holds the character representations of the symbol names.
unsigned char st_info; //specifies the symbol's type and binding attributes (type: object, func, section...; binding: global, local, weak...)
unsigned char st_other; //specifies a symbol's visibility (default, protected, hidden, internal)
Elf64_Half st_shndx; //Every symbol table entry is defined in relation to some section. This member holds the relevant section header table index
Elf64_Addr st_value; //the value of the associated symbol
Elf64_Xword st_size; //associated size (0 jako 0 lub unknown)
} Elf64_Sym;
```
`Elf64_Shdr`: https://www.sco.com/developers/gabi/latest/ch4.sheader.html
Nagłówki sekcji: `readelf -e swap.o` (znamy lokalizację pierwszego i rozmiar - są stałe).
Pozycja symbolu: `objdump --syms swap.o`
## Zadanie 3
:::success
Autor: Mateusz Materek
:::

1. Linker wybrał silny (globalny i zainicjalizowany) symbol `main` z pliku `mismatch-a.c` zamiast słabego (niezainicjalizowanego) z `mismatch-b.c`.
2. Wydrukowana wartość pochodzi z pierwszego bajtu `main`: `objdump -d mismatch-a.o`
3. Jak w 1.
4. *Segmentation fault*.
5. *multiple definition of 'main'*
6. *If you omit this section from your linker script, the linker just puts it into RAM, possibly overlapping with other data. You can check it in the map file. I just tried it with my linker script and found that the content of COMMON was placed at the same memory area as the heap in my case. This means that global variables and anything allocated with, e.g., malloc will overwrite each other. Don't do that. Bad things will happen.*
## Zadanie 4
:::success
Autor: Kamila Goszcz
:::

```
typedef struct {
unsigned char e_ident[EI_NIDENT]; //The initial bytes mark the file as an object file and provide machine-independent data with which to decode and interpret the file's contents.
Elf64_Half e_type; //Typ pliku (np. Shared, Core, Relocatable)
Elf64_Half e_machine; //Architektura (np. EM_X86_64 - plik odpowiedni do odpalenia na AMD x86-64)
Elf64_Word e_version; //Wersja programu (0 - błąd, 1 - obecna)
Elf64_Addr e_entry; //Entry-point
Elf64_Off e_phoff; //Offset tablicy nagłówków programu
Elf64_Off e_shoff; //Offset tablicy nagłówków sekcji
Elf64_Word e_flags; //processor-specific flags associated with the file
Elf64_Half e_ehsize; //ELF header's size in bytes.
Elf64_Half e_phentsize; //the size in bytes of one entry in the file's program header table; all entries are the same size.
Elf64_Half e_phnum; //the number of entries in the program header table.
Elf64_Half e_shentsize; //section header's size in bytes
Elf64_Half e_shnum; //the number of entries in the section header table.
Elf64_Half e_shstrndx; //the section header table index of the entry associated with the section name string table
} Elf64_Ehdr;
```
```
typedef struct {
Elf64_Word p_type; //kind of segment this array element describes or how to interpret the array element's information (pheader, note, shared...)
Elf64_Word p_flags; //flags relevant to the segment (RWX)
Elf64_Off p_offset; //the offset from the beginning of the file at which the first byte of the segment resides
Elf64_Addr p_vaddr; //the virtual address at which the first byte of the segment resides in memory
Elf64_Addr p_paddr; //this member is reserved for the segment's physical address (nieużywany w System V)
Elf64_Xword p_filesz; //the number of bytes in the file image of the segment
Elf64_Xword p_memsz; //the number of bytes in the memory image of the segment
Elf64_Xword p_align; //This member gives the value to which the segments are aligned in memory and in the file
} Elf64_Phdr;
```
- Pierwsza instrukcja pliku wykonywalnego będzie się znajdować dokładnie tam, gdzie wskazuje entry point. Nie jest to pierwsza instrukcja z main.
- Załadowane zostaną sekcje w segmentach z p_type = PT_LOAD.
- Adresy wirtualne -> VirtAddr na wydruku
- Tylko czytanie -> segmenty z R we flagach
## Zadanie 5
:::success
Autor: Mateusz Materek
:::

`objdump -s str-b.o`
Napis *Hello, world!* ląduje w `rodata` - próba pisania tam kończy się błędem dostępu do pamięci (w końcu jest *read only*).
Rozwiązanie: przenieść napis do `data`:
```c=
char *somestr(void) {
static char[] str = "Hello, world!";
return str;
}
```
## Zadanie 6
:::danger
Autor:
:::
```c=
typedef struct {
long offset; /* offset od początku sekcji */
long type:32, /* typ relokacji: względna/bezwzględna */
symbol:32; /* adres do tablicy symboli */
long addend; /* dopełnienie do kolejnej instrukcji */
} Elf64_Rela;
```
## Zadanie 7
:::danger
Autor:
:::
## Zadanie 8
:::danger
Autor:
:::
## Zadanie 9
:::success
Autor: Kamila Goszcz
:::

### Rozmiary sekcji .data i .bss
```
objdump -h foo.o
.data: 8B
.bss: 17B
objdump -h bar.o
.data: 4B
.bss: 30B
```
### Tablica symboli
```
objdump -t foo.o
0000000000000000 g O .bss 0000000000000011 code
0000000000000000 g O .data 0000000000000008 foo
objdump -t bar.o
0000000000000000 g O .bss 000000000000001e dead
0000000000000000 g O .data 0000000000000004 bar
```
### Merge.o różnice:
```
objdump -t merge-1.o
0000000000000020 g O .bss 000000000000001e dead
0000000000000000 g O .data 0000000000000008 foo
0000000000000000 g O .bss 0000000000000011 code
0000000000000008 g O .data 0000000000000004 bar
objdump -t merge-2.o
0000000000000000 g O .bss 000000000000001e dead
0000000000000008 g O .data 0000000000000008 foo
0000000000000020 g O .bss 0000000000000011 code
0000000000000000 g O .data 0000000000000004 bar
```
Merge różnią się kolejnością syboli (w odwrotnej kolejności załadowane są pliki `foo` i `bar` )
### merge.map:
```
cat merge-1.map
.data 0x0000000000000000 0xc
*(.data)
.data 0x0000000000000000 0x8 foo.o
0x0000000000000000 foo
.data 0x0000000000000008 0x4 bar.o
0x0000000000000008 bar
.bss 0x0000000000000000 0x3e
*(.bss)
.bss 0x0000000000000000 0x11 foo.o
0x0000000000000000 code
*fill* 0x0000000000000011 0xf
.bss 0x0000000000000020 0x1e bar.o
0x0000000000000020 dead
cat merge-2.map
.data 0x0000000000000000 0x10
*(.data)
.data 0x0000000000000000 0x4 bar.o
0x0000000000000000 bar
*fill* 0x0000000000000004 0x4
.data 0x0000000000000008 0x8 foo.o
0x0000000000000008 foo
.bss 0x0000000000000000 0x31
*(.bss)
.bss 0x0000000000000000 0x1e bar.o
0x0000000000000000 dead
*fill* 0x000000000000001e 0x2
.bss 0x0000000000000020 0x11 foo.o
0x0000000000000020 code
```
W nagłówkach jest zapisana wartość wyrównania (bar ma align 2^2, zaś foo - 2^3), więc mimo że nie znamy typów zmienia się dodawany padding
## Zadanie 10
:::danger
Autor:
:::