From 52047b5b8dc76ced41cc7a64c80d4721202702ae Mon Sep 17 00:00:00 2001 From: yanpeng Date: Wed, 10 Apr 2024 15:15:47 +0800 Subject: [PATCH 1/8] [lldb] enable libxml2 to lldb-standalone build libxml2 static library and enable libxml2 to lldb-standalone Issue: https://gitee.com/openharmony/third_party_llvm-project/issues/I9FIAZ Signed-off-by: yanpeng --- llvm-build/build.py | 126 ++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 46 deletions(-) diff --git a/llvm-build/build.py b/llvm-build/build.py index bef40a27305b..dd6d845f2a47 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -85,7 +85,7 @@ class BuildConfig(): self.CLANG_VERSION = prebuilts_clang_version self.MINGW_TRIPLE = 'x86_64-windows-gnu' self.build_libs_with_hb = self.build_libs_flags == 'OH' or self.build_libs_flags == 'BOTH' - + self.ARCHIVE_EXTENSION = '.tar.' + self.compression_format self.ARCHIVE_OPTION = '-c' + ('j' if self.compression_format == "bz2" else 'z') self.LIBXML2_VERSION = None @@ -252,7 +252,7 @@ class BuildConfig(): action='store_true', default=False, help='Enable lldb performance monitoring') - + compression_formats = ['bz2', 'gz'] parser.add_argument( @@ -603,6 +603,15 @@ class BuildUtils(object): return None + def get_libxml2_source_path(self): + return self.merge_out_path('third_party', 'libxml2', ('libxml2-' + self.build_config.LIBXML2_VERSION)) + + def get_libxml2_install_path(self, triple): + return self.merge_out_path('third_party', 'libxml2', 'install', triple) + + def get_libxml2_build_path(self, triple): + return self.merge_out_path('third_party', 'libxml2', 'build', triple) + class LlvmCore(BuildUtils): def __init__(self, build_config): @@ -678,7 +687,7 @@ class LlvmCore(BuildUtils): llvm_defines['LibEdit_LIBRARIES'] = os.path.join(self.get_prebuilts_dir('libedit'), 'lib', 'libedit.0.dylib') if self.build_config.build_libxml2: - llvm_defines['LIBXML2_LIBRARIES'] = os.path.join(self.get_prebuilts_dir('libxml2'), self.use_platform(), 'lib', f'libxml2.{self.build_config.LIBXML2_VERSION}.dylib') + llvm_defines['LIBXML2_LIBRARIES'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'lib', f'libxml2.{self.build_config.LIBXML2_VERSION}.dylib') def llvm_compile_linux_defines(self, @@ -724,7 +733,7 @@ class LlvmCore(BuildUtils): llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' if self.build_config.build_libxml2: - llvm_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_prebuilts_dir('libxml2'), self.use_platform(), 'lib', f'libxml2.so.{self.build_config.LIBXML2_VERSION}') + llvm_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'lib', f'libxml2.so.{self.build_config.LIBXML2_VERSION}') def llvm_compile_llvm_defines(self, llvm_defines, llvm_root, cflags, ldflags): llvm_defines['LLVM_ENABLE_PROJECTS'] = ';'.join(self.build_config.host_projects) @@ -773,8 +782,8 @@ class LlvmCore(BuildUtils): if self.build_config.build_libxml2: llvm_defines['LLDB_ENABLE_LIBXML2'] = 'ON' - llvm_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_prebuilts_dir('libxml2'), self.use_platform(), 'include', 'libxml2') - + llvm_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_libxml2_install_path(self.use_platform()), 'include', 'libxml2') + if self.build_config.enable_monitoring: llvm_defines['LLDB_ENABLE_PERFORMANCE'] = 'ON' @@ -899,8 +908,8 @@ class LlvmCore(BuildUtils): if self.build_config.build_libxml2: windows_defines['LLDB_ENABLE_LIBXML2'] = 'ON' - windows_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_prebuilts_dir('libxml2'), 'windows-x86_64', 'include', 'libxml2') - windows_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_prebuilts_dir('libxml2'), 'windows-x86_64', 'lib', 'libxml2.dll.a') + windows_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(self.get_libxml2_install_path('windows-x86_64'), 'include', 'libxml2') + windows_defines['LIBXML2_LIBRARY'] = os.path.join(self.get_libxml2_install_path('windows-x86_64'), 'lib', 'libxml2.dll.a') if self.build_config.enable_monitoring: windows_defines['LLDB_ENABLE_PERFORMANCE'] = 'ON' @@ -1051,7 +1060,7 @@ class SysrootComposer(BuildUtils): target_cpu, '--build-target', target_name, '--gn-args', gn_args, llvm_gn_args, '--deps-guard=false'], shell=False, stdout=subprocess.PIPE, cwd=self.build_config.REPOROOT_DIR) - + def build_musl_libs(self, product_name, target_cpu, target_name, ohos_lib_dir, sysroot_lib_dir, ld_musl_lib, gn_args=''): self.run_hb_build(product_name, target_cpu, target_name, gn_args) @@ -1245,7 +1254,7 @@ class LlvmLibs(BuildUtils): ldflag.append('-Wl,-z,relro,-z,now -pie') if self.build_config.strip and not self.build_config.no_strip_libs: ldflag.append('-s') - + ldflags.extend(ldflag) cflag = [ @@ -1258,7 +1267,7 @@ class LlvmLibs(BuildUtils): cflag.append('-g') cflags.extend(cflag) - + def run_hb_build_libs(self, libs_name): gn_args = 'build_libs_flags={} llvm_lib={}'.format(self.build_config.build_libs_flags, libs_name) self.sysroot_composer.run_hb_build('llvm_build', 'arm', 'build_libs', gn_args) @@ -1319,7 +1328,7 @@ class LlvmLibs(BuildUtils): self.open_ohos_triple('mipsel'), self.open_ohos_triple('x86_64')] libcxx_ndk_install = self.merge_out_path('libcxx-ndk') self.check_create_dir(libcxx_ndk_install) - + if precompilation: self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) continue @@ -1681,6 +1690,13 @@ class LlvmLibs(BuildUtils): lldb_defines['LIBLLDB_BUILD_STATIC'] = 'ON' lldb_target.append('lldb') + if self.build_config.build_libxml2: + self.build_libxml2(llvm_triple, None, llvm_install) + lldb_defines['LLDB_ENABLE_LIBXML2'] = 'ON' + libxml2_install_path = self.get_libxml2_install_path(llvm_triple) + lldb_defines['LIBXML2_INCLUDE_DIR'] = os.path.join(libxml2_install_path, 'include', 'libxml2') + lldb_defines['LIBXML2_LIBRARY'] = os.path.join(libxml2_install_path, 'lib', 'libxml2.a') + if self.build_config.lldb_timeout: lldb_defines['LLDB_ENABLE_TIMEOUT'] = 'True' @@ -1841,39 +1857,64 @@ class LlvmLibs(BuildUtils): return libxml2_defines - def build_libxml2(self, llvm_make, llvm_install): - self.logger().info('Building libxml2') + def build_libxml2(self, triple, llvm_make, llvm_install): + self.logger().info('Building libxml2 for %s', triple) - libxml2_defines = self.build_libxml2_defines() + cmake_path = self.get_libxml2_source_path() + if not os.path.exists(cmake_path): + package_path = os.path.join(self.build_config.REPOROOT_DIR, 'third_party', 'libxml2') + untar_py = os.path.join(package_path, 'install.py') + untar_path = self.merge_out_path('third_party', 'libxml2') + self.check_create_dir(untar_path) + subprocess.run(['python3', untar_py, '--gen-dir', untar_path, '--source-file', package_path]) - libxml2_cmake_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'out', ('libxml2-' + self.build_config.LIBXML2_VERSION))) + build_path = self.get_libxml2_build_path(triple) + install_path = self.get_libxml2_install_path(triple) + self.check_rm_tree(build_path) + self.check_rm_tree(install_path) - libxml2_build_path = self.merge_out_path('libxml2') - libxml2_install_path = os.path.join(self.get_prebuilts_dir('libxml2'), self.use_platform()) - libxml2_defines['CMAKE_INSTALL_PREFIX'] = libxml2_install_path + defines = self.build_libxml2_defines() + defines['CMAKE_INSTALL_PREFIX'] = install_path - self.rm_cmake_cache(libxml2_build_path) + if triple != self.use_platform(): + configs_list, cc, cxx, ar, llvm_config = self.libs_argument(llvm_install) + for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: + if llvm_triple != triple or multilib_suffix != '': + continue - self.invoke_cmake(libxml2_cmake_path, - libxml2_build_path, - libxml2_defines, - env=dict(self.build_config.ORIG_ENV)) + ldflags = [] + cflags = [] + self.build_libs_defines(triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) + defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + defines['CMAKE_LINKER'] = os.path.join(llvm_install, 'bin', 'ld.lld') + defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + defines['CMAKE_CROSSCOMPILING'] = 'True' + defines['BUILD_SHARED_LIBS'] = 'OFF' + break - self.invoke_ninja(out_path=libxml2_build_path, - env=dict(self.build_config.ORIG_ENV), - target=None, - install=True) + self.invoke_cmake(cmake_path, + build_path, + defines, + dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(build_path, + dict(self.build_config.ORIG_ENV), + None, + True) - self.llvm_package.copy_libxml2_to_llvm(llvm_make) - self.llvm_package.copy_libxml2_to_llvm(llvm_install) + if triple == self.use_platform(): + self.llvm_package.copy_libxml2_to_llvm(triple, llvm_make) + self.llvm_package.copy_libxml2_to_llvm(triple, llvm_install) def build_libxml2_for_windows(self, windows64_install): self.logger().info('Building libxml2 for windows') windows_sysroot = self.merge_out_path('mingw', self.build_config.MINGW_TRIPLE) windowstool_path = self.merge_out_path('llvm-install') - libxml2_build_path = self.merge_out_path('libxml2-windows-build') - libxml2_install_path = os.path.join(self.get_prebuilts_dir('libxml2'), 'windows-x86_64') + libxml2_build_path = self.get_libxml2_build_path('windows-x86_64') + libxml2_install_path = self.get_libxml2_install_path('windows-x86_64') cflags = ['--target=x86_64-pc-windows-gnu'] cflags.extend(('-I', os.path.join(windows_sysroot, 'include'))) @@ -1900,8 +1941,7 @@ class LlvmLibs(BuildUtils): libxml2_defines['CMAKE_RC_FLAGS'] = ' '.join(rcflags) libxml2_defines['XML_INCLUDEDIR'] = os.path.join(windows_sysroot, 'include') - libxml2_cmake_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'out', ('libxml2-' + self.build_config.LIBXML2_VERSION))) - + libxml2_cmake_path = self.get_libxml2_source_path() self.invoke_cmake(libxml2_cmake_path, libxml2_build_path, libxml2_defines, @@ -1911,7 +1951,7 @@ class LlvmLibs(BuildUtils): env=dict(self.build_config.ORIG_ENV), target=None, install=True) - + if not os.path.exists(os.path.join(windows64_install, 'bin')): os.makedirs(os.path.join(windows64_install, 'bin')) shutil.copyfile(os.path.join(libxml2_build_path, 'libxml2.dll'), os.path.join(windows64_install, 'bin', 'libxml2.dll')) @@ -2125,7 +2165,7 @@ class LlvmPackage(BuildUtils): 'opt%s' % ext, ] - + necessary_bin_files.extend(necessary_bin_file) @staticmethod @@ -2368,7 +2408,7 @@ class LlvmPackage(BuildUtils): st = os.stat(os.path.join(bin_dir, sh_filename)) os.chmod(os.path.join(bin_dir, sh_filename), st.st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) - def copy_libxml2_to_llvm(self, install_dir): + def copy_libxml2_to_llvm(self, triple, install_dir): self.logger().info('LlvmPackage copy_libxml2_to_llvm install_dir is %s', install_dir) libxml2_version = self.get_libxml2_version() @@ -2378,7 +2418,7 @@ class LlvmPackage(BuildUtils): if self.host_is_linux(): shlib_ext = f'.so.{libxml2_version}' - libxml2_lib_path = self.merge_out_path('libxml2') + libxml2_lib_path = os.path.join(self.get_libxml2_install_path(triple), 'lib') libxml2_src = os.path.join(libxml2_lib_path, 'libxml2%s' % shlib_ext) lib_dst_path = os.path.join(install_dir, 'lib') @@ -2452,7 +2492,7 @@ class LlvmPackage(BuildUtils): # Strip lldb-server self.strip_lldb_server(host, install_dir) - + # Copy lldb script lldb_script_file = 'lldb.cmd' if host.startswith('windows') else 'lldb.sh' self.check_copy_file(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'lldb', 'scripts', lldb_script_file), os.path.join(install_dir, 'bin')) @@ -2528,13 +2568,7 @@ def main(): build_config.build_libxml2 = False if build_config.build_libxml2: - libxml2_untar_py = os.path.join( - build_config.REPOROOT_DIR, 'third_party', 'libxml2', 'install.py') - if not os.path.exists(build_config.REPOROOT_DIR + '/out'): - os.makedirs(build_config.REPOROOT_DIR + '/out') - subprocess.run(['python3', libxml2_untar_py, '--gen-dir', build_config.REPOROOT_DIR + '/out', - '--source-file', build_config.REPOROOT_DIR + '/third_party/libxml2']) - llvm_libs.build_libxml2(llvm_make, llvm_install) + llvm_libs.build_libxml2(build_utils.use_platform(), llvm_make, llvm_install) if build_config.do_build and need_host: llvm_core.llvm_compile( -- Gitee From 3a183daf8e1413a745b25294cd4d7687cb47a117 Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Fri, 19 Apr 2024 14:06:17 +0800 Subject: [PATCH 2/8] [LLDB][Mac] liblzma.dylib not loaded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue:https://gitee.com/openharmony/third_party_llvm-project/issues/I9HYZF?from=project-issue Test: Toolchain Compilation and LLDB Tool test Signed-off-by: xwx1135370 --- llvm-build/MakeLiblzma | 7 ++++--- llvm-build/build.py | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm-build/MakeLiblzma b/llvm-build/MakeLiblzma index b78b86f3496b..4f4ceff1e6c3 100644 --- a/llvm-build/MakeLiblzma +++ b/llvm-build/MakeLiblzma @@ -17,6 +17,7 @@ TARGET_TRIPLE := CC := SRCS := 7zAlloc.c 7zArcIn.c 7zBuf2.c 7zBuf.c 7zCrc.c 7zCrcOpt.c 7zDec.c 7zFile.c 7zStream.c Aes.c AesOpt.c Alloc.c Bcj2.c Bra86.c Bra.c BraIA64.c CpuArch.c Delta.c LzFind.c Lzma2Dec.c Lzma2Enc.c Lzma86Dec.c Lzma86Enc.c LzmaDec.c LzmaEnc.c LzmaLib.c Ppmd7.c Ppmd7Dec.c Ppmd7Enc.c Sha256.c Sha256Opt.c Sort.c Xz.c XzCrc64.c XzCrc64Opt.c XzDec.c XzEnc.c XzIn.c SRC_PREFIX := +LIB_VERSION := ifeq ($(TARGET_TRIPLE),linux-x86_64) CFLAGS := --target=x86_64-unknown-linux-gnu -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC @@ -31,9 +32,9 @@ TARGET_A := liblzma.dll.a else ifeq ($(findstring darwin,$(TARGET_TRIPLE)),darwin) SDKROOT := $(shell xcrun --sdk macosx --show-sdk-path) -CFLAGS := -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -LDFLAGS := -dynamiclib -fuse-ld=lld -Wl,-syslibroot,$(SDKROOT) -install_name @rpath/liblzma.dylib -TARGET := liblzma.dylib +CFLAGS := -D_7ZIP_ST -Wall -Werror -Wno-empty-body -Wno-enum-conversion -Wno-logical-op-parentheses -Wno-self-assign -fPIC -current_version $(LIB_VERSION) -compatibility_version $(LIB_VERSION) +LDFLAGS := -dynamiclib -fuse-ld=lld -Wl,-syslibroot,$(SDKROOT) -install_name @rpath/liblzma.$(LIB_VERSION).dylib +TARGET := liblzma.$(LIB_VERSION).dylib else $(warning *** warning: TARGET_TRIPLE $(TARGET_TRIPLE) has not been set in rights) endif diff --git a/llvm-build/build.py b/llvm-build/build.py index 92b11a801b6b..b06e504e073f 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -89,6 +89,7 @@ class BuildConfig(): self.ARCHIVE_EXTENSION = '.tar.' + self.compression_format self.ARCHIVE_OPTION = '-c' + ('j' if self.compression_format == "bz2" else 'z') self.LIBXML2_VERSION = None + self.LZMA_VERSION = '22.0' logging.basicConfig(level=logging.INFO) self.host_projects = args.host_build_projects @@ -672,7 +673,7 @@ class LlvmCore(BuildUtils): llvm_defines['PANEL_LIBRARIES'] = ncurses_libs if self.build_config.enable_lzma_7zip: - llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', self.use_platform(), 'liblzma.dylib') + llvm_defines['LIBLZMA_LIBRARIES'] = self.merge_out_path('lzma', 'lib', self.use_platform(), f'liblzma.{self.build_config.LZMA_VERSION}.dylib') if self.build_config.build_libedit: llvm_defines['LibEdit_LIBRARIES'] = os.path.join(self.get_prebuilts_dir('libedit'), 'lib', 'libedit.0.dylib') @@ -1785,13 +1786,14 @@ class LlvmLibs(BuildUtils): 'SRC_PREFIX=%s/' % src_dir, 'TARGET_TRIPLE=%s' % target_triple, 'INSTALL_DIR=%s' % liblzma_build_path, + 'LIB_VERSION=%s' % self.build_config.LZMA_VERSION, '-f', 'MakeLiblzma'] os.chdir(self.build_config.LLVM_BUILD_DIR) self.check_call(cmd) if self.host_is_darwin(): - shlib_ext = '.dylib' + shlib_ext = f'.{self.build_config.LZMA_VERSION}.dylib' if self.host_is_linux(): shlib_ext = '.so' lzma_file = os.path.join(liblzma_build_path, 'lib', target_triple, 'liblzma' + shlib_ext) -- Gitee From d9b5038a3364464b7541836b20e9a675ba8dcd5f Mon Sep 17 00:00:00 2001 From: A_Wei Date: Mon, 22 Apr 2024 17:43:19 +0800 Subject: [PATCH 3/8] =?UTF-8?q?[LLDB]=20Fix=20getting=20Aggregate=20class?= =?UTF-8?q?=20return=20value=20Description:=20After=20thread=20step-out,?= =?UTF-8?q?=20return=20value=20cannot=20be=20displayed=20by=20calling=20th?= =?UTF-8?q?read=20info.=20Issue=EF=BC=9Ahttps://gitee.com/openharmony/thir?= =?UTF-8?q?d=5Fparty=5Fllvm-project/issues/I9IPL0=3Ffrom=3Dproject-issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: A_Wei Change-Id: edfd55211d1e1620cc3479a38555bd52339289b0 --- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp index 2896f5920db9..3e87fd196e01 100644 --- a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -471,7 +471,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( llvm::Optional byte_size = value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); - if (byte_size || *byte_size == 0) + if (!byte_size || *byte_size == 0) // OHOS_LOCAL return false; std::unique_ptr heap_data_up( -- Gitee From 7697558d5035f9456065e7824992d8afc6ff2f4d Mon Sep 17 00:00:00 2001 From: Lyupa Anastasia Date: Thu, 18 Apr 2024 12:40:31 +0300 Subject: [PATCH 4/8] [ASan][OHOS] Update tests for OHOS - Enable check-asan-dynamic for OHOS. - Add CHECK-OHOS prefix to large_func_test.cpp and use-after-delete.cpp tests. - Make init_fini_sections.cpp test unsupported because .preinit_array is not supported in musl. - Make global-overflow-bfd.cpp test unsupported because BFD linker does not support such emulation modes. - Make shmctl.cpp xfail because shmget() fails on OHOS. - Change file name for opening in readv.cpp test because /etc/hosts does not exist on OHOS. - Exclude wait4.cpp from XFAIL because it fails only on android. - Not add abort_on_error=0 option if abort_on_error is already present to fix handle_abort_on_error.cpp test because there is abort_on_error=1 in run command. - Add timeout to hdc call. - Make timed out tests xfail (rlimit_mmap_test.cpp, mmap_limit_mb.cpp). Issue: https://gitee.com/openharmony/third_party_llvm-project/issues/I9HWDV Signed-off-by: Lyupa Anastasia --- .../test/asan/TestCases/Linux/global-overflow-bfd.cpp | 3 +++ .../test/asan/TestCases/Linux/init_fini_sections.cpp | 3 +++ .../test/asan/TestCases/Linux/rlimit_mmap_test.cpp | 5 +++++ compiler-rt/test/asan/TestCases/Linux/shmctl.cpp | 2 +- compiler-rt/test/asan/TestCases/Posix/mmap_limit_mb.cpp | 4 ++++ compiler-rt/test/asan/TestCases/Posix/readv.cpp | 6 ++++++ compiler-rt/test/asan/TestCases/Posix/wait4.cpp | 2 +- compiler-rt/test/asan/TestCases/large_func_test.cpp | 6 +++++- compiler-rt/test/asan/TestCases/use-after-delete.cpp | 8 ++++++-- compiler-rt/test/asan/lit.cfg.py | 2 +- .../sanitizer_common/ohos_family_commands/ohos_common.py | 2 +- .../sanitizer_common/ohos_family_commands/ohos_run.py | 7 +++++-- 12 files changed, 41 insertions(+), 9 deletions(-) diff --git a/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp b/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp index 117a761af91f..4dadd579ff3a 100644 --- a/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp @@ -1,6 +1,9 @@ // Test that gc-sections-friendly instrumentation of globals does not introduce // false negatives with the BFD linker. // RUN: %clangxx_asan -fuse-ld=bfd -Wl,-gc-sections -ffunction-sections -fdata-sections -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// +// OHOS_LOCAL +// UNSUPPORTED: ohos_family #include int main(int argc, char **argv) { diff --git a/compiler-rt/test/asan/TestCases/Linux/init_fini_sections.cpp b/compiler-rt/test/asan/TestCases/Linux/init_fini_sections.cpp index 3037b232926e..7cfc708aebc2 100644 --- a/compiler-rt/test/asan/TestCases/Linux/init_fini_sections.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/init_fini_sections.cpp @@ -1,4 +1,7 @@ // RUN: %clangxx_asan %s -o %t && %run %t | FileCheck %s +// +// OHOS_LOCAL +// UNSUPPORTED: ohos_family #include diff --git a/compiler-rt/test/asan/TestCases/Linux/rlimit_mmap_test.cpp b/compiler-rt/test/asan/TestCases/Linux/rlimit_mmap_test.cpp index 7f37727b2eeb..4905e1516224 100644 --- a/compiler-rt/test/asan/TestCases/Linux/rlimit_mmap_test.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/rlimit_mmap_test.cpp @@ -1,5 +1,10 @@ // Check that we properly report mmap failure. // RUN: %clangxx_asan %s -o %t && not %run %t 2>&1 | FileCheck %s +// +// OHOS_LOCAL +// FIXME: timed out test +// XFAIL: ohos_family + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp index 8fed52092be8..eec592c8fbee 100644 --- a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp @@ -1,5 +1,5 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// XFAIL: android && !ohos_family +// XFAIL: android // // RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 // Regression test for diff --git a/compiler-rt/test/asan/TestCases/Posix/mmap_limit_mb.cpp b/compiler-rt/test/asan/TestCases/Posix/mmap_limit_mb.cpp index cb613f53577a..d34e8db9e3e7 100644 --- a/compiler-rt/test/asan/TestCases/Posix/mmap_limit_mb.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/mmap_limit_mb.cpp @@ -10,6 +10,10 @@ // // FIXME: Windows doesn't implement mmap_limit_mb. // XFAIL: windows-msvc +// +// OHOS_LOCAL +// FIXME: timed out test +// XFAIL: ohos_family #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/readv.cpp b/compiler-rt/test/asan/TestCases/Posix/readv.cpp index 27436a1ad3d9..79a4c9cefb0c 100644 --- a/compiler-rt/test/asan/TestCases/Posix/readv.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/readv.cpp @@ -23,7 +23,13 @@ int main() { iov[0].iov_len = 5; iov[1].iov_base = buf + 10; iov[1].iov_len = 2000; +// OHOS_LOCAL begin +#if defined(__OHOS__) + int fd = open("/etc/resolv.conf", O_RDONLY); +#else int fd = open("/etc/hosts", O_RDONLY); +#endif +// OHOS_LOCAL end assert(fd > 0); readv(fd, iov, 2); // CHECK: WRITE of size 5 at diff --git a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp index 1e574d99fe00..a806a0c7badf 100644 --- a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp @@ -4,7 +4,7 @@ // RUN: %clangxx_asan -DWAIT4_RUSAGE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -DWAIT4_RUSAGE -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s -// XFAIL: android +// XFAIL: android && !ohos_family // UNSUPPORTED: darwin #include diff --git a/compiler-rt/test/asan/TestCases/large_func_test.cpp b/compiler-rt/test/asan/TestCases/large_func_test.cpp index 563c1458c966..3a4181e618ba 100644 --- a/compiler-rt/test/asan/TestCases/large_func_test.cpp +++ b/compiler-rt/test/asan/TestCases/large_func_test.cpp @@ -29,6 +29,8 @@ static void LargeFunction(int *x, int zero) { // CHECK-Windows:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-5]] // CHECK-FreeBSD:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-6]] // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-7]] + // OHOS_LOCAL + // CHECK-OHOS: {{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-9]] x[10]++; x[11]++; @@ -53,7 +55,9 @@ int main(int argc, char **argv) { // CHECK-Windows:{{ #0 0x.* in operator new}} // CHECK-FreeBSD:{{ #0 0x.* in operator new}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK-NEXT: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-10]] + // OHOS_LOCAL + // CHECK-OHOS: {{ #0 0x.* in operator new}} + // CHECK-NEXT: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-12]] int y = x[argc]; delete[] x; return y; diff --git a/compiler-rt/test/asan/TestCases/use-after-delete.cpp b/compiler-rt/test/asan/TestCases/use-after-delete.cpp index 4d0c055368bb..f06048de064f 100644 --- a/compiler-rt/test/asan/TestCases/use-after-delete.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-delete.cpp @@ -21,7 +21,9 @@ int main() { // CHECK-Windows:{{ #0 0x.* in operator delete\[\]}} // CHECK-FreeBSD:{{ #0 0x.* in operator delete\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zda}} - // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-14]] + // OHOS_LOCAL + // CHECK-OHOS: {{ #0 0x.* in operator delete\[\]}} + // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-16]] // CHECK: {{previously allocated by thread T0 here:}} // CHECK-Linux: {{ #0 0x.* in operator new\[\]}} @@ -29,7 +31,9 @@ int main() { // CHECK-Windows:{{ #0 0x.* in operator new\[\]}} // CHECK-FreeBSD:{{ #0 0x.* in operator new\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-23]] + // OHOS_LOCAL + // CHECK-OHOS: {{ #0 0x.* in operator new\[\]}} + // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-27]] // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes): diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py index cbe84170c61e..3fb929e3b16a 100644 --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -131,7 +131,7 @@ config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) ) config.substitutions.append( ("%clang_asan ", build_invocation(clang_asan_cflags)) ) config.substitutions.append( ("%clangxx_asan ", build_invocation(clang_asan_cxxflags)) ) if config.asan_dynamic: - if config.host_os in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']: + if config.host_os in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS', 'OHOS']: # OHOS_LOCAL shared_libasan_path = os.path.join(config.compiler_rt_libdir, "libclang_rt.asan{}.so".format(config.target_suffix)) elif config.host_os == 'Darwin': shared_libasan_path = os.path.join(config.compiler_rt_libdir, 'libclang_rt.asan_{}_dynamic.dylib'.format(config.apple_platform)) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py index b84161f8b99c..dbe446a68483 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py @@ -14,7 +14,7 @@ def host_to_device_path(path): def hdc_output(args): command = hdc_constants.get_hdc_cmd_prefix() + args - return subprocess.check_output(command, stderr=subprocess.STDOUT) + return subprocess.check_output(command, stderr=subprocess.STDOUT, timeout=300) def hdc(args, attempts=1, check_stdout=''): if verbose: diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py index 1bdd8ea33771..a6e7596d2178 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py @@ -26,12 +26,15 @@ def build_env(): sanitizers = ( 'HWASAN', 'ASAN', 'LSAN', 'MEMPROF', 'MSAN', 'TSAN', 'UBSAN', 'SCUDO' ) + set_abort_on_error=True for san in sanitizers: - # for all sanitizers we need 'abort_on_error=0', + # for all sanitizers we need 'abort_on_error=0' if 'abort_on_error=1' is not set, # so prepare key for them, to set value later opt_str = '%s_OPTIONS' % san if opt_str not in os.environ: os.environ[opt_str] = '' + elif 'abort_on_error=1' in os.environ[opt_str]: + set_abort_on_error=False # All sanitizers need external symbolizers for some tests # set them by default to llvm-symbolizer @@ -42,7 +45,7 @@ def build_env(): args.append('LD_LIBRARY_PATH=%s' % ( hdc_constants.TMPDIR,)) for (key, value) in os.environ.items(): san_opt = key.endswith('SAN_OPTIONS') - if san_opt: + if san_opt and set_abort_on_error: 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']: -- Gitee From 8dc3460631cfb196bcbdb74890105c1fa164a3e1 Mon Sep 17 00:00:00 2001 From: yinchuang Date: Wed, 27 Mar 2024 17:35:38 +0800 Subject: [PATCH 5/8] [Sanitizer] Support ignore_noninstrumented_modules on Linux Pick from https://reviews.llvm.org/D61708 Issue:I9EKYB Signed-off-by: yinchuang --- .../lib/sanitizer_common/sanitizer_common.cpp | 11 ++ .../lib/sanitizer_common/sanitizer_common.h | 6 + .../sanitizer_linux_libcdep.cpp | 136 ++++++++++++++++++ .../test/tsan/ignore-noninstrumented.cpp | 86 +++++++++++ 4 files changed, 239 insertions(+) create mode 100644 compiler-rt/test/tsan/ignore-noninstrumented.cpp diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp index 82236453157f..1fc4a677a10c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -134,11 +134,22 @@ void RemoveANSIEscapeSequencesFromString(char *str) { *z = '\0'; } +#if SANITIZER_OHOS +// OHOS_LOCAL begin +void LoadedModule::set(const char *module_name, uptr base_address, bool instrumented) { + clear(); + full_name_ = internal_strdup(module_name); + base_address_ = base_address; + instrumented_ = instrumented; +} +#else void LoadedModule::set(const char *module_name, uptr base_address) { clear(); full_name_ = internal_strdup(module_name); base_address_ = base_address; } +// OHOS_LOCAL end +#endif void LoadedModule::set(const char *module_name, uptr base_address, ModuleArch arch, u8 uuid[kModuleUUIDSize], diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index c4153201a1a0..787687db26d0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -807,7 +807,13 @@ class LoadedModule { internal_memset(uuid_, 0, kModuleUUIDSize); ranges_.clear(); } +#if SANITIZER_OHOS +// OHOS_LOCAL begin + void set(const char *module_name, uptr base_address, bool instrumented = false); +#else void set(const char *module_name, uptr base_address); +// OHOS_LOCAL end +#endif void set(const char *module_name, uptr base_address, ModuleArch arch, u8 uuid[kModuleUUIDSize], bool instrumented); void setUuid(const char *uuid, uptr size); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 785c399d0238..4f330ffa10b0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -645,12 +645,148 @@ struct DlIteratePhdrData { bool first; }; +#if SANITIZER_OHOS +// OHOS_LOCAL begin +class DynamicSegment { + ElfW(Addr) base_addr; + size_t symbol_count; + ElfW(Sym *) symbol_table; + const char *string_table; + + public: + DynamicSegment(ElfW(Addr) base_addr, ElfW(Addr) segment_addr) + : base_addr(base_addr), + symbol_count(0), + symbol_table(nullptr), + string_table(nullptr) { + initialize(segment_addr); + CHECK(symbol_count >= 0 && symbol_table && string_table); // OHOS_LOCAL + } + + size_t symbolCount() const { return symbol_count; } + + const char *getSymbolName(size_t index) const { + auto str_index = symbol_table[index].st_name; + return &string_table[str_index]; + } + + private: + // Elf_Addr -> dereferenceable pointer + template + Type *toPtr(ElfW(Addr) addr_or_offset) const { + bool offset = addr_or_offset < base_addr; + ElfW(Addr) ptr = offset ? (base_addr + addr_or_offset) : addr_or_offset; + return reinterpret_cast(ptr); + } + + void initialize(ElfW(Addr) segment_addr) { + auto *entry = toPtr(segment_addr); + for (; entry->d_tag != DT_NULL; entry++) { + auto addr = entry->d_un.d_ptr; + switch (entry->d_tag) { + case DT_HASH: + symbol_count = getSymbolCountFromHash(addr); + break; + case DT_GNU_HASH: + // DT_HASH takes precedence over DT_GNU_HASH + if (symbol_count > 0) + break; + symbol_count = getSymbolCountFromGnuHash(addr); + break; + case DT_SYMTAB: + CHECK_EQ(symbol_table, nullptr); + symbol_table = toPtr(addr); + break; + case DT_STRTAB: + CHECK_EQ(string_table, nullptr); + string_table = toPtr(addr); + break; + } + } + } + + size_t getSymbolCountFromHash(ElfW(Addr) hashtable_addr) const { + struct ht_header { + uint32_t bucket_count; + uint32_t chain_count; + }; + return toPtr(hashtable_addr)->chain_count; + } + + size_t getSymbolCountFromGnuHash(ElfW(Addr) hashtable_addr) const { + struct ht_header { + uint32_t bucket_count; + uint32_t symoffset; + uint32_t bloom_size; + uint32_t bloom_shift; + }; + auto header = toPtr(hashtable_addr); + auto word_size = FIRST_32_SECOND_64(sizeof(uint32_t), sizeof(uint64_t)); + auto buckets_addr = + hashtable_addr + sizeof(ht_header) + (word_size * header->bloom_size); + auto buckets = toPtr(buckets_addr); + auto chains_addr = + buckets_addr + (header->bucket_count * sizeof(buckets[0])); + auto chains = toPtr(chains_addr); + + // Locate the chain that handles the largest index bucket. + uint32_t last_symbol = 0; + for (uint32_t i = 0; i < header->bucket_count; i++) { + last_symbol = Max(buckets[i], last_symbol); + } + + // OHOS_LOCAL + if (!last_symbol) { + return 0; + } + + // Walk the bucket's chain to add the chain length to the total. + uint32_t chain_entry; + do { + chain_entry = chains[last_symbol - header->symoffset]; + last_symbol++; + } while ((chain_entry & 1) == 0); + + return last_symbol; + } +}; + +static bool IsModuleInstrumented(dl_phdr_info *info) { + // Iterate all headers of the library. + for (size_t header = 0; header < info->dlpi_phnum; header++) { + // We are only interested in dynamic segments. + if (info->dlpi_phdr[header].p_type != PT_DYNAMIC) + continue; + + auto base_addr = info->dlpi_addr; + auto segment_addr = info->dlpi_phdr[header].p_vaddr; + DynamicSegment segment(base_addr, segment_addr); + + // Iterate symbol table. + for (size_t i = 0; i < segment.symbolCount(); i++) { + auto *name = segment.getSymbolName(i); + if (internal_strcmp(name, "__tsan_init") == 0) + return true; + } + } + return false; +} +// OHOS_LOCAL end +#endif + static int AddModuleSegments(const char *module_name, dl_phdr_info *info, InternalMmapVectorNoCtor *modules) { if (module_name[0] == '\0') return 0; LoadedModule cur_module; +#if SANITIZER_OHOS +// OHOS_LOCAL begin + bool instrumented = IsModuleInstrumented(info); + cur_module.set(module_name, info->dlpi_addr, instrumented); +#else cur_module.set(module_name, info->dlpi_addr); +// OHOS_LOCAL end +#endif for (int i = 0; i < (int)info->dlpi_phnum; i++) { const Elf_Phdr *phdr = &info->dlpi_phdr[i]; if (phdr->p_type == PT_LOAD) { diff --git a/compiler-rt/test/tsan/ignore-noninstrumented.cpp b/compiler-rt/test/tsan/ignore-noninstrumented.cpp new file mode 100644 index 000000000000..6129d7c39006 --- /dev/null +++ b/compiler-rt/test/tsan/ignore-noninstrumented.cpp @@ -0,0 +1,86 @@ +// Check that ignore_noninstrumented_modules=1 suppresses reports originating +// from interceptors that are called from an un-instrumented library. + +// RUN: rm -rf %t-dir +// RUN: mkdir %t-dir + +// RUN: %clangxx_tsan %s -fPIC -shared -DLIBRARY -fno-sanitize=thread -o %t-dir/libignore_noninstrumented.so +// RUN: %clangxx_tsan %s -L%t-dir -lignore_noninstrumented -o %t + +// Check that without the flag, there are false positives. +// RUN: env LD_LIBRARY_PATH=%t-dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE + +// With ignore_noninstrumented_modules=1, no races are reported. +// RUN: env LD_LIBRARY_PATH=%t-dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=ignore_noninstrumented_modules=1 %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer' + +// With ignore_noninstrumented_modules=1, races in user's code are still reported. +// RUN: env LD_LIBRARY_PATH=%t-dir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} %env_tsan_opts=ignore_noninstrumented_modules=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK-RACE + +// REQUIRES: ohos_family + +#include "test.h" + +#include + +#ifdef LIBRARY +namespace library { +#endif +char global_buf[64]; + +void *Thread1(void *arg) { + auto barrier_wait = (void (*)())arg; + barrier_wait(); + strcpy(global_buf, "hello world"); // NOLINT + return NULL; +} + +void *Thread2(void *arg) { + auto barrier_wait = (void (*)())arg; + strcpy(global_buf, "world hello"); // NOLINT + barrier_wait(); + return NULL; +} + +void Race(void (*barrier_wait)()) { + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread1, (void *)barrier_wait); + pthread_create(&t[1], NULL, Thread2, (void *)barrier_wait); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); +} +#ifdef LIBRARY +} // namespace library +#endif + +#ifndef LIBRARY +namespace library { + void Race(void (*barrier_wait)()); +} + +// Pass pointer to this function to un-instrumented library, so it can access +// TSan-invisible barriers. +void my_barrier_wait() { + barrier_wait(&barrier); +} + +int main(int argc, char *argv[]) { + fprintf(stderr, "Hello world.\n"); + + // Race in un-instrumented library + barrier_init(&barrier, 2); + library::Race(my_barrier_wait); + + // Race in user code, if requested + if (argc > 1 && strcmp(argv[1], "race") == 0) { + barrier_init(&barrier, 2); + Race(my_barrier_wait); + } + + fprintf(stderr, "Done.\n"); +} + +#endif // LIBRARY + +// CHECK: Hello world. +// CHECK-RACE: SUMMARY: ThreadSanitizer: data race +// CHECK: Done. \ No newline at end of file -- Gitee From a5463ea799c460a3a2bf8a5357fef8b5b5fcb110 Mon Sep 17 00:00:00 2001 From: ydx Date: Thu, 25 Apr 2024 08:50:33 +0000 Subject: [PATCH 6/8] !462 [BUILD] Support Windows LLDB debug build * update llvm-build/build.py. * [Build] windows debug build --- llvm-build/build.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm-build/build.py b/llvm-build/build.py index b06e504e073f..6112f4f3359c 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -881,7 +881,7 @@ class LlvmCore(BuildUtils): windows_defines['CMAKE_C_COMPILER'] = cc windows_defines['CMAKE_CXX_COMPILER'] = cxx windows_defines['CMAKE_SYSTEM_NAME'] = 'Windows' - windows_defines['CMAKE_BUILD_TYPE'] = 'Release' + windows_defines['CMAKE_BUILD_TYPE'] = 'Debug' if self.build_config.debug else 'Release' windows_defines['LLVM_BUILD_RUNTIME'] = 'OFF' windows_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON' windows_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF' @@ -928,9 +928,11 @@ class LlvmCore(BuildUtils): ) ldflag = ['-fuse-ld=lld', + '-Wl,--gc-sections', '-stdlib=libc++', '--rtlib=compiler-rt', - '-lunwind', '-Wl,--dynamicbase', + '-lunwind', + '-Wl,--dynamicbase', '-Wl,--nxcompat', '-lucrt', '-lucrtbase', @@ -941,6 +943,7 @@ class LlvmCore(BuildUtils): cflag = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', + '-fdata-sections', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', @@ -1718,7 +1721,7 @@ class LlvmLibs(BuildUtils): cmake_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) - cmake_defines['CMAKE_BUILD_TYPE'] = 'Release' + cmake_defines['CMAKE_BUILD_TYPE'] = 'Debug' if self.build_config.target_debug else 'Release' cmake_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') -- Gitee From 70e4f1e2e7727227976d08636dd00db1b5b8b4e1 Mon Sep 17 00:00:00 2001 From: A_Wei Date: Sat, 27 Apr 2024 17:37:31 +0800 Subject: [PATCH 7/8] =?UTF-8?q?[LLDB]=20Fix=20hdc=20connect=20emulator=20D?= =?UTF-8?q?escription:=20Port=20forwarding=20judgment=20lacks=20conditions?= =?UTF-8?q?=20Issue=EF=BC=9Ahttps://gitee.com/openharmony/third=5Fparty=5F?= =?UTF-8?q?llvm-project/issues/I9JM9A=3Ffrom=3Dproject-issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: A_Wei Change-Id: ed20b1ba41a27eb381240e0c727c35892520aae9 --- .../Plugins/Platform/OHOS/HdcClient.cpp | 2 +- .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 41 ++++++++++++------- .../OHOS/PlatformOHOSRemoteGDBServer.h | 2 + 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp index bcac55f04b7d..26742b8c80eb 100644 --- a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -143,7 +143,7 @@ void HdcClient::SetDeviceID(const std::string &device_id) { const std::string &HdcClient::GetDeviceID() const { return m_device_id; } bool HdcClient::IsServerLocal() { - return m_connect_addr == "localhost"; + return m_connect_addr == "localhost" || m_connect_addr == "127.0.0.1"; } namespace { diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp index 0a6a7b208f40..8f3f54a58472 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -11,6 +11,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UriParser.h" +#include "llvm/Support/Regex.h" #include "PlatformOHOSRemoteGDBServer.h" @@ -40,20 +41,20 @@ static Status ForwardPortWithHdc( device_id = hdc.GetDeviceID(); LLDB_LOGF(log, "Connected to OHOS device \"%s\"", device_id.c_str()); - if (remote_port != 0) { - LLDB_LOGF(log, "Forwarding remote TCP port %d to local TCP port %d", - remote_port, local_port); - return hdc.SetPortForwarding(local_port, remote_port); + if (socket_namespace) { + LLDB_LOGF(log, "Forwarding remote socket \"%s\" to local TCP port %d", + remote_socket_name.str().c_str(), local_port); + return hdc.SetPortForwarding(local_port, remote_socket_name, + *socket_namespace); } - LLDB_LOGF(log, "Forwarding remote socket \"%s\" to local TCP port %d", - remote_socket_name.str().c_str(), local_port); + LLDB_LOGF(log, "Forwarding remote TCP port %d to local TCP port %d", + remote_port, local_port); - if (!socket_namespace) - return Status("Invalid socket namespace"); - - return hdc.SetPortForwarding(local_port, remote_socket_name, - *socket_namespace); + if (remote_port == 0) + return Status("Invalid remote_port"); + + return hdc.SetPortForwarding(local_port, remote_port); } static Status DeleteForwardPortWithHdc(const std::string &connect_addr, @@ -138,9 +139,21 @@ bool PlatformOHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { return m_gdb_client_up->KillSpawnedProcess(pid); } +bool IsValidIPv4(llvm::StringRef ip) { + std::string pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; + llvm::Regex regex(pattern); + return regex.match(ip); +} + +bool IsValidIPv6(llvm::StringRef ip) { + std::string pattern = "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"; + llvm::Regex regex(pattern); + return regex.match(ip); +} + bool PlatformOHOSRemoteGDBServer::IsHostnameDeviceID(llvm::StringRef hostname) { - return hostname != "localhost" && !hostname.contains(':') && - !hostname.contains('.'); + return hostname != "localhost" && !IsValidIPv4(hostname) && + !IsValidIPv6(hostname); } Status PlatformOHOSRemoteGDBServer::ConnectRemote(Args &args) { @@ -249,7 +262,7 @@ Status PlatformOHOSRemoteGDBServer::MakeConnectURL( ForwardPortWithHdc(m_connect_addr, local_port, remote_port, remote_socket_name, m_socket_namespace, m_device_id); if (error.Success()) { - if (remote_port != 0){ + if (!m_socket_namespace){ m_port_forwards[pid] = {local_port, remote_port}; } else{ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h index cb130574d3f6..a4ba2e16d3ed 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -38,6 +38,8 @@ public: lldb_private::Target *target, lldb_private::Status &error) override; + // When 'hostname' is not ipv4, ipv6 or localhost, the function will return true. + // such as IsHostnameDeviceID("127.0.0.1:8080") return true. static bool IsHostnameDeviceID(llvm::StringRef hostname); protected: -- Gitee From c2084a9fb216832d5fdfa388cd1b43b39a8d7731 Mon Sep 17 00:00:00 2001 From: yinchuang Date: Fri, 29 Mar 2024 10:25:04 +0800 Subject: [PATCH 8/8] =?UTF-8?q?[Sanitizer]=20Enable=20ignore=5Fnoninstrume?= =?UTF-8?q?nted=5Fmodules=20on=20Ohos=20=20=201=E3=80=81Libignore=20suppor?= =?UTF-8?q?ts=20the=20identification=20of=20unloaded=20libs=20=20=202?= =?UTF-8?q?=E3=80=81Enable=20hook=20dlopen=5Fimpl=20Signed-off-by:=20yinch?= =?UTF-8?q?uang=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler-rt/cmake/config-ix.cmake | 6 + compiler-rt/lib/asan/asan_interceptors.cpp | 12 + .../sanitizer_common_interceptors.inc | 36 ++- .../sanitizer_common/sanitizer_libignore.cpp | 94 +++++++- .../sanitizer_common/sanitizer_libignore.h | 71 +++++- .../lib/sanitizer_common/sanitizer_linux.cpp | 50 ++++ .../sanitizer_platform_interceptors.h | 5 +- compiler-rt/lib/tsan/rtl/CMakeLists.txt | 17 +- compiler-rt/lib/tsan/rtl/tsan_flags.inc | 6 +- .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 15 +- .../lib/tsan/rtl/tsan_platform_posix.cpp | 3 + compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | 25 +- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 8 + compiler-rt/test/tsan/dlopen_ns.cpp | 93 ++++++++ .../test/tsan/force_background_thread.cpp | 8 +- compiler-rt/test/tsan/getline_nohang.cpp | 4 + compiler-rt/test/tsan/ignore_dlclose.cpp | 223 ++++++++++++++++++ compiler-rt/test/tsan/ignore_lib1.cpp | 4 - compiler-rt/test/tsan/ignore_lib2.cpp | 4 - compiler-rt/test/tsan/ignore_lib3.cpp | 2 +- compiler-rt/test/tsan/ignore_lib4.cpp | 4 - compiler-rt/test/tsan/ignore_lib5.cpp | 4 - compiler-rt/test/tsan/lit.cfg.py | 3 + 23 files changed, 660 insertions(+), 37 deletions(-) create mode 100644 compiler-rt/test/tsan/dlopen_ns.cpp create mode 100644 compiler-rt/test/tsan/ignore_dlclose.cpp diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 3c6fe62e1aaf..565ea795ac0e 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -205,6 +205,12 @@ if(ANDROID) check_library_exists(log __android_log_write "" COMPILER_RT_HAS_LIBLOG) endif() +#OHOS_LOCAL begin +if(OHOS) + llvm_check_compiler_linker_flag(CXX "-Wl,-z,global" COMPILER_RT_HAS_Z_GLOBAL) +endif() +#OHOS_LOCAL end + # Architectures. # List of all architectures we can target. diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 817008253fc0..0a1a4a5535df 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -137,6 +137,18 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) CheckNoDeepBind(filename, flag); \ REAL(dlopen)(filename, flag); \ }) +// OHOS_LOCAL begin +#if SANITIZER_OHOS +#define COMMON_INTERCEPTOR_DLOPEN_IMPL(filename, flag, namespace, caller_addr, \ + extinfo) \ + ({ \ + if (flags()->strict_init_order) \ + StopInitOrderChecking(); \ + CheckNoDeepBind(filename, flag); \ + REAL(dlopen_impl)(filename, flag, namespace, caller_addr, extinfo); \ + }) +#endif +// OHOS_LOCAL end # define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() # define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) # define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index c489cb2979f1..32a9e88f6711 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -281,6 +281,15 @@ extern const short *_tolower_tab_; ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); }) #endif +#if SANITIZER_OHOS +// OHOS_LOCAL begin +#ifndef COMMON_INTERCEPTOR_DLOPEN_IMPL +#define COMMON_INTERCEPTOR_DLOPEN_IMPL(filename, flag, namespace, caller_addr, extinfo) \ + ({ CheckNoDeepBind(filename, flag); REAL(dlopen_impl)(filename, flag, namespace, caller_addr, extinfo); }) +#endif +// OHOS_LOCAL end +#endif + #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0; #endif @@ -6534,6 +6543,24 @@ INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) { #endif #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE +// OHOS_LOCAL begin +#if SANITIZER_OHOS +INTERCEPTOR(void*, dlopen_impl, const char *filename, int flag, const char *ns, const void *caller_addr, + const void *extinfo) { + void *ctx; + COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen_impl, filename, flag, ns, caller_addr, extinfo); + if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); + void *res = COMMON_INTERCEPTOR_DLOPEN_IMPL(filename, flag, ns, caller_addr, extinfo); + Symbolizer::GetOrInit()->InvalidateModuleList(); + COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); + return res; +} + +#define INIT_DLOPEN_DLCLOSE \ + COMMON_INTERCEPT_FUNCTION(dlopen_impl); \ + COMMON_INTERCEPT_FUNCTION(dlclose); + +#else INTERCEPTOR(void*, dlopen, const char *filename, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); @@ -6544,6 +6571,12 @@ INTERCEPTOR(void*, dlopen, const char *filename, int flag) { return res; } +#define INIT_DLOPEN_DLCLOSE \ + COMMON_INTERCEPT_FUNCTION(dlopen); \ + COMMON_INTERCEPT_FUNCTION(dlclose); +#endif +// OHOS_LOCAL end + INTERCEPTOR(int, dlclose, void *handle) { void *ctx; COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); @@ -6552,9 +6585,6 @@ INTERCEPTOR(int, dlclose, void *handle) { COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); return res; } -#define INIT_DLOPEN_DLCLOSE \ - COMMON_INTERCEPT_FUNCTION(dlopen); \ - COMMON_INTERCEPT_FUNCTION(dlclose); #else #define INIT_DLOPEN_DLCLOSE #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp index b7fc9444cc66..36294dbcc6ae 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp @@ -28,11 +28,15 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) { kMaxLibs); Die(); } + VPrintf(2, "[Ignore] Add ignored library %s.\n", name_templ); // OHOS_LOCAL Lib *lib = &libs_[count_++]; lib->templ = internal_strdup(name_templ); lib->name = nullptr; lib->real_name = nullptr; lib->loaded = false; +#if SANITIZER_OHOS + lib->idx = 0; // OHOS_LOCAL +#endif } void LibIgnore::OnLibraryLoaded(const char *name) { @@ -70,8 +74,25 @@ void LibIgnore::OnLibraryLoaded(const char *name) { Die(); } loaded = true; - if (lib->loaded) + if (lib->loaded) { +#if SANITIZER_OHOS + // OHOS_LOCAL begin + if (ignored_code_ranges_[lib->idx].begin == range.beg) { + continue; + } + VReport(1, + "[Ignore] invalidate ignore code range 0x%zx-0x%zx from " + "library '%s' idx:0x%zx\n", + ignored_code_ranges_[lib->idx].begin, + ignored_code_ranges_[lib->idx].end, lib->name, lib->idx); + // It is possible because of dlclose. + atomic_store(&(ignored_code_ranges_[lib->idx].invalid), 1, + memory_order_release); + // OHOS_LOCAL end +#else continue; +#endif + } VReport(1, "Matched called_from_lib suppression '%s' against library" " '%s'\n", @@ -80,7 +101,16 @@ void LibIgnore::OnLibraryLoaded(const char *name) { lib->name = internal_strdup(mod.full_name()); const uptr idx = atomic_load(&ignored_ranges_count_, memory_order_relaxed); +#if SANITIZER_OHOS + lib->idx = idx; // OHOS_LOCAL +#endif CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_)); + // OHOS_LOCAL + VReport(1, + "[Ignore] Adding ignore code range 0x%zx-0x%zx from library " + "'%s' idx:0x%zx\n", + ignored_code_ranges_[idx].begin, ignored_code_ranges_[idx].end, + lib->name, lib->idx); ignored_code_ranges_[idx].begin = range.beg; ignored_code_ranges_[idx].end = range.end; atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release); @@ -88,14 +118,75 @@ void LibIgnore::OnLibraryLoaded(const char *name) { } } if (lib->loaded && !loaded) { +#if SANITIZER_OHOS + // OHOS_LOCAL begin + VReport(1, + "[Ignore] invalidate ignore code range 0x%zx-0x%zx from library " + "'%s' idx:0x%zx\n", + ignored_code_ranges_[lib->idx].begin, + ignored_code_ranges_[lib->idx].end, lib->name, lib->idx); + // Invalidate the address range when the library is unloaded. + lib->loaded = false; + atomic_store(&(ignored_code_ranges_[lib->idx].invalid), 1, + memory_order_release); + // OHOS_LOCAL end +#else Report("%s: library '%s' that was matched against called_from_lib" " suppression '%s' is unloaded\n", SanitizerToolName, lib->name, lib->templ); Die(); +#endif } } // Track instrumented ranges. +#if SANITIZER_OHOS + // OHOS_LOCAL begin + if (track_instrumented_libs_) { + for (const auto &mod : modules) { + for (const auto &range : mod.ranges()) { + if (!range.executable) + continue; + if (!mod.instrumented()) { + // Try to find if it overlap some instrumented ranges, if true, we + // should invalidate them, This is happen when we dlclose an + // instrumented module and reload an uninstrumented module. + auto InvalidateCallback = [&](uptr idx) -> void { + VReport(1, + "[Ignore] invalidate instrumented code range 0x%zx-0x%zx " + "from library '%s'\n", + instrumented_code_ranges_[idx].begin, + instrumented_code_ranges_[idx].end, mod.full_name()); + atomic_store(&(instrumented_code_ranges_[idx].invalid), 1, + memory_order_release); + }; + IterateOverlappingRanges(range.beg, range.end, InvalidateCallback); + continue; + } + // we need to check if whole range is instrumented, consider the + // following scenario: + // - instrumented module A is loaded at address[1-10] + // - instrumented module B is loaded at address[20-30] + // - unload A and B + // - instrumented module C is load at address[5-25] + // we need to make sure [10-20] will be instrumented so we should + // compare the whole range. + if (IsAddressRangeInstrumented(range.beg, range.end)) + continue; + VReport(1, "Adding instrumented range 0x%zx-0x%zx from library '%s'\n", + range.beg, range.end, mod.full_name()); + const uptr idx = + atomic_load(&instrumented_ranges_count_, memory_order_relaxed); + CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_)); + instrumented_code_ranges_[idx].begin = range.beg; + instrumented_code_ranges_[idx].end = range.end; + atomic_store(&instrumented_ranges_count_, idx + 1, + memory_order_release); + } + } + } + // OHOS_LOCAL end +#else if (track_instrumented_libs_) { for (const auto &mod : modules) { if (!mod.instrumented()) @@ -117,6 +208,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) { } } } +#endif } void LibIgnore::OnLibraryUnloaded() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h index 18e4d83ed77f..8bf9459741f2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h @@ -20,7 +20,9 @@ #include "sanitizer_common.h" #include "sanitizer_atomic.h" #include "sanitizer_mutex.h" - +#if SANITIZER_OHOS +#include "sanitizer_vector.h" // OHOS_LOCAL +#endif namespace __sanitizer { class LibIgnore { @@ -48,17 +50,32 @@ class LibIgnore { // Checks whether the provided PC belongs to an instrumented module. bool IsPcInstrumented(uptr pc) const; - private: +#if SANITIZER_OHOS + bool IsAddressRangeInstrumented(uptr beg, uptr end) const; + + // Find all instrumented ranges which is overlapped by this range. + template + void IterateOverlappingRanges(uptr beg, uptr end, + Callback &callback) const; // OHOS_LOCAL +#endif + +private: struct Lib { char *templ; char *name; char *real_name; // target of symlink bool loaded; +#if SANITIZER_OHOS + uptr idx; // OHOS_LOCAL +#endif }; struct LibCodeRange { uptr begin; uptr end; +#if SANITIZER_OHOS + atomic_uint8_t invalid; // OHOS_LOCAL +#endif }; inline bool IsInRange(uptr pc, const LibCodeRange &range) const { @@ -90,7 +107,13 @@ class LibIgnore { inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const { const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire); for (uptr i = 0; i < n; i++) { +#if SANITIZER_OHOS + if (IsInRange(pc, ignored_code_ranges_[i]) && + !atomic_load(&(ignored_code_ranges_[i].invalid), + memory_order_acquire)) { // OHOS_LOCAL +#else if (IsInRange(pc, ignored_code_ranges_[i])) { +#endif *pc_in_ignored_lib = true; return true; } @@ -104,12 +127,56 @@ inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const { inline bool LibIgnore::IsPcInstrumented(uptr pc) const { const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire); for (uptr i = 0; i < n; i++) { +#if SANITIZER_OHOS + if (IsInRange(pc, instrumented_code_ranges_[i]) && + !atomic_load(&(instrumented_code_ranges_[i].invalid), + memory_order_acquire)) // OHOS_LOCAL +#else if (IsInRange(pc, instrumented_code_ranges_[i])) +#endif + return true; + } + return false; +} +#if SANITIZER_OHOS +// OHOS_LOCAL begin +inline bool LibIgnore::IsAddressRangeInstrumented(uptr beg, uptr end) const { + const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire); + for (uptr i = 0; i < n; i++) { + if ((beg == instrumented_code_ranges_[i].begin) && + (end == instrumented_code_ranges_[i].end) && + !atomic_load(&(instrumented_code_ranges_[i].invalid), + memory_order_acquire)) // OHOS_LOCAL return true; } return false; } +inline bool IsOverlapping(uptr beg1, uptr end1, uptr beg2, uptr end2) { + if (beg1 < end2 && beg2 < end1) { + return true; + } + return false; +} + +template +void LibIgnore::IterateOverlappingRanges(uptr beg, uptr end, + Callback &callback) const { + const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire); + for (uptr i = 0; i < n; i++) { + if (IsOverlapping(beg, end, instrumented_code_ranges_[i].begin, + instrumented_code_ranges_[i].end)) { + if (!atomic_load(&(instrumented_code_ranges_[i].invalid), + memory_order_acquire)) { + callback(i); + } + } + } + return; +} +// OHOS_LOCAL end +#endif + } // namespace __sanitizer #endif // SANITIZER_LIBIGNORE_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 630def6c0a57..849019bef9bf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -11,6 +11,7 @@ // sanitizer_libc.h. //===----------------------------------------------------------------------===// +#include "sanitizer_interface_internal.h" // OHOS_LOCAL #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ @@ -2272,7 +2273,56 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +#if SANITIZER_OHOS +// OHOS_LOCAL begin +static bool ShouldCheckInterceptors() { + const char *sanitizer_names[] = {"AddressSanitizer", "ThreadSanitizer"}; + size_t count = sizeof(sanitizer_names) / sizeof(sanitizer_names[0]); + for (size_t i = 0; i < count; i++) { + if (internal_strcmp(sanitizer_names[i], SanitizerToolName) == 0) + return true; + } + return false; +} + +// We need to make sure that dlopen_impl interceptors really work. +// 1. Check sanitizer library has dlopen_impl symbol. +// 2. Check musl has dlopen_impl symbol. +// 3. Check first dlopen_impl symbol is located in sanitizer library. +static void VerifyInterceptorsWorking() { + if (!common_flags()->verify_interceptors || !ShouldCheckInterceptors()) + return; + + Dl_info info_dlopen_impl_default; + RAW_CHECK( + dladdr(dlsym(RTLD_DEFAULT, "dlopen_impl"), &info_dlopen_impl_default)); + + Dl_info info_dlopen_impl_next; + RAW_CHECK(dladdr(dlsym(RTLD_NEXT, "dlopen_impl"), &info_dlopen_impl_next)); + + Dl_info info_runtime; + RAW_CHECK(dladdr((void *)__sanitizer_report_error_summary, &info_runtime)); + + if (internal_strcmp(info_dlopen_impl_default.dli_fname, + info_runtime.dli_fname) != 0) { + Report( + "ERROR: Interceptor dlopen_impl are not working. This may be because " + "%s is " + "loaded too late (e.g. via dlopen). first dlopen_impl addr:%p file:%s " + "second dlopen_impl addr:%p file:%s.\n", + info_runtime.dli_fname, info_dlopen_impl_default.dli_saddr, + info_dlopen_impl_default.dli_fname, info_dlopen_impl_next.dli_saddr, + info_dlopen_impl_next.dli_fname); + RAW_CHECK("interceptors not installed" && 0); + } +} +// OHOS_LOCAL end +#endif + void InitializePlatformEarly() { +#if SANITIZER_OHOS && SANITIZER_INTERCEPT_DLOPEN_DLCLOSE + VerifyInterceptorsWorking(); // OHOS_LOCAL +#endif // Do nothing. } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 66ace37d4d62..81febbdca434 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -450,9 +450,8 @@ #define SANITIZER_INTERCEPT_FCLOSE SI_POSIX #ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE -// OHOS_LOCAL -#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ - (SI_FREEBSD || SI_NETBSD || (SI_LINUX_NOT_ANDROID && !SI_OHOS) || SI_MAC || SI_SOLARIS) +#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ + (SI_FREEBSD || SI_NETBSD || (SI_LINUX_NOT_ANDROID) || SI_MAC || SI_SOLARIS) #endif #define SANITIZER_INTERCEPT_GETPASS \ diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt index e71268eea1fb..af3c9a2de500 100644 --- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt +++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt @@ -11,6 +11,17 @@ set(TSAN_RTL_DYNAMIC_CFLAGS ${TSAN_RTL_CFLAGS}) list(REMOVE_ITEM TSAN_RTL_DYNAMIC_CFLAGS -fPIE) set(TSAN_DYNAMIC_LINK_LIBS ${SANITIZER_CXX_ABI_LIBRARIES} ${SANITIZER_COMMON_LINK_LIBS}) +#OHOS_LOCAL +set(TSAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) + +#OHOS_LOCAL begin +if(OHOS) +# Put tsan library in the global group so that libraries which don't depend on tsan can also find symbols from tsan. + if (COMPILER_RT_HAS_Z_GLOBAL) + list(APPEND TSAN_DYNAMIC_LINK_FLAGS -Wl,-z,global) + endif() +endif() +#OHOS_LOCAL end append_list_if(COMPILER_RT_HAS_LIBDL dl TSAN_DYNAMIC_LINK_LIBS) append_list_if(COMPILER_RT_HAS_LIBM m TSAN_DYNAMIC_LINK_LIBS) @@ -142,7 +153,8 @@ if(APPLE) RTSanitizerCommonSymbolizer RTUbsan CFLAGS ${TSAN_RTL_CFLAGS} - LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS} + #OHOS_LOCAL + LINK_FLAGS ${TSAN_DYNAMIC_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS} LINK_LIBS ${TSAN_LINK_LIBS} objc PARENT_TARGET tsan) add_compiler_rt_object_libraries(RTTsan_dynamic @@ -264,7 +276,8 @@ else() ADDITIONAL_HEADERS ${TSAN_HEADERS} CFLAGS ${TSAN_RTL_DYNAMIC_CFLAGS} LINK_LIBS ${TSAN_DYNAMIC_LINK_LIBS} - LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} + #OHOS_LOCAL + LINK_FLAGS ${TSAN_DYNAMIC_LINK_FLAGS} PARENT_TARGET tsan) add_sanitizer_rt_symbols(clang_rt.tsan ARCHS ${arch} diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.inc b/compiler-rt/lib/tsan/rtl/tsan_flags.inc index 731d776cc893..0846c2af100c 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.inc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.inc @@ -42,6 +42,9 @@ TSAN_FLAG( TSAN_FLAG(bool, force_background_thread, false, "If set, eagerly launch a background thread for memory reclamation " "instead of waiting for a user call to pthread_create.") +// OHOS_LOCAL +TSAN_FLAG(bool, disable_background_thread, SANITIZER_OHOS ? true : false, + "If set, background thread will never be started, used where multithreading is not supported") TSAN_FLAG(bool, halt_on_error, false, "Exit after first reported error.") TSAN_FLAG(int, atexit_sleep_ms, 1000, "Sleep in main thread before exiting for that many ms " @@ -72,7 +75,8 @@ TSAN_FLAG(bool, die_after_fork, true, TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") TSAN_FLAG(bool, ignore_interceptors_accesses, SANITIZER_APPLE ? true : false, "Ignore reads and writes from all interceptors.") -TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_APPLE ? true : false, +// OHOS_LOCAL +TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_APPLE || SANITIZER_OHOS ? true : false, "Interceptors should only detect races when called from instrumented " "modules.") TSAN_FLAG(bool, shared_ptr_interceptor, true, diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 825814f54d82..6b0e255f6db3 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2391,7 +2391,20 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, ThreadIgnoreEnd(thr); \ res; \ }) - +// OHOS_LOCAL begin +#if SANITIZER_OHOS +#define COMMON_INTERCEPTOR_DLOPEN_IMPL(filename, flag, namespace, caller_addr, \ + extinfo) \ + ({ \ + CheckNoDeepBind(filename, flag); \ + ThreadIgnoreBegin(thr, 0); \ + void *res = \ + REAL(dlopen_impl)(filename, flag, namespace, caller_addr, extinfo); \ + ThreadIgnoreEnd(thr); \ + res; \ + }) +#endif +// OHOS_LOCAL end #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \ libignore()->OnLibraryLoaded(filename) diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp index 71874aad8dc5..89960059d42a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_posix.cpp @@ -107,6 +107,9 @@ void CheckAndProtect() { break; Printf("FATAL: ThreadSanitizer: unexpected memory mapping 0x%zx-0x%zx\n", segment.start, segment.end); +#if SANITIZER_OHOS + DumpProcessMap(); // OHOS_LOCAL +#endif Die(); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index ff3bb33eb134..5279ebedc26f 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -456,6 +456,8 @@ static bool InitializeMemoryProfiler() { } static void *BackgroundThread(void *arg) { + VReport(1, "%s: Started BackgroundThread\n", + SanitizerToolName); // OHOS_LOCAL // This is a non-initialized non-user thread, nothing to see here. // We don't use ScopedIgnoreInterceptors, because we want ignores to be // enabled even when the thread function exits (e.g. during pthread thread @@ -503,6 +505,7 @@ static void *BackgroundThread(void *arg) { u64 last = atomic_load(&ctx->last_symbolize_time_ns, memory_order_relaxed); if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) { + VReport(1, "ThreadSanitizer: flushing symbolizer\n"); // OHOS_LOCAL Lock l(&ctx->report_mtx); ScopedErrorReportLock l2; SymbolizeFlush(); @@ -514,14 +517,28 @@ static void *BackgroundThread(void *arg) { } static void StartBackgroundThread() { - ctx->background_thread = internal_start_thread(&BackgroundThread, 0); + // OHOS_LOCAL begin + if (!flags()->disable_background_thread) { + ctx->background_thread = internal_start_thread(&BackgroundThread, 0); + } else { + // Appspawn does not allow the use of multi-threading so we don't start this + // thread. + return; + } + // OHOS_LOCAL end } #ifndef __mips__ static void StopBackgroundThread() { - atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); - internal_join_thread(ctx->background_thread); - ctx->background_thread = 0; + // OHOS_LOCAL begin + if (!flags()->disable_background_thread) { + atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); + internal_join_thread(ctx->background_thread); + ctx->background_thread = 0; + } else { + return; + } + // OHOS_LOCAL end } #endif #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 444f210390cc..706b12a841e1 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -652,6 +652,9 @@ bool OutputReport(ThreadState *thr, const ScopedReport &srep) { Lock lock(&ctx->fired_suppressions_mtx); FiredSuppression s = {srep.GetReport()->typ, pc_or_addr, supp}; ctx->fired_suppressions.push_back(s); + // OHOS_LOCAL + VPrintf(2, "[Suppression] Suppression hit type:%s file:%s pc:0x%zx.\n", + supp->type, supp->templ, pc_or_addr); } { bool suppressed = OnReport(rep, pc_or_addr != 0); @@ -679,6 +682,11 @@ bool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace) { if (trace.trace[j] == s->pc_or_addr) { if (s->supp) atomic_fetch_add(&s->supp->hit_count, 1, memory_order_relaxed); + // OHOS_LOCAL + VPrintf( + 2, + "[Suppression] Fired suppression hit type:%s file:%s pc:0x%zx.\n", + s->supp->type, s->supp->templ, s->pc_or_addr); return true; } } diff --git a/compiler-rt/test/tsan/dlopen_ns.cpp b/compiler-rt/test/tsan/dlopen_ns.cpp new file mode 100644 index 000000000000..5a8f885b6d55 --- /dev/null +++ b/compiler-rt/test/tsan/dlopen_ns.cpp @@ -0,0 +1,93 @@ +// RUN: rm -rf %t-dir +// RUN: mkdir %t-dir + +// RUN: %clangxx_tsan -O0 %s -DSHARED_LIB2 -fPIC -shared -fno-sanitize=thread -o %t-dir/lib_dlopen_ns_test.so +// RUN: %clangxx_tsan -O0 %s -DSHARED_LIB1 -DDLOPEN -fPIC -shared -shared-libsan -o %t-dir/lib_dlopen_ns_dep_shared_tsan_1.so +// RUN: %clangxx_tsan -O0 %s -DSHARED_LIB1 -fPIC -shared -shared-libsan -o %t-dir/lib_dlopen_ns_dep_shared_tsan_2.so + +// RUN: %clangxx_tsan -DTEST1 -shared-libsan -O1 %s %link_libcxx_tsan -o %t-dir/exe1 +// RUN: %run %t-dir/exe1 %t-dir 2>&1 | FileCheck %s --check-prefix=CHECK-DLOPEN-EXT + +// RUN: %clangxx_tsan -DTEST1 -DDLOPEN -shared-libsan -O1 %s %link_libcxx_tsan -o %t-dir/exe2 +// RUN: %run %t-dir/exe2 %t-dir 2>&1 | FileCheck %s --check-prefix=CHECK-DLOPEN + +// Test that dlopen works properly when interceptor dlopen_impl: +// Musl dlopen use the caller address to get a matched ns(namespace) and use it +// to search lib, we need to make sure that matched ns don't change, otherwise +// dlopen will be failed, make the ns of caller library different from the tsan +// library to test whether dlopen is ok. + +// REQUIRES: ohos_family + +#ifdef SHARED_LIB1 +#include +#include +#include +extern "C" __attribute__((noinline)) void *bar(const char *name) { + fprintf(stderr, "bar\n"); + // let lr in this lib. +#if defined(DLOPEN) + return dlopen(name, RTLD_NOW); +#else + return dlopen_ext(name, RTLD_NOW, nullptr); +#endif +} + +extern "C" __attribute__((noinline)) void *foo(const char *name) { + fprintf(stderr, "foo\n"); + return bar(name); +} + +#elif defined(SHARED_LIB2) +extern "C" void hello() { return; } +#else +#include +#include +#include +#include + +int main(int argc, char *argv[]) { +#if defined(DLOPEN) + std::string lib_caller = "lib_dlopen_ns_dep_shared_tsan_1.so"; +#else + std::string lib_caller = "lib_dlopen_ns_dep_shared_tsan_2.so"; +#endif + std::string lib_callee = "lib_dlopen_ns_test.so"; + std::string dir = std::string(dirname(argv[0])); + std::string ns_lib_path = dir + ":/system/lib64"; + Dl_namespace dlns; + dlns_init(&dlns, "test_ns"); + dlns_create(&dlns, ns_lib_path.c_str()); + + void *handle = dlopen_ns(&dlns, lib_caller.c_str(), RTLD_NOW); + if (!handle) { + fprintf(stderr, "dlopen_ns %s failed.\n", lib_caller.c_str()); + return 0; + } + + void *(*funcPtr)(const char *) = + (void *(*)(const char *))dlsym(handle, "foo"); + if (!funcPtr) { + fprintf(stderr, "dlsym %s failed.\n", "foo"); + return 0; + } + + void *res = funcPtr(lib_callee.c_str()); + if (!res) { + fprintf(stderr, "dlopen %s failed.\n", lib_callee.c_str()); + return 0; + } + fprintf(stderr, "DONE\n"); + return 0; +} + +// CHECK-CHECK-DLOPEN-NOT: failed +// CHECK-DLOPEN: foo +// CHECK-DLOPEN: bar +// CHECK-DLOPEN: DONE + +// CHECK-CHECK-DLOPEN-EXT-NOT: failed +// CHECK-DLOPEN-EXT: foo +// CHECK-DLOPEN-EXT: bar +// CHECK-DLOPEN-EXT: DONE +#endif \ No newline at end of file diff --git a/compiler-rt/test/tsan/force_background_thread.cpp b/compiler-rt/test/tsan/force_background_thread.cpp index cf645cdfa914..646f71b013c6 100644 --- a/compiler-rt/test/tsan/force_background_thread.cpp +++ b/compiler-rt/test/tsan/force_background_thread.cpp @@ -1,7 +1,9 @@ // RUN: %clangxx_tsan -O1 %s -o %t -// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000 %run %t 2>&1 | FileCheck %s --implicit-check-not "memory flush check" -// RUN: %deflake %env_tsan_opts=force_background_thread=1:verbosity=1:memory_limit_mb=1000 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD -// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000 %run %t 1 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD +// OHOS_LOCAL begin +// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000:disable_background_thread=0 %run %t 2>&1 | FileCheck %s --implicit-check-not "memory flush check" +// RUN: %deflake %env_tsan_opts=force_background_thread=1:verbosity=1:memory_limit_mb=1000:disable_background_thread=0 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD +// RUN: %deflake %env_tsan_opts=force_background_thread=0:verbosity=1:memory_limit_mb=1000:disable_background_thread=0 %run %t 1 2>&1 | FileCheck %s --check-prefixes=CHECK,THREAD +// OHOS_LOCAL end // Fails with: objc[99984]: task_restartable_ranges_register failed (result 0x2e: (os/kern) service not supported) // UNSUPPORTED: darwin diff --git a/compiler-rt/test/tsan/getline_nohang.cpp b/compiler-rt/test/tsan/getline_nohang.cpp index 027ba7bac26a..62c9302d25cd 100644 --- a/compiler-rt/test/tsan/getline_nohang.cpp +++ b/compiler-rt/test/tsan/getline_nohang.cpp @@ -3,6 +3,10 @@ // Data race randomly triggered. // UNSUPPORTED: netbsd +// Musl try to visit all opening files and close it at exit, +// there will be potential deadlock if this file lock is held by getline on +// another thread. UNSUPPORTED: ohos_family + // Make sure TSan doesn't deadlock on a file stream lock at program shutdown. // See https://github.com/google/sanitizers/issues/454 #ifdef __FreeBSD__ diff --git a/compiler-rt/test/tsan/ignore_dlclose.cpp b/compiler-rt/test/tsan/ignore_dlclose.cpp new file mode 100644 index 000000000000..74d5cafc5df6 --- /dev/null +++ b/compiler-rt/test/tsan/ignore_dlclose.cpp @@ -0,0 +1,223 @@ +// RUN: rm -rf %t-dir +// RUN: mkdir %t-dir + +// RUN: %clangxx_tsan -fno-sanitize=thread -O0 -fno-builtin %s -DLIB -DEXPEND -fPIC -shared -o %t-dir/lib_noninstrumented_1.so +// RUN: %clangxx_tsan -fno-sanitize=thread -O0 -fno-builtin %s -DLIB -DEXPEND -fPIC -shared -o %t-dir/lib_noninstrumented_2.so +// RUN: %clangxx_tsan -O0 -fno-builtin %s -DLIB -fPIC -shared -o %t-dir/lib_instrumented_1.so +// RUN: %clangxx_tsan -O0 -fno-builtin %s -DLIB -fPIC -shared -o %t-dir/lib_instrumented_2.so + +// RUN: %clangxx_tsan -DTEST1 -O0 %s %link_libcxx_tsan -o %t-dir/exe1 +// RUN: %clangxx_tsan -DTEST2 -O0 %s %link_libcxx_tsan -o %t-dir/exe2 + +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=0' %run %t-dir/exe1 2>&1 | FileCheck %s --check-prefix=CHECK-DLOPEN_EXT + +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=1' %deflake %run %t-dir/exe2 instrumented_instrumented | FileCheck %s --check-prefix=CHECK-IGNORE-II +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=1' %deflake %run %t-dir/exe2 instrumented_noninstrumented | FileCheck %s --check-prefix=CHECK-IGNORE-IN +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=1' %deflake %run %t-dir/exe2 noninstrumented_instrumented | FileCheck %s --check-prefix=CHECK-IGNORE-NI +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=1' %run %t-dir/exe2 noninstrumented_noninstrumented 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE-NN + +// RUN: echo "called_from_lib:lib_instrumented_1.so" > %t-dir/exe2.supp +// RUN: %env_tsan_opts='ignore_noninstrumented_modules=0:suppressions='%t-dir/exe2.supp'' %deflake %run %t-dir/exe2 instrumented_instrumented | FileCheck %s --check-prefix=CHECK-SUPPRESS + +// REQUIRES: ohos_family + +#ifndef LIB + +#include +#include +#include +#include +#include + +typedef void (*FUNC)(void); + +FUNC get_symbol_addr(std::string lib, std::string name, bool do_call) { + dl_extinfo extinfo = { + .flag = DL_EXT_RESERVED_ADDRESS_RECURSIVE, + }; + + void *h = dlopen_ext(lib.c_str(), RTLD_NOW, &extinfo); + if (!h) { + fprintf(stderr, "dlopen_ext %s failed.\n", lib.c_str()); + return nullptr; + } + + FUNC f = (void (*)())dlsym(h, name.c_str()); + if (!f) { + fprintf(stderr, "dlsym %s failed.\n", name.c_str()); + if (h) { + dlclose(h); + } + return nullptr; + } + + if (do_call) { + f(); + } + dlclose(h); + + return f; +} + +// Test we can reuse same addrress through dlopen_ext. +bool test1(std::string &dir) { + std::string lib1 = dir + "/lib_noninstrumented_1.so"; + std::string lib2 = dir + "/lib_noninstrumented_2.so"; + FUNC f1 = get_symbol_addr(lib1.c_str(), "libfunc1", 0); + FUNC f2 = get_symbol_addr(lib2.c_str(), "libfunc1", 0); + if (!f1 || !f2) { + fprintf(stderr, + "dlopen_ext with DL_EXT_RESERVED_ADDRESS_RECURSIVE failed " + "func1:%p, func2:%p\n", + f1, f2); + return false; + } else { + fprintf(stderr, + "dlopen_ext with DL_EXT_RESERVED_ADDRESS_RECURSIVE succeed " + "func1:%p, func2:%p\n", + f1, f2); + } + return true; +} + +bool test2(std::string &dir, char *type) { + std::string lib1; + std::string lib2; + + if (!strcmp(type, "instrumented_instrumented")) { + lib1 = dir + "/lib_instrumented_1.so"; + lib2 = dir + "/lib_instrumented_2.so"; + } + + if (!strcmp(type, "instrumented_noninstrumented")) { + lib1 = dir + "/lib_instrumented_1.so"; + lib2 = dir + "/lib_noninstrumented_1.so"; + } + + if (!strcmp(type, "noninstrumented_instrumented")) { + lib1 = dir + "/lib_noninstrumented_1.so"; + lib2 = dir + "/lib_instrumented_1.so"; + } + + if (!strcmp(type, "noninstrumented_noninstrumented")) { + lib1 = dir + "/lib_noninstrumented_1.so"; + lib2 = dir + "/lib_noninstrumented_2.so"; + } + + FUNC f1 = get_symbol_addr(lib1.c_str(), "libfunc1", 1); + FUNC f2 = get_symbol_addr(lib2.c_str(), "libfunc2", 1); + if (!f1 || !f2) { + fprintf(stderr, + "dlopen_ext with DL_EXT_RESERVED_ADDRESS_RECURSIVE failed " + "func1:%p, func2:%p\n", + f1, f2); + return false; + } else { + fprintf(stderr, + "dlopen_ext with DL_EXT_RESERVED_ADDRESS_RECURSIVE succeed " + "func1:%p, func2:%p\n", + f1, f2); + } + return true; +} + +int main(int argc, char *argv[]) { + std::string dir = std::string(dirname(argv[0])); +#if defined(TEST1) + test1(dir); +#endif + +#if defined(TEST2) + test2(dir, argv[1]); +#endif + + fprintf(stderr, "DONE\n"); + return 0; +} + +#else +#include +#include + +// Extend the code segment so that it can overlap with the instrumented module +// address. +#if defined(EXPEND) +template int func() { return func(); } +template <> int func<0>() { return 0; } +#endif + +static int Global1[4]; +static int Global2[4]; + +void *Thread1(void *a) { + memset(&Global1, 0, sizeof(Global1)); + return nullptr; +} + +void *Thread2(void *a) { + memset(&Global1, 1, sizeof(Global1)); + return nullptr; +} + +void *Thread3(void *a) { + memset(&Global2, 0, sizeof(Global2)); + return nullptr; +} + +void *Thread4(void *a) { + memset(&Global2, 1, sizeof(Global2)); + return nullptr; +} + +extern "C" void libfunc1() { +#if defined(EXPEND) + func<15>(); +#endif + fprintf(stderr, "mem1:%p.\n", &Global1); + pthread_t t[2]; + pthread_create(&t[0], nullptr, Thread1, nullptr); + pthread_create(&t[1], nullptr, Thread2, nullptr); + pthread_join(t[0], nullptr); + pthread_join(t[1], nullptr); +} + +extern "C" void libfunc2() { + fprintf(stderr, "mem2:%p.\n", &Global2); + pthread_t t[2]; + pthread_create(&t[0], nullptr, Thread3, nullptr); + pthread_create(&t[1], nullptr, Thread4, nullptr); + pthread_join(t[0], nullptr); + pthread_join(t[1], nullptr); +} +#endif + +// CHECK-DLOPEN_EXT: dlopen_ext with DL_EXT_RESERVED_ADDRESS_RECURSIVE succeed +// CHECK-DLOPEN_EXT: DONE + +// CHECK-IGNORE-II-NOT: failed +// CHECK-IGNORE-II: WARNING: ThreadSanitizer: data race +// CHECK-IGNORE-II: libfunc1 {{.*}}lib_instrumented_1.so{{.*}} +// CHECK-IGNORE-II: libfunc2 {{.*}}lib_instrumented_2.so{{.*}} +// CHECK-IGNORE-II: DONE + +// CHECK-IGNORE-IN-NOT: failed +// CHECK-IGNORE-IN: WARNING: ThreadSanitizer: data race +// CHECK-IGNORE-IN: libfunc1 {{.*}}lib_instrumented_1.so{{.*}} +// CHECK-IGNORE-IN-NOT: libfunc2 +// CHECK-IGNORE-IN: DONE + +// CHECK-IGNORE-NI-NOT: failed +// CHECK-IGNORE-NI: WARNING: ThreadSanitizer: data race +// CHECK-IGNORE-NI-NOT: libfunc1 +// CHECK-IGNORE-NI: libfunc2 {{.*}}lib_instrumented_1.so{{.*}} +// CHECK-IGNORE-NI: DONE + +// CHECK-IGNORE-NN-NOT: failed +// CHECK-IGNORE-NN-NOT: WARNING: ThreadSanitizer: data race +// CHECK-IGNORE-NN: DONE + +// CHECK-SUPPRESS-NOT: failed +// CHECK-SUPPRESS: WARNING: ThreadSanitizer: data race +// CHECK-SUPPRESS-NOT: libfunc1 +// CHECK-SUPPRESS: libfunc2 {{.*}}lib_instrumented_2.so{{.*}} +// CHECK-SUPPRESS: DONE \ No newline at end of file diff --git a/compiler-rt/test/tsan/ignore_lib1.cpp b/compiler-rt/test/tsan/ignore_lib1.cpp index 2b17dee50141..01139519e491 100644 --- a/compiler-rt/test/tsan/ignore_lib1.cpp +++ b/compiler-rt/test/tsan/ignore_lib1.cpp @@ -16,10 +16,6 @@ // FIXME: This test regularly fails on powerpc64 LE possibly starting with // r279664. Re-enable the test once the problem(s) have been fixed. -// OHOS_LOCAL -// dlopen not intercepted on OHOS -// UNSUPPORTED: ohos_family - #ifndef LIB #include diff --git a/compiler-rt/test/tsan/ignore_lib2.cpp b/compiler-rt/test/tsan/ignore_lib2.cpp index 24b7f5e66a3e..05b7c2ed915a 100644 --- a/compiler-rt/test/tsan/ignore_lib2.cpp +++ b/compiler-rt/test/tsan/ignore_lib2.cpp @@ -6,10 +6,6 @@ // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t-dir/executable // RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t-dir/executable | FileCheck %s -// OHOS_LOCAL -// dlopen not intercepted on OHOS -// UNSUPPORTED: ohos_family - // Tests that called_from_lib suppression matched against 2 libraries // causes program crash (this is not supported). diff --git a/compiler-rt/test/tsan/ignore_lib3.cpp b/compiler-rt/test/tsan/ignore_lib3.cpp index b13229184141..76ea0709a69a 100644 --- a/compiler-rt/test/tsan/ignore_lib3.cpp +++ b/compiler-rt/test/tsan/ignore_lib3.cpp @@ -12,7 +12,7 @@ // REQUIRES: stable-runtime // OHOS_LOCAL -// dlopen not intercepted on OHOS +// The expected log will not be printed because ohos libignore support dlclose. // UNSUPPORTED: ohos_family #ifndef LIB diff --git a/compiler-rt/test/tsan/ignore_lib4.cpp b/compiler-rt/test/tsan/ignore_lib4.cpp index 00bde34639d0..06241c7b89f3 100644 --- a/compiler-rt/test/tsan/ignore_lib4.cpp +++ b/compiler-rt/test/tsan/ignore_lib4.cpp @@ -13,10 +13,6 @@ // is matched against 2 libraries". // UNSUPPORTED: aarch64 -// OHOS_LOCAL -// dlopen not intercepted on OHOS -// UNSUPPORTED: ohos_family - // Test longjmp in ignored lib. // It used to crash since we jumped out of ScopedInterceptor scope. diff --git a/compiler-rt/test/tsan/ignore_lib5.cpp b/compiler-rt/test/tsan/ignore_lib5.cpp index 9ae3f7bcbb95..a71d560ab913 100644 --- a/compiler-rt/test/tsan/ignore_lib5.cpp +++ b/compiler-rt/test/tsan/ignore_lib5.cpp @@ -21,10 +21,6 @@ // ReadProcMaps() on NetBSD does not handle >=1MB of memory layout information // UNSUPPORTED: netbsd -// OHOS_LOCAL -// dlopen not intercepted on OHOS -// UNSUPPORTED: ohos_family - #ifndef LIB #include diff --git a/compiler-rt/test/tsan/lit.cfg.py b/compiler-rt/test/tsan/lit.cfg.py index ddd4d21642fa..4f0bf242800e 100644 --- a/compiler-rt/test/tsan/lit.cfg.py +++ b/compiler-rt/test/tsan/lit.cfg.py @@ -29,6 +29,9 @@ if config.host_os == 'Darwin': default_tsan_opts += ['ignore_noninstrumented_modules=0'] default_tsan_opts += ['ignore_interceptors_accesses=0'] +if config.host_os == 'OHOS': + default_tsan_opts += ['ignore_noninstrumented_modules=0'] + # Platform-specific default TSAN_OPTIONS for lit tests. default_tsan_opts_str = ':'.join(default_tsan_opts) if default_tsan_opts_str: -- Gitee