--- title: 「你所不知道的 C 語言:連結器和執行檔資訊」 筆記 tags: Computer Science,System Software description: 2019.08.05 --- 「你所不知道的 C 語言:連結器和執行檔資訊」 筆記 === ###### 2019.08.05 *Copyright © 2019 by srhuang* ![](https://i.imgur.com/eCCH4Mw.png) [影片](https://youtu.be/7Zraf5487YA) [講義](http://hackfoldr.org/dykc/https%253A%252F%252Fhackmd.io%252Fs%252FSysiUkgUV) Original by [jserv](http://wiki.csie.ncku.edu.tw/User/jserv) --- ## 簡介 * linker:https://youtu.be/7Zraf5487YA?t=34 * 可掛(卸)載模組:insmod / rmmod,kernel module 真正實作的地方也跟 linker 有關。 * loader 是如何演化成 linker (ld)。 ## 嵌入一個二進位檔案到執行檔 * 前言:https://youtu.be/7Zraf5487YA?t=357 * 可以在沒有檔案系統的情況下,讀取檔案。 * secure boot * 安裝程式 setup.exe * 實作:https://youtu.be/7Zraf5487YA?t=609 * 寫個測試程式 (test.c):https://youtu.be/7Zraf5487YA?t=1063 * objcopy_to_carray:https://youtu.be/7Zraf5487YA?t=1648 * objcopy uses the GNU BFD Library to read and write the object files. * readelf:This program performs a similar function to objdump but it goes into more detail and it exists independently of the BFD library, so if there is a bug in BFD then readelf will not be affected. ## init script 示範 * init hooks:https://youtu.be/7Zraf5487YA?t=2283 * 讓初始化流程可以集中在某個地方,卻又不想破壞程式結構。 * 使用 INIT_HOOK 巨集,就可以在核心啟動早期就執行。 * INIT_HOOK 巨集做的事情就是將函式名稱放到 “.init_hook” section。 * 利用 linker script 配置 “.init_hook” section 空間。 ## 連結器在軟體最佳化扮演重要角色 * 前言:https://youtu.be/7Zraf5487YA?t=2948 * 手機裡面就有多個作業系統:Android, Trusty Tee (Trusty Kernel), Modem, secure enclave (apple). ![](https://i.imgur.com/RDC5XMs.png) ![](https://i.imgur.com/27WXKlv.png) * 雲端的應用:伺服器往往找不到效能瓶頸,但是可以動用連結器讓程式去最佳化程式。 * 複習「你所不知道的 C 語言」: 編譯器和最佳化原理篇:https://youtu.be/7Zraf5487YA?t=3638 * 編譯、組譯、連結三大步驟:https://youtu.be/7Zraf5487YA?t=3693 * IR:https://youtu.be/7Zraf5487YA?t=3893 * SSA (Static Single Assignment):https://youtu.be/7Zraf5487YA?t=3946 * IPO (Inter-Procedural Optimization):https://youtu.be/7Zraf5487YA?t=4025 * Compilation Unit * 最簡單的 IPO 就是 function inlining,簡單來說就是把整個 function body copy 到 caller 的程式碼裡面。 * 為了減少 function call 的 cost for small function。 * Link Time Optimization (LTO) for Linux * Linker 的命令列也是一種語言:https://youtu.be/7Zraf5487YA?t=4660 * Google gold linker:https://youtu.be/7Zraf5487YA?t=4743 * LLVM:https://youtu.be/7Zraf5487YA?t=5144 * Ian Wienand 的電子書: Chapter 7. The Toolchain:https://youtu.be/7Zraf5487YA?t=5256 * Symbol Visibility:https://youtu.be/7Zraf5487YA?t=5325 * 所有「不是 static」的 symbol 都可會開放給其他 compilation unit 去存取。 * interpositioning、static / extern * The linking process:https://youtu.be/7Zraf5487YA?t=5526 * relocation。 * name mangling (C++):c++filt 解析名字修飾。 * Example:hello 程式。 * collect2:負責傳遞參數給 ld 。 * The Executable。 * 10分鐘讀懂 linker scripts:https://youtu.be/7Zraf5487YA?t=6402 * 背景知識 * Sections * Section Address * 簡單範例:mini-arm-os * Linker Script 初探 - GNU Linker ld 手冊略讀:https://youtu.be/7Zraf5487YA?t=6836 * 為什麼需要了解 Linker:https://youtu.be/7Zraf5487YA?t=6892 * 為了大型程式,例如網頁瀏覽器。 * WeChat OS * libreoffice * libxul mozilla:https://youtu.be/7Zraf5487YA?t=7170 * https://wiki.mozilla.org/XUL:Lib_XUL * XPCOM : cross platform. 物件導向設計 * 裡面的引擎叫做「gecko」,包含 XPCOM, networking, DOM, layout, rendering…. * gecko 裡面最核心的部分就是「libxul」。 * It is a library that provides frozen API for XUL apps and embedders of gecko. * 使用者體驗小故事:程式啟動影響使用者體驗相當關鍵。 * 程式啟動執行的早期,大部分都在載入動態連結,而非執行程式碼。 * Elfhack apply libxul startup:壓縮動態連結器的成本,Elfhack compress the relocations。 * Improving libxul startup I/O by hacking the ELF format:https://youtu.be/7Zraf5487YA?t=7792 * Optimizing large applications:https://youtu.be/7Zraf5487YA?t=8039 * 減少空間不一定會提升速度,因為要考慮動態連結的成本,CRT成本,函式呼叫的成本等。 * Firefox startup:6% 動態連結,15% relocation,46% 初始化,剩下才是程式碼執行。 * 要改善使用者體驗,就是必須從前面的 dynamic linker 著手。 * 「a.out」 shared libraries was hell to maintain。 * 「ELF」introduced shared libraries that are very flexible [1995] * symbol interpositioning:LD_PRELOAD. * symbol versioning. e.g. GNU glibc. * symbol visibility. * PIC (position-independent code) for 動態連結。GOT/PLT for 動態連結的基礎建設。 * qsort (is not quick sort):take address of function or static variable in code. * 載入 ELF 執行檔範例:https://youtu.be/7Zraf5487YA?t=8647 * GIMP startup * Libreoffice startup * prelink [2004] * speeding up dynamic linker runtime. [2006] * feedback directed reordering [2013]:https://youtu.be/7Zraf5487YA?t=9203 * valgrind * GCC FDO (feedback directed optimization):修改執行檔,插入可以在執行時期搜集資料的程式碼,再把這些資料重新編譯,是一種 build-run-build 的概念。 ![](https://i.imgur.com/fFDpmkA.png) * Google AutoFDO:https://static.googleusercontent.com/media/research.google.com/zh-TW//pubs/archive/45290.pdf * LTO (Link Time Optimization):https://youtu.be/7Zraf5487YA?t=9574 * 需要更多的 CPU and Memory 資源。 * 可以大幅提升速度。 * Linktime optimization in GCC (2014):https://youtu.be/7Zraf5487YA?t=9716 * part 1 - brief history * part 2 - Firefox * part 3 - LibreOffice * [What makes LLD so fast?](https://fosdem.org/2019/schedule/event/llvm_lld/):https://youtu.be/7Zraf5487YA?t=10154 * LLD is the LLVM linker. * The missing link: explaining ELF static linking, semantically:https://youtu.be/7Zraf5487YA?t=10698 * formal proof * 把 linker 的行為重新描述一次。 ## 在 Linux 核心的應用案例 * Shrinking the kernel with link-time garbage collection:https://youtu.be/7Zraf5487YA?t=10940 * Shrinking the kernel with link-time optimization:https://youtu.be/7Zraf5487YA?t=11307 * Shrinking the kernel with an axe:https://youtu.be/7Zraf5487YA?t=11661 ## 其他 * tramp-test:https://youtu.be/7Zraf5487YA?t=11778 * dt_infect:https://youtu.be/7Zraf5487YA?t=11998 ## 總結:https://youtu.be/7Zraf5487YA?t=12078