draperlaboratory / VIBES

Verified, Incremental, Binary Editing with Synthesis
MIT License
51 stars 1 forks source link

Out of range conditional branches #195

Closed bmourad01 closed 2 years ago

bmourad01 commented 2 years ago

The following patch code:

if (x == 0) {
  goto L_0x1234;
}

may be lowered to the following BIR:

00000001:
00000002: when x = 0 goto 0x1234

and then the following ARM assembly:

blk00000001:
cmp x, #0
beq <something>

However, depending on where this patch is actually situated in the binary, the address 0x1234 may be out of range, and the assembler will reject the program.

This can sometimes be fixed by lowering instead to:

00000001:
00000002: when x = 0 goto %00000004
00000003: goto %00000006

00000004:
00000005: goto 0x1234

00000006:

which may have the following assembly:

blk00000001:
cmp x, #0
beq blk00000004
b blk00000006
blk00000004:
b <something>
blk00000006:

Since unconditional branches in ARM have a wider range of addresses, the assembler may accept this code.

The ARM manual speaks about "veneers" which are inserted by the linker for branch targets that are out of range: https://www.keil.com/support/man/docs/armlink/armlink_pge1406301797482.htm

We should investigate whether this is an option for us, or whether we need to look into other solutions.

ivg commented 2 years ago

It is applicable to many architectures and the common approach is to delay the choice of the branch kind and perform branch relaxation at the later stages. See this article as an example.

bmourad01 commented 2 years ago

This is (kind of) fixed in #210.