1 //===-- Unittests for memset ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "memory_utils/memory_check_utils.h" 10 #include "src/__support/macros/config.h" 11 #include "src/__support/macros/properties/os.h" // LIBC_TARGET_OS_IS_LINUX 12 #include "src/string/memset.h" 13 #include "test/UnitTest/Test.h" 14 15 #if !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) 16 #include "memory_utils/protected_pages.h" 17 #endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) 18 19 namespace LIBC_NAMESPACE_DECL { 20 21 // Adapt CheckMemset signature to memset. 22 static inline void Adaptor(cpp::span<char> p1, uint8_t value, size_t size) { 23 LIBC_NAMESPACE::memset(p1.begin(), value, size); 24 } 25 26 TEST(LlvmLibcMemsetTest, SizeSweep) { 27 static constexpr size_t kMaxSize = 400; 28 Buffer DstBuffer(kMaxSize); 29 for (size_t size = 0; size < kMaxSize; ++size) { 30 const char value = size % 10; 31 auto dst = DstBuffer.span().subspan(0, size); 32 ASSERT_TRUE((CheckMemset<Adaptor>(dst, value, size))); 33 } 34 } 35 36 #if !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) 37 38 TEST(LlvmLibcMemsetTest, CheckAccess) { 39 static constexpr size_t MAX_SIZE = 1024; 40 LIBC_ASSERT(MAX_SIZE < GetPageSize()); 41 ProtectedPages pages; 42 const Page write_buffer = pages.GetPageA().WithAccess(PROT_WRITE); 43 const cpp::array<int, 2> fill_chars = {0, 0x7F}; 44 for (int fill_char : fill_chars) { 45 for (size_t size = 0; size < MAX_SIZE; ++size) { 46 // We cross-check the function with two destinations. 47 // - The first of them (bottom) is always page aligned and faults when 48 // accessing bytes before it. 49 // - The second one (top) is not necessarily aligned and faults when 50 // accessing bytes after it. 51 uint8_t *destinations[2] = {write_buffer.bottom(size), 52 write_buffer.top(size)}; 53 for (uint8_t *dst : destinations) { 54 LIBC_NAMESPACE::memset(dst, fill_char, size); 55 } 56 } 57 } 58 } 59 60 #endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX) 61 62 } // namespace LIBC_NAMESPACE_DECL 63