From 773c1061ebf95be2b4d599c44ce82945f2c5de39 Mon Sep 17 00:00:00 2001 From: Wim de With Date: Sat, 26 Apr 2025 16:01:54 +0200 Subject: [PATCH 1/3] librasan: Use musl implementations of some libc functions --- libafl_qemu/librasan/asan/build.rs | 53 ++---- .../librasan/asan/cc/src/.clang-format-ignore | 6 + libafl_qemu/librasan/asan/cc/src/memcmp.c | 43 +++++ libafl_qemu/librasan/asan/cc/src/memcpy.c | 152 ++++++++++++++++++ libafl_qemu/librasan/asan/cc/src/memmove.c | 70 ++++++++ libafl_qemu/librasan/asan/cc/src/memset.c | 118 ++++++++++++++ libafl_qemu/librasan/asan/cc/src/strlen.c | 52 ++++++ libafl_qemu/librasan/asan/src/mem.rs | 110 ------------- 8 files changed, 456 insertions(+), 148 deletions(-) create mode 100644 libafl_qemu/librasan/asan/cc/src/.clang-format-ignore create mode 100644 libafl_qemu/librasan/asan/cc/src/memcmp.c create mode 100644 libafl_qemu/librasan/asan/cc/src/memcpy.c create mode 100644 libafl_qemu/librasan/asan/cc/src/memmove.c create mode 100644 libafl_qemu/librasan/asan/cc/src/memset.c create mode 100644 libafl_qemu/librasan/asan/cc/src/strlen.c diff --git a/libafl_qemu/librasan/asan/build.rs b/libafl_qemu/librasan/asan/build.rs index 1064983e2c..b40828ba76 100644 --- a/libafl_qemu/librasan/asan/build.rs +++ b/libafl_qemu/librasan/asan/build.rs @@ -1,12 +1,4 @@ -fn main() { - println!("cargo:rerun-if-changed=cc/include/hooks.h"); - println!("cargo:rerun-if-changed=cc/include/trace.h"); - println!("cargo:rerun-if-changed=cc/include/printf.h"); - println!("cargo:rerun-if-changed=cc/src/asprintf.c"); - println!("cargo:rerun-if-changed=cc/src/log.c"); - println!("cargo:rerun-if-changed=cc/src/printf.c"); - println!("cargo:rerun-if-changed=cc/src/vasprintf.c"); - +fn compile(file: &str, output: &str) { cc::Build::new() .define("_GNU_SOURCE", None) .opt_level(3) @@ -14,36 +6,21 @@ fn main() { .flag("-fno-stack-protector") .flag("-ffunction-sections") .include("cc/include/") - .file("cc/src/asprintf.c") - .compile("asprintf"); + .file(file) + .compile(output); +} - cc::Build::new() - .define("_GNU_SOURCE", None) - .opt_level(3) - .flag("-Werror") - .flag("-fno-stack-protector") - .flag("-ffunction-sections") - .include("cc/include/") - .file("cc/src/log.c") - .compile("log"); +fn main() { + println!("cargo:rerun-if-changed=cc"); - cc::Build::new() - .define("_GNU_SOURCE", None) - .opt_level(3) - .flag("-Werror") - .flag("-fno-stack-protector") - .flag("-ffunction-sections") - .include("cc/include/") - .file("cc/src/printf.c") - .compile("printf"); + compile("cc/src/asprintf.c", "asprintf"); + compile("cc/src/log.c", "log"); + compile("cc/src/printf.c", "printf"); + compile("cc/src/vasprintf.c", "vasprintf"); - cc::Build::new() - .define("_GNU_SOURCE", None) - .opt_level(3) - .flag("-Werror") - .flag("-fno-stack-protector") - .flag("-ffunction-sections") - .include("cc/include/") - .file("cc/src/vasprintf.c") - .compile("vasprintf"); + compile("cc/src/memcmp.c", "memcmp"); + compile("cc/src/memcpy.c", "memcpy"); + compile("cc/src/memmove.c", "memmove"); + compile("cc/src/memset.c", "memset"); + compile("cc/src/strlen.c", "strlen"); } diff --git a/libafl_qemu/librasan/asan/cc/src/.clang-format-ignore b/libafl_qemu/librasan/asan/cc/src/.clang-format-ignore new file mode 100644 index 0000000000..a8f124b45b --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/.clang-format-ignore @@ -0,0 +1,6 @@ +# These files are ignored since they are copied verbatim from musl +memcmp.c +memcpy.c +memmove.c +memset.c +strlen.c diff --git a/libafl_qemu/librasan/asan/cc/src/memcmp.c b/libafl_qemu/librasan/asan/cc/src/memcmp.c new file mode 100644 index 0000000000..5000b1bdab --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/memcmp.c @@ -0,0 +1,43 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/memcmp.c?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The bcmp function has been added since it is identical to memcmp. + */ + +#include + +int memcmp(const void *vl, const void *vr, size_t n) +{ + const unsigned char *l=vl, *r=vr; + for (; n && *l == *r; n--, l++, r++); + return n ? *l-*r : 0; +} + +int bcmp(const void *s1, const void *s2, size_t n) +{ + return memcmp(s1, s2, n); +} diff --git a/libafl_qemu/librasan/asan/cc/src/memcpy.c b/libafl_qemu/librasan/asan/cc/src/memcpy.c new file mode 100644 index 0000000000..ba3f3f622a --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/memcpy.c @@ -0,0 +1,152 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +void *memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + unsigned char *d = dest; + const unsigned char *s = src; + +#ifdef __GNUC__ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define LS >> +#define RS << +#else +#define LS << +#define RS >> +#endif + + typedef uint32_t __attribute__((__may_alias__)) u32; + uint32_t w, x; + + for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++; + + if ((uintptr_t)d % 4 == 0) { + for (; n>=16; s+=16, d+=16, n-=16) { + *(u32 *)(d+0) = *(u32 *)(s+0); + *(u32 *)(d+4) = *(u32 *)(s+4); + *(u32 *)(d+8) = *(u32 *)(s+8); + *(u32 *)(d+12) = *(u32 *)(s+12); + } + if (n&8) { + *(u32 *)(d+0) = *(u32 *)(s+0); + *(u32 *)(d+4) = *(u32 *)(s+4); + d += 8; s += 8; + } + if (n&4) { + *(u32 *)(d+0) = *(u32 *)(s+0); + d += 4; s += 4; + } + if (n&2) { + *d++ = *s++; *d++ = *s++; + } + if (n&1) { + *d = *s; + } + return dest; + } + + if (n >= 32) switch ((uintptr_t)d % 4) { + case 1: + w = *(u32 *)s; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + n -= 3; + for (; n>=17; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+1); + *(u32 *)(d+0) = (w LS 24) | (x RS 8); + w = *(u32 *)(s+5); + *(u32 *)(d+4) = (x LS 24) | (w RS 8); + x = *(u32 *)(s+9); + *(u32 *)(d+8) = (w LS 24) | (x RS 8); + w = *(u32 *)(s+13); + *(u32 *)(d+12) = (x LS 24) | (w RS 8); + } + break; + case 2: + w = *(u32 *)s; + *d++ = *s++; + *d++ = *s++; + n -= 2; + for (; n>=18; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+2); + *(u32 *)(d+0) = (w LS 16) | (x RS 16); + w = *(u32 *)(s+6); + *(u32 *)(d+4) = (x LS 16) | (w RS 16); + x = *(u32 *)(s+10); + *(u32 *)(d+8) = (w LS 16) | (x RS 16); + w = *(u32 *)(s+14); + *(u32 *)(d+12) = (x LS 16) | (w RS 16); + } + break; + case 3: + w = *(u32 *)s; + *d++ = *s++; + n -= 1; + for (; n>=19; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+3); + *(u32 *)(d+0) = (w LS 8) | (x RS 24); + w = *(u32 *)(s+7); + *(u32 *)(d+4) = (x LS 8) | (w RS 24); + x = *(u32 *)(s+11); + *(u32 *)(d+8) = (w LS 8) | (x RS 24); + w = *(u32 *)(s+15); + *(u32 *)(d+12) = (x LS 8) | (w RS 24); + } + break; + } + if (n&16) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&8) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&4) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&2) { + *d++ = *s++; *d++ = *s++; + } + if (n&1) { + *d = *s; + } + return dest; +#endif + + for (; n; n--) *d++ = *s++; + return dest; +} diff --git a/libafl_qemu/librasan/asan/cc/src/memmove.c b/libafl_qemu/librasan/asan/cc/src/memmove.c new file mode 100644 index 0000000000..c9a281c06b --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/memmove.c @@ -0,0 +1,70 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/memmove.c?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#ifdef __GNUC__ +typedef __attribute__((__may_alias__)) size_t WT; +#define WS (sizeof(WT)) +#endif + +void *memmove(void *dest, const void *src, size_t n) +{ + char *d = dest; + const char *s = src; + + if (d==s) return d; + if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n); + + if (d=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s; + } +#endif + for (; n; n--) *d++ = *s++; + } else { +#ifdef __GNUC__ + if ((uintptr_t)s % WS == (uintptr_t)d % WS) { + while ((uintptr_t)(d+n) % WS) { + if (!n--) return dest; + d[n] = s[n]; + } + while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n); + } +#endif + while (n) n--, d[n] = s[n]; + } + + return dest; +} diff --git a/libafl_qemu/librasan/asan/cc/src/memset.c b/libafl_qemu/librasan/asan/cc/src/memset.c new file mode 100644 index 0000000000..adec723e2e --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/memset.c @@ -0,0 +1,118 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/memset.c?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +void *memset(void *dest, int c, size_t n) +{ + unsigned char *s = dest; + size_t k; + + /* Fill head and tail with minimal branching. Each + * conditional ensures that all the subsequently used + * offsets are well-defined and in the dest region. */ + + if (!n) return dest; + s[0] = c; + s[n-1] = c; + if (n <= 2) return dest; + s[1] = c; + s[2] = c; + s[n-2] = c; + s[n-3] = c; + if (n <= 6) return dest; + s[3] = c; + s[n-4] = c; + if (n <= 8) return dest; + + /* Advance pointer to align it at a 4-byte boundary, + * and truncate n to a multiple of 4. The previous code + * already took care of any head/tail that get cut off + * by the alignment. */ + + k = -(uintptr_t)s & 3; + s += k; + n -= k; + n &= -4; + +#ifdef __GNUC__ + typedef uint32_t __attribute__((__may_alias__)) u32; + typedef uint64_t __attribute__((__may_alias__)) u64; + + u32 c32 = ((u32)-1)/255 * (unsigned char)c; + + /* In preparation to copy 32 bytes at a time, aligned on + * an 8-byte bounary, fill head/tail up to 28 bytes each. + * As in the initial byte-based head/tail fill, each + * conditional below ensures that the subsequent offsets + * are valid (e.g. !(n<=24) implies n>=28). */ + + *(u32 *)(s+0) = c32; + *(u32 *)(s+n-4) = c32; + if (n <= 8) return dest; + *(u32 *)(s+4) = c32; + *(u32 *)(s+8) = c32; + *(u32 *)(s+n-12) = c32; + *(u32 *)(s+n-8) = c32; + if (n <= 24) return dest; + *(u32 *)(s+12) = c32; + *(u32 *)(s+16) = c32; + *(u32 *)(s+20) = c32; + *(u32 *)(s+24) = c32; + *(u32 *)(s+n-28) = c32; + *(u32 *)(s+n-24) = c32; + *(u32 *)(s+n-20) = c32; + *(u32 *)(s+n-16) = c32; + + /* Align to a multiple of 8 so we can fill 64 bits at a time, + * and avoid writing the same bytes twice as much as is + * practical without introducing additional branching. */ + + k = 24 + ((uintptr_t)s & 4); + s += k; + n -= k; + + /* If this loop is reached, 28 tail bytes have already been + * filled, so any remainder when n drops below 32 can be + * safely ignored. */ + + u64 c64 = c32 | ((u64)c32 << 32); + for (; n >= 32; n-=32, s+=32) { + *(u64 *)(s+0) = c64; + *(u64 *)(s+8) = c64; + *(u64 *)(s+16) = c64; + *(u64 *)(s+24) = c64; + } +#else + /* Pure C fallback with no aliasing violations. */ + for (; n; n--, s++) *s = c; +#endif + + return dest; +} diff --git a/libafl_qemu/librasan/asan/cc/src/strlen.c b/libafl_qemu/librasan/asan/cc/src/strlen.c new file mode 100644 index 0000000000..b0e9eb438f --- /dev/null +++ b/libafl_qemu/librasan/asan/cc/src/strlen.c @@ -0,0 +1,52 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/strlen.c?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Parentheses have been added to HASZERO macro to fix compiler warning. + */ + +#include +#include +#include + +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +size_t strlen(const char *s) +{ + const char *a = s; +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + const word *w; + for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; + for (w = (const void *)s; !HASZERO(*w); w++); + s = (const void *)w; +#endif + for (; *s; s++); + return s-a; +} diff --git a/libafl_qemu/librasan/asan/src/mem.rs b/libafl_qemu/librasan/asan/src/mem.rs index 0a33793b37..cd80e61e44 100644 --- a/libafl_qemu/librasan/asan/src/mem.rs +++ b/libafl_qemu/librasan/asan/src/mem.rs @@ -1,8 +1,3 @@ -use core::{ - cmp::Ordering, - slice::{from_raw_parts, from_raw_parts_mut}, -}; - #[cfg(all(feature = "global_allocator", feature = "dlmalloc"))] use crate::allocator::backend::dlmalloc::DlmallocBackend; @@ -33,108 +28,3 @@ static GLOBAL_ALLOCATOR: DlmallocBackend = DlmallocBackend::new(PAGE_SIZE) ))] static GLOBAL_ALLOCATOR: baby_mimalloc::MimallocMutexWrapper> = baby_mimalloc::MimallocMutexWrapper::with_os_allocator(DlmallocBackend::new(PAGE_SIZE)); - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, count: usize) { - let src_slice = unsafe { from_raw_parts(src, count) }; - let dest_slice = unsafe { from_raw_parts_mut(dest, count) }; - - if src < dest { - #[allow(clippy::manual_memcpy)] - for i in 0..count { - let idx = count - 1 - i; - dest_slice[idx] = src_slice[idx]; - } - } else { - #[allow(clippy::manual_memcpy)] - for i in 0..count { - dest_slice[i] = src_slice[i]; - } - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, count: usize) { - let src_slice = unsafe { from_raw_parts(src, count) }; - let dest_slice = unsafe { from_raw_parts_mut(dest, count) }; - #[allow(clippy::manual_memcpy)] - for i in 0..count { - dest_slice[i] = src_slice[i]; - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memset(dest: *mut u8, value: u8, count: usize) { - unsafe { - let mut cursor = dest; - let word_value = match value { - u8::MIN => Some(usize::MIN), - u8::MAX => Some(usize::MAX), - _ => None, - }; - - if let Some(word_value) = word_value { - let num_words = count / size_of::(); - for _ in 0..num_words { - *(cursor as *mut usize) = word_value; - cursor = cursor.wrapping_add(size_of::()); - } - - let num_bytes = count % size_of::(); - for _ in 0..num_bytes { - *cursor = value; - cursor = cursor.wrapping_add(1); - } - } else { - for _ in 0..count { - *cursor = value; - cursor = cursor.wrapping_add(1); - } - } - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memcmp(ptr1: *const u8, ptr2: *const u8, count: usize) -> i32 { - let slice1 = unsafe { from_raw_parts(ptr1, count) }; - let slice2 = unsafe { from_raw_parts(ptr2, count) }; - - for i in 0..count { - match slice1[i].cmp(&slice2[i]) { - Ordering::Equal => (), - Ordering::Less => return -1, - Ordering::Greater => return 1, - } - } - - 0 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn bcmp(ptr1: *const u8, ptr2: *const u8, count: usize) -> i32 { - let slice1 = unsafe { from_raw_parts(ptr1, count) }; - let slice2 = unsafe { from_raw_parts(ptr2, count) }; - - for i in 0..count { - if slice1[i] != slice2[i] { - return 1; - } - } - - 0 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn strlen(s: *const u8) -> usize { - let mut i = 0; - let mut cursor = s; - - unsafe { - while *cursor != 0 { - cursor = cursor.offset(1); - i += 1; - } - } - - i -} From 03e63701c20e315d0f1052a9b090101491d385f3 Mon Sep 17 00:00:00 2001 From: Wim de With Date: Mon, 28 Apr 2025 21:19:10 +0200 Subject: [PATCH 2/3] librasan: Rename cc to libc --- libafl_qemu/librasan/asan/build.rs | 22 +++++++++---------- .../asan/{cc => libc}/include/hooks.h | 0 .../asan/{cc => libc}/include/printf.h | 0 .../asan/{cc => libc}/include/trace.h | 0 .../{cc => libc}/src/.clang-format-ignore | 0 .../librasan/asan/{cc => libc}/src/asprintf.c | 0 .../librasan/asan/{cc => libc}/src/log.c | 0 .../librasan/asan/{cc => libc}/src/memcmp.c | 0 .../librasan/asan/{cc => libc}/src/memcpy.c | 0 .../librasan/asan/{cc => libc}/src/memmove.c | 0 .../librasan/asan/{cc => libc}/src/memset.c | 0 .../librasan/asan/{cc => libc}/src/printf.c | 0 .../librasan/asan/{cc => libc}/src/strlen.c | 0 .../asan/{cc => libc}/src/vasprintf.c | 0 14 files changed, 11 insertions(+), 11 deletions(-) rename libafl_qemu/librasan/asan/{cc => libc}/include/hooks.h (100%) rename libafl_qemu/librasan/asan/{cc => libc}/include/printf.h (100%) rename libafl_qemu/librasan/asan/{cc => libc}/include/trace.h (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/.clang-format-ignore (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/asprintf.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/log.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/memcmp.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/memcpy.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/memmove.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/memset.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/printf.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/strlen.c (100%) rename libafl_qemu/librasan/asan/{cc => libc}/src/vasprintf.c (100%) diff --git a/libafl_qemu/librasan/asan/build.rs b/libafl_qemu/librasan/asan/build.rs index b40828ba76..e5318f8aa0 100644 --- a/libafl_qemu/librasan/asan/build.rs +++ b/libafl_qemu/librasan/asan/build.rs @@ -5,22 +5,22 @@ fn compile(file: &str, output: &str) { .flag("-Werror") .flag("-fno-stack-protector") .flag("-ffunction-sections") - .include("cc/include/") + .include("libc/include/") .file(file) .compile(output); } fn main() { - println!("cargo:rerun-if-changed=cc"); + println!("cargo:rerun-if-changed=libc"); - compile("cc/src/asprintf.c", "asprintf"); - compile("cc/src/log.c", "log"); - compile("cc/src/printf.c", "printf"); - compile("cc/src/vasprintf.c", "vasprintf"); + compile("libc/src/asprintf.c", "asprintf"); + compile("libc/src/log.c", "log"); + compile("libc/src/printf.c", "printf"); + compile("libc/src/vasprintf.c", "vasprintf"); - compile("cc/src/memcmp.c", "memcmp"); - compile("cc/src/memcpy.c", "memcpy"); - compile("cc/src/memmove.c", "memmove"); - compile("cc/src/memset.c", "memset"); - compile("cc/src/strlen.c", "strlen"); + compile("libc/src/memcmp.c", "memcmp"); + compile("libc/src/memcpy.c", "memcpy"); + compile("libc/src/memmove.c", "memmove"); + compile("libc/src/memset.c", "memset"); + compile("libc/src/strlen.c", "strlen"); } diff --git a/libafl_qemu/librasan/asan/cc/include/hooks.h b/libafl_qemu/librasan/asan/libc/include/hooks.h similarity index 100% rename from libafl_qemu/librasan/asan/cc/include/hooks.h rename to libafl_qemu/librasan/asan/libc/include/hooks.h diff --git a/libafl_qemu/librasan/asan/cc/include/printf.h b/libafl_qemu/librasan/asan/libc/include/printf.h similarity index 100% rename from libafl_qemu/librasan/asan/cc/include/printf.h rename to libafl_qemu/librasan/asan/libc/include/printf.h diff --git a/libafl_qemu/librasan/asan/cc/include/trace.h b/libafl_qemu/librasan/asan/libc/include/trace.h similarity index 100% rename from libafl_qemu/librasan/asan/cc/include/trace.h rename to libafl_qemu/librasan/asan/libc/include/trace.h diff --git a/libafl_qemu/librasan/asan/cc/src/.clang-format-ignore b/libafl_qemu/librasan/asan/libc/src/.clang-format-ignore similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/.clang-format-ignore rename to libafl_qemu/librasan/asan/libc/src/.clang-format-ignore diff --git a/libafl_qemu/librasan/asan/cc/src/asprintf.c b/libafl_qemu/librasan/asan/libc/src/asprintf.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/asprintf.c rename to libafl_qemu/librasan/asan/libc/src/asprintf.c diff --git a/libafl_qemu/librasan/asan/cc/src/log.c b/libafl_qemu/librasan/asan/libc/src/log.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/log.c rename to libafl_qemu/librasan/asan/libc/src/log.c diff --git a/libafl_qemu/librasan/asan/cc/src/memcmp.c b/libafl_qemu/librasan/asan/libc/src/memcmp.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/memcmp.c rename to libafl_qemu/librasan/asan/libc/src/memcmp.c diff --git a/libafl_qemu/librasan/asan/cc/src/memcpy.c b/libafl_qemu/librasan/asan/libc/src/memcpy.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/memcpy.c rename to libafl_qemu/librasan/asan/libc/src/memcpy.c diff --git a/libafl_qemu/librasan/asan/cc/src/memmove.c b/libafl_qemu/librasan/asan/libc/src/memmove.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/memmove.c rename to libafl_qemu/librasan/asan/libc/src/memmove.c diff --git a/libafl_qemu/librasan/asan/cc/src/memset.c b/libafl_qemu/librasan/asan/libc/src/memset.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/memset.c rename to libafl_qemu/librasan/asan/libc/src/memset.c diff --git a/libafl_qemu/librasan/asan/cc/src/printf.c b/libafl_qemu/librasan/asan/libc/src/printf.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/printf.c rename to libafl_qemu/librasan/asan/libc/src/printf.c diff --git a/libafl_qemu/librasan/asan/cc/src/strlen.c b/libafl_qemu/librasan/asan/libc/src/strlen.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/strlen.c rename to libafl_qemu/librasan/asan/libc/src/strlen.c diff --git a/libafl_qemu/librasan/asan/cc/src/vasprintf.c b/libafl_qemu/librasan/asan/libc/src/vasprintf.c similarity index 100% rename from libafl_qemu/librasan/asan/cc/src/vasprintf.c rename to libafl_qemu/librasan/asan/libc/src/vasprintf.c From c23aae1d6cbd4ca2af291392a218f67430c8096f Mon Sep 17 00:00:00 2001 From: Wim de With Date: Tue, 29 Apr 2025 20:20:29 +0200 Subject: [PATCH 3/3] librasan: Use hand-optimized assembly implementations from musl --- libafl_qemu/librasan/asan/Cargo.toml | 3 + libafl_qemu/librasan/asan/build.rs | 39 +- .../librasan/asan/libc/src/aarch64/memcpy.S | 214 ++++++++ .../librasan/asan/libc/src/aarch64/memset.S | 143 +++++ .../librasan/asan/libc/src/arm/memcpy.S | 507 ++++++++++++++++++ .../librasan/asan/libc/src/i386/memcpy.s | 60 +++ .../librasan/asan/libc/src/i386/memmove.s | 50 ++ .../librasan/asan/libc/src/i386/memset.s | 104 ++++ .../librasan/asan/libc/src/x86_64/memcpy.s | 53 ++ .../librasan/asan/libc/src/x86_64/memmove.s | 44 ++ .../librasan/asan/libc/src/x86_64/memset.s | 100 ++++ libafl_qemu/librasan/gasan/Cargo.toml | 1 + libafl_qemu/librasan/qasan/Cargo.toml | 1 + libafl_qemu/librasan/zasan/Cargo.toml | 1 + 14 files changed, 1317 insertions(+), 3 deletions(-) create mode 100644 libafl_qemu/librasan/asan/libc/src/aarch64/memcpy.S create mode 100644 libafl_qemu/librasan/asan/libc/src/aarch64/memset.S create mode 100644 libafl_qemu/librasan/asan/libc/src/arm/memcpy.S create mode 100644 libafl_qemu/librasan/asan/libc/src/i386/memcpy.s create mode 100644 libafl_qemu/librasan/asan/libc/src/i386/memmove.s create mode 100644 libafl_qemu/librasan/asan/libc/src/i386/memset.s create mode 100644 libafl_qemu/librasan/asan/libc/src/x86_64/memcpy.s create mode 100644 libafl_qemu/librasan/asan/libc/src/x86_64/memmove.s create mode 100644 libafl_qemu/librasan/asan/libc/src/x86_64/memset.s diff --git a/libafl_qemu/librasan/asan/Cargo.toml b/libafl_qemu/librasan/asan/Cargo.toml index 1a2fec4697..741956b193 100644 --- a/libafl_qemu/librasan/asan/Cargo.toml +++ b/libafl_qemu/librasan/asan/Cargo.toml @@ -21,6 +21,7 @@ default = [ "mimalloc", "test", "tracking", + "optimized-assembly", ] ## Enable support for the `dlmalloc` allocator backend dlmalloc = ["dep:dlmalloc"] @@ -46,6 +47,8 @@ mimalloc = ["dep:baby-mimalloc"] test = [] ## Enable support for memory tracking tracking = [] +## Enable the optimized assembly implementations of various libc functions +optimized-assembly = [] [dependencies] baby-mimalloc = { version = "0.2.1", default-features = false, features = [ diff --git a/libafl_qemu/librasan/asan/build.rs b/libafl_qemu/librasan/asan/build.rs index e5318f8aa0..8262e87dac 100644 --- a/libafl_qemu/librasan/asan/build.rs +++ b/libafl_qemu/librasan/asan/build.rs @@ -1,3 +1,5 @@ +use std::env; + fn compile(file: &str, output: &str) { cc::Build::new() .define("_GNU_SOURCE", None) @@ -5,6 +7,7 @@ fn compile(file: &str, output: &str) { .flag("-Werror") .flag("-fno-stack-protector") .flag("-ffunction-sections") + .flag("-Wa,--noexecstack") .include("libc/include/") .file(file) .compile(output); @@ -12,6 +15,7 @@ fn compile(file: &str, output: &str) { fn main() { println!("cargo:rerun-if-changed=libc"); + let target = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); compile("libc/src/asprintf.c", "asprintf"); compile("libc/src/log.c", "log"); @@ -19,8 +23,37 @@ fn main() { compile("libc/src/vasprintf.c", "vasprintf"); compile("libc/src/memcmp.c", "memcmp"); - compile("libc/src/memcpy.c", "memcpy"); - compile("libc/src/memmove.c", "memmove"); - compile("libc/src/memset.c", "memset"); + + let mut memcpy = "libc/src/memcpy.c"; + let mut memmove = "libc/src/memmove.c"; + let mut memset = "libc/src/memset.c"; + + if cfg!(feature = "optimized-assembly") { + match target.as_str() { + "aarch64" => { + memcpy = "libc/src/aarch64/memcpy.S"; + memset = "libc/src/aarch64/memset.S"; + } + "arm" => { + memcpy = "libc/src/arm/memcpy.S"; + } + "x86" => { + memcpy = "libc/src/i386/memcpy.s"; + memmove = "libc/src/i386/memmove.s"; + memset = "libc/src/i386/memset.s"; + } + "x86_64" => { + memcpy = "libc/src/x86_64/memcpy.s"; + memmove = "libc/src/x86_64/memmove.s"; + memset = "libc/src/x86_64/memset.s"; + } + _ => {} + } + } + + compile(memcpy, "memcpy"); + compile(memmove, "memmove"); + compile(memset, "memset"); + compile("libc/src/strlen.c", "strlen"); } diff --git a/libafl_qemu/librasan/asan/libc/src/aarch64/memcpy.S b/libafl_qemu/librasan/asan/libc/src/aarch64/memcpy.S new file mode 100644 index 0000000000..fb5f8f6c96 --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/aarch64/memcpy.S @@ -0,0 +1,214 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/aarch64/memcpy.S?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * memcpy - copy memory area + * + * Copyright (c) 2012-2020, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +/* Assumptions: + * + * ARMv8-a, AArch64, unaligned accesses. + * + */ + +#define dstin x0 +#define src x1 +#define count x2 +#define dst x3 +#define srcend x4 +#define dstend x5 +#define A_l x6 +#define A_lw w6 +#define A_h x7 +#define B_l x8 +#define B_lw w8 +#define B_h x9 +#define C_l x10 +#define C_lw w10 +#define C_h x11 +#define D_l x12 +#define D_h x13 +#define E_l x14 +#define E_h x15 +#define F_l x16 +#define F_h x17 +#define G_l count +#define G_h dst +#define H_l src +#define H_h srcend +#define tmp1 x14 + +/* This implementation of memcpy uses unaligned accesses and branchless + sequences to keep the code small, simple and improve performance. + + Copies are split into 3 main cases: small copies of up to 32 bytes, medium + copies of up to 128 bytes, and large copies. The overhead of the overlap + check is negligible since it is only required for large copies. + + Large copies use a software pipelined loop processing 64 bytes per iteration. + The destination pointer is 16-byte aligned to minimize unaligned accesses. + The loop tail is handled by always copying 64 bytes from the end. +*/ + +.global memcpy +.type memcpy,%function +memcpy: + add srcend, src, count + add dstend, dstin, count + cmp count, 128 + b.hi .Lcopy_long + cmp count, 32 + b.hi .Lcopy32_128 + + /* Small copies: 0..32 bytes. */ + cmp count, 16 + b.lo .Lcopy16 + ldp A_l, A_h, [src] + ldp D_l, D_h, [srcend, -16] + stp A_l, A_h, [dstin] + stp D_l, D_h, [dstend, -16] + ret + + /* Copy 8-15 bytes. */ +.Lcopy16: + tbz count, 3, .Lcopy8 + ldr A_l, [src] + ldr A_h, [srcend, -8] + str A_l, [dstin] + str A_h, [dstend, -8] + ret + + .p2align 3 + /* Copy 4-7 bytes. */ +.Lcopy8: + tbz count, 2, .Lcopy4 + ldr A_lw, [src] + ldr B_lw, [srcend, -4] + str A_lw, [dstin] + str B_lw, [dstend, -4] + ret + + /* Copy 0..3 bytes using a branchless sequence. */ +.Lcopy4: + cbz count, .Lcopy0 + lsr tmp1, count, 1 + ldrb A_lw, [src] + ldrb C_lw, [srcend, -1] + ldrb B_lw, [src, tmp1] + strb A_lw, [dstin] + strb B_lw, [dstin, tmp1] + strb C_lw, [dstend, -1] +.Lcopy0: + ret + + .p2align 4 + /* Medium copies: 33..128 bytes. */ +.Lcopy32_128: + ldp A_l, A_h, [src] + ldp B_l, B_h, [src, 16] + ldp C_l, C_h, [srcend, -32] + ldp D_l, D_h, [srcend, -16] + cmp count, 64 + b.hi .Lcopy128 + stp A_l, A_h, [dstin] + stp B_l, B_h, [dstin, 16] + stp C_l, C_h, [dstend, -32] + stp D_l, D_h, [dstend, -16] + ret + + .p2align 4 + /* Copy 65..128 bytes. */ +.Lcopy128: + ldp E_l, E_h, [src, 32] + ldp F_l, F_h, [src, 48] + cmp count, 96 + b.ls .Lcopy96 + ldp G_l, G_h, [srcend, -64] + ldp H_l, H_h, [srcend, -48] + stp G_l, G_h, [dstend, -64] + stp H_l, H_h, [dstend, -48] +.Lcopy96: + stp A_l, A_h, [dstin] + stp B_l, B_h, [dstin, 16] + stp E_l, E_h, [dstin, 32] + stp F_l, F_h, [dstin, 48] + stp C_l, C_h, [dstend, -32] + stp D_l, D_h, [dstend, -16] + ret + + .p2align 4 + /* Copy more than 128 bytes. */ +.Lcopy_long: + + /* Copy 16 bytes and then align dst to 16-byte alignment. */ + + ldp D_l, D_h, [src] + and tmp1, dstin, 15 + bic dst, dstin, 15 + sub src, src, tmp1 + add count, count, tmp1 /* Count is now 16 too large. */ + ldp A_l, A_h, [src, 16] + stp D_l, D_h, [dstin] + ldp B_l, B_h, [src, 32] + ldp C_l, C_h, [src, 48] + ldp D_l, D_h, [src, 64]! + subs count, count, 128 + 16 /* Test and readjust count. */ + b.ls .Lcopy64_from_end + +.Lloop64: + stp A_l, A_h, [dst, 16] + ldp A_l, A_h, [src, 16] + stp B_l, B_h, [dst, 32] + ldp B_l, B_h, [src, 32] + stp C_l, C_h, [dst, 48] + ldp C_l, C_h, [src, 48] + stp D_l, D_h, [dst, 64]! + ldp D_l, D_h, [src, 64]! + subs count, count, 64 + b.hi .Lloop64 + + /* Write the last iteration and copy 64 bytes from the end. */ +.Lcopy64_from_end: + ldp E_l, E_h, [srcend, -64] + stp A_l, A_h, [dst, 16] + ldp A_l, A_h, [srcend, -48] + stp B_l, B_h, [dst, 32] + ldp B_l, B_h, [srcend, -32] + stp C_l, C_h, [dst, 48] + ldp C_l, C_h, [srcend, -16] + stp D_l, D_h, [dst, 64] + stp E_l, E_h, [dstend, -64] + stp A_l, A_h, [dstend, -48] + stp B_l, B_h, [dstend, -32] + stp C_l, C_h, [dstend, -16] + ret + +.size memcpy,.-memcpy diff --git a/libafl_qemu/librasan/asan/libc/src/aarch64/memset.S b/libafl_qemu/librasan/asan/libc/src/aarch64/memset.S new file mode 100644 index 0000000000..4807dc5c5a --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/aarch64/memset.S @@ -0,0 +1,143 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/aarch64/memset.S?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * memset - fill memory with a constant byte + * + * Copyright (c) 2012-2020, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +/* Assumptions: + * + * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. + * + */ + +#define dstin x0 +#define val x1 +#define valw w1 +#define count x2 +#define dst x3 +#define dstend x4 +#define zva_val x5 + +.global memset +.type memset,%function +memset: + + dup v0.16B, valw + add dstend, dstin, count + + cmp count, 96 + b.hi .Lset_long + cmp count, 16 + b.hs .Lset_medium + mov val, v0.D[0] + + /* Set 0..15 bytes. */ + tbz count, 3, 1f + str val, [dstin] + str val, [dstend, -8] + ret + nop +1: tbz count, 2, 2f + str valw, [dstin] + str valw, [dstend, -4] + ret +2: cbz count, 3f + strb valw, [dstin] + tbz count, 1, 3f + strh valw, [dstend, -2] +3: ret + + /* Set 17..96 bytes. */ +.Lset_medium: + str q0, [dstin] + tbnz count, 6, .Lset96 + str q0, [dstend, -16] + tbz count, 5, 1f + str q0, [dstin, 16] + str q0, [dstend, -32] +1: ret + + .p2align 4 + /* Set 64..96 bytes. Write 64 bytes from the start and + 32 bytes from the end. */ +.Lset96: + str q0, [dstin, 16] + stp q0, q0, [dstin, 32] + stp q0, q0, [dstend, -32] + ret + + .p2align 4 +.Lset_long: + and valw, valw, 255 + bic dst, dstin, 15 + str q0, [dstin] + cmp count, 160 + ccmp valw, 0, 0, hs + b.ne .Lno_zva + +#ifndef SKIP_ZVA_CHECK + mrs zva_val, dczid_el0 + and zva_val, zva_val, 31 + cmp zva_val, 4 /* ZVA size is 64 bytes. */ + b.ne .Lno_zva +#endif + str q0, [dst, 16] + stp q0, q0, [dst, 32] + bic dst, dst, 63 + sub count, dstend, dst /* Count is now 64 too large. */ + sub count, count, 128 /* Adjust count and bias for loop. */ + + .p2align 4 +.Lzva_loop: + add dst, dst, 64 + dc zva, dst + subs count, count, 64 + b.hi .Lzva_loop + stp q0, q0, [dstend, -64] + stp q0, q0, [dstend, -32] + ret + +.Lno_zva: + sub count, dstend, dst /* Count is 16 too large. */ + sub dst, dst, 16 /* Dst is biased by -32. */ + sub count, count, 64 + 16 /* Adjust count and bias for loop. */ +.Lno_zva_loop: + stp q0, q0, [dst, 32] + stp q0, q0, [dst, 64]! + subs count, count, 64 + b.hi .Lno_zva_loop + stp q0, q0, [dstend, -64] + stp q0, q0, [dstend, -32] + ret + +.size memset,.-memset + diff --git a/libafl_qemu/librasan/asan/libc/src/arm/memcpy.S b/libafl_qemu/librasan/asan/libc/src/arm/memcpy.S new file mode 100644 index 0000000000..b410f182f0 --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/arm/memcpy.S @@ -0,0 +1,507 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/arm/memcpy.S?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +/* + * Optimized memcpy() for ARM. + * + * note that memcpy() always returns the destination pointer, + * so we have to preserve R0. + */ + +/* + * This file has been modified from the original for use in musl libc. + * The main changes are: addition of .type memcpy,%function to make the + * code safely callable from thumb mode, adjusting the return + * instructions to be compatible with pre-thumb ARM cpus, removal of + * prefetch code that is not compatible with older cpus and support for + * building as thumb 2 and big-endian. + */ + +.syntax unified + +.global memcpy +.type memcpy,%function +memcpy: + /* The stack must always be 64-bits aligned to be compliant with the + * ARM ABI. Since we have to save R0, we might as well save R4 + * which we can use for better pipelining of the reads below + */ + .fnstart + .save {r0, r4, lr} + stmfd sp!, {r0, r4, lr} + /* Making room for r5-r11 which will be spilled later */ + .pad #28 + sub sp, sp, #28 + + /* it simplifies things to take care of len<4 early */ + cmp r2, #4 + blo copy_last_3_and_return + + /* compute the offset to align the source + * offset = (4-(src&3))&3 = -src & 3 + */ + rsb r3, r1, #0 + ands r3, r3, #3 + beq src_aligned + + /* align source to 32 bits. We need to insert 2 instructions between + * a ldr[b|h] and str[b|h] because byte and half-word instructions + * stall 2 cycles. + */ + movs r12, r3, lsl #31 + sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ + ldrbmi r3, [r1], #1 + ldrbcs r4, [r1], #1 + ldrbcs r12,[r1], #1 + strbmi r3, [r0], #1 + strbcs r4, [r0], #1 + strbcs r12,[r0], #1 + +src_aligned: + + /* see if src and dst are aligned together (congruent) */ + eor r12, r0, r1 + tst r12, #3 + bne non_congruent + + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack + * frame. Don't update sp. + */ + stmea sp, {r5-r11} + + /* align the destination to a cache-line */ + rsb r3, r0, #0 + ands r3, r3, #0x1C + beq congruent_aligned32 + cmp r3, r2 + andhi r3, r2, #0x1C + + /* conditionnaly copies 0 to 7 words (length in r3) */ + movs r12, r3, lsl #28 + ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ + ldmmi r1!, {r8, r9} /* 8 bytes */ + stmcs r0!, {r4, r5, r6, r7} + stmmi r0!, {r8, r9} + tst r3, #0x4 + ldrne r10,[r1], #4 /* 4 bytes */ + strne r10,[r0], #4 + sub r2, r2, r3 + +congruent_aligned32: + /* + * here source is aligned to 32 bytes. + */ + +cached_aligned32: + subs r2, r2, #32 + blo less_than_32_left + + /* + * We preload a cache-line up to 64 bytes ahead. On the 926, this will + * stall only until the requested world is fetched, but the linefill + * continues in the the background. + * While the linefill is going, we write our previous cache-line + * into the write-buffer (which should have some free space). + * When the linefill is done, the writebuffer will + * start dumping its content into memory + * + * While all this is going, we then load a full cache line into + * 8 registers, this cache line should be in the cache by now + * (or partly in the cache). + * + * This code should work well regardless of the source/dest alignment. + * + */ + + /* Align the preload register to a cache-line because the cpu does + * "critical word first" (the first word requested is loaded first). + */ + @ bic r12, r1, #0x1F + @ add r12, r12, #64 + +1: ldmia r1!, { r4-r11 } + subs r2, r2, #32 + + /* + * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi + * for ARM9 preload will not be safely guarded by the preceding subs. + * When it is safely guarded the only possibility to have SIGSEGV here + * is because the caller overstates the length. + */ + @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */ + stmia r0!, { r4-r11 } + bhs 1b + + add r2, r2, #32 + +less_than_32_left: + /* + * less than 32 bytes left at this point (length in r2) + */ + + /* skip all this if there is nothing to do, which should + * be a common case (if not executed the code below takes + * about 16 cycles) + */ + tst r2, #0x1F + beq 1f + + /* conditionnaly copies 0 to 31 bytes */ + movs r12, r2, lsl #28 + ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */ + ldmmi r1!, {r8, r9} /* 8 bytes */ + stmcs r0!, {r4, r5, r6, r7} + stmmi r0!, {r8, r9} + movs r12, r2, lsl #30 + ldrcs r3, [r1], #4 /* 4 bytes */ + ldrhmi r4, [r1], #2 /* 2 bytes */ + strcs r3, [r0], #4 + strhmi r4, [r0], #2 + tst r2, #0x1 + ldrbne r3, [r1] /* last byte */ + strbne r3, [r0] + + /* we're done! restore everything and return */ +1: ldmfd sp!, {r5-r11} + ldmfd sp!, {r0, r4, lr} + bx lr + + /********************************************************************/ + +non_congruent: + /* + * here source is aligned to 4 bytes + * but destination is not. + * + * in the code below r2 is the number of bytes read + * (the number of bytes written is always smaller, because we have + * partial words in the shift queue) + */ + cmp r2, #4 + blo copy_last_3_and_return + + /* Use post-incriment mode for stm to spill r5-r11 to reserved stack + * frame. Don't update sp. + */ + stmea sp, {r5-r11} + + /* compute shifts needed to align src to dest */ + rsb r5, r0, #0 + and r5, r5, #3 /* r5 = # bytes in partial words */ + mov r12, r5, lsl #3 /* r12 = right */ + rsb lr, r12, #32 /* lr = left */ + + /* read the first word */ + ldr r3, [r1], #4 + sub r2, r2, #4 + + /* write a partial word (0 to 3 bytes), such that destination + * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) + */ + movs r5, r5, lsl #31 + +#if __ARMEB__ + movmi r3, r3, ror #24 + strbmi r3, [r0], #1 + movcs r3, r3, ror #24 + strbcs r3, [r0], #1 + movcs r3, r3, ror #24 + strbcs r3, [r0], #1 +#else + strbmi r3, [r0], #1 + movmi r3, r3, lsr #8 + strbcs r3, [r0], #1 + movcs r3, r3, lsr #8 + strbcs r3, [r0], #1 + movcs r3, r3, lsr #8 +#endif + + cmp r2, #4 + blo partial_word_tail + +#if __ARMEB__ + mov r3, r3, lsr r12 + mov r3, r3, lsl r12 +#endif + + /* Align destination to 32 bytes (cache line boundary) */ +1: tst r0, #0x1c + beq 2f + ldr r5, [r1], #4 + sub r2, r2, #4 +#if __ARMEB__ + mov r4, r5, lsr lr + orr r4, r4, r3 + mov r3, r5, lsl r12 +#else + mov r4, r5, lsl lr + orr r4, r4, r3 + mov r3, r5, lsr r12 +#endif + str r4, [r0], #4 + cmp r2, #4 + bhs 1b + blo partial_word_tail + + /* copy 32 bytes at a time */ +2: subs r2, r2, #32 + blo less_than_thirtytwo + + /* Use immediate mode for the shifts, because there is an extra cycle + * for register shifts, which could account for up to 50% of + * performance hit. + */ + + cmp r12, #24 + beq loop24 + cmp r12, #8 + beq loop8 + +loop16: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + subs r2, r2, #32 + ldrhs r12, [r1], #4 +#if __ARMEB__ + orr r3, r3, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r6, lsr #16 + mov r6, r6, lsl #16 + orr r6, r6, r7, lsr #16 + mov r7, r7, lsl #16 + orr r7, r7, r8, lsr #16 + mov r8, r8, lsl #16 + orr r8, r8, r9, lsr #16 + mov r9, r9, lsl #16 + orr r9, r9, r10, lsr #16 + mov r10, r10, lsl #16 + orr r10, r10, r11, lsr #16 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsl #16 +#else + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r6, lsl #16 + mov r6, r6, lsr #16 + orr r6, r6, r7, lsl #16 + mov r7, r7, lsr #16 + orr r7, r7, r8, lsl #16 + mov r8, r8, lsr #16 + orr r8, r8, r9, lsl #16 + mov r9, r9, lsr #16 + orr r9, r9, r10, lsl #16 + mov r10, r10, lsr #16 + orr r10, r10, r11, lsl #16 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #16 +#endif + bhs 1b + b less_than_thirtytwo + +loop8: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + subs r2, r2, #32 + ldrhs r12, [r1], #4 +#if __ARMEB__ + orr r3, r3, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r6, lsr #24 + mov r6, r6, lsl #8 + orr r6, r6, r7, lsr #24 + mov r7, r7, lsl #8 + orr r7, r7, r8, lsr #24 + mov r8, r8, lsl #8 + orr r8, r8, r9, lsr #24 + mov r9, r9, lsl #8 + orr r9, r9, r10, lsr #24 + mov r10, r10, lsl #8 + orr r10, r10, r11, lsr #24 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsl #8 +#else + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r6, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r7, lsl #24 + mov r7, r7, lsr #8 + orr r7, r7, r8, lsl #24 + mov r8, r8, lsr #8 + orr r8, r8, r9, lsl #24 + mov r9, r9, lsr #8 + orr r9, r9, r10, lsl #24 + mov r10, r10, lsr #8 + orr r10, r10, r11, lsl #24 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #8 +#endif + bhs 1b + b less_than_thirtytwo + +loop24: + ldr r12, [r1], #4 +1: mov r4, r12 + ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} + subs r2, r2, #32 + ldrhs r12, [r1], #4 +#if __ARMEB__ + orr r3, r3, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r6, lsr #8 + mov r6, r6, lsl #24 + orr r6, r6, r7, lsr #8 + mov r7, r7, lsl #24 + orr r7, r7, r8, lsr #8 + mov r8, r8, lsl #24 + orr r8, r8, r9, lsr #8 + mov r9, r9, lsl #24 + orr r9, r9, r10, lsr #8 + mov r10, r10, lsl #24 + orr r10, r10, r11, lsr #8 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsl #24 +#else + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r6, lsl #8 + mov r6, r6, lsr #24 + orr r6, r6, r7, lsl #8 + mov r7, r7, lsr #24 + orr r7, r7, r8, lsl #8 + mov r8, r8, lsr #24 + orr r8, r8, r9, lsl #8 + mov r9, r9, lsr #24 + orr r9, r9, r10, lsl #8 + mov r10, r10, lsr #24 + orr r10, r10, r11, lsl #8 + stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} + mov r3, r11, lsr #24 +#endif + bhs 1b + +less_than_thirtytwo: + /* copy the last 0 to 31 bytes of the source */ + rsb r12, lr, #32 /* we corrupted r12, recompute it */ + add r2, r2, #32 + cmp r2, #4 + blo partial_word_tail + +1: ldr r5, [r1], #4 + sub r2, r2, #4 +#if __ARMEB__ + mov r4, r5, lsr lr + orr r4, r4, r3 + mov r3, r5, lsl r12 +#else + mov r4, r5, lsl lr + orr r4, r4, r3 + mov r3, r5, lsr r12 +#endif + str r4, [r0], #4 + cmp r2, #4 + bhs 1b + +partial_word_tail: + /* we have a partial word in the input buffer */ + movs r5, lr, lsl #(31-3) +#if __ARMEB__ + movmi r3, r3, ror #24 + strbmi r3, [r0], #1 + movcs r3, r3, ror #24 + strbcs r3, [r0], #1 + movcs r3, r3, ror #24 + strbcs r3, [r0], #1 +#else + strbmi r3, [r0], #1 + movmi r3, r3, lsr #8 + strbcs r3, [r0], #1 + movcs r3, r3, lsr #8 + strbcs r3, [r0], #1 +#endif + + /* Refill spilled registers from the stack. Don't update sp. */ + ldmfd sp, {r5-r11} + +copy_last_3_and_return: + movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ + ldrbmi r2, [r1], #1 + ldrbcs r3, [r1], #1 + ldrbcs r12,[r1] + strbmi r2, [r0], #1 + strbcs r3, [r0], #1 + strbcs r12,[r0] + + /* we're done! restore sp and spilled registers and return */ + add sp, sp, #28 + ldmfd sp!, {r0, r4, lr} + bx lr + diff --git a/libafl_qemu/librasan/asan/libc/src/i386/memcpy.s b/libafl_qemu/librasan/asan/libc/src/i386/memcpy.s new file mode 100644 index 0000000000..ab57b8d449 --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/i386/memcpy.s @@ -0,0 +1,60 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/i386/memcpy.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memcpy +.global __memcpy_fwd +.hidden __memcpy_fwd +.type memcpy,@function +memcpy: +__memcpy_fwd: + push %esi + push %edi + mov 12(%esp),%edi + mov 16(%esp),%esi + mov 20(%esp),%ecx + mov %edi,%eax + cmp $4,%ecx + jc 1f + test $3,%edi + jz 1f +2: movsb + dec %ecx + test $3,%edi + jnz 2b +1: mov %ecx,%edx + shr $2,%ecx + rep + movsl + and $3,%edx + jz 1f +2: movsb + dec %edx + jnz 2b +1: pop %edi + pop %esi + ret diff --git a/libafl_qemu/librasan/asan/libc/src/i386/memmove.s b/libafl_qemu/librasan/asan/libc/src/i386/memmove.s new file mode 100644 index 0000000000..43917f8a2a --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/i386/memmove.s @@ -0,0 +1,50 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/i386/memmove.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memmove +.type memmove,@function +memmove: + mov 4(%esp),%eax + sub 8(%esp),%eax + cmp 12(%esp),%eax +.hidden __memcpy_fwd + jae __memcpy_fwd + push %esi + push %edi + mov 12(%esp),%edi + mov 16(%esp),%esi + mov 20(%esp),%ecx + lea -1(%edi,%ecx),%edi + lea -1(%esi,%ecx),%esi + std + rep movsb + cld + lea 1(%edi),%eax + pop %edi + pop %esi + ret diff --git a/libafl_qemu/librasan/asan/libc/src/i386/memset.s b/libafl_qemu/librasan/asan/libc/src/i386/memset.s new file mode 100644 index 0000000000..94ce6506d9 --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/i386/memset.s @@ -0,0 +1,104 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/i386/memset.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memset +.type memset,@function +memset: + mov 12(%esp),%ecx + cmp $62,%ecx + ja 2f + + mov 8(%esp),%dl + mov 4(%esp),%eax + test %ecx,%ecx + jz 1f + + mov %dl,%dh + + mov %dl,(%eax) + mov %dl,-1(%eax,%ecx) + cmp $2,%ecx + jbe 1f + + mov %dx,1(%eax) + mov %dx,(-1-2)(%eax,%ecx) + cmp $6,%ecx + jbe 1f + + shl $16,%edx + mov 8(%esp),%dl + mov 8(%esp),%dh + + mov %edx,(1+2)(%eax) + mov %edx,(-1-2-4)(%eax,%ecx) + cmp $14,%ecx + jbe 1f + + mov %edx,(1+2+4)(%eax) + mov %edx,(1+2+4+4)(%eax) + mov %edx,(-1-2-4-8)(%eax,%ecx) + mov %edx,(-1-2-4-4)(%eax,%ecx) + cmp $30,%ecx + jbe 1f + + mov %edx,(1+2+4+8)(%eax) + mov %edx,(1+2+4+8+4)(%eax) + mov %edx,(1+2+4+8+8)(%eax) + mov %edx,(1+2+4+8+12)(%eax) + mov %edx,(-1-2-4-8-16)(%eax,%ecx) + mov %edx,(-1-2-4-8-12)(%eax,%ecx) + mov %edx,(-1-2-4-8-8)(%eax,%ecx) + mov %edx,(-1-2-4-8-4)(%eax,%ecx) + +1: ret + +2: movzbl 8(%esp),%eax + mov %edi,12(%esp) + imul $0x1010101,%eax + mov 4(%esp),%edi + test $15,%edi + mov %eax,-4(%edi,%ecx) + jnz 2f + +1: shr $2, %ecx + rep + stosl + mov 4(%esp),%eax + mov 12(%esp),%edi + ret + +2: xor %edx,%edx + sub %edi,%edx + and $15,%edx + mov %eax,(%edi) + mov %eax,4(%edi) + mov %eax,8(%edi) + mov %eax,12(%edi) + sub %edx,%ecx + add %edx,%edi + jmp 1b diff --git a/libafl_qemu/librasan/asan/libc/src/x86_64/memcpy.s b/libafl_qemu/librasan/asan/libc/src/x86_64/memcpy.s new file mode 100644 index 0000000000..ce1488273d --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/x86_64/memcpy.s @@ -0,0 +1,53 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/x86_64/memcpy.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memcpy +.global __memcpy_fwd +.hidden __memcpy_fwd +.type memcpy,@function +memcpy: +__memcpy_fwd: + mov %rdi,%rax + cmp $8,%rdx + jc 1f + test $7,%edi + jz 1f +2: movsb + dec %rdx + test $7,%edi + jnz 2b +1: mov %rdx,%rcx + shr $3,%rcx + rep + movsq + and $7,%edx + jz 1f +2: movsb + dec %edx + jnz 2b +1: ret diff --git a/libafl_qemu/librasan/asan/libc/src/x86_64/memmove.s b/libafl_qemu/librasan/asan/libc/src/x86_64/memmove.s new file mode 100644 index 0000000000..2f8592a991 --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/x86_64/memmove.s @@ -0,0 +1,44 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/x86_64/memmove.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memmove +.type memmove,@function +memmove: + mov %rdi,%rax + sub %rsi,%rax + cmp %rdx,%rax +.hidden __memcpy_fwd + jae __memcpy_fwd + mov %rdx,%rcx + lea -1(%rdi,%rdx),%rdi + lea -1(%rsi,%rdx),%rsi + std + rep movsb + cld + lea 1(%rdi),%rax + ret diff --git a/libafl_qemu/librasan/asan/libc/src/x86_64/memset.s b/libafl_qemu/librasan/asan/libc/src/x86_64/memset.s new file mode 100644 index 0000000000..39e3f5ff3d --- /dev/null +++ b/libafl_qemu/librasan/asan/libc/src/x86_64/memset.s @@ -0,0 +1,100 @@ +/* + * https://git.musl-libc.org/cgit/musl/tree/src/string/x86_64/memset.s?h=v1.2.5 + * + * This file has been copied from musl v1.2.5, which is licensed under the + * following license: + * + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.global memset +.type memset,@function +memset: + movzbq %sil,%rax + mov $0x101010101010101,%r8 + imul %r8,%rax + + cmp $126,%rdx + ja 2f + + test %edx,%edx + jz 1f + + mov %sil,(%rdi) + mov %sil,-1(%rdi,%rdx) + cmp $2,%edx + jbe 1f + + mov %ax,1(%rdi) + mov %ax,(-1-2)(%rdi,%rdx) + cmp $6,%edx + jbe 1f + + mov %eax,(1+2)(%rdi) + mov %eax,(-1-2-4)(%rdi,%rdx) + cmp $14,%edx + jbe 1f + + mov %rax,(1+2+4)(%rdi) + mov %rax,(-1-2-4-8)(%rdi,%rdx) + cmp $30,%edx + jbe 1f + + mov %rax,(1+2+4+8)(%rdi) + mov %rax,(1+2+4+8+8)(%rdi) + mov %rax,(-1-2-4-8-16)(%rdi,%rdx) + mov %rax,(-1-2-4-8-8)(%rdi,%rdx) + cmp $62,%edx + jbe 1f + + mov %rax,(1+2+4+8+16)(%rdi) + mov %rax,(1+2+4+8+16+8)(%rdi) + mov %rax,(1+2+4+8+16+16)(%rdi) + mov %rax,(1+2+4+8+16+24)(%rdi) + mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx) + mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx) + mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx) + mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx) + +1: mov %rdi,%rax + ret + +2: test $15,%edi + mov %rdi,%r8 + mov %rax,-8(%rdi,%rdx) + mov %rdx,%rcx + jnz 2f + +1: shr $3,%rcx + rep + stosq + mov %r8,%rax + ret + +2: xor %edx,%edx + sub %edi,%edx + and $15,%edx + mov %rax,(%rdi) + mov %rax,8(%rdi) + sub %rdx,%rcx + add %rdx,%rdi + jmp 1b diff --git a/libafl_qemu/librasan/gasan/Cargo.toml b/libafl_qemu/librasan/gasan/Cargo.toml index 1a408e0d04..28e64455ab 100644 --- a/libafl_qemu/librasan/gasan/Cargo.toml +++ b/libafl_qemu/librasan/gasan/Cargo.toml @@ -20,6 +20,7 @@ asan = { path = "../asan", default-features = false, features = [ "libc", "mimalloc", "tracking", + "optimized-assembly", ] } dummy_libc = { path = "../dummy_libc", default-features = false } log = { version = "0.4.22", default-features = false, features = [ diff --git a/libafl_qemu/librasan/qasan/Cargo.toml b/libafl_qemu/librasan/qasan/Cargo.toml index 58679a6570..0831cd81d6 100644 --- a/libafl_qemu/librasan/qasan/Cargo.toml +++ b/libafl_qemu/librasan/qasan/Cargo.toml @@ -20,6 +20,7 @@ asan = { path = "../asan", default-features = false, features = [ "libc", "mimalloc", "tracking", + "optimized-assembly", ] } dummy_libc = { path = "../dummy_libc", default-features = false } libc = { version = "0.2.169", default-features = false } diff --git a/libafl_qemu/librasan/zasan/Cargo.toml b/libafl_qemu/librasan/zasan/Cargo.toml index 2672c57a4f..33c071181d 100644 --- a/libafl_qemu/librasan/zasan/Cargo.toml +++ b/libafl_qemu/librasan/zasan/Cargo.toml @@ -20,6 +20,7 @@ asan = { path = "../asan", default-features = false, features = [ "host", "linux", "tracking", + "optimized-assembly", ] } log = { version = "0.4.22", default-features = false, features = [ "release_max_level_info",