●該章節主要講解的是ELF文件的結構。 web
●靜態庫的概念編程
●動態庫(又叫共享庫)的概念,通常用於操做系統,普通應用程序做用不大。數組
●程序的加載過程。服務器
該書中對連接的解釋也不夠詳細。在章節最後,做者也認可:在計算機系統文獻中並無很好的記錄連接。由於連接是處在編譯器、計算機體系結構和操做系統的交叉點上,他要求理解代碼生成、機器語言編程、程序實例化和虛擬存儲器。它剛好不落在某個一般的計算機系統領域中。函數
該章節講述Linux的X86系統,使用標準的ELF目標文件,不管是什麼樣的操做系統,細節可能不盡相同,可是概念是相同的。工具
讀完這一章節後,對「符號」的概念非常模糊。性能
這裏再說一下編譯系統。大多數編譯系統提供編譯驅動程序,它表明用戶在須要的時候調用語言預處理、編譯器、彙編器、和連接器。我本身畫了一個結構圖。spa
7.2靜態連接操作系統
可定位目標文件的結構:讓你深刻了解程序段,數據段,bss段,符號表等等。.net
7.4可重定位目標文件——參考7.3
符號表是一個數組,數組裏存放一個結構體。
原則是:編譯器只容許每一個模塊中每一個本地符號只有一個定義。並且對全局的符號的解析很棘手,由於多個目標文件可能會定義相同的符號。C++和Java使用mangling手段來支持重載。
多重定義的全局符號,請看下面的程序:
你們能猜到輸出的結果是15212;這是由於:bar.c中的x全局變量沒有初始化,致使函數f中使用的是foo文件中的x變量。
根據Unix鏈接器使用下面的規則來處理多重定義的符號:
●規則1:不容許有多個強符號。
●規則2:若是有一個強符號和多個弱符號,那麼選擇強符號(這就是上面這道題的答案,初始化的int x=15213是強符號,而int x;是弱符號)
●規則3:若是有多個弱符號,那麼從這些弱符號中任意選擇一個(多麼可怕啊)
靜態庫
事先寫好的一些可重定位的目標文件打包成一個單獨的文件,它能夠用做鏈接器的輸入。當鏈接器構造一個輸出的可執行文件時,它只拷貝靜態庫裏被應用程序引用的目標模塊。(稍後講解動態連接庫,也稱之爲共享庫)。
在Unix系統中,靜態庫以一種成爲存檔(archive)的特殊文件格式存放在磁盤中。存檔文件是一組鏈接起來的可重定位目標文件的集合。有一個頭部用來描述每一個成員目標文件的大小和位置。存檔文件的後綴是.a標識。是否能夠這麼理解.a文件的結構呢?(本身畫圖)
下面用展現一個靜態庫鏈接的過程:
7.7重定位
參考7.3節圖中央部分。可執行文件跟可重定位目標文件很是類似。只是可執行文件多了「init」和「段頭部表"少了,」.rel.text「和」.rel.data「兩個節。
從7.3節圖中能夠發現,右部是加載後的程序結構。ELF目標文件被設計的很是容易加載到存儲器。須要注意的是Unix中,程序總的代碼段老是從0x0804800處開始(這就是虛擬存儲器的做用)。數據段是在接下來的下一個4KB對齊的地址處。運行時堆在"讀/寫段"以後接下來的第一個4KB對齊的地址處,並經過malloc庫往上增加。而棧老是往下生長。
動態庫是爲了解決靜態庫的兩個弊端而出現的,靜態庫的兩個弊端:1)靜態庫更新後,程序要得到該靜態庫而後再編譯。2)不一樣程序可能使用相同的靜態庫,致使不少靜態庫中的代碼重複被加載到存儲器中。
共享庫是致力於解決靜態庫的缺陷而出現的現代創新型產物。共享庫是一塊目標模塊,在運行時,能夠加載到任意的存儲器地址,並和一個在存儲其中的程序連接起來。這個過程稱之爲」動態連接「,是由一個叫作」動態連接器「的程序來完成的。
共享庫是以梁總方式來共享的:1)全部引用該庫的程序都共享一個.so文件中的代碼和數據,而不是靜態庫同樣拷貝一份。2)在存儲器中,一個共享庫的.text節的一個副本能夠被不一樣正在運行的進城共享,從而節約寶貴的存儲器資源。(Unix中動態庫以.so後綴表示。)
理解動態庫=共享庫的概念很是重要。動態庫通常是大型軟件或者操做系統的最愛,由於對於普通應用來講,沒有那麼多庫給別人使用,絕大多數都是本身用,因此靜態庫就夠了。
應用程序還可能從應用程序中加載和連接任意共享庫,而無需編譯時連接那些庫到應用中(這個牛逼大了)!
Windows中的更新大部分是這個技術。另外還有構建高性能web服務器。
Linux爲動態連接器提供了一系列簡單的接口:
Java定義了一個標準的調用規則,叫作Java本地接口(Java NativeInterface,JNI),它容許Java程序調用本地的C和C++函數。JNI的基本思想是將本地的C函數,如foo,編譯到共享庫中,如foo.so .當一個正在運行的Java程序試圖調用函數foo時,Java解析程序利用dlopen接口(或者相似的接口)動態連接和加載foo.so,而後調用foo。
7.12與位置無關的代碼(PIC)
7.13處理目標文件的工具
原文:http://blog.csdn.net/hherima/article/details/8953787