【发布时间】:2020-10-22 21:37:34
【问题描述】:
我目前正在为一种玩具语言编写编译器;这对我来说是一个新领域。我正在使用 LLVM C++ API 来生成 LLVM IR 并从那里生成一个对象。
问题在于(我认为)链接对象并能够执行它。
main.ll 包含了我能想到的最低限度的 IR:
define void @main() {
ret void
}
lli main.ll 运行得很好,即它什么也不做。
我将其编译为对象格式:llc --filetype=obj -o main.{o,ll}。
并且链接到不存在的库:ld.lld -o main{,.o}
但是生成的二进制文件会立即出现段错误。我接受了一些教程的建议,这些教程引导我尝试通过 GCC 进行链接,我被告知“在制作 PIE 对象时不能使用 [Relocations]”,维基百科告诉我这是指生成的二进制文件中的位置独立性。
所以我重新编译为对象:llc --filetype=obj --relocation-model=pic main.{o,ll} 并使用 GCC 重新编译,它运行正常,运行输出没有按预期执行。
但是再次运行ld.lld 命令并再次尝试运行该二进制文件,会立即出现段错误。
所以,我遇到的第一个问题是:对于这个简单的示例,我在链接对象(假设我链接正确)和二进制文件之间缺少什么步骤?
我是否缺少 ld 标志,一些必需的库,即使我没有特别使用任何一个?
当我尝试链接 libc 以在 IR 中使用 printf 时,即使使用 GCC 方法也会出现更多问题,但我认为在攻击之前我需要更好地理解这个简单的示例。
任何帮助将不胜感激。
【问题讨论】:
标签: compilation llvm executable llvm-ir