gcc无法链接llc输出的汇编文件 缺少.global main如何解决
问题原因
你生成的LLVM IR中main函数使用了internal链接属性,该属性会限制函数仅在当前模块内可见,链接器无法从外部引用该符号,因此llc生成汇编时不会添加.global main导出声明,最终触发链接错误。
而lli属于LLVM IR级别的执行工具,会主动查找模块内的main函数作为入口,不受链接属性约束,因此可以正常运行。
解决方法
修改你生成的LLVM IR中main函数的定义,遵循Linux系统可执行文件的入口约定:
- 去掉
internal修饰符,改为默认的外部可见链接属性,可添加dso_local适配Ubuntu 20.04默认开启的PIE编译规则 - 将返回值类型从
void改为标准的i32,结尾返回0表示正常退出
修改后的main函数定义示例:
define dso_local i32 @main() { entrypoint: ; 此处保留你原本的所有业务逻辑代码 store i32 1, i32* @iv, align 4 ; ... 中间原有代码全部保留 ... call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0), i8 %tmp13) ; 修改返回语句 ret i32 0 }
修改后再用llc生成汇编代码,会自动包含.globl main导出声明,直接用gcc buildtest.s -o buildtest即可正常链接生成可执行文件。
如果暂时不想修改IR的返回值定义,也可以在链接时增加参数指定入口:
gcc buildtest.s -o buildtest -Wl,-e,main
但该方法属于临时适配,建议优先修改IR符合标准约定。
内容的提问来源于stack exchange,提问作者Martin Lee
相关产品推荐
相关产品推荐

