为什么带有解释器的LLVMRunFunction对于不同的函数返回相同的值?

时间:2019-01-12 22:52:44

标签: llvm

我使用LLVM C API构建了2个函数。每个都返回指向全局字符串的不同指针(“第一”和“第二”)。但是,当我使用LLVM解释器使用LLVMRunFunction运行它们时,它们都返回一个指向字符串“ first”的指针。

当我返回整数或函数指针时,不会发生此问题。 我尝试查看生成的llvm代码,它是正确的,每个函数返回一个不同的指针。

以下是一个可以重现该问题的示例(在LLVM 7.0.1上)

#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include <stdio.h>

int main() {
    auto module = LLVMModuleCreateWithName("test");
    LLVMExecutionEngineRef interpreter;
    LLVMCreateInterpreterForModule(&interpreter, module, nullptr);
    auto funType = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), nullptr, 0, 0);
    auto fun = LLVMAddFunction(module, "fun1", funType);
    auto builder = LLVMCreateBuilder();
    auto entry = LLVMAppendBasicBlock(fun, "entry");
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMBuildRet(builder, LLVMBuildGlobalStringPtr(builder, "first", ""));
    auto generic = LLVMRunFunction(interpreter, fun, 0, nullptr);
    printf("%s\n", (const char*)LLVMGenericValueToPointer(generic));
    fun = LLVMAddFunction(module, "fun2", funType);
    entry = LLVMAppendBasicBlock(fun, "entry");
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMBuildRet(builder, LLVMBuildGlobalStringPtr(builder, "second", ""));
    generic = LLVMRunFunction(interpreter, fun, 0, nullptr);
    printf("%s\n", (const char*)LLVMGenericValueToPointer(generic));
    return 0;
}

我希望输出

first
second

相反,它输出

first
first

1 个答案:

答案 0 :(得分:0)

仔细查看生成的LLVM之后,我注意到用LLVMBuildGlobalStringPtr构建的全局字符串具有unnamed_addr修饰符。当手动构建全局字符串而不是使用LLVMBuildGlobalStringPtr时,解释器实际上返回正确的字符串指针,并且输出变为预期的结果:

auto glbstr = LLVMAddGlobal(mBuilder.module_, llvmType, "glbstr");
LLVMSetInitializer(glbstr, LLVMConstString(toStringz(arg.value), cast(uint) arg.value.length, 0));
auto firstCharPtr = LLVMBuildGEP(builder, glbstr, [LLVMConstInt(LLVMInt8Type(), 0, 0), LLVMConstInt(LLVMInt8Type(), 0, 0)].ptr, 2, "");