Assembly 从程序集使用.reloc

Assembly 从程序集使用.reloc,assembly,ld,arm64,relocation,Assembly,Ld,Arm64,Relocation,这是我在AArch64上面临的问题的简化版本: 我有一个宏,它不断地将一些数据转储到一个节中 #define GEN_DATA(_type) \ .pushsection .mydata_##_type, "aw"; \ .ifndef start; \ start:; \ .endif; \ .word 1; \ .reloc end_loc, R_AARCH64_ABS64, .; \ .popsection 以及: .pushsect

这是我在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 0 虚拟位置: .quad 0 波普科长 所以我想知道:

  • 为什么
    end\u loc
    被错误地修复了?多个绝对重新定位条目有什么问题吗?难道链接器不需要按顺序进行检查,最后一个就生效了吗

  • 为什么仅仅添加一个虚拟的重新定位就可以让一切正常呢

基本上,发生了什么

最后,我可以尝试其他方法吗


编辑:我现在已经将示例代码推到了一个新的位置。使用
make
make break=1
查看反汇编。需要在
$PATH

我不知道重新定位是怎么回事,但要完成您正在尝试完成的任务,最简单的方法是使用链接器脚本。这将允许您将所有
.mydata\u XXX\u type
节分组在一起,并为分组节的开始和结束提供符号。大概是这样的:

.pushsection .head, "aw" .quad start end_loc: .quad 0 .popsection
SECTIONS
{
    .mydata :
    {
        start   = .;
        *(.mydata*);
        end_loc = .;
    }
}
    .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
您可以将其与以下程序集文件一起使用:

.pushsection .head, "aw" .quad start end_loc: .quad 0 .popsection
SECTIONS
{
    .mydata :
    {
        start   = .;
        *(.mydata*);
        end_loc = .;
    }
}
    .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
(我使用汇编宏而不是C宏,因为它们更容易使用。)您可以像这样使用上面的两个文件:

.pushsection .head, "aw" .quad start end_loc: .quad 0 .popsection
SECTIONS
{
    .mydata :
    {
        start   = .;
        *(.mydata*);
        end_loc = .;
    }
}
    .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\u XXX\u type
部分之间