使用Cranelift生成代码调用malloc/puts时触发段错误
基于Cranelift的小型编程语言调用libc函数触发段错误
我正在开发一款基于Cranelift编译的小型编程语言,目前发现生成的代码在调用malloc甚至puts时会触发段错误。以下是针对malloc的简化测试案例:
等效伪C代码
void _start(){ malloc(8); exit(0); return; }
注:并非编译C语言,因此使用汇编风格的_start入口而非C语言的main。
生成的Cranelift IR
function u0:0() system_v { sig0 = (i64) -> i64 system_v # malloc sig1 = (i32) system_v # exit fn0 = u0:0 sig0 # fn1 is not defined for some reason? block0: v0 = iconst.i64 8 v1 = call fn0(v0) ; v0 = 8 v2 = iconst.i32 0 call fn1(v2) ; v2 = 0 return }
链接命令
该IR编译为目标文件后,使用以下命令链接:
ld -pie -O2 --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -o test -lc test.o
尝试移除-pie和-O2选项,但无效果。系统默认链接器为/lib/ld64,无法生成有效可执行文件。
汇编输出
objdump反汇编结果
<other functions omitted> 00000000000010f0 <_start>: 10f0: 55 push %rbp 10f1: 48 89 e5 mov %rsp,%rbp 10f4: bf 08 00 00 00 mov $0x8,%edi 10f9: 48 8b 15 f0 1e 00 00 mov 0x1ef0(%rip),%rdx # 2ff0 <malloc@GLIBC_2.2.5> 1100: ff d2 call *%rdx 1102: 31 ff xor %edi,%edi 1104: 48 8b 15 ed 1e 00 00 mov 0x1eed(%rip),%rdx # 2ff8 <exit@GLIBC_2.2.5> 110b: ff d2 call *%rdx 110d: 48 89 ec mov %rbp,%rsp 1110: 5d pop %rbp 1111: c3 ret
Cranelift自身反汇编结果
pushq %rbp unwind PushFrameRegs { offset_upward_to_caller_sp: 16 } movq %rsp, %rbp unwind DefineNewFrame { offset_upward_to_caller_sp: 16, offset_downward_to_clobbers: 0 } block0: movl $8, %edi load_ext_name userextname0+0, %rdx call *%rdx xorl %edi, %edi, %edi load_ext_name userextname1+0, %rdx call *%rdx movq %rbp, %rsp popq %rbp ret
GDB栈跟踪信息
(gdb) backtrace #0 0x00007ffff7ca4540 in _int_malloc (av=av@entry=0x7ffff7e19c80 <main_arena>, bytes=bytes@entry=640) at ./malloc/malloc.c:4375 #1 0x00007ffff7ca4a49 in tcache_init () at ./malloc/malloc.c:3245 #2 0x00007ffff7ca525e in tcache_init () at ./malloc/malloc.c:3241 #3 __GI___libc_malloc (bytes=8) at ./malloc/malloc.c:3306 #4 0x0000555555555102 in _start ()
Cranelift配置选项
use_colocated_libcalls: "false" is_pic: "true" opt_level: "speed" regalloc_checker: "true" enable_alias_analysis: "true" enable_verifier: "true" enable_probestack: "false"
可提供strace和valgrind输出信息。环境为Ubuntu 22.04 x64,使用Cranelift 0.93.1(通过cranelift-object生成目标文件)。
内容的提问来源于stack exchange,提问作者nickkoro
相关产品推荐
相关产品推荐

