---
# System prepended metadata

title: Linux lab 1 note (Journal)
tags: [linux, linux-2022-autumn]

---

# Linux lab 1 note (Journal)

###### tags: `linux`, `linux-2022-autumn`

</br>

> linux & windows 基本上不使用 segment descriptor
> 因此 virtual address 和 linear address 基本上一樣

```
sudo virsh net-start default
```

obj-y (in kernel)
obj-m (module)

https://hackmd.io/@combo-tw/Linux-%E8%AE%80%E6%9B%B8%E6%9C%83/%2F%40combo-tw%2FBJPoAcqQS

[install qemu-kvm](https://medium.com/codemonday/setup-virt-manager-qemu-libvert-and-kvm-on-ubuntu-20-04-fa448bdecde3)
```
sudo apt install libvirt-daemon-driver-lxc    
```

https://askubuntu.com/questions/858649/how-can-i-copypaste-from-the-host-to-a-kvm-guest
```
make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'.  Stop.
make: *** [Makefile:1809: certs] Error 2

# solution
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
```

```sh
# in gust os
sudo apt install spice-vdagent
```

## KVM qemu
https://github.com/jedi4ever/veewee/issues/996
```
# /etc/libvirt/qemu.conf
user = "wasabi-neko"
group = "wasabi-neko"
```
mode: squash
```
sudo mount -t 9p -o trans=virtio /sharepoint ~/share
```

## fedora preparation

```sh
sudo dnf group install "Development Tools"
sudo dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
```

```
sudo dnf install dwarves
```


### problem when compiling kernel
https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8

disable most of the modules

```
ld: arch/x86/entry/syscall_64.o:(.rodata+0xe08): undefined reference to `__x64_sys_hello_world'
  BTF     .btf.vmlinux.bin.o
```

https://stackoverflow.com/questions/68413677/kernel-make-generates-ld-arch-x86-entry-syscall-64-o-rodata0xdc0-undefine

```
make menuconfig
make -j8    # i should able do it on host 
sudo make modules_install -j8
sudo make install -j8

sudo reboot now
```

```
make -j12  1148.20s user 124.99s system 882% cpu 2:24.21 total
```

### 第三次

成功 install 進去 新的 kernel
但是 hello_world 一值出問題

### 第四次

嘗試在 host compile kernel 然後在 guest make install
在 host compile 只需要 25m36sec
出現 libcrpt.o file not found error & xxxx error
一段時間後進入 emergency mode

等等查查看這個 bug，以及把 security option 關掉看看

### 5

compile directily on my machine
hope my computer won't catch on fire after this

https://askubuntu.com/questions/1329538/compiling-the-kernel-5-11-11

```bash
$ sudo make install -j12
...
Error! Bad return status for module build on kernel: 5.15.77 (x86_64)
Consult /var/lib/dkms/nvidia/520.56.06/build/make.log for more information.
```

```bash
$ uname -r 
5.15.0-52-generic
```

tyring compile the linux-5.15.77

```bash
$ view /var/lib/dkms/nvidia/520.56.06/build/make.log
DKMS make.log for nvidia-520.56.06 for kernel 5.15.77 (x86_64)
Sun 06 Nov 2022 04:37:27 AM CST
make[1]: warning: -j12 forced in submake: resetting jobserver mode.
Makefile:18: /Kbuild: No such file or directory
make[1]: *** No rule to make target '/Kbuild'.  Stop.

```

Maybe just nvidia driver's problem. make install anyway
The Most scary part is comming... `sudo reboot now`

#### NICE it dead

```
The initrd is too big
...
...
[ end kernel panic not syncing:VFS: Unable to mount root fs on unkown-block]
```

use grub to boot my old 15.15.0, and try to fix it

```
# in /etc/initramfs-tools/initramfs.conf,
Change "MODULES=most" to "MODULES=dep"

update-initramfs -u -k all
```

IT WORKS !!!
the version is now 5.15.77
and ofcourse nvidia driver i broken

### add hello world syscall

跟著接學做

稍微刪減一些不會用到的功能後 build

```
ld: arch/x86/entry/syscall_64.o:(.rodata+0xa78): undefined reference to `__x64_sys_hello_world'
ld: arch/x86/entry/syscall_x32.o:(.rodata+0xa78): undefined reference to `__x64_sys_hello_world'
  BTF     .btf.vmlinux.bin.o
pahole: .tmp_vmlinux.btf: No such file or directory
  LD      .tmp_vmlinux.kallsyms1
.btf.vmlinux.bin.o: file not recognized: file format not recognized
make: *** [Makefile:1216: vmlinux] Error 1

```

https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8
this version using 5.x

https://www.kernel.org/doc/html/latest/process/adding-syscalls.html#designing-the-api-planning-for-extension
the offical doc? can't understand at all

kernel panic not syncing attempted to kill init!

###  嘗試單獨消減 module build
成功
看來 nvidia driver 每次 compile 都會爆炸，不過裝好之後再重裝就 ok 了

### 嘗試加入 hello_world syscall
改成 449
問題：should i make clean?

https://hackmd.io/@PIFOPlfSS3W_CehLxS3hBQ/S14tx4MqP

### check  vm-area_struct

用 `get_pid_task` 取得當前 process 的 `task_struct`
`task_struct->mmstruct.mmap->vm_area_struct`

![](https://i.imgur.com/PwkAo9J.png)

![](https://i.imgur.com/LnKgOM5.png)

![](https://i.imgur.com/XqFGuNF.png)

### Write a script to find informations of segment

從之前寫好的 system call 可以得知每個 segment 的 `start address`, `end address`, `size`, `flag` 和 `prot` 等資訊，但是還不清楚 segment 實際上所對應的是 process 的哪個部分。

而從原本的 multithread program 的實驗結果可以看到各個變數所在的記憶體位置，並且也可以查看兩者的 segment 有哪些是共用的。

![](https://i.imgur.com/KHPFiZU.png)

有了這些資訊，接下來就可以寫一個簡單的 script 來比對資訊，並且輸出 segment 對應關係的 table。



```=
Hello World!
size: 00001000, start: 55a8ad927000, end: 55a8ad928000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 55a8ad928000, end: 55a8ad929000, flag: 8000075, prot: 0000000000000025 <-main_text, thread1_text, thread2_text
size: 00001000, start: 55a8ad929000, end: 55a8ad92a000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 55a8ad92a000, end: 55a8ad92b000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 55a8ad92b000, end: 55a8ad92c000, flag: 8100073, prot: 8000000000000025 <-bss, data
size: 00021000, start: 55a8ae20b000, end: 55a8ae22c000, flag: 8100073, prot: 8000000000000025 <-main_heap
size: 00021000, start: 7f81f8000000, end: 7f81f8021000, flag: 8200073, prot: 8000000000000025 <-thread1_heap, thread2_heap
size: 03fdf000, start: 7f81f8021000, end: 7f81fc000000, flag: 8200070, prot: 0000000000000120
size: 00001000, start: 7f81fca1b000, end: 7f81fca1c000, flag: 8000070, prot: 0000000000000120
size: 00800000, start: 7f81fca1c000, end: 7f81fd21c000, flag: 8100073, prot: 8000000000000025 <-thread2_stack
size: 00003000, start: 7f81fd21c000, end: 7f81fd21f000, flag: 8000071, prot: 8000000000000025
size: 00012000, start: 7f81fd21f000, end: 7f81fd231000, flag: 8000075, prot: 0000000000000025
size: 00004000, start: 7f81fd231000, end: 7f81fd235000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f81fd235000, end: 7f81fd236000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f81fd236000, end: 7f81fd237000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f81fd237000, end: 7f81fd238000, flag: 8000070, prot: 0000000000000120
size: 00803000, start: 7f81fd238000, end: 7f81fda3b000, flag: 8100073, prot: 8000000000000025 <-thread1_stack
size: 00022000, start: 7f81fda3b000, end: 7f81fda5d000, flag: 8000071, prot: 8000000000000025
size: 00178000, start: 7f81fda5d000, end: 7f81fdbd5000, flag: 8000075, prot: 0000000000000025
size: 0004e000, start: 7f81fdbd5000, end: 7f81fdc23000, flag: 8000071, prot: 8000000000000025
size: 00004000, start: 7f81fdc23000, end: 7f81fdc27000, flag: 8100071, prot: 8000000000000025
size: 00002000, start: 7f81fdc27000, end: 7f81fdc29000, flag: 8100073, prot: 8000000000000025
size: 00004000, start: 7f81fdc29000, end: 7f81fdc2d000, flag: 8100073, prot: 8000000000000025
size: 00006000, start: 7f81fdc2d000, end: 7f81fdc33000, flag: 8000071, prot: 8000000000000025
size: 00011000, start: 7f81fdc33000, end: 7f81fdc44000, flag: 8000075, prot: 0000000000000025
size: 00006000, start: 7f81fdc44000, end: 7f81fdc4a000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f81fdc4a000, end: 7f81fdc4b000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f81fdc4b000, end: 7f81fdc4c000, flag: 8100073, prot: 8000000000000025
size: 00006000, start: 7f81fdc4c000, end: 7f81fdc52000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f81fdc6e000, end: 7f81fdc6f000, flag: 8000071, prot: 8000000000000025
size: 00023000, start: 7f81fdc6f000, end: 7f81fdc92000, flag: 8000075, prot: 0000000000000025
size: 00008000, start: 7f81fdc92000, end: 7f81fdc9a000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f81fdc9b000, end: 7f81fdc9c000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f81fdc9c000, end: 7f81fdc9d000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f81fdc9d000, end: 7f81fdc9e000, flag: 8100073, prot: 8000000000000025
size: 00021000, start: 7ffe943af000, end: 7ffe943d0000, flag: 0100173, prot: 8000000000000025 <-main_stack
size: 00004000, start: 7ffe943f3000, end: 7ffe943f7000, flag: c044411, prot: 8000000000000025
size: 00002000, start: 7ffe943f7000, end: 7ffe943f9000, flag: 8040075, prot: 0000000000000025
```

另一種取得 vm_area 的方法：
```
$ cat /proc/$pid/maps
```
```=
#address                  perms offset  device inode                     pathname
5595acc05000-5595acc06000 r--p 00000000 103:0a 530447                    /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out
5595acc06000-5595acc07000 r-xp 00001000 103:0a 530447                    /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out
5595acc07000-5595acc08000 r--p 00002000 103:0a 530447                    /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out
5595acc08000-5595acc09000 r--p 00002000 103:0a 530447                    /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out
5595acc09000-5595acc0a000 rw-p 00003000 103:0a 530447                    /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out
5595ad1aa000-5595ad1cb000 rw-p 00000000 00:00 0                          [heap]
7f6e18000000-7f6e18021000 rw-p 00000000 00:00 0
7f6e18021000-7f6e1c000000 ---p 00000000 00:00 0
7f6e20000000-7f6e20021000 rw-p 00000000 00:00 0
7f6e20021000-7f6e24000000 ---p 00000000 00:00 0
7f6e26b2d000-7f6e26b2e000 ---p 00000000 00:00 0
7f6e26b2e000-7f6e2732e000 rw-p 00000000 00:00 0
7f6e2732e000-7f6e2732f000 ---p 00000000 00:00 0
7f6e2732f000-7f6e27b32000 rw-p 00000000 00:00 0
7f6e27b32000-7f6e27b54000 r--p 00000000 103:0a 6948009                   /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f6e27b54000-7f6e27ccc000 r-xp 00022000 103:0a 6948009                   /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f6e27ccc000-7f6e27d1a000 r--p 0019a000 103:0a 6948009                   /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f6e27d1a000-7f6e27d1e000 r--p 001e7000 103:0a 6948009                   /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f6e27d1e000-7f6e27d20000 rw-p 001eb000 103:0a 6948009                   /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f6e27d20000-7f6e27d24000 rw-p 00000000 00:00 0
7f6e27d24000-7f6e27d25000 r--p 00000000 103:0a 6953248                   /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f6e27d25000-7f6e27d27000 r-xp 00001000 103:0a 6953248                   /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f6e27d27000-7f6e27d28000 r--p 00003000 103:0a 6953248                   /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f6e27d28000-7f6e27d29000 r--p 00003000 103:0a 6953248                   /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f6e27d29000-7f6e27d2a000 rw-p 00004000 103:0a 6953248                   /usr/lib/x86_64-linux-gnu/libdl-2.31.so
7f6e27d2a000-7f6e27d30000 r--p 00000000 103:0a 6960663                   /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f6e27d30000-7f6e27d41000 r-xp 00006000 103:0a 6960663                   /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f6e27d41000-7f6e27d47000 r--p 00017000 103:0a 6960663                   /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f6e27d47000-7f6e27d48000 r--p 0001c000 103:0a 6960663                   /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f6e27d48000-7f6e27d49000 rw-p 0001d000 103:0a 6960663                   /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f6e27d49000-7f6e27d4f000 rw-p 00000000 00:00 0
7f6e27d6b000-7f6e27d6c000 r--p 00000000 103:0a 6947394                   /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f6e27d6c000-7f6e27d8f000 r-xp 00001000 103:0a 6947394                   /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f6e27d8f000-7f6e27d97000 r--p 00024000 103:0a 6947394                   /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f6e27d98000-7f6e27d99000 r--p 0002c000 103:0a 6947394                   /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f6e27d99000-7f6e27d9a000 rw-p 0002d000 103:0a 6947394                   /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f6e27d9a000-7f6e27d9b000 rw-p 00000000 00:00 0
7fff30d81000-7fff30da2000 rw-p 00000000 00:00 0                          [stack]
7fff30de5000-7fff30de9000 r--p 00000000 00:00 0                          [vvar]
7fff30de9000-7fff30deb000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]
```

推測有 inode 的 segment 為該 file map 來 memory 的。
```bash
$ ls -i /usr/lib/x86_64-linux-gnu/libc-2.31.so
6948009
```

vm_flag in `include/linux/mm.h`

```
#define VM_NONE     0x00000000

