diff --git a/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp b/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp index ea8e72be287da8c92ed0ba7a53a583c04d226729..75d806bbec9a39f23a7e5fb75dc26235180a90d9 100644 --- a/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp +++ b/compiler-rt/lib/gwp_asan/optional/backtrace_linux_libc.cpp @@ -18,6 +18,8 @@ #include "gwp_asan/optional/printf.h" #include "gwp_asan/options.h" +#include "print_backtrace_linux_libc.inc" // OHOS_LOCAL + namespace { size_t Backtrace(uintptr_t *TraceBuffer, size_t Size) { static_assert(sizeof(uintptr_t) == sizeof(void *), "uintptr_t is not void*"); @@ -32,28 +34,6 @@ GWP_ASAN_ALWAYS_INLINE size_t SegvBacktrace(uintptr_t *TraceBuffer, size_t Size, void * /*Context*/) { return Backtrace(TraceBuffer, Size); } - -static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, - gwp_asan::Printf_t Printf) { - if (TraceLength == 0) { - Printf(" \n\n"); - return; - } - - char **BacktraceSymbols = - backtrace_symbols(reinterpret_cast(Trace), TraceLength); - - for (size_t i = 0; i < TraceLength; ++i) { - if (!BacktraceSymbols) - Printf(" #%zu %p\n", i, Trace[i]); - else - Printf(" #%zu %s\n", i, BacktraceSymbols[i]); - } - - Printf("\n"); - if (BacktraceSymbols) - free(BacktraceSymbols); -} } // anonymous namespace namespace gwp_asan { diff --git a/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp index 442ba653303ab0219dc34cb34865c535d7aaf416..4ac52449b7d7384019312dbd8ff844b3bd4e2098 100644 --- a/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp +++ b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp @@ -6,15 +6,39 @@ // //===----------------------------------------------------------------------===// +#include + +#include "gwp_asan/definitions.h" #include "gwp_asan/optional/backtrace.h" +#include "gwp_asan/optional/printf.h" +#include "gwp_asan/options.h" + +extern "C" char **backtrace_symbols(void *const *trace, size_t len); + +#include "print_backtrace_linux_libc.inc" + +extern "C" GWP_ASAN_WEAK size_t +libc_gwp_asan_unwind_fast(size_t *frame_buf, size_t max_record_stack, + __attribute__((unused)) void *signal_context); namespace gwp_asan { namespace backtrace { -// These interfaces are implemented by OHOS musl which is registered with gwp_asan. -options::Backtrace_t getBacktraceFunction() { return nullptr; } -PrintBacktrace_t getPrintBacktraceFunction() { return nullptr; } -SegvBacktrace_t getSegvBacktraceFunction() { return nullptr; } +// These interfaces are implemented by OHOS musl which is registered with +// gwp_asan. +options::Backtrace_t getBacktraceFunction() { + assert(&libc_gwp_asan_unwind_fast && + "libc_gwp_asan_unwind_fast wasn't provided from musl."); + return [](size_t *frame_buf, size_t max_record_stack) { + return libc_gwp_asan_unwind_fast(frame_buf, max_record_stack, nullptr); + }; +} +PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; } +SegvBacktrace_t getSegvBacktraceFunction() { + assert(&libc_gwp_asan_unwind_fast && + "libc_gwp_asan_unwind_fast wasn't provided from musl."); + return libc_gwp_asan_unwind_fast; +} } // namespace backtrace } // namespace gwp_asan diff --git a/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc b/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc new file mode 100644 index 0000000000000000000000000000000000000000..5a91746e8dc3e734a54d69bff4bcc42f3c61890a --- /dev/null +++ b/compiler-rt/lib/gwp_asan/optional/print_backtrace_linux_libc.inc @@ -0,0 +1,43 @@ +//===-- print_backtrace_linux_libc.inc --------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include + +#include "gwp_asan/definitions.h" +#include "gwp_asan/optional/backtrace.h" +#include "gwp_asan/optional/printf.h" +#include "gwp_asan/options.h" + +namespace { +void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, + gwp_asan::Printf_t Printf) { + if (TraceLength == 0) { + Printf(" \n\n"); + return; + } + + char **BacktraceSymbols = + backtrace_symbols(reinterpret_cast(Trace), TraceLength); + + for (size_t i = 0; i < TraceLength; ++i) { + if (!BacktraceSymbols) + Printf(" #%zu %p\n", i, Trace[i]); + else + Printf(" #%zu %s\n", i, BacktraceSymbols[i]); + } + + Printf("\n"); + if (BacktraceSymbols) + free(BacktraceSymbols); +} +} // anonymous namespace diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h index 475b176ccd4742ac7293121db2201f7e1fd2fca5..347fadb99632dfcaa0f4fa333fdb994c82561e5d 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h @@ -48,7 +48,7 @@ static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t), #if defined(__OHOS__) // Musl doesn't support libc using TLS variables now, // so musl puts gwp_asan tls on the pthread, this interface can return the corresponding address. -extern "C" void* get_platform_gwp_asan_tls_slot(); +extern "C" GWP_ASAN_WEAK void *get_platform_gwp_asan_tls_slot(); namespace gwp_asan { inline ThreadLocalPackedVariables *getThreadLocals() { return reinterpret_cast(get_platform_gwp_asan_tls_slot()); diff --git a/compiler-rt/lib/scudo/CMakeLists.txt b/compiler-rt/lib/scudo/CMakeLists.txt index 31a6976960f766ebc6acd6473afddc5a11bc58cd..31ee06ad36d7fb13226110c06b8b1344bdc6cb42 100644 --- a/compiler-rt/lib/scudo/CMakeLists.txt +++ b/compiler-rt/lib/scudo/CMakeLists.txt @@ -30,6 +30,13 @@ if(ANDROID) endif() endif() +# OHOS_LOCAL begin +if(OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS + list(APPEND SCUDO_CFLAGS -fno-emulated-tls) +endif() +# OHOS_LOCAL end + # The minimal Scudo runtime does not include the UBSan runtime. set(SCUDO_MINIMAL_OBJECT_LIBS RTSanitizerCommonNoTermination diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt index 55e97ac0dadf49ce7438f8042422b16a0e7130a0..ad4a5e303267ed7c8531debc5d9b02e25ed7ff6a 100644 --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -44,7 +44,10 @@ list(APPEND SCUDO_LINK_FLAGS -ffunction-sections -fdata-sections -Wl,--gc-sectio append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SCUDO_LINK_FLAGS) append_list_if(CXX_SUPPORTS_UNWINDLIB_NONE_FLAG --unwindlib=none SCUDO_LINK_FLAGS) -if(ANDROID) +# OHOS_LOCAL begin +if(ANDROID OR OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS +# OHOS_LOCAL end list(APPEND SCUDO_CFLAGS -fno-emulated-tls) # Put the shared library in the global group. For more details, see diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt index 8200cd2588b35428474987554ab1ef06cf69067f..bff4c771fdb5cfd1bfc89d862eddf3c4611aba6c 100644 --- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt @@ -22,7 +22,10 @@ if(COMPILER_RT_DEBUG) list(APPEND SCUDO_UNITTEST_CFLAGS -DSCUDO_DEBUG=1) endif() -if(ANDROID) +# OHOS_LOCAL begin +if(ANDROID OR OHOS) + # OHOS currently uses TSD_EXCLUSIVE with TLS storage in scudo, so disable EmuTLS +# OHOS_LOCAL end list(APPEND SCUDO_UNITTEST_CFLAGS -fno-emulated-tls) endif() diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp index 616cf5491b5e25a9065184d293c6ffcefc03c749..73215df13cdbeec9bc984433d500b10ed59efc3a 100644 --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp @@ -20,16 +20,29 @@ #define __GLIBC_PREREQ(x, y) 0 #endif +// OHOS_LOCAL begin extern "C" { void malloc_enable(void); void malloc_disable(void); -int malloc_iterate(uintptr_t base, size_t size, - void (*callback)(uintptr_t base, size_t size, void *arg), - void *arg); void *valloc(size_t size); void *pvalloc(size_t size); } +using MallocIterateBaseT = +#ifdef __OHOS__ + // OHOS has a different function signature + void * +#else + uintptr_t +#endif + ; + +extern "C" int malloc_iterate(MallocIterateBaseT base, size_t size, + void (*callback)(MallocIterateBaseT base, + size_t size, void *arg), + void *arg); +// OHOS_LOCAL end + // Note that every C allocation function in the test binary will be fulfilled // by Scudo (this includes the gtest APIs, etc.), which is a test by itself. // But this might also lead to unexpected side-effects, since the allocation and @@ -301,14 +314,16 @@ TEST(ScudoWrappersCTest, MallInfo2) { static uintptr_t BoundaryP; static size_t Count; -static void callback(uintptr_t Base, size_t Size, void *Arg) { +// OHOS_LOCAL begin +static void callback(MallocIterateBaseT Base, size_t Size, void *Arg) { if (scudo::archSupportsMemoryTagging()) { - Base = scudo::untagPointer(Base); + Base = (MallocIterateBaseT)scudo::untagPointer((uintptr_t)Base); BoundaryP = scudo::untagPointer(BoundaryP); } - if (Base == BoundaryP) + if ((uintptr_t)Base == BoundaryP) Count++; } +// OHOS_LOCAL end // Verify that a block located on an iteration boundary is not mis-accounted. // To achieve this, we allocate a chunk for which the backing block will be @@ -343,8 +358,11 @@ TEST(ScudoWrappersCTest, MallocIterateBoundary) { Count = 0U; malloc_disable(); - malloc_iterate(Block - PageSize, PageSize, callback, nullptr); - malloc_iterate(Block, PageSize, callback, nullptr); + // OHOS_LOCAL begin + malloc_iterate((MallocIterateBaseT)(Block - PageSize), PageSize, callback, + nullptr); + malloc_iterate((MallocIterateBaseT)Block, PageSize, callback, nullptr); + // OHOS_LOCAL end malloc_enable(); EXPECT_EQ(Count, 1U); diff --git a/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py b/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py index 245d434faed9936dd705d887dc861dfd22576e06..269944fc8449539fa6485baf3ee1e4beeac24c7b 100644 --- a/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py +++ b/compiler-rt/test/cfi/cross-dso/lit.local.cfg.py @@ -5,7 +5,7 @@ def getRoot(config): root = getRoot(config) -if root.host_os not in ['Linux', 'FreeBSD', 'NetBSD']: +if root.host_os not in ['Linux', 'FreeBSD', 'NetBSD', 'OHOS']: # OHOS_LOCAL config.unsupported = True # Android O (API level 26) has support for cross-dso cfi in libdl.so. diff --git a/compiler-rt/test/gwp_asan/CMakeLists.txt b/compiler-rt/test/gwp_asan/CMakeLists.txt index 86260027426feb1283385f94290932b9e0ab2f5e..89e8d3edf50ab56f717d0199d69869b4c8235333 100644 --- a/compiler-rt/test/gwp_asan/CMakeLists.txt +++ b/compiler-rt/test/gwp_asan/CMakeLists.txt @@ -14,7 +14,7 @@ set(GWP_ASAN_TEST_DEPS # exported libc++ from the Android NDK is x86-64, even though it's part of the # ARM[64] toolchain... See similar measures for ASan and sanitizer-common that # disable unit tests for Android. -if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_GWP_ASAN AND NOT ANDROID) +if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_GWP_ASAN AND NOT ANDROID AND NOT OHOS) # OHOS_LOCAL list(APPEND GWP_ASAN_TEST_DEPS GwpAsanUnitTests) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 53a9df0252c656ed9fc11985c9d1cced84050719..3d7d3442b086b84df5a857c82e1b65fc2d23a701 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -626,7 +626,7 @@ def is_windows_lto_supported(): if config.host_os == 'Darwin' and is_darwin_lto_supported(): config.lto_supported = True config.lto_flags = [ '-Wl,-lto_library,' + liblto_path() ] -elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD']: +elif config.host_os in ['Linux', 'FreeBSD', 'NetBSD', 'OHOS']: # OHOS_LOCAL config.lto_supported = False if config.use_lld: config.lto_supported = True diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in index c010b35b3ee73eddf041f8c798552dc2d5293a2b..5afa0c69dfe604065687aae027e7fc88506587f9 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py.in @@ -28,7 +28,7 @@ def map_list(value, sep, regex, get_path_and_do_push): def build_env(do_push=True): args = [] sanitizers = ( - 'HWASAN', 'ASAN', 'LSAN', 'MEMPROF', 'MSAN', 'TSAN', 'UBSAN', 'SCUDO' + 'HWASAN', 'ASAN', 'LSAN', 'MEMPROF', 'MSAN', 'TSAN', 'UBSAN', 'SCUDO', 'GWP_ASAN' ) set_abort_on_error=True for san in sanitizers: @@ -46,10 +46,11 @@ def build_env(do_push=True): args.append('%s=%s' % (symb_name, os.environ.get('LLVM_SYMBOLIZER_PATH', os.path.join(TMPDIR,'llvm-symbolizer-aarch64')))) # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. - args.append('LD_LIBRARY_PATH=%s' % ( TMPDIR,)) + os.environ['LD_LIBRARY_PATH'] = '%s:%s' % (os.environ.get('LD_LIBRARY_PATH', ''), TMPDIR) for (key, value) in os.environ.items(): san_opt = key.endswith('SAN_OPTIONS') - if san_opt and set_abort_on_error: + if san_opt and key != 'GWP_ASAN_OPTIONS' and set_abort_on_error: + # GWP_ASAN doesn't have abort_on_error option value += ':abort_on_error=0' if key in ['ASAN_ACTIVATION_OPTIONS', 'SCUDO_OPTIONS'] or san_opt or key == 'LD_LIBRARY_PATH': if key in ['TSAN_OPTIONS', 'UBSAN_OPTIONS']: diff --git a/compiler-rt/test/scudo/rss.c b/compiler-rt/test/scudo/rss.c index 7f182b6dd6e5e504381b4dbc95365dca2e4e8136..dbe07f551563e211823b40b8234e7fcf18944951 100644 --- a/compiler-rt/test/scudo/rss.c +++ b/compiler-rt/test/scudo/rss.c @@ -22,6 +22,12 @@ #include #include +// OHOS_LOCAL begin +#ifdef __OHOS__ +# include +#endif +// OHOS_LOCAL end + static const size_t kNumAllocs = 64; static const size_t kAllocSize = 1 << 20; // 1MB. @@ -41,10 +47,16 @@ int main(int argc, char *argv[]) { } for (int i = 0; i < kNumAllocs; i++) free(allocs[i]); + // OHOS_LOCAL begin +#ifdef __OHOS__ + // remove the RSS limit, in case RSS check is not caught up and EmuTLS is in libc internals + __scudo_set_rss_limit(0, 0); +#endif if (returned_null == 0) - printf("All malloc calls succeeded\n"); + fprintf(stderr, "All malloc calls succeeded\n"); else - printf("%d malloc calls returned NULL\n", returned_null); + fprintf(stderr, "%d malloc calls returned NULL\n", returned_null); + // OHOS_LOCAL end return 0; } diff --git a/compiler-rt/test/scudo/tsd_destruction.c b/compiler-rt/test/scudo/tsd_destruction.c index 2964df99745b32adf46fa3609db99727c4ed274c..898f9dd7b86e0cbe2870db86054229668d5f0d6c 100644 --- a/compiler-rt/test/scudo/tsd_destruction.c +++ b/compiler-rt/test/scudo/tsd_destruction.c @@ -28,7 +28,11 @@ void *thread_func(void *arg) { if ((i & 1) == 0) free(malloc(16)); // Calling strerror_l allows for strerror_thread_freeres to be called. - strerror_l(0, LC_GLOBAL_LOCALE); + // OHOS_LOCAL begin + locale_t locale = duplocale(LC_GLOBAL_LOCALE); + strerror_l(0, locale); + freelocale(locale); + // OHOS_LOCAL end return 0; }