# 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`



### Write a script to find informations of segment
從之前寫好的 system call 可以得知每個 segment 的 `start address`, `end address`, `size`, `flag` 和 `prot` 等資訊,但是還不清楚 segment 實際上所對應的是 process 的哪個部分。
而從原本的 multithread program 的實驗結果可以看到各個變數所在的記憶體位置,並且也可以查看兩者的 segment 有哪些是共用的。

有了這些資訊,接下來就可以寫一個簡單的 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
---
# 不相關

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