diff --git a/src/arm.rs b/src/arm.rs index 7beb91aa..a49e5d84 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -1,60 +1,54 @@ -extern "C" { - fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; - fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; - fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8; -} - // FIXME: The `*4` and `*8` variants should be defined as aliases. #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) { - memcpy(dest, src, n); + ::libc::memcpy(dest, src, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) { - memcpy(dest, src, n); + ::libc::memcpy(dest, src, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) { - memcpy(dest, src, n); + ::libc::memcpy(dest, src, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) { - memmove(dest, src, n); + ::libc::memmove(dest, src, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) { - memmove(dest, src, n); + ::libc::memmove(dest, src, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) { - memmove(dest, src, n); + ::libc::memmove(dest, src, n); } // Note the different argument order #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) { - memset(dest, c, n); + ::libc::memset(dest, c, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) { - memset(dest, c, n); + ::libc::memset(dest, c, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) { - memset(dest, c, n); + ::libc::memset(dest, c, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) { - memset(dest, 0, n); + ::libc::memset(dest, 0, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) { - memset(dest, 0, n); + ::libc::memset(dest, 0, n); } #[no_mangle] pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { - memset(dest, 0, n); + ::libc::memset(dest, 0, n); } diff --git a/src/lib.rs b/src/lib.rs index 01aca767..1bf74420 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,9 +2,12 @@ #![cfg_attr(not(test), no_std)] #![feature(asm)] #![feature(core_intrinsics)] +#![feature(linkage)] #![feature(naked_functions)] +#![no_builtins] // TODO(rust-lang/rust#35021) uncomment when that PR lands // #![feature(rustc_builtins)] +// #![rustc_builtins] #[cfg(test)] extern crate core; @@ -14,6 +17,11 @@ use core::mem; #[cfg(target_arch = "arm")] pub mod arm; +// NOTE LLVM's weak linkage only appears to work with the ELF backend +#[cfg(not(any(target_os = "macos", + target_os = "windows")))] +pub mod libc; + #[cfg(test)] mod test; diff --git a/src/libc.rs b/src/libc.rs new file mode 100644 index 00000000..29b76916 --- /dev/null +++ b/src/libc.rs @@ -0,0 +1,44 @@ +// NOTE Implementations copy pasted from rlibc (https://crates.io/crates/rlibc) + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { + let mut i = 0; + while i < n { + *dest.offset(i as isize) = *src.offset(i as isize); + i += 1; + } + dest +} + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { + if src < dest as *const u8 { + // copy from end + let mut i = n; + while i != 0 { + i -= 1; + *dest.offset(i as isize) = *src.offset(i as isize); + } + } else { + // copy from beginning + let mut i = 0; + while i < n { + *dest.offset(i as isize) = *src.offset(i as isize); + i += 1; + } + } + dest +} + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 { + let mut i = 0; + while i < n { + *s.offset(i as isize) = c as u8; + i += 1; + } + s +}