首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LLVM万花筒教程局部外挂失败

LLVM万花筒教程局部外挂失败
EN

Stack Overflow用户
提问于 2019-01-05 01:47:11
回答 1查看 533关注 0票数 2

我正在通过LLVM万花筒教程工作。除了本地的外行(与数学函数相反),一切都很好。

代码语言:javascript
复制
[c34n10 kaleidoscope] ./toy
ready> extern sin(x); sin(1);
ready> Read extern:
declare double @sin(double)

ready> ready> Evaluated to 0.841471
ready> extern putchard(x); putchard(120);
ready> Read extern:
declare double @putchard(double)

ready> ready> Failure value returned from cantFail wrapped call
UNREACHABLE executed at /gpfs/loomis/project/fas/manohar/emb99/llvm/include/llvm/Support/Error.h:732!
Aborted (core dumped)

根据本教程,putchard在我的代码中声明为

代码语言:javascript
复制
/// putchard - putchar that takes a double and returns 0.
extern "C" DLLEXPORT double putchard(double X) {
  fputc((char)X, stderr);
  return 0;
}

其他在线帖子指出,这个问题可能是由于不使用-rdynamic进行编译而引起的,但我是

实际错误发生在以下代码中

代码语言:javascript
复制
auto ExprSymbol = TheJIT->findSymbol("__anon_expr");
assert(ExprSymbol && "Function not found");

// cast to double-returning function
double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
fprintf(stderr, "Evaluated to %f\n", FP());

对GDB的一些调查表明,hasError标志ExprSymbol.getAddress()是正确的,这就是为什么cantFail失败的原因。至于为什么要挂那面旗子,我不明白。

这似乎不是函数本身的问题:在GDB中,我可以成功地运行call putchard(120),因此符号肯定存在于可执行文件中。

最后,我的makefile看起来像

代码语言:javascript
复制
LIBS=core orcjit native analysis executionengine instcombine object runtimedyld scalaropts support
FLAGS=`llvm-config --cxxflags --ldflags --system-libs --libs $(LIBS)`

%: %.cpp
        clang++ -v -g3 -O0 $^ -o $@ $(FLAGS) -rdynamic
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-03 03:12:50

我在LLVM 8中遇到了完全相同的问题。

问题是符号解析器不尝试在本地进程的地址中查找请求的符号,Expected<T>需要强制检查错误。

我对KaleidoscopeJIT.h做了一点改变来克服它。

将KaleidoscopeJIT的构造函数替换为以下构造函数:

代码语言:javascript
复制
KaleidoscopeJIT()
      : Resolver(createLegacyLookupResolver(
            ES,
            [this](const std::string &Name) {
              auto symbol = ObjectLayer.findSymbol(Name, true);
              if (!symbol)
              {
                if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
                  return JITSymbol(SymAddr, JITSymbolFlags::Exported);
              }
              return symbol;
            },
            [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
        TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
        ObjectLayer(ES,
                    [this](VModuleKey) {
                      return ObjLayerT::Resources{
                          std::make_shared<SectionMemoryManager>(), Resolver};
                    }),
        CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
    llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
  }

唯一的改变是,如果在调用ObjectLayer.findSymbol()之后没有找到符号,它将转到RTDyldMemoryManager::getSymbolAddressInProcess()来查找和创建JITSymbol对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54048268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档