android linker (1) —— __linker_init(),androidlinker

來源:互聯網
上載者:User

android linker (1) —— __linker_init(),androidlinker

__linker_init() 在 begin.S 中被調用,並傳入兩個參數:sp(堆棧指標)、#0。

                        

 

linker(動態連結器,也稱解譯器)本身也是一個 shared object,__linker_init() 負責初始化 linker,完成 linker 的重定位等工作。由於在調用 __linker_init() 之前,linker 的重定位還沒有完成(GOT還不可用),所以任何對外部變數或函數的引用都會產生 segfault。

由於 linker 的重定位由其自己完成,所以該過程稱為 bootstrap(自舉)。

 

__linker_init() 的第一步是分解參數,把由 sp 參數傳入的 argc、argv、環境變數、ELF aux vectors 分別裝入KernelArgumentBlock 對象的相應成員中,方便訪問。

在 auxv 數組中,類型為 AT_BASE 的項儲存有 linker 鏡像的開始地址。__linker_init() 由此得到 linker_addr,繼而得到 elf_hdr(elf header) 和 phdr(program header) 的地址。

 

__linker_init() 接著填充一個 soinfo 結構變數。

 

成員 flags 設定上 FLAG_LINKER,後面見此標記就不會列印調試資訊,因為那些調試函數在 linker 完成重定位前尚不可用。

phdr_table_get_load_size() 計算整個 linker 鏡像的大小,方法是根據 program header ,找到段記憶體的最大地址和最小地址,在完成頁對齊之後相減。

get_elf_exec_load_bias() 得到 linker 在記憶體中的載入地址,實際上是第一個可載入段(PT_LOAD)在記憶體中的虛擬位址。

__linker_init() 接著以 linker_so 作為參數,調用 soinfo_link_image()。

在 soinfo_link_image() 中先找到動態連結段(PT_DYNAMIC)的地址,並得到動態連結結構的數量。然後遍曆所有動態連結結構,擷取諸如“字串表地址”、“符號表地址”、“重定位表地址”等重要訊息,填充到 soinfo 結構的相應成員中。接著載入所有依賴庫,但其實在 linker 自舉過程中,它並不依賴於任何其他shared object。重定位工作也是在 soinfo_link_image() 中完成,包括 rel 和 plt_rel(與 PLT 關聯的重定位項)。

__linker_init() 最後調用 __linker_init_post_relocation(),從名字可以看出,那些需要在重定位之後才能進行的工作都在這個函數中完成。

__linker_init() 最後返回鏡像的入口地址,也就是 elf header 中的 e_entry 儲存的虛擬位址。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.