我希望使用系统printf
能够从我正在为其编写编译器的编程语言中打印单个整数,如print(3)
中所示。执行编译的IR时,我遇到了段错误。
跟随this example,我的代码是
#include "llvm/ADT/APInt.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <vector>
using namespace llvm;
static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
int main() {
static std::unique_ptr<Module> TheModule;
TheModule = std::make_unique<Module>("inputFile", TheContext);
std::vector<Type *> Nats(1, Type::getInt32Ty(TheContext));
FunctionType *PNFT =
FunctionType::get(Type::getInt32Ty(TheContext), Nats, false);
Function *PNF = Function::Create(PNFT, Function::ExternalLinkage, "printf",
TheModule.get());
for (auto &Arg : PNF->args()) {
Arg.setName("x");
}
FunctionType *mainType = FunctionType::get(Builder.getInt32Ty(), false);
Function *main = Function::Create(mainType, Function::ExternalLinkage, "main",
TheModule.get());
BasicBlock *entry = BasicBlock::Create(TheContext, "entry", main);
Builder.SetInsertPoint(entry);
std::vector<Value *> printArgs;
printArgs.push_back(ConstantInt::get(TheContext, APInt(32, 20)));
Builder.CreateCall(TheModule->getFunction("printf"), printArgs);
Builder.CreateRet(ConstantInt::get(TheContext, APInt(32, 0)));
TheModule->print(llvm::outs(), nullptr);
}
我用clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` test.cpp
编译
这将输出LLVM IR
; ModuleID = 'inputFile'
source_filename = "inputFile"
declare i32 @printf(i32)
define i32 @main() {
entry:
%0 = call i32 @printf(i32 20)
ret i32 0
}
我将其放入文件test.ll
中并编译为clang test.ll
。我将段错误代码放入lldb
中,发现在strchr
中存在代码段错误:
(lldb) bt
* thread #1, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0x14)
* frame #0: 0x00007ffff7f300fc libc.so.6`__strchrnul_avx2 + 28
frame #1: 0x00007ffff7e38a53 libc.so.6`__vfprintf_internal + 163
frame #2: 0x00007ffff7e25a2f libc.so.6`_IO_printf + 175
frame #3: 0x000055555555514b a.out`main + 11
frame #4: 0x00007ffff7df5002 libc.so.6`__libc_start_main + 242
frame #5: 0x000055555555506e a.out`_start + 46
我认为问题不在于编译IR,因为在我的实际代码中(不是上面显示的MVE),我直接通过传递来发出目标代码(如part eight中所建议(仍然是kaleidescope教程的一部分),仍然遇到相同的问题。我在这里错了吗?
谢谢。