[LLVMdev] Patching jump tables at run-time

Riyaz Puthiyapurayil
Tue, 06 Aug 2013 21:07:55 -0000

I am looking for guidance on how to:

1. At compile time: ensure that a jump table is generated for a *specific*
switch instruction
2. At runtime: get hold of the jump table entries for a specific pair of values
and swap them.

Let's say I have:

     switch i32 %2, label %7 [
       i32 0, label %3
       i32 1, label %4
       i32 2, label %5
       i32 3, label %6
     ]
       :
       :
for which the following assembly code gets generated:
    jmpq    *.LJTI0_0(,%rdi,8)
       :
   .LJTI0_0:
    .quad   .LBB0_2
    .quad   .LBB0_3
    .quad   .LBB0_4
    .quad   .LBB0_5

Based on some run-time conditions, I may want to change the behavior of the
switch instruction by swapping the jump table entries for 0 and 2 at runtime. My
jump table should then become:

   .LJTI0_0:
    .quad   .LBB0_4
    .quad   .LBB0_3
    .quad   .LBB0_2
    .quad   .LBB0_5

As this is a very simple transformation, I don't want to incur the overhead
of recompiling the entire function at run-time.

My target architectures are x86 and x86_64. I understand that the above
transformation may not be safe in general, but I know that for the specific
switch instructions that I am targeting, it is safe. I am not very familiar with
the LLVM code generator and so any advice on how to do this will be appreciated.
I don't want to touch the code generator but if there is a way to tag the
switch instruction and somehow get the jump table corresponding to that switch
at run-time, that's all I need. If I can use intrinsics to achieve this,
that would be great. Also is there a way to guarantee the generation of jump
table for a switch instruction? My switch labels correspond to a continuous
range of values [0..N].

One approach is not to use the switch instruction to lower my switch statement
to LLVM. Instead, implement the jump table myself and use the indirectbr
instruction. Then I have full control over the jump table. Is this feasible? How
would I initialize my global array representing the jump table with the local
labels in a function?