#define VM_READ     0x00000001  /* currently active flags */
#define VM_WRITE    0x00000002
#define VM_EXEC     0x00000004
#define VM_SHARED   0x00000008

#define VM_GROWSDOWN    0x00000100  /* general info on the segment */
#define VM_UFFD_MISSING 0x00000200  /* missing pages tracking */
#define VM_PFNMAP   0x00000400  /* Page-ranges managed without "struct page", just pure PFN */
#define VM_UFFD_WP  0x00001000  /* wrprotect pages tracking */

#define VM_LOCKED   0x00002000
#define VM_IO           0x00004000  /* Memory mapped I/O or similar */

                    /* Used by sys_madvise() */
#define VM_SEQ_READ 0x00008000  /* App will access data sequentially */
#define VM_RAND_READ    0x00010000  /* App will not benefit from clustered reads */

#define VM_DONTCOPY 0x00020000      /* Do not copy this vma on fork */
#define VM_DONTEXPAND   0x00040000  /* Cannot expand with mremap() */
#define VM_LOCKONFAULT  0x00080000  /* Lock the pages covered when they are faulted in */
#define VM_ACCOUNT  0x00100000  /* Is a VM accounted object */
#define VM_NORESERVE    0x00200000  /* should the VM suppress accounting */
#define VM_HUGETLB  0x00400000  /* Huge TLB Page VM */
#define VM_SYNC     0x00800000  /* Synchronous page faults */
#define VM_ARCH_1   0x01000000  /* Architecture-specific flag */
#define VM_WIPEONFORK   0x02000000  /* Wipe VMA contents in child. */
#define VM_DONTDUMP 0x04000000  /* Do not include in the core dump */
```

==TODO:== how about page info ?? check `/proc/$pid/status`
https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html

可以觀察出: thread1 and thread2 位於不同 vm area
thread1 thread2 heap 位於同一個 vm area, 但是與 main 位於不同　area

!!! 在後來幾次跑程式的時候發現 thread1_heap and thread2_heap might not be in same segment

```=
Hello World!
size: 00001000, start: 55a37da32000, end: 55a37da33000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 55a37da33000, end: 55a37da34000, flag: 8000075, prot: 0000025 <-main_text, thread1_text, thread2_text
size: 00001000, start: 55a37da34000, end: 55a37da35000, flag: 8000071, prot: 8000000000000025 <-.rodata
size: 00001000, start: 55a37da35000, end: 55a37da36000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 55a37da36000, end: 55a37da37000, flag: 8100073, prot: 8000000000000025 <-bss, data
size: 00021000, start: 55a37f214000, end: 55a37f235000, flag: 8100073, prot: 8000000000000025 <-main_heap, main_big_heap
size: 00021000, start: 7f8c64000000, end: 7f8c64021000, flag: 8200073, prot: 8000000000000025 <-thread2_smol_heap, thread2_big_heap
size: 03fdf000, start: 7f8c64021000, end: 7f8c68000000, flag: 8200070, prot: 0000120
size: 00001000, start: 7f8c6b7ff000, end: 7f8c6b800000, flag: 8000070, prot: 0000120
size: 00800000, start: 7f8c6b800000, end: 7f8c6c000000, flag: 8100073, prot: 8000000000000025 <-thread2_stack
size: 00021000, start: 7f8c6c000000, end: 7f8c6c021000, flag: 8200073, prot: 8000000000000025 <-thread1_smol_heap, thread1_big_heap
size: 03fdf000, start: 7f8c6c021000, end: 7f8c70000000, flag: 8200070, prot: 0000120
size: 00001000, start: 7f8c70329000, end: 7f8c7032a000, flag: 8000070, prot: 0000120
size: 00803000, start: 7f8c7032a000, end: 7f8c70b2d000, flag: 8100073, prot: 8000000000000025 <-thread1_stack
size: 00022000, start: 7f8c70b2d000, end: 7f8c70b4f000, flag: 8000071, prot: 8000000000000025
size: 00178000, start: 7f8c70b4f000, end: 7f8c70cc7000, flag: 8000075, prot: 0000025 <-libc
size: 0004e000, start: 7f8c70cc7000, end: 7f8c70d15000, flag: 8000071, prot: 8000000000000025
size: 00004000, start: 7f8c70d15000, end: 7f8c70d19000, flag: 8100071, prot: 8000000000000025
size: 00002000, start: 7f8c70d19000, end: 7f8c70d1b000, flag: 8100073, prot: 8000000000000025 <-libc-var
size: 00004000, start: 7f8c70d1b000, end: 7f8c70d1f000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f8c70d1f000, end: 7f8c70d20000, flag: 8000071, prot: 8000000000000025
size: 00002000, start: 7f8c70d20000, end: 7f8c70d22000, flag: 8000075, prot: 0000025
size: 00001000, start: 7f8c70d22000, end: 7f8c70d23000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f8c70d23000, end: 7f8c70d24000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f8c70d24000, end: 7f8c70d25000, flag: 8100073, prot: 8000000000000025
size: 00006000, start: 7f8c70d25000, end: 7f8c70d2b000, flag: 8000071, prot: 8000000000000025
size: 00011000, start: 7f8c70d2b000, end: 7f8c70d3c000, flag: 8000075, prot: 0000025
size: 00006000, start: 7f8c70d3c000, end: 7f8c70d42000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f8c70d42000, end: 7f8c70d43000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f8c70d43000, end: 7f8c70d44000, flag: 8100073, prot: 8000000000000025
size: 00006000, start: 7f8c70d44000, end: 7f8c70d4a000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f8c70d66000, end: 7f8c70d67000, flag: 8000071, prot: 8000000000000025
size: 00023000, start: 7f8c70d67000, end: 7f8c70d8a000, flag: 8000075, prot: 0000025
size: 00008000, start: 7f8c70d8a000, end: 7f8c70d92000, flag: 8000071, prot: 8000000000000025
size: 00001000, start: 7f8c70d93000, end: 7f8c70d94000, flag: 8100071, prot: 8000000000000025
size: 00001000, start: 7f8c70d94000, end: 7f8c70d95000, flag: 8100073, prot: 8000000000000025
size: 00001000, start: 7f8c70d95000, end: 7f8c70d96000, flag: 8100073, prot: 8000000000000025
size: 00021000, start: 7fffbb3b5000, end: 7fffbb3d6000, flag: 0100173, prot: 8000000000000025 <-main_stack, argv, env
size: 00004000, start: 7fffbb3d7000, end: 7fffbb3db000, flag: c044411, prot: 8000000000000025
size: 00002000, start: 7fffbb3db000, end: 7fffbb3dd000, flag: 8040075, prot: 0000025
```

```
libc 0x7f8c70b73a40
libc-var 0x7f8c70d1a6a0
main_stack 0x7fffbb3d3648
main_heap 0x55a37f2142a0
main_big_heap 0x55a37f2142a0
main_text 0x55a37da33309
bss 0x55a37da36030
data 0x55a37da36010
.rodata 0x55a37da34004
argv 0x7fffbb3d3798
env 0x7fffbb3d58c5
thread1_stack 0x7f8c70b28ed4
thread1_smol_heap 0x7f8c6c000b80
thread1_big_heap 0x7f8c6c000b60
thread1_text 0x55a37da33320
thread2_stack 0x7f8c6bffeed4
thread2_smol_heap 0x7f8c64000b80
thread2_big_heap 0x7f8c64000b60
thread2_text 0x55a37da33320
```

```c=
#define _GNU_SOURCE     /* for RTLD_NEXT */
#include <dlfcn.h>

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

