Skip to content

Commit 801e808

Browse files
authored
minimal_rt: fix intrinsics to correctly return original pointer (#2041)
The implementation for intrinsics in minimal_rt was incorrect. For example, the inline asm block for `memcpy` correctly describes that `rdi` will be clobbered by `rep movsb`, but `memcpy`'s API requires that the return value is the _original_ destination pointer, not the incremented pointer. Fix this by removing the mut on `dest` and indicating to the compiler to discard the clobbered value. It seems that in most cases, the compiler ignored the return value of memcpy, except when #2031 was being added. Certain compilation options or function implementations would cause the compiler to use the inlined returned value of `memcpy` directly from the call to realloc, which would then cause a later an assertion failure due to the pointer not being what was expected and overlapping with the new destination. Fix all the intrinsics in `minimal_rt` to correctly return the unmodified `dest` or `ptr` as they should.
1 parent 8aa8b61 commit 801e808

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

openhcl/minimal_rt/src/arch/aarch64/intrinsics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
1111
// there is no libc for this to conflict with.
1212
#[unsafe(no_mangle)]
13-
unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *mut u8 {
13+
unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, len: usize) -> *mut u8 {
1414
// SAFETY: the caller guarantees the pointers and length are correct.
1515
unsafe {
1616
core::arch::asm!(r#"
@@ -25,7 +25,7 @@ unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *m
2525
2:
2626
add x0, x0, x2
2727
"#,
28-
inout("x0") dest,
28+
inout("x0") dest => _,
2929
in("x1") src,
3030
in("x2") len,
3131
);
@@ -38,7 +38,7 @@ unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *m
3838
// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
3939
// there is no libc for this to conflict with.
4040
#[unsafe(no_mangle)]
41-
unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
41+
unsafe extern "C" fn memset(ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
4242
// SAFETY: the caller guarantees the pointer and length are correct.
4343
unsafe {
4444
core::arch::asm!(r#"
@@ -52,7 +52,7 @@ unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
5252
add x0, x0, x2
5353
2:
5454
"#,
55-
inout("x0") ptr,
55+
inout("x0") ptr => _,
5656
in("x1") val,
5757
in("x2") len);
5858
}

openhcl/minimal_rt/src/arch/x86_64/intrinsics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
1111
// there is no libc for this to conflict with.
1212
#[unsafe(no_mangle)]
13-
unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
13+
unsafe extern "C" fn memset(ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
1414
// SAFETY: The caller guarantees that the pointer and length are correct.
1515
unsafe {
1616
core::arch::asm!(r#"
@@ -19,7 +19,7 @@ unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
1919
"#,
2020
in("rax") val,
2121
in("rcx") len,
22-
inout("rdi") ptr);
22+
inout("rdi") ptr => _);
2323
}
2424
ptr
2525
}
@@ -29,7 +29,7 @@ unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
2929
// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
3030
// there is no libc for this to conflict with.
3131
#[unsafe(no_mangle)]
32-
unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *mut u8 {
32+
unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, len: usize) -> *mut u8 {
3333
// SAFETY: The caller guarantees that the pointers and length are correct.
3434
unsafe {
3535
core::arch::asm!(r#"
@@ -38,7 +38,7 @@ unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *m
3838
"#,
3939
in("rsi") src,
4040
in("rcx") len,
41-
inout("rdi") dest);
41+
inout("rdi") dest => _);
4242
}
4343
dest
4444
}

0 commit comments

Comments
 (0)