链接器如何通过R_RISCV_PCREL_LO12I定位对应R_RISCV_PCREL_HI20的符号?
RISC-V链接器中R_RISCV_PCREL_LO12I对应HI20重定位的查找实现
首先看问题中的指令与重定位示例:
1: auipc x10,%pcrel_hi(some_symbol) R_RISCV_PCREL_HI20 some_symbol lw x11,%pcrel_lo(1b)(x10) R_RISCV_PCREL_LO12I 1b // symbol refers to the auipc instruction above.
处理R_RISCV_PCREL_LO12I重定位时,虽然能通过符号1b定位到auipc指令的位置,但ELF规范仅提供重定位到符号的单向映射,无法直接获取该auipc关联的some_symbol,必须找到对应的R_RISCV_PCREL_HI20重定位项,常见实现方式有两种:
方式一:建立反向索引表
- 遍历目标文件的所有重定位项时,筛选出
R_RISCV_PCREL_HI20类型的条目,以其关联的符号(包括本地标签如1b)为键,将重定位项本身作为值存入哈希表或字典结构。 - 当处理
R_RISCV_PCREL_LO12I时,直接用其关联的符号(如1b)查询该索引表,即可快速获取对应的HI20重定位项,进而提取出目标符号some_symbol。
这种方法查找效率高,适合处理大型目标文件,是工业级链接器的常用方案。
方式二:基于指令地址的直接匹配
- 首先通过
LO12I重定位关联的符号1b,解析得到auipc指令的绝对地址或偏移地址。 - 遍历所有
R_RISCV_PCREL_HI20重定位项,对比每个项记录的指令地址与auipc的地址,匹配成功的项即为对应的HI20重定位,从中提取目标符号。
这种方法无需额外构建索引结构,实现逻辑简单,适合小型链接器的快速开发,但在重定位项较多时,遍历开销会相对较大。
内容的提问来源于stack exchange,提问作者John Källén
相关产品推荐
相关产品推荐

