今天更新昨天提到的LLVM patch。主要是根据要求添加了一些测试, 以及修复了一个小问题。
具体来说, 这一patch是为RISC-V添加CFI跳转表支持的, 跳转表要求每个表项大小确定且一致, 功能为跳转到目标函数处。为了满足这一要求和功能, 我最初采用了如下代码片段:
1: auipc t0, %pcrel_hi(xxx) jr %pcrel_lo(1b)(t0)
并且, 我关闭了C扩展和链接器relax, 这样就能够确保最终生成的指令一定是两条四字节的指令。
然而, 经过我充分测试, 上述代码片段在编译调用了外部函数的动态链接可执行文件时会出现链接错误, 链接器无法处理此处的重定位条目, 无法在此处填写外部函数的地址, 因为这个地址只有程序执行时才能从GOT获得, 或者程序可以直接调用PLT对应条目来调用这一函数。进而, 我尝试将xxx
改为xxx@plt
来指示链接器可以链接PLT对应函数的地址到此处, 但是似乎链接器并不支持这么写。
经过查阅复习RISC-V规范, 我意识到tail
伪指令就可以保证生成auipc
和jr
的组合, 同时支持xxx@plt
的写法。顺便一提, 若在静态链接时使用xxx@plt
, 链接器也会直接使用目标函数地址, 而不会生成额外的PLT。
发表评论