const int global_constant = 0xc8763; // .rodata
char global_str[] = "Global Str.";  // Data segment
char global_var;  // Bss segment
void (*func_ptr)();

void foo() {  // Text segment
    printf("foo func here!\n");
}

void* func4thread1(void *arg) {
    int local = 0xdeadbeef;
    int *smol_heap_ptr = (int*) malloc(5);
    int *big_heap_ptr = (int*) malloc(10000);

    smol_heap_ptr[0] = 0xc8763;
    big_heap_ptr[0] = 0xc8763;

    // func_ptr = foo;
    // printf("This is thread1.\n");
    printf("thread1_stack %p\n", &local);
    printf("thread1_smol_heap %p\n", big_heap_ptr);
    printf("thread1_big_heap %p\n", smol_heap_ptr);
    printf("thread1_text %p\n", func4thread1);
    // printf("Address of global_str \"%s\": %p\n", global_str, global_str);
    // printf("Address of global_var: %p\n", &global_var);
    // printf("Address of foo: %p\n", func_ptr);
    // printf("Address of str_in_heap \"%s\": %p\n", (char *)arg, arg);
	
    fflush(stdout);

    sleep(100000);
    pthread_exit(NULL);
}

void* func4thread2(void *arg) {
    int local = 0xdeadbeef;
    int *smol_heap_ptr = (int*) malloc(5);
    int *big_heap_ptr = (int*) malloc(10000);

    // func_ptr = foo;
    // printf("This is thread2.\n");
    printf("thread2_stack %p\n" , &local);
    printf("thread2_smol_heap %p\n", big_heap_ptr);
    printf("thread2_big_heap %p\n", smol_heap_ptr);
    printf("thread2_text %p\n", func4thread1);
    // printf("Address of global_str \"%s\": %p\n", global_str, global_str);
    // printf("Address of global_var: %p\n", &global_var);
    // printf("Address of foo: %p\n", func_ptr);
    // printf("Address of str_in_heap \"%s\": %p\n", (char *)arg, arg);
    fflush(stdout);

    sleep(10000);
    pthread_exit(NULL);
}

