2015-08-20 26 views
1

由於某些原因,我想強制PLT部分輸入一些條目。我已經設法爲一些條目做到這一點,但是某些功能從未插入到PLT中。PLT部分中的強制條目

因此,可以說,我有main.c

int main(){ 
// some code 
strcmp(a,b); //suppose a, b strings 
// more code 
// suppose that result of strcmp is used, so it won't be optimised away 
} 

help.c

// declaration 
void forceplt() __attribute__((__used__)); 
// definition 
void forceplt(){ 
abs(-1); 
__aeabi_dadd(0, 0); 
} 

然後,我編譯和鏈接以上兩個重定位目標,爲可執行的對象。爲確保absdadd函數將保留在PLT部分中,我使用-O0編譯helper.omain.o可以編譯一個更高的級別,可以說'-O1'。

對於可執行對象,我期望看到所有3個函數的條目:strcmp,absdadd。然而,這種情況並非如此。

我在這裏錯過了什麼嗎? 鏈接器是否有可能遺漏某些內容,因爲它發現它們從未被調用?儘管使用O0作爲助手,並使用了forceplt函數的屬性?

幫我做一個適當的慶祝..十。百萬。問題!

乾杯!

回答

2

absstrcmp被GCC特別認可,編譯器似乎發現這些調用即使在-O0中也是無用的。如果您查看生成程序集(gcc foo.c -S -o-),您會看到沒有相應的調用指令。

PLT條目不是由編譯器生成的:它們不存在於.o文件中。它們是由鏈接編輯器在其輸入.o文件之一中找到相應的重定位時生成的。爲了生成PLT條目,您需要在您的輸入.o文件之一中生成合適的重定位條目。一個.o重定位總是適用於.o文件的一部分:您需要在某些.o的某個部分中有一些內存字節,您將使用支持PLT的重定位進行重定位。它可以通過(可能無用的)指令或其他(可能無用的)字節。

解決方案是創建(彙編)明確使用預期PLT條目的指令。隨着x86_64的這個功能也可以用:

.text 
    .type forceplt2,@function 
forceplt2: 
    callq [email protected] 

我想這是這樣寫的ARM:

.text 
    .type forceplt2,%function 
forceplt2: 
    bl [email protected] 

或者你可以(再次在x86_64)爲您的搬遷原始字節:

.data 
    .align 8 
    .type forceplt3, @object 
    .size forceplt3, 8 
forceplt3: 
    .quad [email protected] 

On x_86_64,您應該可以使用@GOT,@GOTPLT,@GOTOFF,@GOTPCREL,@PLT@PLTOFF。我不太確定這是怎麼寫的for ARM

任何這些解決方案都會發出合適的重定位條目,這將導致鏈接編輯器發出PLT條目和PLT GOT條目。