使用 llvm pass 插入跳转指令

Insert a jump instruction by using llvm pass

我想通过LLVM的pass在目标程序中插入一条跳转指令。我知道在LLVM中可以使用branchinst来实现基本块的跳转。但是我想要实现的是在同一个基本块中的指令跳转(假设我知道跳转的目的地址)。我怎么做?简单吗?能举个例子吗?

例如,在 C 中我可以实现这个:

// before insert jmp
#include <stdio.h>
int main()
{
    int a = 0;
    int b = 2;
    if(a<b)
    {
        printf("hh\n");
        printf("jump hh\n");
    }
    return 0;
}

result:  hh
         jump hh

// after insert jmp
#include <stdio.h>
int main()
{
    int a = 0;
    int b = 2;
    if(a<b)
    {
        asm("jmp main+0x30;");
        printf("hh\n");
        printf("jump hh\n");
    }
    return 0;
}

result:  jump hh

cmp    -0x4(%rbp),%eax
jge    1185 <main+0x3c>
jmp    1179 <main+0x30>
lea    0xe90(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
callq  1050 <puts@plt>
lea    0xe87(%rip),%rdi        # 2007 <_IO_stdin_used+0x7>
callq  1050 <puts@plt>

这是维基百科对基本块的定义:

In compiler construction, a basic block is a straight-line code sequence with no branches in except to the entry and no branches out except at the exit. This restricted form makes a basic block highly amenable to analysis. Compilers usually decompose programs into their basic blocks as a first step in the analysis process.

对于基本块,如果到达块中的第 n 条指令,则必须到达块中的第 (n-1) 条指令,直到第一条指令。因此,根据定义,基本块中间的指令没有分支。

@arnt 的建议是正确的:在 LLVM 中构建它的方法是拆分基本块。为此有一个 API,请参阅 BasicBlock 上“splitBasicBlock”的各种风格:https://llvm.org/doxygen/classllvm_1_1BasicBlock.html