将llvm产生的目标代码与ld链接

时间:2018-08-03 17:24:19

标签: gcc llvm ld

我编写了一个小型编译器,该编译器使用llvm(通过c ++)来生成目标文件(在Linux系统中)。

当我将编译后的输出与gcc链接时,程序运行正常:

method1

但是,如果我尝试将其与ld链接,则在运行程序时会遇到分段错误:

myCompiler source.mylang -o objCode
gcc objCode -o program
./program #runs fine

这是编译器输出的llvm代码(使用myLlvmModule-> print函数):

myCompiler source.mylang -o objCode
ld objCode -e main -o program   #ld does not print any error or warning.
./program #Segmentation fault (core dumped)

当gcc成功时,为什么ld失败? 我以为编写完编译器后,唯一需要做的步骤就是调用链接器。是否需要其他编译器(例如gcc)?

如果是,为什么? 如果没有,我该如何工作?

编辑: 工作二进制文件的readelf -d:

; ModuleID = 'entryPointModule'
source_filename = "entryPointModule"

define i32 @main() {
entry:
  %x = alloca i32
  store i32 55, i32* %x
  ret i32 0
  ret i32 0
}

针对损坏的二进制文件的相同命令:

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

1 个答案:

答案 0 :(得分:2)

您的入口点尝试返回到堆栈上不存在的返回地址,这就是程序跳转到地址零的原因。

程序的入口点不应返回。它必须通过调用_exit(或相关的系统调用)来终止该过程。