从 Cranelift 生成的代码调用 malloc 或 puts 时出现段错误

问题描述 投票:0回答:0

我正在研究一种使用 cranelift 编译的小型编程语言。现在,每当我调用

malloc
甚至
puts
时,我生成的代码都会出现段错误。我将专注于
malloc
的一个小例子:

我尝试编译的代码大致相当于下面的伪C程序:

void _start(){
   malloc(8);
   exit(0);
   return;
}

请注意,我实际上并没有编译 C,因此使用

_start
入口点,就像在汇编程序中一样,而不是 Cs
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
}

它被编译成一个目标文件,我使用它链接

ld -pie -O2 --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -o test -lc test.o

我尝试省略

-pie
-O2
没有效果。由于某些原因,默认链接解释器是
/lib/ld64
,它不会在我的系统上生成有效的可执行文件。

此 Cranelift IR 相当于以下组件:

Dissassembled使用

objdump -d test.o

<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-Stacktrace:

(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 ()

二手起重机选项:

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
发出 obj 文件)。

c assembly segmentation-fault compiler-construction wasmtime
© www.soinside.com 2019 - 2024. All rights reserved.