簡體   English   中英

LLVM從結構值中提取i8 *

[英]LLVM extract i8* out of structure value

我正在編寫一個使用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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM