Re: [問題] 關於 Position Independent Code 的概念
※ 引述《nowar100 (拋磚引玉)》之銘言:
: 其實我對於您提出的例子,沒辦法理解,以下是我的謬論(?)
: 假設 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 有差別吧
: 感覺還是似懂非懂,麻煩前輩們請多再指教
但是DSO並不知道自己會被載入到哪個位址
所以位址固定,其實對DSO來說應該是 "在我自己的範圍裡,位址固定"
假設DSO的起點 = base
那這個image大概會長這樣
base:
.data:
// TYPE NAME
int32 x
...
...
.text:
inc:
load [x] -> %r0
add %r0, %r0, 1
store [x] <- %r0
ret
指令請自行想像XD
然後 load x -> %r0 要怎麼知道x的位址呢?
因為編譯時不知道base是多少,
如果不選擇編譯成PIC的話,直接hard-coded進去是最省的
這樣子就違反.text跟位址無關的原則了
編譯成PIC的話,實際上可能得這樣做
_tmp:
move %base -> %r0 // 找出我的base
add %r0, offset(x) -> %r0
load %r0 -> %r0 // 從%r0裡的address讀出值
這部分在各種平台可能有很不同的做法,並非每個平台都有這個%base可用
所以很多平台是用當前的PC來算
畢竟inc()跟x的距離是固定的,加上一個常數就可以找到x
像ARM在data access方面也支援PC-relative addressing mode
他就不需要特地取PC也能直接讀到x的值
x86的話就需要迂迴一點去取PC了
call _this
_this:
pop %eax
這樣就可以把PC騙到%eax裡
(gcc是call進一個小function,然後mov [%esp] -> %ebx)
接著就是 addr(x) = _this - (offset(_this) - offset(x))
以上是static int x的處理方式
跟int x是不一樣的,不過先不要管這麼多好了XD
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.42.87.44
→
10/11 00:50, , 1F
10/11 00:50, 1F
推
10/11 00:53, , 2F
10/11 00:53, 2F
→
10/11 00:53, , 3F
10/11 00:53, 3F
推
10/11 01:35, , 4F
10/11 01:35, 4F
→
10/11 01:36, , 5F
10/11 01:36, 5F
→
10/11 01:37, , 6F
10/11 01:37, 6F
→
10/11 01:39, , 7F
10/11 01:39, 7F
→
10/11 01:39, , 8F
10/11 01:39, 8F
→
10/11 01:41, , 9F
10/11 01:41, 9F
→
10/11 01:48, , 10F
10/11 01:48, 10F
→
10/11 01:48, , 11F
10/11 01:48, 11F
→
10/11 01:50, , 12F
10/11 01:50, 12F
→
10/11 01:51, , 13F
10/11 01:51, 13F
→
10/11 01:53, , 14F
10/11 01:53, 14F
→
10/11 01:54, , 15F
10/11 01:54, 15F
推
10/11 04:19, , 16F
10/11 04:19, 16F
推
10/11 04:24, , 17F
10/11 04:24, 17F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 7 之 7 篇):