Я пытаюсь создать функцию LLVM, которая читает поле из структуры, которую я передаю, я погуглил кое-что о инструкции getelementptr, и я думаю, что это то, что мне нужно здесь, но как именно это используется вC API.Структура определена в C, но я пытаюсь получить доступ к ее полям через LLVM, так как они находятся в одной и той же среде выполнения, я думаю, это будет работать?(Поправьте меня, если я ошибаюсь)
Вот код на данный момент.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
typedef struct {
char* name;
int age;
} user;
int main() {
LLVMTypeRef type = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.user");
LLVMModuleRef module = LLVMModuleCreateWithName("test");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMTypeRef ret = LLVMFunctionType(LLVMPointerType(LLVMInt32Type(), 0),
(LLVMTypeRef[]){ LLVMPointerType(type, 0) }, 1, false);
LLVMValueRef fn = LLVMAddFunction(module, "stuff", ret);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(fn, "entry");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef gep = LLVMBuildGEP(builder, LLVMGetParam(fn, 0), (LLVMValueRef[]){ LLVMConstInt(LLVMInt32Type(), 0, false),
LLVMConstInt(LLVMInt32Type(), 1, false) }, 2, "gep");
LLVMBuildRet(builder, gep);
char *error = NULL;
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
LLVMExecutionEngineRef engine;
error = NULL;
LLVMLinkInMCJIT();
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
if(LLVMCreateExecutionEngineForModule(&engine, module, &error) != 0) {
fprintf(stderr, "failed to create execution engine\n");
abort();
}
if(error) {
fprintf(stderr, "error: %s\n", error);
LLVMDisposeMessage(error);
exit(EXIT_FAILURE);
}
user m;
m.name = "John";
m.age = 17;
int* (*stuff)(user*) = (int* (*)(user*)) LLVMGetFunctionAddress(engine, "stuff");
printf("%d\n", *stuff(&m));
LLVMDisposeBuilder(builder);
LLVMDisposeExecutionEngine(engine);
return 0;
}
В принципе, функция, которую я пытаюсь построить, равна примерно такой в C
int* stuff(user* u) {
return &u->age;
}
Так что же происходит, когда происходит сбой с ошибкой сегментации, я отлаживал его с помощью GDB, и кажется, что это происходит в строке, где я выполняю вызов BuildGEP со следующей ошибкой из общей библиотеки LLVM
Program received signal SIGSEGV, Segmentation fault.
0xb533baec in llvm::PointerType::get(llvm::Type*, unsigned int) ()
Теперь я понятия не имею, что я делаю.
Основные 2 вопроса, на которые мне нужно ответить: Как вы используете LLVMBuildGEP из C API?Я думаю, что это совершенно неправильно?