发出IR的段错误,用于`printf`调用

问题描述 投票:0回答:1

我希望使用系统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教程的一部分),仍然遇到相同的问题。我在这里错了吗?

谢谢。

llvm llvm-ir llvm-c++-api
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.