【发布时间】:2018-08-03 17:24:19
【问题描述】:
我编写了一个小型编译器,它使用 llvm(通过 c++)生成目标文件(在 linux 系统中)。
当我用 gcc 链接编译后的输出时,程序运行良好:
myCompiler source.mylang -o objCode
gcc objCode -o program
./program #runs fine
但如果我尝试将其与 ld 链接,则在运行程序时会出现分段错误:
myCompiler source.mylang -o objCode
ld objCode -e main -o program #ld does not print any error or warning.
./program #Segmentation fault (core dumped)
这是编译器输出的 llvm 代码(使用 myLlvmModule->print 函数):
; ModuleID = 'entryPointModule'
source_filename = "entryPointModule"
define i32 @main() {
entry:
%x = alloca i32
store i32 55, i32* %x
ret i32 0
ret i32 0
}
为什么 ld 失败,而 gcc 成功了? 我认为编写编译器后,唯一需要的步骤就是调用链接器。是否需要其他编译器(如 gcc)?
如果是,为什么? 如果没有,我怎样才能让 ld 工作?
编辑: readelf -d 工作二进制文件:
Dynamic section at offset 0xe00 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x4b8
0x000000000000000d (FINI) 0x684
0x0000000000000019 (INIT_ARRAY) 0x200df0
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x200df8
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x298
0x0000000000000005 (STRTAB) 0x348
0x0000000000000006 (SYMTAB) 0x2b8
0x000000000000000a (STRSZ) 125 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x200fc0
0x0000000000000007 (RELA) 0x3f8
0x0000000000000008 (RELASZ) 192 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
0x000000006ffffffe (VERNEED) 0x3d8
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x3c6
0x000000006ffffff9 (RELACOUNT) 3
0x0000000000000000 (NULL) 0x0
损坏的二进制文件的相同命令:
There is no dynamic section in this file.
【问题讨论】:
-
您需要与 C 运行时库链接。 en.wikipedia.org/wiki/Runtime_library
-
您能发布两个生成的最终二进制文件中
readelf -d的输出吗?另外,当你用gdb运行它时会发生什么?回溯是什么? -
而 gdb 说“程序收到信号 SIGSEGV,分段错误。0x0000000000000001 in ?? ()”
-
至于 readelf,我更新了帖子并包含了输出。
-
ewindes,你能解释一下为什么我需要 c-runtime 库吗?该程序只是声明一个变量并返回。我想了解 c 运行时库将添加到程序中的内容。此外,当我在 ld 命令中添加 -lc 时,最终的二进制文件根本不会执行。我得到“bash:../data/pr:没有这样的文件或目录”,即使它确实存在。