gcc无法链接llc输出的objfile
我是LLVM的新手,尝试在wsl上的Ubuntu20.04上构建自己的编译器。我使用的是llvm-12,得到的llvm IR文件如下:gcc无法链接llc输出的objfile,gcc,llvm,Gcc,Llvm,我是LLVM的新手,尝试在wsl上的Ubuntu20.04上构建自己的编译器。我使用的是llvm-12,得到的llvm IR文件如下: ; ModuleID = 'main' source_filename = "main" @ic = constant i32 1 @rc = constant double 1.500000e+00 @bc = constant i1 false @cc = constant i8 97 @iv = global i32 0 @rv =
; ModuleID = 'main'
source_filename = "main"
@ic = constant i32 1
@rc = constant double 1.500000e+00
@bc = constant i1 false
@cc = constant i8 97
@iv = global i32 0
@rv = global double 0.000000e+00
@bv = global i1 false
@cv = global i8 0
@.str = constant [4 x i8] c"%d\0A\00"
@.str.1 = constant [5 x i8] c"%lf\0A\00"
@.str.2 = constant [4 x i8] c"%d\0A\00"
@.str.3 = constant [4 x i8] c"%c\0A\00"
@.str.4 = constant [4 x i8] c"%d\0A\00"
@.str.5 = constant [5 x i8] c"%lf\0A\00"
@.str.6 = constant [4 x i8] c"%d\0A\00"
@.str.7 = constant [4 x i8] c"%c\0A\00"
define internal void @main() {
entrypoint:
store i32 1, i32* @iv, align 4
store double 9.990000e+01, double* @rv, align 8
store i1 true, i1* @bv, align 1
store i8 97, i8* @cv, align 1
%tmp = load i32, i32* @ic, align 4
%printf = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %tmp)
%tmp1 = load double, double* @rc, align 8
%printf2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i32 0, i32 0), double %tmp1)
%tmp3 = load i1, i1* @bc, align 1
%printf4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i1 %tmp3)
%tmp5 = load i8, i8* @cc, align 1
%printf6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0), i8 %tmp5)
%tmp7 = load i32, i32* @iv, align 4
%printf8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), i32 %tmp7)
%tmp9 = load double, double* @rv, align 8
%printf10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i32 0, i32 0), double %tmp9)
%tmp11 = load i1, i1* @bv, align 1
%printf12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i32 0, i32 0), i1 %tmp11)
%tmp13 = load i8, i8* @cv, align 1
%printf14 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0), i8 %tmp13)
ret void
}
declare i32 @printf(i8*, ...)
declare i32 @scanf(...)
我可以使用lli来运行它,它运行得很好。但我想构建可执行二进制文件,所以我使用llc生成asm代码,并得到以下结果:
.text
.file "main"
.p2align 4, 0x90 # -- Begin function main
.type main,@function
main: # @main
.cfi_startproc
# %bb.0: # %entrypoint
pushq %r15
.cfi_def_cfa_offset 16
pushq %r14
.cfi_def_cfa_offset 24
pushq %r12
.cfi_def_cfa_offset 32
pushq %rbx
.cfi_def_cfa_offset 40
pushq %rax
.cfi_def_cfa_offset 48
.cfi_offset %rbx, -40
.cfi_offset %r12, -32
.cfi_offset %r14, -24
.cfi_offset %r15, -16
movq iv@GOTPCREL(%rip), %rbx
movl $1, (%rbx)
movq rv@GOTPCREL(%rip), %r12
movabsq $4636730254480218522, %rax # imm = 0x4058F9999999999A
movq %rax, (%r12)
movq bv@GOTPCREL(%rip), %r15
movb $1, (%r15)
movq cv@GOTPCREL(%rip), %r14
movb $97, (%r14)
movq ic@GOTPCREL(%rip), %rax
movl (%rax), %esi
movq .str@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
movq rc@GOTPCREL(%rip), %rax
movsd (%rax), %xmm0 # xmm0 = mem[0],zero
movq .str.1@GOTPCREL(%rip), %rdi
movb $1, %al
callq printf@PLT
movq bc@GOTPCREL(%rip), %rax
movzbl (%rax), %esi
movq .str.2@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
movq cc@GOTPCREL(%rip), %rax
movzbl (%rax), %esi
movq .str.3@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
movl (%rbx), %esi
movq .str.4@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
movsd (%r12), %xmm0 # xmm0 = mem[0],zero
movq .str.5@GOTPCREL(%rip), %rdi
movb $1, %al
callq printf@PLT
movzbl (%r15), %esi
movq .str.6@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
movzbl (%r14), %esi
movq .str.7@GOTPCREL(%rip), %rdi
xorl %eax, %eax
callq printf@PLT
addq $8, %rsp
.cfi_def_cfa_offset 40
popq %rbx
.cfi_def_cfa_offset 32
popq %r12
.cfi_def_cfa_offset 24
popq %r14
.cfi_def_cfa_offset 16
popq %r15
.cfi_def_cfa_offset 8
retq
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.type ic,@object # @ic
.section .rodata,"a",@progbits
.globl ic
.p2align 2
ic:
.long 1 # 0x1
.size ic, 4
.type rc,@object # @rc
.globl rc
.p2align 3
rc:
.quad 0x3ff8000000000000 # double 1.5
.size rc, 8
.type bc,@object # @bc
.globl bc
bc:
.byte 0 # 0x0
.size bc, 1
.type cc,@object # @cc
.globl cc
cc:
.byte 97 # 0x61
.size cc, 1
.type iv,@object # @iv
.bss
.globl iv
.p2align 2
iv:
.long 0 # 0x0
.size iv, 4
.type rv,@object # @rv
.globl rv
.p2align 3
rv:
.quad 0x0000000000000000 # double 0
.size rv, 8
.type bv,@object # @bv
.globl bv
bv:
.byte 0 # 0x0
.size bv, 1
.type cv,@object # @cv
.globl cv
cv:
.byte 0 # 0x0
.size cv, 1
.type .str,@object # @.str
.section .rodata,"a",@progbits
.globl .str
.str:
.asciz "%d\n"
.size .str, 4
.type .str.1,@object # @.str.1
.globl .str.1
.str.1:
.asciz "%lf\n"
.size .str.1, 5
.type .str.2,@object # @.str.2
.globl .str.2
.str.2:
.asciz "%d\n"
.size .str.2, 4
.type .str.3,@object # @.str.3
.globl .str.3
.str.3:
.asciz "%c\n"
.size .str.3, 4
.type .str.4,@object # @.str.4
.globl .str.4
.str.4:
.asciz "%d\n"
.size .str.4, 4
.type .str.5,@object # @.str.5
.globl .str.5
.str.5:
.asciz "%lf\n"
.size .str.5, 5
.type .str.6,@object # @.str.6
.globl .str.6
.str.6:
.asciz "%d\n"
.size .str.6, 4
.type .str.7,@object # @.str.7
.globl .str.7
.str.7:
.asciz "%c\n"
.size .str.7, 4
.section ".note.GNU-stack","",@progbits
正如您所看到的,没有“.global main”,因此当我运行gcc buildtest.s-o buildtest时,我得到:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
因此,我必须自己添加“.global main”。我怎样才能摆脱这个问题?你好,Martin Lee,欢迎来到stack overflow。你可以尝试从主DEF中移除“内部”链接类型,定义Value@主(){看看它是否工作。谢谢,这是有效的。但是我怎样才能自动地删除LVVM?你运行什么命令来创建位码?我写C++代码(使用LLVM C++ API)为了构建一个输出LLVM IR的分析器,类似于,我想我在代码中忘记了一些东西,所以LLVM把主元素看作是一个内部函数。当你使用正确的链接类型时,就这样。我使用<代码>外部链接> /代码>。