【问题标题】:Linking fails with "relocation truncated to fit" with aggressive inlining链接失败,“重定位被截断以适应”激进的内联
【发布时间】:2017-05-01 10:06:21
【问题描述】:

为了解决a Rust compiler bug in the AVR backend,我将很多函数标记为#[inline(always)],只需添加注释,直到足够的案例优化等会触发我不再遇到问题。

但是,使用这些注释,链接现在会失败,并带有大量 relocation truncated to fit 消息:

target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_18':
chip8_avr.cgu-0.rs:(.text.main+0x432): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_23':
chip8_avr.cgu-0.rs:(.text.main+0x45c): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_31':
chip8_avr.cgu-0.rs:(.text.main+0x4ae): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_34':
chip8_avr.cgu-0.rs:(.text.main+0x4d2): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_146':
chip8_avr.cgu-0.rs:(.text.main+0x58a): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
chip8_avr.cgu-0.rs:(.text.main+0x58e): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
chip8_avr.cgu-0.rs:(.text.main+0x592): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
target/avr-atmega328p/release/deps/chip8_avr-41c427b8d446a439.o: In function `LBB5_153':
chip8_avr.cgu-0.rs:(.text.main+0x59a): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
chip8_avr.cgu-0.rs:(.text.main+0x59e): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
chip8_avr.cgu-0.rs:(.text.main+0x5a6): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
chip8_avr.cgu-0.rs:(.text.main+0x5aa): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status

This SO answer 暗示大的函数内跳转是编译器需要准备的。 Rust 的等效设置是什么?

【问题讨论】:

    标签: linker rust llvm avr relocation


    【解决方案1】:

    在足够详细地查看反汇编之后,事实证明这些重定位目标都在分支指令的偏移量中,而不是(短)跳转;例如在 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 分支当前生成这些带有空 (.+0) 偏移量的分支,然后尝试使用链接器来填充它们。对于足够大的函数,这些函数内偏移量可能会变得大于适合的值成一条分支指令。

    我在 Rust 的 AVR 分支中有 reported this as a compiler bug。一个潜在的解决方案是让链接器在偏移不适合的情况下生成一个两步分支(一个跳转的分支);另一个是根本不使用链接器:由于所讨论的分支是函数内的,因此在编译时应该知道相对地址,以便在需要时生成两步分支。

    【讨论】:

      猜你喜欢
      • 2012-01-01
      • 2013-12-25
      • 1970-01-01
      • 2016-05-01
      • 2016-04-03
      • 1970-01-01
      • 2018-04-06
      • 2020-05-23
      • 2015-10-20
      相关资源
      最近更新 更多