Re: [問題] 關於 Position Independent Code 的概念

看板C_and_CPP作者 (拋磚引玉)時間15年前 (2010/10/10 11:15), 編輯推噓0(005)
留言5則, 2人參與, 最新討論串5/7 (看更多)
其實我對於您提出的例子,沒辦法理解,以下是我的謬論(?) 假設 libfoo.so 的 Code 如您所說 int x; void inc() { ++x; } 那麼在編譯及連結之後, x 應該是長在該 DSO 自己的 .data 區 也就是我推文所講的,應該是可以直接從 .data 的 offset 算出要填入的位址 這應該跟 PIC 無關才對吧,照這樣看,還沒載入之前,位址就應該都是固定的吧 這樣即使 A, B 兩行程同時使用 libfoo.so,該 DSO 的 .text 應該也是固定的阿 我以為,只有在 libfoo.so 參考其他 libbar.so 這種情況下 PIC 才會對 load time relocation 有差別吧 感覺還是似懂非懂,麻煩前輩們請多再指教 ※ 引述《littleshan (我要加入劍道社!)》之銘言: : ※ 引述《nowar100 (拋磚引玉)》之銘言: : : 遇到的問題: (題意請描述清楚) : : 本人最近在閱讀某本書,看到動態連結這邊看了老半天,查了一堆資料 : : 卻還是沒辦法完全參透他的意思 : 先猜那本書就是「程式設計師的自我修養」XD : : 在介紹動態連結的時候 : : 他一開始提出的方案為 load time relocation,也就是把重定推遲到載入時才執行 : : 後來書上說 : : 這樣會讓多個行程無法共用該 DSO,沒有達到節省記憶體空間的好處 : : 因此後來出現了 PIC 的概念 : : 這樣可以讓 .text 載入的時候不用重定,而 .data 又可以在不同行程有副本 : : 這幾句話我看了老半天看不懂 : : 1. 為什麼 load time relocation 會造成 DSO 無法被共用? : 假設有一段 code 是這樣: : int x; // global variable : void inc() : { : ++x; : } : compile 的時候,因為 x 的位址無法確定 : 所以 inc 的指令會像這樣 : .code : inc: : mov XXXX, %eax : inc %eax : mov %eax, XXXX : 其中 XXXX 代表變數 x 的位址,這個位址要交給 linker 決定後再填入 : 假設有兩支程式 A 和 B 都會用到 inc() : 那麼在執行 A 的時候 : ld.so 會進行一次 relocation : 並且把 XXXX 代換成 x 真正在記憶體中的位址 : 所以 inc 這段函式載入到記憶體後可能長這樣: : .code : inc: : mov 0x0004, %eax (這邊的意思是把 0x0004 這個位址的內容放進 %eax) : inc %eax (很久沒寫組語了,語法小錯誤請多見諒) : mov %eax, 0x0004 : OK,現在 A 還沒跑玩,使用者又執行了 B 程式 : ld.so 又進行第二次 relocation : 不幸的是 B 這支程式包含了許多其它模組,因此 ld.so 把 x 分配到 0x2000 這個位址 : 這麼一來 inc() 會變這樣: : .code : inc: : mov 0x2000, %eax : inc %eax : mov %eax, 0x2000 : 也就是說,如果不使用 Position independent code : 那麼 inc 這個函式編譯出來的碼 : 與不同的程式連結時,其指令的內容也會跟著不同 : 這麼一來 inc 這個函式勢必在記憶體中要有兩份副本 : 一份是給 A 用的 (x位址為 0x0004的版本) : 另一份是給 B 用的 (x位址為 0x2000的版本) : : 2. .data 裡面的 GOT,書上說在載入的時候 ld.so 會更新裡面欄位的值, : : 這跟多行程能否共用該 DSO,在不同行程有副本又有什麼關係? : GOT 的目的是為了讓這個 DSO 可以存取另一個 DSO 中的 data : 考慮一下上面的例子 : 如果 x 是定義於另一個 DSO 中的資料 : 同時我們又希望「存取 x 的指令本身是 position independent」 : 那方法就是繞一圈:先取得 GOT 的位址 (GOT 對於 DSO 來說算是定義於模組內的資料) : 然後再從 GOT 的內容 (由ld.so填入) 去取得 x 的位址 這部分也因為上面沒參透,不懂為什麼 x 的位址需要動態來取得 等第一題我先解決了再來研究 : : 短短幾頁就讓我無法頓悟,希望對這方面有心得的前輩可以多多幫忙一下 : : 謝謝大家 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.250.174.228

10/10 19:18, , 1F
等討論一段落,我把本串收進精華區好了,版上資料好少
10/10 19:18, 1F

10/10 22:43, , 2F
因為不考慮超過一個以上的process同時共用的情況的話,
10/10 22:43, 2F

10/10 22:44, , 3F
不用offset,直接取address會比較快,所以非PIC的情況下,
10/10 22:44, 3F

10/10 22:45, , 4F
那段code會被編成直接取address的code,然後loader在init的
10/10 22:45, 4F

10/10 22:45, , 5F
根據分配的記憶體位址填入。
10/10 22:45, 5F
文章代碼(AID): #1CiQ1hYq (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
以下文章回應了本文 (最舊先):
完整討論串 (本文為第 5 之 7 篇):
文章代碼(AID): #1CiQ1hYq (C_and_CPP)