int main(int argc, char **argv) {
    pid_t pid = getpid();

    pthread_t t1, t2;
    char str[] = "str in heap.";
    char *str_in_heap = (char *)malloc(sizeof(char) * 12);
    char *big_str_in_heap = (char *)malloc(sizeof(char) * 1000);
    strncpy(str_in_heap, str, 12);

    void (*exit_addr)(int) = dlsym(RTLD_NEXT, "exit");
    char *env_home = getenv("HOME");



    printf("libc %p\n", exit_addr);
    printf("libc-var %p\n", stdout);
    printf("main_stack %p\n", &pid);
    printf("main_heap %p\n", str_in_heap);
    printf("main_big_heap %p\n", str_in_heap);
    printf("main_text %p\n", foo);
    // printf("main_heap2 %p\n", heap_ptr);
    printf("bss %p\n", &global_var);
    printf("data %p\n", global_str);
    
    printf(".rodata %p\n", &global_constant);
    printf("argv %p\n", argv);
    printf("env %p\n", env_home);
    fflush(stdout);

	// call the syscall before createing the thread
    long retval = syscall(449, pid);
    pthread_create(&t1, NULL, func4thread1, (void *)str_in_heap);
    sleep(1);

    pthread_create(&t2, NULL, func4thread2, (void *)str_in_heap);
    sleep(1);

    retval = syscall(449, pid);

	pthread_join(t1, NULL);
	pthread_join(t2, NULL);

	// sleep(10000);
	int a;
	scanf("%d", &a);
    return 0;
}
```

</br>
</br>
</br>
</br>

### PGD、P4D、PUD、PMD、PTE

---
# 不相關
![](https://upload.wikimedia.org/wikipedia/commons/e/e4/ELF_Executable_and_Linkable_Format_diagram_by_Ange_Albertini.png)

what's the diffence between section in elf and segment
https://stackoverflow.com/questions/14361248/whats-the-difference-of-section-and-segment-in-elf-file-format

==TODO:== Write a program to translate virtual address into physical address

:::info
**Basic Idea**

使用 `mm_struct` 中的 `pgd`
:::

get_current()

pthread 用了哪些 syscall

## Days after

### others

There's so many same macros/functions being define in different header files with different impelementation.
i'm so confusing rn

`syd_get_mem_layout` -> `sys_get_mem_layout`
stupid

**PCB (processing control block) 通常也稱為 struct tast_struct**
Wow idk `taskc_struct` IS PCB

### current

```c
// arch/x86/include/asm/current.h
static __always_inline struct task_struct *get_current(void)
{
	return this_cpu_read_stable(current_task);
}

