LLVM JIT无法找到符号___chkstk_ms问题求助
我正在使用LLVM C++ API进行测试,编写了如下IR代码:
%allocArr = alloca ptr, i32 2, align 8 %4 = getelementptr inbounds ptr, ptr %allocArr, i32 0 store ptr @internalString, ptr %4, align 8 %5 = getelementptr inbounds ptr, ptr %allocArr, i32 1 store ptr @internalString.1, ptr %5, align 8 call void @runtimeErr(ptr @internalString.2, ptr %allocArr, i32 2) call void @print(i64 %3) ret void
当使用Kaleidoscope教程中的JIT引擎执行该代码时,出现以下错误:
JIT session error: Symbols not found: [ ___chkstk_ms ] Failed to materialize symbols: { (<main>, { anon }) } // anon是我的函数名
经查询得知,___chkstk_ms是libgcc提供的运行时函数。我自行编译了LLVM,使用MinGW 11.0.0(搭配GCC 13.1.0),其/lib目录下确实存在libgcc_s.a文件,但JIT仍无法找到该符号,请求帮助解决此问题。
显式让JIT链接libgcc_s.a
Kaleidoscope的默认JIT不会自动链接系统库,需要手动将libgcc_s.a加入JIT的处理流程:- 使用LLVM的
object::ObjectFile加载libgcc_s.a文件:auto LibGCCPath = "path/to/mingw/lib/libgcc_s.a"; auto Buffer = llvm::MemoryBuffer::getFile(LibGCCPath); if (!Buffer) { /* 处理文件加载失败逻辑 */ } auto ObjFile = llvm::object::ObjectFile::createObjectFile(*Buffer.get()); if (!ObjFile) { /* 处理对象文件创建失败逻辑 */ } - 将加载后的对象文件添加到JIT实例中:
auto &JIT = /* 你的Kaleidoscope JIT实例 */; JIT.addObjectFile(std::move(*ObjFile.get()));
完成后JIT解析符号时就能从libgcc_s.a中找到___chkstk_ms。
- 使用LLVM的
调整LLVM编译配置
重新编译LLVM时,启用MinGW相关支持,让LLVM绑定正确的运行时库:
编译时添加CMake参数:-DLLVM_USE_MINGW=ON -DGCC_INSTALL_PREFIX=/path/to/mingw,确保LLVM编译过程中关联到你的MinGW环境,后续JIT会自动处理这类系统符号依赖。修改栈分配逻辑避免触发栈检查
___chkstk_ms是栈空间分配时的栈检查函数,可通过以下方式规避:- 将IR中的
alloca替换为动态内存分配(比如调用malloc),绕过栈检查逻辑; - 在生成IR时关闭栈检查,比如通过
Module的配置或编译选项添加-disable-stack-check(需确认LLVM版本支持该选项)。
- 将IR中的
校验目标三元组匹配
确保JIT的目标三元组与MinGW编译的libgcc_s.a架构完全一致:
打印JIT的目标三元组:JIT.getTargetTriple().str(),确认是x86_64-w64-mingw32(64位)或i686-w64-mingw32(32位),与libgcc_s.a的编译架构匹配。
内容的提问来源于stack exchange,提问作者Andre_404

