天天看點

深入了解LINUX下動态庫連結器/加載器ld-linux.so.2【轉】1. 什麼是 ld.linux.so ? 

(轉自:https://blog.csdn.net/elfprincexu/article/details/51701242)

最近在Linux 環境下開發,搞了好幾天 Compiler 和 linker,覺得有必要來寫一篇關于Linux環境下 ld.so的文章了,google上搜尋了很多相關介紹性的文檔,發現國内百度上卻很少有相關類文檔,覺得有必要來梳理一下:

ld-linux.so.2 是linux下的動态庫加載器/連結器,這篇文章主要來講一下 ld-linux.so.2 是如何和Linux 以及相關應用打交道的。

1. 什麼是 ld.linux.so ? 

很多現代應用都是通過動态編譯連結的,當一個 需要動态連結 的應用被作業系統加載時,系統必須要 定位 然後 加載它所需要的所有動态庫檔案。 在Linux環境下,這項工作是由ld-linux.so.2來負責完成的,我們可以通過 ldd 指令來檢視一個 應用需要哪些依賴的動态庫:

$ ldd `which ls`
      linux-gate.so.1 =>  (0xb7fff000)
      librt.so.1 => /lib/librt.so.1 (0x00b98000)
      libacl.so.1 => /lib/libacl.so.1 (0x00769000)
      libselinux.so.1 => /lib/libselinux.so.1 (0x00642000)
      libc.so.6 => /lib/libc.so.6 (0x007b2000)
      libpthread.so.0 => /lib/libpthread.so.0 (0x00920000)
      /lib/ld-linux.so.2 (0x00795000)
      libattr.so.1 => /lib/libattr.so.1 (0x00762000)
      libdl.so.2 => /lib/libdl.so.2 (0x0091a000)
      libsepol.so.1 => /lib/libsepol.so.1 (0x0065b000)
           

當最常見的ls小程式加載時,作業系統會将 控制權 交給 ld-linux.so 而不是 交給程式正常的進入位址。 ld-linux.so.2 會尋找然後加載所有需要的庫檔案,然後再将控制權交給應用的起始入口。

上面的ls在啟動時,就需要ld-linux.so加載器将所有的動态庫加載後然後再将控制權移交給ls程式的入口。

ld-linux.so.2 man page給我們更高一層的全局介紹, 它是在 連結器(通常是ld)在運作狀态下的部件,用來定位和加載動态庫到應用的運作位址(或者是運作記憶體)當中去。通常,動态連結是 在連接配接階段當中 隐式指定的。 gcc -W1 options -L/path/included -lxxx 會将 options 傳遞到ld 然後指定相應的動态庫加載。 ELF 檔案提供了相應的加載資訊, GCC包含了一個特殊的 ELF 頭: INTERP, 這個 INTERP指定了 加載器的路徑,我們可以用readelf 來檢視相應的程式

$ readelf -l a.out

Elf file type is EXEC (Executable file)
Entry point 0x8048310
There are 9 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x004cc 0x004cc R E 0x1000
  LOAD           0x000f0c 0x08049f0c 0x08049f0c 0x0010c 0x00110 RW  0x1000
. . .
           

ELF 規格要求,假如 PT_INTERP 存在的話,作業系統必須建立這個 interpreter檔案的運作映射,而不是這個程式本身, 控制權會交給這個interpreter,用來定位和加載所有的動态庫。