#define current get_current()
```
```c
// arch/x86/include/asm/percpu.h

/*
 * this_cpu_read() makes gcc load the percpu variable every time it is
 * accessed while this_cpu_read_stable() allows the value to be cached.
 * this_cpu_read_stable() is more efficient and can be used if its value
 * is guaranteed to be valid across cpus.  The current users include
 * get_current() and get_thread_info() both of which are actually
 * per-thread variables implemented as per-cpu variables and thus
 * stable for the duration of the respective task.
 */
#define this_cpu_read_stable_1(pcp)	percpu_stable_op(1, "mov", pcp)
#define this_cpu_read_stable_2(pcp)	percpu_stable_op(2, "mov", pcp)
#define this_cpu_read_stable_4(pcp)	percpu_stable_op(4, "mov", pcp)
#define this_cpu_read_stable_8(pcp)	percpu_stable_op(8, "mov", pcp)
#define this_cpu_read_stable(pcp)	__pcpu_size_call_return(this_cpu_read_stable_, pcp)
```

### virt_to_phys

https://linux-kernel-labs.github.io/refs/heads/master/lectures/address-space.html


https://zhuanlan.zhihu.com/p/436879901
```c
// this not really work in linux 5.15.77
struct * page;
pgd_t pgd;
pmd_t pmd;
pud_t pud;
pte_t pte;
void *laddr, *paddr;

