計算機系統篇之鏈接(6):動態鏈接

計算機系統篇之鏈接(6):動態鏈接

Author:stormQ

Wednesday, 15. April 2020 04:35PM


引入共享庫的動機

共享庫,也被稱爲可共享目標文件,可以被動態鏈接器在加載期或運行期加載到任意的內存地址,並和一個內存中的程序鏈接起來。

引入共享庫的目的是爲了解決靜態庫的缺點。相比於靜態庫的三個缺點,共享庫對應的優點爲:1)可以在加載期或運行期進行鏈接過程。因此,共享庫更新後不用像靜態庫那樣,可執行目標文件必須顯式地重新鏈接。2)節省磁盤空間。共享庫的代碼和數據被所有引用該共享庫的可執行目標文件共享。3)節省內存空間。共享庫的代碼在內存中的一份拷貝被所有引用該共享庫的進程共享。

靜態鏈接與動態鏈接的區別

區別 使用的鏈接器 作用對象 發生的時期
靜態鏈接 靜態鏈接器(如:ld on Linux) 靜態庫 編譯期
動態鏈接 動態鏈接器(如:ld-linux-x86-64.so.2 on Linux) 動態庫 加載期或運行期
  • 注:

    • Linux 中的靜態鏈接器ld是可執行目標文件,Linux 中的動態鏈接器(如ld-linux-x86-64.so.2)是可共享目標文件。

    • Linux 中的靜態鏈接器ld的輸入文件可以是共享庫,但只是拷貝了重定位信息和符號表,並未進行符號解析和重定位過程。也就是說,即便共享庫可以作爲Linux 中的靜態鏈接器ld的輸入文件,但實際上沒有發生鏈接過程。

如何生成共享庫

1)生成共享庫(On Linux x86-64)

$ g++ -o libtest.so test.cpp -shared -fpic
  • 注:

    • -shared選項指示鏈接器生成共享庫。

    • -fpic選項指示編譯器生成位置無關代碼。

    • -fno-pic選項指示編譯器不生成位置無關代碼,但在 Linux x86-64 中使用該選項生成上述共享庫時鏈接器會報錯:/usr/bin/x86_64-linux-gnu-ld: /tmp/ccdwqRF4.o: relocation R_X86_64_PC32 against symbol g_val_1 can not be used when making a shared object; recompile with -fPIC /usr/bin/x86_64-linux-gnu-ld: final link failed: Bad value collect2: error: ld returned 1 exit status

查看 test.cpp 和 main.cpp 的源碼:

$ cat test.cpp 
int g_val_1 = 1;
int g_val_2 = 2;

void func()
{
  g_val_1 *= 2;
  g_val_2 *= 2;
}
$ cat main.cpp
extern int g_val_1;
extern int g_val_2;

void func();

int main()
{
  func();
  return 0;
}

使用共享庫:

$ g++ -o main main.cpp ./libtest.so

雖然生成的可執行目標文件引用了共享庫中的函數或全局變量,但是共享庫中的代碼和數據不會拷貝到可執行目標文件中。實際上,只是將共享庫中的重定位信息和符號表拷貝到了可執行目標文件中,以便於在加載期解析對共享庫中的函數或全局變量的引用。

當加載器加載並運行可執行目標文件時,如果可執行目標文件中包含 .interp section(該 section 用於指定動態鏈接器的路徑),那麼加載器會加載並運行動態鏈接器,動態鏈接器完成鏈接過程後,動態鏈接器會將控制權交給應用程序,從而開始執行應用程序的入口點函數。

查看可執行目標文件 main 需要的共享庫:

$ ldd main
	linux-vdso.so.1 =>  (0x00007ffc8e793000)
	./libtest.so (0x00007f21de5ed000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21de223000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f21de7ef000)

查看可執行目標文件 main 的 .interp section:

$ readelf -p .interp main

String dump of section '.interp':
  [     0]  /lib64/ld-linux-x86-64.so.2

關注公衆號,即可查看完整內容。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章