2 years ago

#62443

test-img

Emanon

No output when JIT compile RISC-V assembly

I'm writing myself a toy JIT compiler, it basically just mmap a chunk of memory, write binary to it, mark this chunk of memory as executable, convert it to a function pointer and call it. It works well in my x86 laptop, but partially fails when I try to expand it to RISC-V: simple register arithmetic are OK, but it doesn't print anything when I try ecall.

x86 runs on my Intel CPU laptop, RISC-V runs on SiFive Unmatched board.

My JIT code:

    // all binary are copied from as and ld-ed riscv assembly code via objdump
    let addone_riscv = vec![
        0x13,0x05,0x15,0x00, //  addi    a0,a0,1
        0x67,0x80,0x00,0x00  //  ret
    ];// run ok, return arg+1

    let addone_x86 = vec![
        0x8d,0x47,0x01,  //    ea    0x1(%rdi),%eax
        0xc3             //    retq
    ];// run ok, return arg+1

    let helloworld_riscv = vec![
        0x13,0x05,0x10,0x00,//                li      a0,1
        0x97,0x15,0x00,0x00,//                auipc   a1,0x1
        0x93,0x85,0x05,0x02,//                addi    a1,a1,32 # 110d4 <__DATA_BEGIN__>
        0x13,0x06,0xd0,0x00,//                li      a2,13
        0x93,0x08,0x00,0x04,//                li      a7,64
        0x73,0x00,0x00,0x00,//                ecall
        0x13,0x05,0x00,0x00,//                li      a0,0
        0x93,0x08,0xd0,0x05,//                li      a7,93
        0x73,0x00,0x00,0x00,//                ecall
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64,0x21,0x0a// helloworld string 
    ]; // no output

    let helloworld_x86 = vec![
        0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, //    mov    rax,0x1
        0x48, 0xc7, 0xc7, 0x01, 0x00, 0x00, 0x00, //    mov    rdi,0x1
        0x48, 0x8d, 0x35, 0x0a, 0x00, 0x00, 0x00, //    lea    rsi,[rip+0xa]        # 0x1f
        0x48, 0xc7, 0xc2, 0x11, 0x00, 0x00, 0x00, //    mov    rdx,0x11
        0x0f, 0x05,                               //    syscall
        0xc3,                                     //    ret
        0x48,                                     //    helloworld string
        0x65, 0x6c,                               //    
        0x6c,                                     //    
        0x6f,                                     //    
        0x2c, 0x20,                               //    
        0x59,                                     //    
        0x6f,                                     //   
        0x75, 0x72,                               //  
        0x20, 0x4e, 0x61,                         //   
        0x6d,                                     //   
        0x65, 0x0a, 0x00                          // 
    ]; // run OK, print helloworld

    // allocate mem 
    let r = PageHandle::from(PageSize::from(helloworld_riscv.capacity()), &helloworld_riscv);
    // cast it to function pointer
    let code: extern "C" fn() -> () = unsafe { std::mem::transmute(r.get_ptr()) };
    
    // run
    code();

How can I fix or debug this?

assembly

system-calls

jit

riscv

0 Answers

Your Answer

Accepted video resources