我使用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
答案 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, "");