链接失败与“重定位截断以适应”积极内联

时间:2017-05-01 10:06:22

标签: linker rust llvm avr relocation

要解决a Rust compiler bug in the AVR backend,我已经将我的许多功能标记为manager,只需添加注释,直到足够的案例优化等会触发我不再遇到这个问题。

但是,通过这些注释,链接现在会失败并显示许多#[inline(always)]条消息:

relocation truncated to fit

This SO answer意味着大型的函数内跳转是编译器需要准备的东西。 Rust的等效设置是什么?

1 个答案:

答案 0 :(得分:0)

在仔细查看反汇编之后,事实证明这些重定位目标都是分支指令的偏移,而不是(短)跳转;例如在0x08:

00000000 <_ZN12chip8_engine7opcodes6decode17haab3c6c935229a6aE>:
   0:   e8 2f           mov     r30, r24
   2:   f9 2f           mov     r31, r25
   4:   80 e0           ldi     r24, 0x00       ; 0
   6:   61 30           cpi     r22, 0x01       ; 1
   8:   01 f4           brne    .+0             ; 0xa <_ZN12chip8_engine7opcodes6decode17haab3c6c935229a6aE+0xa>
   a:   81 83           std     Z+1, r24        ; 0x01
   c:   82 83           std     Z+2, r24        ; 0x02
   e:   81 e0           ldi     r24, 0x01       ; 1

00000010 <LBB0_2>:
  10:   80 83           st      Z, r24
  12:   08 95           ret

Rust编译器的AVR fork当前生成具有空(.+0)偏移量的这些分支,然后尝试使用链接器填充它们。对于足够大的函数,这些函数内偏移量可能会大于什么适合单个分支指令。

我在Rust的AVR分支中reported this as a compiler bug。提出的一个可能的解决方案是让链接器为偏移量不适合的情况生成两步分支(跳转分支);另一种是根本不使用链接器:因为有问题的分支是函数内部的,所以在编译时应该知道相对地址,允许在需要时生成两步分支。