RISCV 因为两个函数不在 2G 范围内,所以报错 relocation trancated to fit?

102 天前
 amiwrong123

https://blog.csdn.net/qq_24402247/article/details/140617233

报错原理应该是和 这篇博客一样,因为两个函数最多只能+-2GB 空间。 我这两个函数,都是在 32 位空间内(也就是整个 4G 空间),但这两个函数的距离超过了 2G 的距离(因为我 ld 脚本的写法)。

一些必要信息:

一些猜想:我看了我编译出来的反汇编,大部分函数调用是 jal ,有很少的 jalr 。我理解 jalr ,就可以随便跳转了吧,为啥编译器不帮我 编译成使用 jalr 的汇编呢。

PS:问了大模型,搜了谷歌,还是没有帮助。

1228 次点击
所在节点    程序员
10 条回复
julyclyde
102 天前
你用 64bit 模式试试?
xixijay1988
101 天前
用 JALR 的话也只能在+-2G 的地址空间内;最高比特决定了向前还是向后,剩余的也只有 31bit 的位置信息; JALR 里面的 12 位相对位置 offset 的立即数不是 2 的倍数,否则的话还有戏
xixijay1988
101 天前
RV64 上感觉是编译器故意做的限制,内核设计上应该是参照的规范来的,否则编出来的话在其他内核上跑不了;
heiher
101 天前
不是还有-mcmodel=large 嘛
amiwrong123
101 天前
@heiher #4
我是查看的 RISCV 的 Machine-Dependent Options 里面,我看里面只有-mcmodel=medlow 和-mcmodel=medany 啊?
heiher
101 天前
amiwrong123
97 天前
@xixijay1988 #2
@xixijay1988 #3
好吧,那这 JALR 也不行的话。那我应该怎么解决这个问题了啊😂
amiwrong123
84 天前
@heiher #4
我尝试了一下,我这个 gcc 居然不支持 large 呢。哈哈,只有自己实现一个 中转函数了
heiher
84 天前
@amiwrong123 那应该是 GCC 版本太老了吧。那也可以用 JALR 间接跳转了,不用再经过一个中间函数中转呀,JALR 是完整地址空间任意位置都能覆盖到。
amiwrong123
83 天前
@heiher #9 #9
void jumpAgent(void (*target_func)()) {
asm volatile(
"jalr x1, 0(%0)\n\t"
:
: "r"((uint64_t)target_func)
);
}

写了一个这个函数,但是我调用的时候,是这样 jumpAgent(myWantFunc);在调用 jumpAgent 的地方又会报错,因为传参是传给 x10 (它是第一个参数),传参的汇编是 auipc+addi 来把 myWantFunc 加载进 x10 ,然后这里就会报错 trancated to fit

这好像有点无解了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1117197

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX