Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fla处理后报错“Terminator found in the middle of a basic block!”,基本块中含有多个terminator #39

Open
c10udlnk opened this issue Dec 17, 2024 · 0 comments

Comments

@c10udlnk
Copy link

c10udlnk commented Dec 17, 2024

在实际使用fla模式发现会报错:
image

测试代码:

#include <stdio.h>
#include <stdint.h>

int main() {
    uint32_t v[2] = {0x12345678, 0x12345678};
    uint32_t k[4] = {0x90ABCDEF, 0x90ABCDEF, 0x90ABCDEF, 0x90ABCDEF};
    uint32_t sum = 0, delta = 0x9e3779b9;
    for (int i = 0; i < 32; i++) {
        sum += delta;
        v[0] += ((v[1]<<4) + k[0]) ^ (v[1] + sum) ^ ((v[1]>>5) + k[1]);
        v[1] += ((v[0]<<4) + k[2]) ^ (v[0] + sum) ^ ((v[0]>>5) + k[3]);
    }
    printf("%u %u", v[0], v[1]);
    return 0;
}

fla处理后的IR:
image

可见确实有两个terminator,这违反了LLVM验证时的“每个基本块末尾必须只有一个合法的终结符指令”要求。

查看Flattening.cpp发现:只有在第一个基本块(entryBB)的末尾是条件跳转时,才会删除entryBB的terminator(后面的基本块判断BB->getTerminator()->getNumSuccessors() == 1时也是这个代码,重复处理?)。但按照平坦化的原理来说块后面增加到returnBB的跳转之前也要把原来的跳转删掉?即:

// 原65行
    if (bEntryBB_isConditional) {
        entryBB.getTerminator()->eraseFromParent();
    }
// 改为
    entryBB.getTerminator()->eraseFromParent();
// 原97行
            if (bEntryBB_isConditional) {
                entryBB.getTerminator()->eraseFromParent();
            }
// 改为
            BB->getTerminator()->eraseFromParent();

修改后再编译,测试程序就能被平坦化处理且能正常运行了。

然后查看commits发现这是在 2f70402 里面刚刚改的,为什么这个commit里删除terminator前要做一个bEntryBB_isConditional的判断呢……?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant