gpt4 book ai didi

c - ARM + gcc : don't use one big . rodata 部分

转载 作者:行者123 更新时间:2023-12-04 02:43:05 24 4
gpt4 key购买 nike

我想用 gcc 为 ARM 处理器编译一个链接时间优化的程序。当我在没有 LTO 的情况下编译时,系统会编译。当我启用 LTO(使用 -flto),我得到以下汇编程序错误:

Error: invalid literal constant: pool needs to be closer

在网上查了一下,发现这和我系统中的常量有关系,这些常量放在一个叫做.rodata的特殊部分,这个部分叫做常量池,放在.text部分的后面我的系统。似乎在使用 LTO 进行编译时,由于内联和其他优化,此 .rodata 部分与指令相距太远,因此不再可能对常量进行寻址。是否可以将常量放在使用它们的函数之后?或者是否可以使用另一种寻址模式,以便 .rodata 部分仍然可以寻址?谢谢。

最佳答案

这是一条汇编器消息,而不是链接器消息,所以这发生在生成节之前。

汇编程序有一条伪指令用于将常量加载到寄存器中:

    ldr r0, =0x12345678

这扩展为

    ldr r0, [constant_12345678, r15]
...
bx lr
constant_12345678:
dw 0x12345678

常量池通常跟在return指令之后。使用函数内联,函数可以变得足够长以至于返回指令太远;不幸的是,编译器不知道内存地址之间的距离,汇编器不知道控制流,除了“流不会超出返回指令之外,所以在这里发出常量池是安全的”。

很遗憾,目前没有好的解决方案。

你可以尝试一个包含

asm block
    b 1f
.ltorg
1:

这将在此时以额外的分支指令为代价强制发出常量池。

如果常量池为空,可以指示汇编器省略分支,但我目前无法测试,所以这可能是无效的:

    .if (2f - 1f)
.b 2f
.endif
1:
.ltorg
2:

关于c - ARM + gcc : don't use one big . rodata 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23014449/

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