簡體   English   中英

ELF object 文件和共享 object 文件之間的 ELF header 區別是什么?

[英]What are the ELF header differences between an ELF object file and shared object?

首先,我是從技術的角度來問這個問題,而不是從庫代碼用戶的角度來問這個問題。 差異的一個示例是共享對象包含程序頭,而普通的 object 文件不包含。 其他的區別是什么?

As to the purpose of my question, I'm trying to figure out what content would need to be removed from a shared object file to have the linker treat it as an ordinary object file and attempt to relocate and static link it into the generated executable文件,而不是將其標識為共享庫並生成DT_NEEDED引用。 這反過來是將共享庫原始“轉換”為可以靜態鏈接的東西的第一步(但是,可能需要進一步工作以使重定位可滿足)。

您會發現的主要區別之一是,在最后的鏈接階段,許多 C 庫組件靜態鏈接到庫中,形成 INIT 和 FINI 符號等。 這些在程序 header 中用DT_INITDT_FINI條目指定; 您需要將這些轉換為 static 構造函數/析構函數條目。 DT_NEEDED 條目將在轉換為 ao 時丟失; 您將需要手動重新添加它們。

最終鏈接階段生成的 PLT 需要與最終的 output 文件合並,或者轉換回普通重定位; 這很重要,因為 PLT 只是代碼。 GOT 也是一個問題。 它位於與 .text 段的固定相對偏移量處,並包含指向數據成員的指針。 但是,它還包含一個指向 _DYNAMIC 結構的指針,每個庫或可執行文件只能有一個。 而且您不能更改 GOT 中的偏移量,因為它們是直接從代碼中引用的。

所以再次將 a.so 轉換為 true.o 是相當困難的; 信息在轉換為 PLT/GOT 時丟失。 A better approach might be to alter the dynamic linker in the C library to support linking a shared library that's already mapped in memory as a static image. 也就是說,您只需將.so 轉換為與頁面對齊的只讀部分即可將其轉換為ao; 然后將此傳遞給動態 linker 以使用適當的權限重新映射並執行正常的共享庫初始化。 然后添加一個 static 構造函數調用到 C 庫來初始化共享庫。 最后,添加適當的導出符號以對應共享庫的.text 段中的動態符號。

但是,這種方法的一個問題是 static 構造函數可能在初始化假 solib 的 static 構造函數之前運行。 在這種情況下,他們不能嘗試從 solib 調用函數,否則您可能會崩潰,因為 solib 尚未初始化。 這可以通過使導出的符號指向蹦床 function 來避免這種情況,以確保首先初始化 solib(不過,對於數據符號來說並不那么容易!)

您可能還會發現這個先前的問題可能對您有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM