rcore-os / rCore

Rust version of THU uCore OS. Linux compatible.
MIT License
3.42k stars 369 forks source link

Weird code generation on RISC-V 64 #79

Open gjz010 opened 3 years ago

gjz010 commented 3 years ago

The following code in memory.rs emits strange assembly code causing an infinite loop:

// T is specialized to some struct sized 336..
#[naked]
#[inline(never)]
#[link_section = ".text.copy_user"]
unsafe extern "C" fn write_user<T>(dst: *mut T, src: *const T) -> usize {
    dst.copy_from_nonoverlapping(src, 1);
    0
}

Generated assembly:

ffffffffc02000d6 <_ZN5rcore6memory12copy_to_user10write_user17h75f60bbde319fcafE>:
ffffffffc02000d6:   15000613            li  a2,336 // struct size. 3rd argument of memcpy.
ffffffffc02000da:   00086097            auipc   ra,0x86 // WHY IS IT USING ra FOR INTERMEDIATE ADDRESS CALCULATION?
ffffffffc02000de:   0f0080e7            jalr    240(ra) # ffffffffc02861ca <memcpy> // now ra = ffffffffc02000e2 <li a0, 0>
ffffffffc02000e2:   4501                    li  a0,0 // BANG!
ffffffffc02000e4:   8082                    ret // goto BANG!

It seems that rustc optimizing copy_from_nonoverlapping into memcpy (in the naked function) results in this issue, but I'm not sure.

wangrunji0408 commented 3 years ago

Seems these codes were introduced by @jiegec: https://github.com/rcore-os/rCore/commit/92a9674f6640be7563613b3dc6cf7f18ab965818#diff-daec1639ddc202cd1b84917f388b4323b107696dab34069cdb0af3133837102d

@jiegec πŸ‰πŸ‰πŸ‰