pgd = pgd_offset(mm, vaddr);
pud = pud_offet(pgd, vaddr);
pmd = pmd_offset(pud, vaddr);
pte = pte_offset(pmd, vaddr);
page = pte_page(pte);
laddr = page_address(page);
paddr = virt_to_phys(laddr);
```

```c
#define __for_each_thread(signal, t)	\
	list_for_each_entry_rcu(t, &(signal)->thread_head, thread_node)

#define for_each_thread(p, t)		\
	__for_each_thread((p)->signal, t)

/* Careful: this is a double loop, 'break' won't work as expected. */
#define for_each_process_thread(p, t)	\
	for_each_process(p) for_each_thread(p, t)
```
```c
#define list_for_each_entry_rcu(pos, head, member, cond...)		\
	for (__list_check_rcu(dummy, ## cond, 0),			\
	     pos = list_entry_rcu((head)->next, typeof(*pos), member);	\
		&pos->member != (head);					\
		pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
```

### copy kernel to user space

keyword: high memory
>  However, highmem is also used on 64bit systems but the use-case there is mainly to allow arbitrary mappings in kernel space.

`void __user *buffer`

```c
copy_to_user(user_buffer, ktmp, sizeof(struct my_struct))
copy_from_user(user_buffer, ktmp, sizeof(struct my_struct))
```

### pid ? tid?

user space 不同 thread 的 pid 一樣，
但是在 kernel space 可以發現他們有不同的 pid 

```bash
$ ps -H -m | grep hello

  17528 pts/0         0    119     1 84574 21144     -   552     -     -    - ./hello3.out
  17528 pts/0         0      6     1 84574 21144     -   552     -     -    - ./hello3.out
  17528 pts/0         0      1     1 84574 21144     -   552     -     -    - ./hello3.out
```
```bash
$ dmesg

[ 1294.741433] pid: 17530, tgid: 17528
[ 1294.741458] pid: 17528, tgid: 17528
[ 1296.741409] pid: 17531, tgid: 17528

```

中間發生了什麼事？？

### same vma list ???

因為 phys 轉出來很奇怪便嘗試分析 thread 間的差異
但是不同 thread 的 task_struct->mm->vma list 居然一樣？？
HOW WHY WHAT IDK 

brain smash detected, code dump
kernel panic