llvm - 与 ld.lld 链接的 LLVM 字节码给出分段错误
问题描述
我写了一个简单的C程序:
例子.c:
int main() {
return 0;
}
然后通过使用将其转换为 .ll
clang -S -emit-llvm example.c
它生成了一个 example.ll 文件,如下所示:
; ModuleID = 'example.c'
source_filename = "example.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
store i32 0, i32* %1, align 4
ret i32 0
}
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 8.0.0-3 (tags/RELEASE_800/final)"}
然后我使用以下方法将 .ll 文件转换为 .o:
llc -filetype=obj example.ll
然后我尝试使用以下方法链接该文件以使其可执行:
ld.lld example.o -o example -e main
它创建了一个可执行文件 ./example。
运行示例产生分段错误
29185 segmentation fault (core dumped) ./example
example.o 的 objdump 如下所示:
example.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
b: 31 c0 xor %eax,%eax
d: 5d pop %rbp
e: c3 retq
可执行文件如下所示:
example: file format elf64-x86-64
Disassembly of section .text:
0000000000201000 <main>:
201000: 55 push %rbp
201001: 48 89 e5 mov %rsp,%rbp
201004: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
20100b: 31 c0 xor %eax,%eax
20100d: 5d pop %rbp
20100e: c3 retq
我还尝试将目标文件与ld链接,但这也没有用。我是不是错过了什么。如何使 llvm 对象文件可执行?请注意,没有任何命令产生任何错误或警告。
解决方案
好吧,这不是您应该链接可执行文件的方式。例如入口点应该被命名为“_start”等等,所以你在这里缺少一堆运行时初始化对象/库。
使用 clang(soclang example.ll
或clang example.o
)链接或将 -v 传递给 clang 调用以获取正确的链接器 cmdline。
推荐阅读
- java - 将 java 数据列表转换为 JSON 数组数组
- javascript - 在客户端执行过滤并在服务器端进行搜索
- java - 从 SCDF 启动任务时如何解决执行“java.lang.IllegalArgumentException: Invalid TaskExecution, ID 3”?
- swift - 过滤 Firebase 数据 SwiftUI
- apache-royale - apache Royale 现在支持双向数据绑定吗?
- html - 注册后欢迎电子邮件中的添加到日历按钮
- javascript - 不起作用,Javascript 在单击按钮之前验证文本输入
- shell - 是否有任何 Dart 资源可以将命令行字符串拆分为列表
论据? - amazon-web-services - AWS S3 CLI 在使用 mv 命令时创建多个目录
- javascript - 如何将表单变量和画布图片发送到 php 服务器?