2016-12-26 23 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部分之间。