2016-12-26 26 views
3

此使用.reloc節是我面臨AArch64問題的一個簡化版本:從裝配

我有這個宏,保持一些數據傾倒的部分。

 
#define GEN_DATA(_type) \ 
    .pushsection .mydata_##_type, "aw"; \ 
    .ifndef start; \ 
    start:; \ 
    .endif; \ 
    .word 1; \ 
    .reloc end_loc, R_AARCH64_ABS64, .; \ 
    .popsection 

我最終想捕捉相似類型的起點和終點在這樣的結構:

 
    .pushsection .head, "aw" 
    .quad start 
    end_loc: 
    .quad 0 
    .popsection 

我可以跟蹤。其中,部分與start符號開始。我不知道在構建中會有多少個GEN_DATA()的調用,所以我無法定義end。我也不知道有多少款_type也會用,所以不能放置警戒符號腳本。因此,我決定離開end_loc的重定位條目,以便鏈接器最終修復整個部分結束的位置。是的,同一個end_loc會有多個重定位條目,但由於它們是絕對重定位,我認爲它們不會發生衝突。

我有預感,但在最後的二進制文件中,end_loc正在修復一個錯誤的地址。我會把它歸咎於多個重定位條目,但奇怪的是,如果我還添加了一個虛擬的額外重定位條目 - 也就是一切都好 - 即。我修改上面的結構:

 
#define GEN_DATA(_type) \ 
    .pushsection .mydata_##_type, "aw"; \ 
    .ifndef start; \ 
    start:; \ 
    .endif; \ 
    .word 1; \ 
    .reloc end_loc, R_AARCH64_ABS64, .; \ 
    .reloc dummy_loc, R_AARCH64_ABS64, .; \ 
    .popsection 

和:

 
    .pushsection .head, "aw" 
    .quad start 
    end_loc: 
    .quad 0 
    dummy_loc: 
    .quad 0 
    .popsection 

所以我想知道:

  • 爲什麼end_loc搞定了錯誤?多重絕對重新定位條目有什麼問題?鏈接器是否有望按順序通過它們,而最後一個才能生效?

  • 爲什麼簡單地添加一個虛擬重定位使一切正常?

基本上,發生了什麼?!

最後,有沒有其他方法可以嘗試?

編輯:我現在把示例代碼推到Git repository。使用makemake broken=1查看反彙編。需要Linaro AArch64 tool chain$PATH

回答

0

我不知道重定位發生了什麼,但最簡單的方法就是使用鏈接器腳本。這將讓您將所有.mydata_XXX_type部分組合在一起,併爲分組部分的開始和結束提供符號。事情是這樣的:

SECTIONS 
{ 
    .mydata : 
    { 
     start = .; 
     *(.mydata*); 
     end_loc = .; 
    } 
} 

,你會用這樣的彙編文件使用:代替C宏

.macro gen_data, type 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

(我使用匯編器宏,因爲他們更容易的工作。)你會使用上面的兩個文件是這樣的:

as -o test.o test.s 
    ld -o test test.o test.ld 

如果你知道所有可能的部分「類型」那你就去做,而不使用鏈接腳本所依託的事實,鏈接器將在未知的部分命令它首先遇到它們。例如:

.section .mydata_start, "aw" 
start: 
    .section .mydata_foo_type, "aw" 
    .section .mydata_bar_type, "aw" 
    .section .mydata_baz_type, "aw" 
    .section .mydata_end, "aw" 
end_loc: 

    .macro gen_data, type 
    .ifndef .mydata_\()\type\()_type 
    .error "gen_data invoked with unknown type '\type\()'" 
    .endif 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 
    # gen_data unk 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

如果你有使用宏多個彙編文件,確保所有的彙編文件包括在開始所以不要緊,他們出現在鏈接器命令行上順序上面顯示的.section指令。

請注意,這兩種解決方案都可以解決您的宏問題,如果它們碰巧出現在鏈接器中,那麼其他未知部分可以放置在您的.mydata_XXX_type部分之間。