gpt4 book ai didi

assembly - 使用汇编中的 .reloc

转载 作者:行者123 更新时间:2023-12-02 19:52:52 26 4
gpt4 key购买 nike

这是我在 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 。使用 makemakebroken=1 查看反汇编结果。需求Linaro AArch64 tool chain$PATH中。

最佳答案

我不知道重定位发生了什么,但完成您想要完成的任务的最简单方法是使用链接器脚本。这将允许您将所有 .mydata_XXX_type 部分分组在一起,并为分组部分的开始和结束提供符号。像这样的事情:

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

(我使用汇编器宏而不是 C 宏,因为它们更容易使用。)您可以像这样使用上面的两个文件:

    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 部分之间放置其他未知部分.

关于assembly - 使用汇编中的 .reloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41331206/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com