Index: lib/asan/asan_interface_internal.h =================================================================== --- lib/asan/asan_interface_internal.h +++ lib/asan/asan_interface_internal.h @@ -79,6 +79,20 @@ SANITIZER_INTERFACE_ATTRIBUTE void __asan_after_dynamic_init(); + // Sets bytes of the given range of the shadow memory into specific value. + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_00(uptr addr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_f1(uptr addr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_f2(uptr addr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_f3(uptr addr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_f5(uptr addr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_shadow_f8(uptr addr, uptr size); + // These two functions are used by instrumented code in the // use-after-scope mode. They mark memory for local variables as // unaddressable when they leave scope and addressable before the Index: lib/asan/asan_poisoning.cc =================================================================== --- lib/asan/asan_poisoning.cc +++ lib/asan/asan_poisoning.cc @@ -314,6 +314,30 @@ } } +void __asan_set_shadow_00(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0, size); +} + +void __asan_set_shadow_f1(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0xf1, size); +} + +void __asan_set_shadow_f2(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0xf2, size); +} + +void __asan_set_shadow_f3(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0xf3, size); +} + +void __asan_set_shadow_f5(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0xf5, size); +} + +void __asan_set_shadow_f8(uptr addr, uptr size) { + REAL(memset)((void *)addr, 0xf8, size); +} + void __asan_poison_stack_memory(uptr addr, uptr size) { if (!__asan_option_detect_stack_use_after_scope) return; VReport(1, "poisoning: %p %zx\n", (void *)addr, size); Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -264,6 +264,7 @@ volatile int fake_condition = 0; // prevent dead condition elimination. // __asan_report_* functions are noreturn, so we need a switch to prevent // the compiler from removing any of them. + // clang-format off switch (fake_condition) { case 1: __asan_report_load1(0); break; case 2: __asan_report_load2(0); break; @@ -303,7 +304,14 @@ case 37: __asan_unpoison_stack_memory(0, 0); break; case 38: __asan_region_is_poisoned(0, 0); break; case 39: __asan_describe_address(0); break; + case 40: __asan_set_shadow_00(0, 0); break; + case 41: __asan_set_shadow_f1(0, 0); break; + case 42: __asan_set_shadow_f2(0, 0); break; + case 43: __asan_set_shadow_f3(0, 0); break; + case 44: __asan_set_shadow_f5(0, 0); break; + case 45: __asan_set_shadow_f8(0, 0); break; } + // clang-format on } static void asan_atexit() { Index: lib/asan/asan_win_dll_thunk.cc =================================================================== --- lib/asan/asan_win_dll_thunk.cc +++ lib/asan/asan_win_dll_thunk.cc @@ -261,6 +261,13 @@ INTERFACE_FUNCTION(__asan_memset); INTERFACE_FUNCTION(__asan_memmove); +INTERFACE_FUNCTION(__asan_set_shadow_00); +INTERFACE_FUNCTION(__asan_set_shadow_f1); +INTERFACE_FUNCTION(__asan_set_shadow_f2); +INTERFACE_FUNCTION(__asan_set_shadow_f3); +INTERFACE_FUNCTION(__asan_set_shadow_f5); +INTERFACE_FUNCTION(__asan_set_shadow_f8); + INTERFACE_FUNCTION(__asan_alloca_poison); INTERFACE_FUNCTION(__asan_allocas_unpoison); Index: lib/asan/tests/CMakeLists.txt =================================================================== --- lib/asan/tests/CMakeLists.txt +++ lib/asan/tests/CMakeLists.txt @@ -193,6 +193,7 @@ asan_asm_test.cc asan_globals_test.cc asan_interface_test.cc + asan_internal_interface_test.cc asan_test.cc asan_oob_test.cc asan_mem_test.cc Index: lib/asan/tests/asan_interface_test.cc =================================================================== --- lib/asan/tests/asan_interface_test.cc +++ lib/asan/tests/asan_interface_test.cc @@ -420,4 +420,3 @@ for (size_t i = 0, n = pointers.size(); i < n; i++) free(pointers[i]); } - Index: lib/asan/tests/asan_internal_interface_test.cc =================================================================== --- /dev/null +++ lib/asan/tests/asan_internal_interface_test.cc @@ -0,0 +1,36 @@ +//===-- asan_internal_interface_test.cc -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +//===----------------------------------------------------------------------===// +#include "asan_interface_internal.h" +#include "asan_test_utils.h" + +TEST(AddressSanitizerInterface, SetShadow) { + std::vector buffer(17, 0xff); + + __asan_set_shadow_00((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0x00), buffer); + + __asan_set_shadow_f1((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0xf1), buffer); + + __asan_set_shadow_f2((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0xf2), buffer); + + __asan_set_shadow_f3((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0xf3), buffer); + + __asan_set_shadow_f5((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0xf5), buffer); + + __asan_set_shadow_f8((uptr)buffer.data(), buffer.size()); + EXPECT_EQ(std::vector(buffer.size(), 0xf8), buffer); +}