--- title: 「你所不知道的 C 語言:動態連結器篇」 筆記 tags: Computer Science,System Software description: 2019.08.07 --- 「你所不知道的 C 語言:動態連結器篇」 筆記 === ###### 2019.08.07 *Copyright © 2019 by srhuang* ![](https://i.imgur.com/KyaeILQ.png) [影片](https://youtu.be/7aYVDPuH2uI) [講義](http://hackfoldr.org/dykc/https%253A%252F%252Fhackmd.io%252Fs%252FHkK7Uf4Ml) Original by [jserv](http://wiki.csie.ncku.edu.tw/User/jserv) --- ## 跨越程式語言的交流:透過 C 語言 * lingua franca:https://youtu.be/7aYVDPuH2uI?t=34 * 理解動態連結不僅是重新回顧 C 語言,更是透過橋接語言,深入理解系統運作 * P-code 與 Kenneth Bowles 教授:https://youtu.be/7aYVDPuH2uI?t=228 * P-code 是種設計來執行於虛擬 CPU 上的機械碼,也就是所謂的 bytecode 的前身,後來 P-code 衍生來稱呼這類虛擬機器,像是 Java 虛擬機器或者 Visual BASIC 編譯出來的中間機械碼。 ## 貌似簡單的問題:「如何得知 malloc/free 的呼叫次數?」 * 前言:https://youtu.be/7aYVDPuH2uI?t=476 * 簡單的作法:https://youtu.be/7aYVDPuH2uI?t=604 * 透過巨集。 * 沒更換到無法追蹤、C++ new/delete 無法追蹤、函式庫也無法追蹤。 * 要徹底解決這問題,就需要動用到動態連結器 (dynamic linker) * 動態連結 malloc_count.c:https://youtu.be/7aYVDPuH2uI?t=820 * 使用 dlsym obtain address of a symbol in a shared object (malloc). * Function designator:將利用 dlsym 取得的 function address 指派給 function symbol name. * LD_PRELOAD=/tmp/libmcount.so ls:在執行 ls 之前,會先動態連結 ==libmcount.so==. * 這樣的技巧,我們稱為 interpositioning。 * TCMalloc (Google):https://youtu.be/7aYVDPuH2uI?t=1785 * glibc 2.3 malloc takes approximately 300 nanoseconds, the TCMalloc implementation takes approximately 50 nanoseconds. * Google Heap Checker/Profiler:https://gperftools.github.io/gperftools/heapprofile.html * Dynamic linker tricks:https://youtu.be/7aYVDPuH2uI?t=2207 * 幹壞事是進步的原動力。 * Dynamic Linker 簡述:https://youtu.be/7aYVDPuH2uI?t=2625 * 動態連結器是可以直接執行的。 * 動態連結器通常會在 /lib/ 目錄下。 * glibc-abi。 * LD_PRELOAD 環境變數:https://youtu.be/7aYVDPuH2uI?t=3084 * 需要搭配 dynamic linker。 * 類似環境變數 PATH。 * * GNU ld 有個選項 -Bsymbolic-functions 會影響 LD_PRELOAD 的行為 * Symbolism and ELF files:https://youtu.be/7aYVDPuH2uI?t=3333 * 用 LD_PRELOAD 替換動態連結的函式庫:https://youtu.be/7aYVDPuH2uI?t=3506 ## “No such file or directory” 可能跟你猜想的不一樣 * 前言:https://youtu.be/7aYVDPuH2uI?t=3553 * linux 核心的程式碼 fs/binfmt_elf.c:https://youtu.be/7aYVDPuH2uI?t=3619 * https://elixir.bootlin.com/linux/latest/source/fs/binfmt_elf.c * SVr4:UNIX System V (five) r4,第一個商業化的 UNIX。 * load_elf_binary:Linux Kernel 中負責載入 ELF 格式的執行檔。 * This is the program interpreter used for shared libraries. * requesting program interpreter : Dynamic Linker path. * 延伸閱讀:https://youtu.be/7aYVDPuH2uI?t=4260 * 《Binary Hacks》 * ELF Hacks ## 複習 編譯器和最佳化原理 * Compilation Unit:https://youtu.be/7aYVDPuH2uI?t=4554 * A compilation unit is C source code that is compiled and treated as one logical unit. * 建議 local function 要宣告成 static,因為 Compiler 不能砍掉沒人使用的 non-static global variable。 * Preprocessor:https://youtu.be/7aYVDPuH2uI?t=4859 * DIGITAL UNIX:https://youtu.be/7aYVDPuH2uI?t=4970 * Scoping 的問題:https://youtu.be/7aYVDPuH2uI?t=5120 * static 只能在同個 Compilation Unit 看得到。 * Compilation Unit 會阻礙最佳化空間,non-static function 無法確定其他 Compilation Unit 是否有使用到。 * 解法:LTO (Link Time Optimization):當 function call 的成本大於執行 function 本身,在連結時期直接展開 function,將會大幅縮減載入時間。 * Modern C:https://youtu.be/7aYVDPuH2uI?t=5848 * 一旦物件宣告為 static const,那麼編譯器就可以施加更多樣的最佳化策略。 * Shrinking the kernel with link-time optimization:https://youtu.be/7aYVDPuH2uI?t=6194 * Optimize uClinux for ARM Cortex-M4:https://elinux.org/images/d/d4/Optimize_uClinux_for_ARM_Cortex-M4.pdf * Function inlining LTO:效能最佳化。 * Constant folding LTO:空間最佳化。 * Skymizer:台灣編譯器最佳化公司。 ## Symbol Visibility * 前言:https://youtu.be/7aYVDPuH2uI?t=6821 * 預設的情況下,所有的 symbol 都是可以被 export。 * Why is the new C++ visibility support so useful?:https://youtu.be/7aYVDPuH2uI?t=7116 * C++ Standard Template Library (STL) 產生出來的程式碼往往膨脹很快。 * It reduces the size of your DSO(Dynamic Shared Object) by 5-20%. * you cut out the 60-80% of unnecessary symbols. * 需要 compiler and linker 的協助。 * 使用:__attribute__ ((visibility ("hidden"))) * gcc 和 clang 都支援 visibility 屬性和 -fvisibility 編譯命令:https://youtu.be/7aYVDPuH2uI?t=7628 * Why symbol visibility is good:https://youtu.be/7aYVDPuH2uI?t=7867 * weak symbol:以其他人為主,若無其他人,則使用自己的。 * sym.c:https://youtu.be/7aYVDPuH2uI?t=8080 * Bind:GLOBAL / LOCAL / WEAK。 ## 「作中學」:從實踐中學習 * min-dl:https://youtu.be/7aYVDPuH2uI?t=10980 * android_crazy_linker (Google):https://youtu.be/7aYVDPuH2uI?t=11093 * 讓 android 系統可以載入特定 native code。 ## 總結:https://youtu.be/7aYVDPuH2uI?t=11296