How linkers resolve Multiply defined global symbols
Rules1. Multiply strong symbols are not allowed
2. Given a strong symbol and multiple weak symbols, choose the strong one.
3. Given multiple weak symbols, choose any of them.
考慮下面一段程式:
在IA32 linux上進行編譯串連時不會報錯,但是實際上是有潛在問題的。由於32位linux上int是4位元組而double是8個位元組,此時bar5中會將x提升到double類型,此時會造成x在記憶體中地址的改變這點是我們通常會忽視的狀況,很有可能很多莫名其妙的錯誤來源於此…以後需要注意。
GCC -fno-common
加上此標誌後會就重複聲明的全域變數進行提示,實際上,我感覺最好是避免全域變數的重複定義,感覺純粹的OO語言裡面這種現象出現的機率會比較小,但是還是需要注意的地方啊。此時我們可能會比較疑惑的是…Overload的function腫麼辦?因為名字是一樣的嘛。因為它們的arg list是不一樣的,因此編譯器會根名字和arg list重新打包命名交給linker處理。這個重新命名的過程就是mangling,反之稱為demangling。mangling的機制java和c++是互相相容的。首先類名由原類名和類名的字元個數組成。foo就是foo3。例如
Foo:: bar(int,long)
變成了 bar__3Fooil也就是說,mangling的方法是:OriginalMethodName__MangledClassNameAndLettersOfEachArguments
“The general rules for libraries is to place them at end of command line”
也就是說,靜態連結庫最好放在編譯命令列的最末,不然的話,若是首先對.a檔案進行編譯串連,則此時集合U(unresolved symbols)中沒有任何元素,連接器不會將該靜態庫添加到集合E(產生可執行檔需要的檔案)中,接著若是連結一個object檔案中引用到了靜態庫中的檔案時,連接器就會報告unresolved symbol這種錯誤。所以在編譯串連時,越是基本的庫約要放在較後的位置進行處理。若是各個庫之間沒有相互引用,則無所謂放置的位置。
Libraries can be repeated on the command line if necessary to satisfy the dependence requirements
也就是說…要是你願意…同一個庫你可以在命令列重複輸入多遍,但是最好不要這麼做…這樣的話建議將能合并的庫都合并了(ーー;)例題:寫個最短的命令列解決編譯問題,要解決各種依賴關係。a->b表示a依賴b
p.o->libx.a->liby.a and liby.a->libx.a->p.osolution:
gcc p.o libx.a liby.a libx.a
7.7 Relocation
Relocation consists of two steps1. Relocating sections and symbol definitions. After this step, every instruction and global variable in the program has a unique run-time memory address. 2. Relocating symbol reference within sections. To perform this step, the linker relies on data structures in the relocatable object module known as the relocatable entries.
根據deassembler課題看到,重新置放需要相應的重定位類型,地址以及symbol。之後成為一個可執行檔,unix shell會根據其類型調用系統駐留程式,即loader,進行載入運行。Disadvantage :
Static libraries, like all software, need to be maintained and updated periodically
7.7 Relocation
Relocation consists of two steps1. Relocating sections and symbol definitions. After this step, every instruction and global variable in the program has a unique run-time memory address. 2. Relocating symbol reference within sections. To perform this step, the linker relies on data structures in the relocatable object module known as the relocatable entries.
根據deassembler課題看到,重新置放需要相應的重定位類型,地址以及symbol。之後成為一個可執行檔,unix shell會根據其類型調用系統駐留程式,即loader,進行載入運行。Disadvantage :
Static libraries, like all software, need to be maintained and updated periodically
7.10 Dynamic linking with shared librariesShared libraries are shared in 2 different ways:
First, in any given file system, there is exactly one .so file for a particular library.Second, a single copy of the .text section of a shared library in memory can be shared by different running processes.
Linux系統下允許應用程式調用外部的動態連結程式庫的介面是:#include <dlfcn.h>void *dlopen(const char *filename, int flag);該函數用於載入動態連結程式庫filename#include <dlfcn.h>void *dlsym(void *handle, char *symbol)該函數通過前一個開啟的動態連結程式庫的控制代碼,以及symbol名,返回symbol的地址,沒有的話返回NULL#include <dlfcn.h>int dlclose(void *handle);若無其他動態連結程式庫佔用,可對當前動態連結程式庫進行卸載操作。#include <dlfcn.h>const char *dlerror(void);對於上三個函數調用過程中錯誤資訊的返回。7.12 Position Independent Code (PIC)
How can multiple process share a single copy of code?Compile library code that it can be loaded and executed at any address. Such code is known as position-independent code(PIC)
不管在何處載入何種object模組,data段永遠緊跟在code段之後進行地址的分配。這樣保證了地址的差值是一定的,也就是說實際上使用的是相對位址,這樣就不會有絕對位址會造成的問題了。所以編譯器在段一開始處便會有一個位移地址對照表,方便之後根據對照表進行地址的尋找。
Tools for manipulating object filesAR: Creates static libraries, and inserts, deletes, lists, and extracts members.STRINGS: Lists all of the printable strings contained in an object file.STRIP: Delete symbol table information from an object file.NM: Lists the names and sizes of the sections in an object file.SIZE: Lists the name and sections in an object file.READELF: Displays the complete structure of an object file, including all of the information encoded in the ELF header, subsumed the functionality of SIZE and NM.OBJDUMP: The mother of all library tools. Can display all the information in an object file. It's most useful function is disassembling the binary instructions in the .text section.LDD: list the shared libraries that is needed at run time.