https://blog.csdn.net/qq_24402247/article/details/140617233
报错原理应该是和 这篇博客一样,因为两个函数最多只能+-2GB 空间。 我这两个函数,都是在 32 位空间内(也就是整个 4G 空间),但这两个函数的距离超过了 2G 的距离(因为我 ld 脚本的写法)。
一些必要信息:
一些猜想:我看了我编译出来的反汇编,大部分函数调用是 jal ,有很少的 jalr 。我理解 jalr ,就可以随便跳转了吧,为啥编译器不帮我 编译成使用 jalr 的汇编呢。
PS:问了大模型,搜了谷歌,还是没有帮助。
1
julyclyde 22 天前
你用 64bit 模式试试?
|
2
xixijay1988 22 天前
用 JALR 的话也只能在+-2G 的地址空间内;最高比特决定了向前还是向后,剩余的也只有 31bit 的位置信息; JALR 里面的 12 位相对位置 offset 的立即数不是 2 的倍数,否则的话还有戏
|
3
xixijay1988 22 天前
RV64 上感觉是编译器故意做的限制,内核设计上应该是参照的规范来的,否则编出来的话在其他内核上跑不了;
|
![]() |
4
heiher 21 天前
不是还有-mcmodel=large 嘛
|
![]() |
5
amiwrong123 OP @heiher #4
我是查看的 RISCV 的 Machine-Dependent Options 里面,我看里面只有-mcmodel=medlow 和-mcmodel=medany 啊? |
![]() |
6
heiher 21 天前
|
![]() |
7
amiwrong123 OP |
![]() |
8
amiwrong123 OP @heiher #4
我尝试了一下,我这个 gcc 居然不支持 large 呢。哈哈,只有自己实现一个 中转函数了 |
![]() |
9
heiher 4 天前
@amiwrong123 那应该是 GCC 版本太老了吧。那也可以用 JALR 间接跳转了,不用再经过一个中间函数中转呀,JALR 是完整地址空间任意位置都能覆盖到。
|
![]() |
10
amiwrong123 OP @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 这好像有点无解了 |