瞭解動態連結(四)—— 延遲綁定,動態綁定

來源:互聯網
上載者:User

瞭解動態連結(四)—— 延遲綁定,動態綁定

基本思想是當函數第一次被調用時才進行綁定,所謂綁定就是符號尋找和地址重定位。對於一些錯誤處理函數或不常用的功能函數,可能就避免了“綁定浪費”。採用延遲綁定,能加快程式的啟動速度,特別有利於一些大型程式。

當函數第一次被調用時,由動態連結器完成地址綁定工作。他必須知道地址綁定發生在哪個模組的哪個函數,並且要有一個完成綁定工作的函數。

具體實現時,調用某個外部函數要先跳轉到 PLT,再跳轉到 GOT 得到外部函數地址。每個外部函數都在 PLT 表中有一個相應的項。比如:

1 bar@plt:2   jmp *(bar@GOT)3   push n4   push moduleID5   jump _dl_runtime_resolve

第一條指令跳轉 bar@GOT,此時 bar@GOT 中儲存的是上面代碼中的第二條指令“push n”的地址,所以又跳回來。兩條 push 指令分別將符號在重定位表中的下標和模組 ID 入棧,然後調用動態連結器的 _dl_runtime_resolve 函數來完成符號尋找和地址重定位,最後將 bar 函數的真正地址填入 bar@GOT。當再次調用 bar@plt 時,第一條 jmp 指令就可以經由 bar@GOT 直接跳轉到 bar 函數,而無需再做重定位了。

在具體實現時,ELF 將儲存外部函數地址的 GOT 剝離出來,放到 .got.plt 中。.got.plt 的前三項特殊:

  • 第一項儲存“.dynamic”的地址;
  • 第二項儲存本模組的 ID;
  • 第三項儲存 _dl_runtime_resolve 的地址

所以上面的 bar@plt 可以這樣:

1 bar@plt:2   jmp *(bar@GOT)3   push n4   push *(GOT + 4)5   jump *(GOT + 8)

因為最後兩條指令對於每個 plt 項都一樣,為了避免代碼重複,將這兩條指令提出來,放到 PLT0。所以 bar@plt 實際上是這樣:

1 PLT0:2   push *(GOT + 4)3   jump *(GOT + 8)4   …5 bar@plt:6   jmp *(bar@GOT)7   push n8   jmp PLT0

學習資料: 《程式員的自我修養——連結、裝載和庫》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.