Compiler-assisted-fuzzing / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
0 stars 0 forks source link

Eliminate relaxation of relocations #5

Open ArsenyBochkarev opened 1 day ago

ArsenyBochkarev commented 1 day ago

Break the relaxation of relocations provided in LLVM. High-level steps are:

Additionally take a look at these links:

ArsenyBochkarev commented 1 day ago

Turned out "relaxation" is not only an optimization. There are cases when we must do a relaxation to compile the program. For example, from LLVM's llvm/test/MC/RISCV/long-jump-disable-relax.s test:

  .text
# Branches to defined out-of-range symbols should report an error
# ONLY when we compile without relaxation!
test_defined_out_of_range:
  bne a0, a1, 1f # error: fixup value out of range
  .skip (1 << 12)
1:
  c.beqz a0, 1f # error: fixup value out of range
  .skip (1 << 8)
1:
  c.j 1f # error: fixup value out of range
  .skip (1 << 11)
1:

but if a relaxation happens, the RISCV::BNE instruction in RISCVAsmBackend::getRelaxedOpcode transforms into RISCV::PseudoLongBNE, which is then translated into inverted conditional branch and an unconditional jump. So I cannot simply passthrough the -riscv-asm-relax-branches=0 option to backend. However, we still can unfold all branches into such a sequence. I did a hack in RISCVAsmBackend::fixupNeedsRelaxationAdvanced, always returning true for RISCV::fixup_riscv_branch case. Here is the example (based on LLVM's llvm/test/MC/RISCV/long-jump-disable-relax.s test):

Test case:

test_defined_out_of_range:
  bne a0, a1, 1f
  .skip (1 << 12)
1:
  c.beqz a0, 1f
  .skip (1 << 8)
1:
  c.j 1f
  .skip (1 << 11)
1:

without fuzzing:

./relaxation_test_output.out:   file format elf64-littleriscv

Disassembly of section .text:

0000000000000000 <test_defined_out_of_range>:
       0: 63 04 b5 00   beq     a0, a1, 0x8 <test_defined_out_of_range+0x8>
       4: 6f 10 40 00   jal     zero, 0x1008 <test_defined_out_of_range+0x1008>
                ...
    1008: 63 02 05 10   beq     a0, zero, 0x110c <test_defined_out_of_range+0x110c>
                ...
    110c: 6f 00 50 00   jal     zero, 0x1910 <test_defined_out_of_range+0x1910>
                ...

with fuzzing:

./relaxation_test_output.out:   file format elf64-littleriscv

Disassembly of section .text:

0000000000000000 <test_defined_out_of_range>:
       0: 63 04 b5 00   beq     a0, a1, 0x8 <test_defined_out_of_range+0x8>
       4: 6f 10 40 00   jal     zero, 0x1008 <test_defined_out_of_range+0x1008>
                ...
    1008: 19 e1         c.bnez  a0, 0x100e <test_defined_out_of_range+0x100e>
    100a: 6f 00 40 10   jal     zero, 0x110e <test_defined_out_of_range+0x110e>
                ...
    110e: 6f 00 50 00   jal     zero, 0x1912 <test_defined_out_of_range+0x1912>
                ...