gpt4 book ai didi

c++ - LLVM 从结构值中提取 i8*

转载 作者:太空狗 更新时间:2023-10-29 21:45:18 26 4
gpt4 key购买 nike

我正在编写一个使用 LLVM 作为后端的编译器,我已经编写了前端(解析器等),现在我来到了十字路口。

我有一个结构 (%Primitive),它包含一个字段、一个 i8* 值、一个指向字符数组的指针。

%Primitive = type { i8* }

在编译器中,Primitive 的实例在堆栈上传递。我正在尝试使用 puts 函数将此字符数组写入标准输出,但它并没有像我希望的那样工作。

declare i32 @puts(i8*) ; Declare the libc function 'puts'

define void @WritePrimitive(%Primitive) {
entry:
%1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive.
%2 = call i32 @puts(i8* %1) ; Write it
ret void
}

当我尝试运行代码时(使用 ExecutionEngine 或 LLVM 解释器程序 lli),我得到了同样的错误;段错误。

错误在于传递给puts 的地址不知何故是数组中第一个字符的ASCII 字符代码。传递的地址似乎不是指向 8 位字符数组的指针,而是等于取消引用的字符串的 8 位宽指针。

例如,如果我用原语调用@WritePrimitive,其中 i8* 成员指向字符串 "hello"puts 是调用时字符串地址为 0x68

有什么想法吗?

谢谢

编辑:你是对的,我错误地初始化了我的 Primitive,我的新初始化函数是:

llvm::Value* PrimitiveHelper::getConstantPrimitive(const std::string& str, llvm::BasicBlock* bb)
{
ConstantInt* int0 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0);
Constant* strConstant = ConstantDataArray::getString(getGlobalContext(), str, true);

GlobalVariable* global = new GlobalVariable(module,
strConstant->getType(),
true, // Constant
GlobalValue::ExternalLinkage,
strConstant,
"str");

Value* allocated = new AllocaInst(m_primitiveType, "allocated", bb);

LoadInst* onStack1 = new LoadInst(allocated, "onStack1", bb);

GetElementPtrInst* ptr = GetElementPtrInst::Create(global, std::vector<Value*>(2,int0), "", bb);

InsertValueInst* onStack2 = InsertValueInst::Create(onStack1, ptr, std::vector<unsigned>(1, 0), "", bb);

return onStack2;
}

我错过了,谢谢!

最佳答案

您上面粘贴的代码没有任何问题;我自己试了一下,效果很好。我猜问题是您没有正确初始化指针,或者没有将其正确设置到结构中。

我使用的完整代码是:

@str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"

; Your code
%Primitive = type { i8* }

declare i32 @puts(i8*) ; Declare the libc function 'puts'

define void @WritePrimitive(%Primitive) {
entry:
%1 = extractvalue %Primitive %0, 0 ; Extract the character array from the primitive.
%2 = call i32 @puts(i8* %1) ; Write it
ret void
}

; /Your code

define void @main() {
%allocated = alloca %Primitive
%onstack1 = load %Primitive* %allocated
%onstack2 = insertvalue %Primitive %onstack1, i8* getelementptr ([13 x i8]* @str, i64 0, i64 0), 0
call void @WritePrimitive(%Primitive %onstack2)
ret void
}

关于c++ - LLVM 从结构值中提取 i8*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17906533/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com