From a1e09987caaeb0a37ad7f535c9f976b1d2f7cae6 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Wed, 4 Dec 2024 12:34:37 +0300 Subject: [PATCH 01/13] Add a script to run lit tests from compiler-rt for sanitizers using ADLT --- lit-tests/compiler-rt/README.md | 21 ++ lit-tests/compiler-rt/adlt.asan.site.cfg.py | 41 ++++ .../compiler-rt/cmake/Platform/OHOS.cmake | 24 ++ .../compiler-rt/common/adlt_test_format.py | 207 ++++++++++++++++++ lit-tests/compiler-rt/common/main.c | 19 ++ tools/run_lit_sanitizers.py | 123 +++++++++++ 6 files changed, 435 insertions(+) create mode 100644 lit-tests/compiler-rt/README.md create mode 100644 lit-tests/compiler-rt/adlt.asan.site.cfg.py create mode 100644 lit-tests/compiler-rt/cmake/Platform/OHOS.cmake create mode 100644 lit-tests/compiler-rt/common/adlt_test_format.py create mode 100644 lit-tests/compiler-rt/common/main.c create mode 100644 tools/run_lit_sanitizers.py diff --git a/lit-tests/compiler-rt/README.md b/lit-tests/compiler-rt/README.md new file mode 100644 index 0000000..6170e58 --- /dev/null +++ b/lit-tests/compiler-rt/README.md @@ -0,0 +1,21 @@ +## Compiler-rt lit tests +--- +This directory contains auxiliary scripts for running lit tests from compiler-rt using ADLT. + +The main idea: +- CMake configuration occurs in the `llvm-adlt/out/build` directory. +- The lit tests are run using a special config `adlt.{testname}.site.cfg.py` (where `{testname}` specifies the type of tests, e.g. `asan`). The custom config overrides the steps of building and running lit tests to be ADLT-compatible. + +Contents: +- `common`: + - `common/main.c` - is a wrapper used to call the original `main` from the test. + - `common/adlt_test_format.py` - script with overriding steps for running lit tests. +- `cmake`: + - `cmake/Platform/OHOS.cmake` - file with CMake configuration for building. +- `adlt.asan.site.cfg.py` - configuration for running `asan` tests. + + +*To add a new test, you need to: +- Create a new configuration file, e.g. `adlt.tsan.site.cfg.py`. +- Inside the created file you need to override `test_format`. Optionally, you can pass a list of unsupported tests. +- In `llvm-adlt/tools/run_lit_sanitizers.py` update list of supported tests. diff --git a/lit-tests/compiler-rt/adlt.asan.site.cfg.py b/lit-tests/compiler-rt/adlt.asan.site.cfg.py new file mode 100644 index 0000000..e0ec0b0 --- /dev/null +++ b/lit-tests/compiler-rt/adlt.asan.site.cfg.py @@ -0,0 +1,41 @@ +""" +@file adlt.asan.site.cfg.py + +@brief The script describes the settings for running asan lit based tests with ADLT. +""" + +import os +import sys + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +ROOT_DIR = f"{SCRIPT_DIR}/../.." +ASAN_DIR = f"{ROOT_DIR}/out/build/lit-tests/compiler-rt/test/asan/AARCH64OHOSConfig/" + +sys.path.append(f"{SCRIPT_DIR}/common") + +from adlt_test_format import AdltTestFormat + +unsupported = [ + # qemu: uncaught target signal 5 (Trace/breakpoint trap): main function returns nothing in the test, which causes an error. + "TestCases/Linux/aligned_delete_test.cpp", + "TestCases/Linux/thread_local_quarantine_size_kb.cpp", + "TestCases/Posix/unpoison-alternate-stack.cpp" + "TestCases/asan_and_llvm_coverage_test.cpp", + "TestCases/handle_noreturn_bug.cpp", + "TestCases/intercept-rethrow-exception.cpp", + "TestCases/invalid-pointer-pairs.cpp", + "TestCases/malloc_fill.cpp", + "TestCases/realloc.cpp", +] + +config.available_features.add("ohos_family") +config.host_os = "Linux" + +lit_config.load_config( + config, + f"{ASAN_DIR}/lit.site.cfg.py", +) + +config.test_format = AdltTestFormat(unsupported) +config.test_exec_root = f"{ASAN_DIR}" +config.lit_test_times = f"{ASAN_DIR}/lit_test_times.txt" diff --git a/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake b/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake new file mode 100644 index 0000000..aad6544 --- /dev/null +++ b/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(Platform/Linux) + +set(OHOS 1) + +# OHOS has soname, but binary names must end in ".so" so we cannot append +# a version number. Also we cannot portably represent symlinks on the host. +set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) + +# OHOS reportedly ignores RPATH, and we cannot predict the install +# location anyway. +set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py new file mode 100644 index 0000000..497cc28 --- /dev/null +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -0,0 +1,207 @@ +""" +@file adlt_test_format.py + +@brief Describes a custom format for building and running lit tests for ADLT. +""" + +import os +import sys +import lit.util +import re +from lit.formats import ShTest +import lit.TestRunner as TR + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +ROOT_DIR = f"{SCRIPT_DIR}/../../../" + +sys.path.append(f"{ROOT_DIR}/tools") +from tools import shell +from config import Config + + +class AdltTestFormat(ShTest): + """ + AdltTestFormat class. + + AdltTestFormat class describes the format for building and running lit tests using ADLT. + + Args: + unsupportedList (list): List with unsupported tests. + """ + + def __init__(self, unsupportedList: list = []) -> None: + super().__init__() + self.unsupportedList = unsupportedList + + def execute( + self, test: lit.Test.Test, litConfig: lit.LitConfig.LitConfig + ) -> lit.Test.Result: + """ + Execute a test from the suite. + """ + return self.parse_command( + test, + litConfig, + self.execute_external, + self.extra_substitutions, + self.preamble_commands, + ) + + def parse_command( + self, + test: lit.Test.Test, + litConfig: lit.LitConfig.LitConfig, + useExternalSh: bool, + extra_substitutions: list = [], + preamble_commands: list = [], + ) -> lit.Test.Result: + """ + Parsing lit commands from source files, variable substitution. + + These steps are taken from the original `ShTest``, + but this method adds a check for a custom list of unsupported tests. And also call expand_for_adlt function. + """ + if test.config.unsupported: + return lit.Test.Result(lit.Test.UNSUPPORTED, "Test is unsupported") + + srcFile = test.getSourcePath() + + for testName in self.unsupportedList: + if srcFile.endswith(testName): + return lit.Test.Result(lit.Test.UNSUPPORTED, "Test is unsupported") + + script = list(preamble_commands) + parsed = TR.parseIntegratedTestScript(test, require_script=not script) + + if isinstance(parsed, lit.Test.Result): + return parsed + script += parsed + + if litConfig.noExecute: + return lit.Test.Result(lit.Test.PASS) + + tmpDir, tmpBase = TR.getTempPaths(test) + + substitutions = list(extra_substitutions) + substitutions += TR.getDefaultSubstitutions( + test, tmpDir, tmpBase, normalize_slashes=useExternalSh + ) + + conditions = {feature: True for feature in test.config.available_features} + + script = TR.applySubstitutions( + script, + substitutions, + conditions, + recursion_limit=test.config.recursiveExpansionLimit, + ) + + script = self.expand_for_adlt(test, script) + + return TR._runShTest(test, litConfig, useExternalSh, script, tmpBase) + + def expand_for_adlt(self, test: lit.Test.Test, script: list) -> list: + """ + Adding additional commands (builds, linking, etc.) to the original command to run tests using ADLT. + """ + tmpDir, tmpBase = TR.getTempPaths(test) + + testExt = tmpBase.split(".")[-1] + outFile = f"{tmpBase}.tmp" + srcFile = test.getSourcePath() + + defines = "" + + # We need to know which signature of the main function + # is used in the test to set the correct define for wrapper. + with open(srcFile) as f: + data = f.read() + if "int argc" in data: + if "const char *argv" in data: + defines += " -DMAIN_WITH_ARGS_CONST" + else: + defines += " -DMAIN_WITH_ARGS" + + # Generate an environment for QEMU. + if not os.path.exists(f"{tmpDir}/lib"): + shell( + f"rm -rf {tmpDir}/lib {tmpDir}/lib_orig {tmpDir}/obj {tmpDir}/toolchain" + ) + shell(f"python3 {ROOT_DIR}/tools/gen_qemu_env.py -od {tmpDir}") + + # Updating the script commands. + for i in range(len(script)): + # Sometimes, a RUN script may contain multiple commands separated by `&&`, + # so we need to check each one. + runCmd = script[i].split("&&") + + for j in range(len(runCmd)): + cmd = runCmd[j] + + # If command contains `qemu-aarch64-static` in it, + # then it's the command to start the program. Let's update the arguments. + if "qemu-aarch64-static" in cmd: + cmd = cmd.replace( + "qemu-aarch64-static", + f"env MUSL_LOG_DISABLE_CONNECT=1 qemu-aarch64-static -L {tmpDir} -E -LD_LIBRARY_PATH={tmpDir}", + ) + cmd = cmd.replace(f".{testExt}.tmp", ".elf") + runCmd[j] = cmd + + # Otherwise, if a command contains source file, + # then it's the compile command. + elif f"{srcFile} " in cmd: + # Add compilation step with `-c`. + compileOut = outFile.replace(f".{testExt}.tmp", ".o") + compileCmd = f"{srcFile} -fPIC -Dmain=testMain -c " + compileCmd = cmd.replace(f"{srcFile} ", compileCmd) + compileCmd = compileCmd.replace(outFile, compileOut) + + croppedCmd = cmd[:] + croppedCmd = re.sub(".*%.*RUN.*\) +", "", croppedCmd) + + # Add object file linking step. + linkOut = outFile.replace(f".{testExt}.tmp", ".so") + linkCmd = croppedCmd + linkCmd = linkCmd.replace(outFile, linkOut) + linkCmd = linkCmd.replace( + f"{srcFile} ", f"-fPIC -Wl,--emit-relocs -shared {compileOut} " + ) + + # Add the lld call with --adlt. + adltOut = f"{linkOut}.adlt" + adltCmd = croppedCmd + adltCmd = adltCmd.split(" ")[0] + adltCmd = f"{adltCmd} --adlt {linkOut} -o {adltOut} --emit-relocs" + adltCmd = adltCmd.replace("clang", "ld.lld") + + # Add wrapper for main. + mainOut = outFile.replace(f".{testExt}.tmp", "_main.o") + mainCmd = croppedCmd + mainCmd = mainCmd.replace( + f"{srcFile} ", + f"-c {SCRIPT_DIR}/main.c {defines} ", + ) + mainCmd = mainCmd.replace(outFile, mainOut) + + # Link the wrapper for main and the test shared library. + linkAllArgs = ( + f"--rtlib=compiler-rt -Wl,--emit-relocs {mainOut} {linkOut} " + ) + linkAllCmd = croppedCmd + linkAllCmd = linkAllCmd.replace(f".{testExt}.tmp", ".elf") + linkAllCmd = linkAllCmd.replace(f"{srcFile} ", linkAllArgs) + + # For library we need to call adlt_makelinks.py, to set the links. + # It's mandatory to pass environment variables, since llvm-lit clears them. + makelinksCmd = f"env SDK_ROOT={Config.SDK_ROOT} LLVM={Config.LLVM} python3 {ROOT_DIR}/tools/adlt_makelinks.py -i {linkOut} -od {tmpDir}/lib -o {adltOut}" + + # Combine all the commands into one and replace. + runCmd[j] = ( + f"{compileCmd} && {linkCmd} && {adltCmd} && {mainCmd} && {linkAllCmd} && {makelinksCmd}" + ) + + # If there were multiple commands, then update. + script[i] = " && ".join(runCmd) + + return script diff --git a/lit-tests/compiler-rt/common/main.c b/lit-tests/compiler-rt/common/main.c new file mode 100644 index 0000000..22d1dd1 --- /dev/null +++ b/lit-tests/compiler-rt/common/main.c @@ -0,0 +1,19 @@ +#define CHAR_CONST + +#if defined(MAIN_WITH_ARGS) +int testMain(int argc, char **argv); +#elif defined(MAIN_WITH_ARGS_CONST) +int testMain(int argc, const char **argv); +#undef CHAR_CONST +#define CHAR_CONST const +#else +int testMain(); +#endif + +int main(int argc, CHAR_CONST char **argv) { +#if defined(MAIN_WITH_ARGS) || defined(MAIN_WITH_ARGS_CONST) + return testMain(argc, argv); +#else + return testMain(); +#endif +} diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py new file mode 100644 index 0000000..c28628e --- /dev/null +++ b/tools/run_lit_sanitizers.py @@ -0,0 +1,123 @@ +#!/usr/bin/python3 +""" +@file run_lit_sanitizers.py + +@brief The script provides an interface to run lit tests from compiler-rt with qemu and ADLT. +""" +import argparse +from config import Config +from tools import shell + +# TODO: Support more tests. +supportedTests = ["asan"] + + +def parseArgs() -> argparse.Namespace: + """ + Parsing command line arguments. + """ + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument( + "--test", + "-t", + help=f"Test to test, available: {', '.join(supportedTests)}", + default=None, + ) + parser.add_argument( + "--llvm-project", + help="Path to llvm project directory.", + default=None, + ) + parser.add_argument( + "--llvm-install", + help="Path to llvm binaries.", + default=Config.LLVM, + required=False, + ) + + args = parser.parse_args() + + return args + + +def configureCompilerRt(llvmProject: str, llvmInstall: str) -> None: + """ + Configuring a compiler-rt project using CMake to run lit tests. + + Args: + llvmProject (str): Path to llvm project directory. + llvmInstall (str): Path to llvm binaries. + """ + workDir = Config.BUILD_DIR / "lit-tests" / "compiler-rt" + shell(f"rm -rf {workDir}") + + cmakeCmd = f""" + cmake \ + -B {workDir} \ + -DCMAKE_SYSTEM_NAME=OHOS \ + -DOHOS=1 \ + {llvmProject}/compiler-rt \ + -G Ninja \ + -DCMAKE_MODULE_PATH="{Config.ROOT_DIR}/lit-tests/compiler-rt/cmake" \ + -DCMAKE_SYSTEM_NAME=OHOS \ + -DCMAKE_AR="{llvmInstall}/bin/llvm-ar" \ + -DLLVM_CONFIG_PATH="{llvmInstall}/bin/llvm-config" \ + -DCMAKE_ASM_COMPILER_TARGET="aarch64-linux-ohos" \ + -DCMAKE_ASM_FLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ + -DCMAKE_C_COMPILER="{llvmInstall}/bin/clang" \ + -DCMAKE_C_COMPILER_TARGET="aarch64-linux-ohos" \ + -DCMAKE_C_FLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ + -DCMAKE_CXX_COMPILER="{llvmInstall}/bin/clang++" \ + -DCMAKE_CXX_COMPILER_TARGET="aarch64-linux-ohos" \ + -DCMAKE_CXX_FLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ + -DCMAKE_EXE_LINKER_FLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ + -DCOMPILER_RT_BUILD_BUILTINS=OFF \ + -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \ + -DCOMPILER_RT_BUILD_MEMPROF=OFF \ + -DCOMPILER_RT_BUILD_PROFILE=ON \ + -DCOMPILER_RT_BUILD_SANITIZERS=ON \ + -DCOMPILER_RT_BUILD_XRAY=OFF \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + -DCOMPILER_RT_INCLUDE_TESTS=ON \ + -DCOMPILER_RT_CAN_EXECUTE_TESTS=ON \ + -DCOMPILER_RT_TEST_COMPILER="{llvmInstall}/bin/clang" \ + -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ + -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF \ + -DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON \ + """ + + shell(cmakeCmd) + + +def run(test: str) -> None: + """ + Running compiler-rt lit tests with llvm-lit. + + Args: + test (str): Test name. + """ + lit = Config.BUILD_DIR / "lit-tests" / "compiler-rt" / "bin" / "llvm-lit" + cfgPath = Config.ROOT_DIR / "lit-tests" / "compiler-rt" + runCmd = f"{lit} -v {cfgPath} --config-prefix adlt.{test} --param emulator=qemu-aarch64-static" + shell(runCmd) + + +def main() -> None: + global supportedTests + + args = parseArgs() + + if args.test not in supportedTests: + print("The unknown name of the test! Use --help.") + exit(1) + + if not args.llvm_project: + print("The path to llvm-project is not set! Use --help.") + + configureCompilerRt(args.llvm_project, args.llvm_install) + + run(args.test) + + +if __name__ == "__main__": + main() -- Gitee From 4b94bae2cf63211cd1324c6587ed1b57aa891995 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Thu, 5 Dec 2024 00:44:21 +0300 Subject: [PATCH 02/13] Disable unsupported asan tests, refactoring --- lit-tests/compiler-rt/README.md | 10 ++-- .../lit.site.cfg.py} | 56 ++++++++++++++++++- .../compiler-rt/common/adlt_test_format.py | 17 ++++-- .../compiler-rt/common/{main.c => main.cpp} | 6 ++ tools/run_lit_sanitizers.py | 4 +- 5 files changed, 80 insertions(+), 13 deletions(-) rename lit-tests/compiler-rt/{adlt.asan.site.cfg.py => asan/lit.site.cfg.py} (34%) rename lit-tests/compiler-rt/common/{main.c => main.cpp} (87%) diff --git a/lit-tests/compiler-rt/README.md b/lit-tests/compiler-rt/README.md index 6170e58..20ed77a 100644 --- a/lit-tests/compiler-rt/README.md +++ b/lit-tests/compiler-rt/README.md @@ -4,7 +4,8 @@ This directory contains auxiliary scripts for running lit tests from compiler-rt The main idea: - CMake configuration occurs in the `llvm-adlt/out/build` directory. -- The lit tests are run using a special config `adlt.{testname}.site.cfg.py` (where `{testname}` specifies the type of tests, e.g. `asan`). The custom config overrides the steps of building and running lit tests to be ADLT-compatible. +- The lit tests are run using a special config `lit.site.cfg.py`. The custom config overrides the steps of building and running lit tests to be ADLT-compatible. + Contents: - `common`: @@ -12,10 +13,11 @@ Contents: - `common/adlt_test_format.py` - script with overriding steps for running lit tests. - `cmake`: - `cmake/Platform/OHOS.cmake` - file with CMake configuration for building. -- `adlt.asan.site.cfg.py` - configuration for running `asan` tests. +- `asan`: + - `asan/lit.site.cfg.py` - configuration for running `asan` tests. -*To add a new test, you need to: -- Create a new configuration file, e.g. `adlt.tsan.site.cfg.py`. +To add a new test, you need to: +- Create new folder for test suite and create a new configuration file, e.g. `lit.site.cfg.py` inside. - Inside the created file you need to override `test_format`. Optionally, you can pass a list of unsupported tests. - In `llvm-adlt/tools/run_lit_sanitizers.py` update list of supported tests. diff --git a/lit-tests/compiler-rt/adlt.asan.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py similarity index 34% rename from lit-tests/compiler-rt/adlt.asan.site.cfg.py rename to lit-tests/compiler-rt/asan/lit.site.cfg.py index e0ec0b0..c4a823d 100644 --- a/lit-tests/compiler-rt/adlt.asan.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -8,16 +8,18 @@ import os import sys SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) -ROOT_DIR = f"{SCRIPT_DIR}/../.." +ROOT_DIR = f"{SCRIPT_DIR}/../../../" ASAN_DIR = f"{ROOT_DIR}/out/build/lit-tests/compiler-rt/test/asan/AARCH64OHOSConfig/" -sys.path.append(f"{SCRIPT_DIR}/common") +sys.path.append(f"{SCRIPT_DIR}/../common") from adlt_test_format import AdltTestFormat unsupported = [ # qemu: uncaught target signal 5 (Trace/breakpoint trap): main function returns nothing in the test, which causes an error. "TestCases/Linux/aligned_delete_test.cpp", + "TestCases/Linux/asan_default_suppressions.cpp", + "TestCases/Linux/interception_readdir_r_test.cpp", "TestCases/Linux/thread_local_quarantine_size_kb.cpp", "TestCases/Posix/unpoison-alternate-stack.cpp" "TestCases/asan_and_llvm_coverage_test.cpp", @@ -26,6 +28,56 @@ unsupported = [ "TestCases/invalid-pointer-pairs.cpp", "TestCases/malloc_fill.cpp", "TestCases/realloc.cpp", + + # Multiple source files in the test: + "TestCases/Darwin/unset-insert-libraries-on-exec.cpp", + "TestCases/Linux/initialization-bug-any-order.cpp", + "TestCases/Windows/iostream_sbo.cpp", + "TestCases/global-underflow.cpp", + "TestCases/ignorelist.cpp", + "TestCases/init-order-atexit.cpp", + "TestCases/initialization-bug.cpp", + "TestCases/initialization-constexpr.cpp", + "TestCases/initialization-ignorelist.cpp", + "TestCases/initialization-nobug.cpp", + + # Two build steps with `-c`. + # TODO: support in the future. + "TestCases/Darwin/cstring_section.c", + "TestCases/Darwin/empty-section.cpp", + "TestCases/Darwin/haswell-symbolication.cpp", + "TestCases/Darwin/linked-only.cpp", + "TestCases/Darwin/mixing-global-constructors.cpp", + "TestCases/Darwin/odr-lto.cpp", + "TestCases/Linux/activation-options.cpp", + "TestCases/Linux/local_alias.cpp", + "TestCases/Linux/longjmp_chk.c", + "TestCases/Posix/global-registration.c", + "TestCases/Posix/init-order-pthread-create.cpp", + "TestCases/Posix/start-deactivated.cpp", + "TestCases/Windows/dll_and_lib.cpp", + "TestCases/Windows/dll_large_function.cpp", + "TestCases/Windows/seh.cpp", + "TestCases/Windows/unsymbolized.cpp", + + # The output file is a .so file. + # TODO: support in the future. + "TestCases/Linux/activation-options.cpp", + "TestCases/Linux/asan_preload_test-1.cpp", + "TestCases/Linux/dlopen-mixed-c-cxx.c", + "TestCases/Linux/function-sections-are-bad.cpp", + "TestCases/Linux/init-order-dlopen.cpp", + "TestCases/Linux/printf-fortify-1.c", + "TestCases/Linux/printf-fortify-2.c", + "TestCases/Linux/printf-fortify-3.c", + "TestCases/Linux/printf-fortify-4.c", + "TestCases/Linux/printf-fortify-5.c", + "TestCases/Linux/pthread_create_from_constructor.cpp", + "TestCases/Linux/static_tls.cpp", + "TestCases/Posix/asan-symbolize-sanity-test.cpp", + "TestCases/Posix/dlclose-test.cpp", + "TestCases/Posix/shared-lib-test.cpp", + "TestCases/Posix/start-deactivated.cpp", ] config.available_features.add("ohos_family") diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 497cc28..4ac4ff4 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -32,6 +32,7 @@ class AdltTestFormat(ShTest): def __init__(self, unsupportedList: list = []) -> None: super().__init__() self.unsupportedList = unsupportedList + self.execute_external = False def execute( self, test: lit.Test.Test, litConfig: lit.LitConfig.LitConfig @@ -107,11 +108,13 @@ class AdltTestFormat(ShTest): tmpDir, tmpBase = TR.getTempPaths(test) testExt = tmpBase.split(".")[-1] - outFile = f"{tmpBase}.tmp" srcFile = test.getSourcePath() defines = "" + if testExt == "c": + defines += " -DC_EXTERN" + # We need to know which signature of the main function # is used in the test to set the correct define for wrapper. with open(srcFile) as f: @@ -151,8 +154,12 @@ class AdltTestFormat(ShTest): # Otherwise, if a command contains source file, # then it's the compile command. elif f"{srcFile} " in cmd: + # Get filename after `-o`. + outFile = re.split(r' -o ', cmd)[-1].strip() + outFile = outFile.split(" ")[0] + # Add compilation step with `-c`. - compileOut = outFile.replace(f".{testExt}.tmp", ".o") + compileOut = f"{outFile}.o" compileCmd = f"{srcFile} -fPIC -Dmain=testMain -c " compileCmd = cmd.replace(f"{srcFile} ", compileCmd) compileCmd = compileCmd.replace(outFile, compileOut) @@ -161,7 +168,7 @@ class AdltTestFormat(ShTest): croppedCmd = re.sub(".*%.*RUN.*\) +", "", croppedCmd) # Add object file linking step. - linkOut = outFile.replace(f".{testExt}.tmp", ".so") + linkOut = f"{outFile}.so" linkCmd = croppedCmd linkCmd = linkCmd.replace(outFile, linkOut) linkCmd = linkCmd.replace( @@ -176,11 +183,11 @@ class AdltTestFormat(ShTest): adltCmd = adltCmd.replace("clang", "ld.lld") # Add wrapper for main. - mainOut = outFile.replace(f".{testExt}.tmp", "_main.o") + mainOut = f"{outFile}.main.o" mainCmd = croppedCmd mainCmd = mainCmd.replace( f"{srcFile} ", - f"-c {SCRIPT_DIR}/main.c {defines} ", + f"-c {SCRIPT_DIR}/main.cpp {defines} ", ) mainCmd = mainCmd.replace(outFile, mainOut) diff --git a/lit-tests/compiler-rt/common/main.c b/lit-tests/compiler-rt/common/main.cpp similarity index 87% rename from lit-tests/compiler-rt/common/main.c rename to lit-tests/compiler-rt/common/main.cpp index 22d1dd1..ba67cf7 100644 --- a/lit-tests/compiler-rt/common/main.c +++ b/lit-tests/compiler-rt/common/main.cpp @@ -1,5 +1,8 @@ #define CHAR_CONST +#ifdef C_EXTERN +extern "C" { +#endif #if defined(MAIN_WITH_ARGS) int testMain(int argc, char **argv); #elif defined(MAIN_WITH_ARGS_CONST) @@ -9,6 +12,9 @@ int testMain(int argc, const char **argv); #else int testMain(); #endif +#ifdef C_EXTERN +} +#endif int main(int argc, CHAR_CONST char **argv) { #if defined(MAIN_WITH_ARGS) || defined(MAIN_WITH_ARGS_CONST) diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py index c28628e..bce5fb6 100644 --- a/tools/run_lit_sanitizers.py +++ b/tools/run_lit_sanitizers.py @@ -97,8 +97,8 @@ def run(test: str) -> None: test (str): Test name. """ lit = Config.BUILD_DIR / "lit-tests" / "compiler-rt" / "bin" / "llvm-lit" - cfgPath = Config.ROOT_DIR / "lit-tests" / "compiler-rt" - runCmd = f"{lit} -v {cfgPath} --config-prefix adlt.{test} --param emulator=qemu-aarch64-static" + cfgPath = Config.ROOT_DIR / "lit-tests" / "compiler-rt" / test + runCmd = f"{lit} -v {cfgPath} --param emulator=qemu-aarch64-static" shell(runCmd) -- Gitee From 023e450ddf7806dcf25dae69e8b4d3c1c7435f56 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 10 Dec 2024 12:51:31 +0300 Subject: [PATCH 03/13] Disable more unsupported tests, refactoring --- lit-tests/compiler-rt/asan/lit.site.cfg.py | 29 +++++++++++++++ .../compiler-rt/common/adlt_test_format.py | 35 ++++++------------- .../compiler-rt/common/{main.cpp => main.c} | 20 +++++------ lit-tests/compiler-rt/common/qemu.py | 26 ++++++++++++++ tools/run_lit_sanitizers.py | 3 +- 5 files changed, 75 insertions(+), 38 deletions(-) rename lit-tests/compiler-rt/common/{main.cpp => main.c} (45%) create mode 100755 lit-tests/compiler-rt/common/qemu.py diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index c4a823d..e4fac89 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -59,6 +59,7 @@ unsupported = [ "TestCases/Windows/dll_large_function.cpp", "TestCases/Windows/seh.cpp", "TestCases/Windows/unsymbolized.cpp", + "TestCases/coverage-trace-pc.cpp", # The output file is a .so file. # TODO: support in the future. @@ -78,6 +79,34 @@ unsupported = [ "TestCases/Posix/dlclose-test.cpp", "TestCases/Posix/shared-lib-test.cpp", "TestCases/Posix/start-deactivated.cpp", + + # Tests without launch steps (compilation only): + "TestCases/Linux/globals-gc-sections-lld.cpp", + "TestCases/malloc-no-intercept.c", + + # Complex command parsing. + # TODO: support in the future. + "TestCases/Linux/read_binary_name_regtest.c", + + # Tests using -shared libraries: + # TODO: support in the future. + "TestCases/Linux/odr-violation.cpp", + "TestCases/Linux/odr-vtable.cpp", + "TestCases/Linux/odr_c_test.c", + "TestCases/Linux/preinit_test.cpp", + "TestCases/Linux/stress_dtls.c", + "TestCases/Posix/coverage-module-unloaded.cpp", + "TestCases/Posix/coverage-reset.cpp", + "TestCases/Posix/coverage.cpp", + "TestCases/Posix/interception-in-shared-lib-test.cpp", + "TestCases/suppressions-library.cpp", + + # Compilation error, clang is used instead of clang++. + # "error: ISO C++ forbids forward references to 'enum' types" + "TestCases/Linux/ptrace.cpp", + + # The test does not contain C/C++ code, it is empty and designed for compilation only. + "TestCases/default_ignorelist.cpp", ] config.available_features.add("ohos_family") diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 4ac4ff4..1ba7f00 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -141,38 +141,30 @@ class AdltTestFormat(ShTest): for j in range(len(runCmd)): cmd = runCmd[j] - # If command contains `qemu-aarch64-static` in it, - # then it's the command to start the program. Let's update the arguments. - if "qemu-aarch64-static" in cmd: - cmd = cmd.replace( - "qemu-aarch64-static", - f"env MUSL_LOG_DISABLE_CONNECT=1 qemu-aarch64-static -L {tmpDir} -E -LD_LIBRARY_PATH={tmpDir}", - ) - cmd = cmd.replace(f".{testExt}.tmp", ".elf") - runCmd[j] = cmd - - # Otherwise, if a command contains source file, # then it's the compile command. - elif f"{srcFile} " in cmd: + if f"{srcFile} " in cmd and "clang" in cmd: # Get filename after `-o`. - outFile = re.split(r' -o ', cmd)[-1].strip() + outFile = re.split(r" -o ", cmd)[-1].strip() outFile = outFile.split(" ")[0] # Add compilation step with `-c`. compileOut = f"{outFile}.o" - compileCmd = f"{srcFile} -fPIC -Dmain=testMain -c " + compileCmd = f"{srcFile} -fPIC -c " compileCmd = cmd.replace(f"{srcFile} ", compileCmd) compileCmd = compileCmd.replace(outFile, compileOut) croppedCmd = cmd[:] croppedCmd = re.sub(".*%.*RUN.*\) +", "", croppedCmd) + croppedCmd = re.sub(r" +", " ", croppedCmd) + croppedCmd = re.sub(r"^.*?clang", "clang", croppedCmd) # Add object file linking step. linkOut = f"{outFile}.so" linkCmd = croppedCmd linkCmd = linkCmd.replace(outFile, linkOut) linkCmd = linkCmd.replace( - f"{srcFile} ", f"-fPIC -Wl,--emit-relocs -shared {compileOut} " + f"{srcFile} ", + f"-fPIC -Wl,--emit-relocs -shared {compileOut} -Wl,-soname,{linkOut} ", ) # Add the lld call with --adlt. @@ -183,20 +175,13 @@ class AdltTestFormat(ShTest): adltCmd = adltCmd.replace("clang", "ld.lld") # Add wrapper for main. + clangPath = croppedCmd.split(" ")[0].replace("clang++", "clang") mainOut = f"{outFile}.main.o" - mainCmd = croppedCmd - mainCmd = mainCmd.replace( - f"{srcFile} ", - f"-c {SCRIPT_DIR}/main.cpp {defines} ", - ) - mainCmd = mainCmd.replace(outFile, mainOut) + mainCmd = f"{clangPath} {defines} --target=aarch64-linux-ohos -c {SCRIPT_DIR}/main.c -o {mainOut}" # Link the wrapper for main and the test shared library. - linkAllArgs = ( - f"--rtlib=compiler-rt -Wl,--emit-relocs {mainOut} {linkOut} " - ) + linkAllArgs = f"-Wl,--wrap=main --rtlib=compiler-rt -Wl,--emit-relocs {mainOut} {linkOut} " linkAllCmd = croppedCmd - linkAllCmd = linkAllCmd.replace(f".{testExt}.tmp", ".elf") linkAllCmd = linkAllCmd.replace(f"{srcFile} ", linkAllArgs) # For library we need to call adlt_makelinks.py, to set the links. diff --git a/lit-tests/compiler-rt/common/main.cpp b/lit-tests/compiler-rt/common/main.c similarity index 45% rename from lit-tests/compiler-rt/common/main.cpp rename to lit-tests/compiler-rt/common/main.c index ba67cf7..ad62552 100644 --- a/lit-tests/compiler-rt/common/main.cpp +++ b/lit-tests/compiler-rt/common/main.c @@ -1,25 +1,21 @@ #define CHAR_CONST -#ifdef C_EXTERN -extern "C" { -#endif #if defined(MAIN_WITH_ARGS) -int testMain(int argc, char **argv); +extern int __real_main(int argc, char **argv); #elif defined(MAIN_WITH_ARGS_CONST) -int testMain(int argc, const char **argv); +extern int __real_main(int argc, const char **argv); #undef CHAR_CONST #define CHAR_CONST const #else -int testMain(); -#endif -#ifdef C_EXTERN -} +extern int __real_main(); #endif -int main(int argc, CHAR_CONST char **argv) { +int __wrap_main(int argc, CHAR_CONST char **argv) { + int res; #if defined(MAIN_WITH_ARGS) || defined(MAIN_WITH_ARGS_CONST) - return testMain(argc, argv); + res = __real_main(argc, argv); #else - return testMain(); + res = __real_main(); #endif + return res; } diff --git a/lit-tests/compiler-rt/common/qemu.py b/lit-tests/compiler-rt/common/qemu.py new file mode 100755 index 0000000..70723b6 --- /dev/null +++ b/lit-tests/compiler-rt/common/qemu.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" +@file qemu.py + +@brief Wrapper for running tests with qemu-aarch64-static. +""" +import sys +import os +import subprocess + +runFile = sys.argv[1] +workingDir = os.path.dirname(runFile) +cmd = ( + f"MUSL_LOG_DISABLE_CONNECT=1 qemu-aarch64-static -L {workingDir} -E -LD_LIBRARY_PATH={workingDir} " + + " ".join(sys.argv[1:]) +) + +result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=600) + +sys.stdout.write(result.stdout) +sys.stderr.write(result.stderr) +sys.stdout.flush() +sys.stderr.flush() + +retcode = result.returncode +sys.exit(result.returncode) diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py index bce5fb6..827a732 100644 --- a/tools/run_lit_sanitizers.py +++ b/tools/run_lit_sanitizers.py @@ -98,7 +98,8 @@ def run(test: str) -> None: """ lit = Config.BUILD_DIR / "lit-tests" / "compiler-rt" / "bin" / "llvm-lit" cfgPath = Config.ROOT_DIR / "lit-tests" / "compiler-rt" / test - runCmd = f"{lit} -v {cfgPath} --param emulator=qemu-aarch64-static" + commonPath = Config.ROOT_DIR / "lit-tests" / "compiler-rt" / "common" + runCmd = f"{lit} -v {cfgPath} --param emulator={commonPath}/qemu.py" shell(runCmd) -- Gitee From cac4c3fa68d6898c13460c6f5cbb889467cd440a Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 10 Dec 2024 13:27:13 +0300 Subject: [PATCH 04/13] Use OHOS.cmake from sdk prebuilts --- lit-tests/compiler-rt/asan/lit.site.cfg.py | 2 +- .../compiler-rt/cmake/Platform/OHOS.cmake | 24 ------------------- tools/run_lit_sanitizers.py | 2 +- 3 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 lit-tests/compiler-rt/cmake/Platform/OHOS.cmake diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index e4fac89..0dc7de3 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -118,5 +118,5 @@ lit_config.load_config( ) config.test_format = AdltTestFormat(unsupported) -config.test_exec_root = f"{ASAN_DIR}" +config.test_exec_root = ASAN_DIR config.lit_test_times = f"{ASAN_DIR}/lit_test_times.txt" diff --git a/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake b/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake deleted file mode 100644 index aad6544..0000000 --- a/lit-tests/compiler-rt/cmake/Platform/OHOS.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -include(Platform/Linux) - -set(OHOS 1) - -# OHOS has soname, but binary names must end in ".so" so we cannot append -# a version number. Also we cannot portably represent symlinks on the host. -set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) - -# OHOS reportedly ignores RPATH, and we cannot predict the install -# location anyway. -set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py index 827a732..721c96a 100644 --- a/tools/run_lit_sanitizers.py +++ b/tools/run_lit_sanitizers.py @@ -58,7 +58,7 @@ def configureCompilerRt(llvmProject: str, llvmInstall: str) -> None: -DOHOS=1 \ {llvmProject}/compiler-rt \ -G Ninja \ - -DCMAKE_MODULE_PATH="{Config.ROOT_DIR}/lit-tests/compiler-rt/cmake" \ + -DCMAKE_MODULE_PATH="{Config.SDK_ROOT}/prebuilts/cmake/linux-x86/share/cmake-3.28/Modules/" \ -DCMAKE_SYSTEM_NAME=OHOS \ -DCMAKE_AR="{llvmInstall}/bin/llvm-ar" \ -DLLVM_CONFIG_PATH="{llvmInstall}/bin/llvm-config" \ -- Gitee From 0b27b94158b4e2736ad3afe1ef5c416ceffea714 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 10 Dec 2024 20:21:01 +0300 Subject: [PATCH 05/13] Remove old comment --- lit-tests/compiler-rt/common/adlt_test_format.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 1ba7f00..bdc09f0 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -141,7 +141,6 @@ class AdltTestFormat(ShTest): for j in range(len(runCmd)): cmd = runCmd[j] - # then it's the compile command. if f"{srcFile} " in cmd and "clang" in cmd: # Get filename after `-o`. outFile = re.split(r" -o ", cmd)[-1].strip() -- Gitee From 23f1e6c2c856fbda3199a8e630f1449ecce2d4ac Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Thu, 12 Dec 2024 10:29:42 +0300 Subject: [PATCH 06/13] Disable unsupported tests, update documentation --- docs/DEBUGGING.md | 3 ++ lit-tests/compiler-rt/asan/lit.site.cfg.py | 46 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/docs/DEBUGGING.md b/docs/DEBUGGING.md index 82b88e7..f94895f 100644 --- a/docs/DEBUGGING.md +++ b/docs/DEBUGGING.md @@ -32,6 +32,9 @@ ADLT_TRACE=1 ./main.py -cb ... # run all tests from base/ folder with --no-relax for output ADLT libs. ADLT_NO_RELAX=1 ./main.py -cb base -r base + +# run asan lit-tests from compiler-rt: +python3 tools/run_lit_sanitizers.py --test asan --llvm-project $HOME/work/sdk/toolchain/llvm-project/ ``` ### Debugging notes diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index 0dc7de3..5e8ae9e 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -107,6 +107,52 @@ unsupported = [ # The test does not contain C/C++ code, it is empty and designed for compilation only. "TestCases/default_ignorelist.cpp", + + # Tests fail on arm64 host: + "TestCases/Linux/function-sections-are-bad.cpp", + "TestCases/Linux/initialization-bug-any-order.cpp", + "TestCases/Posix/asan-sigbus.cpp", + "TestCases/Posix/global-registration.c", + "TestCases/Posix/handle_abort_on_error.cpp", + "TestCases/Posix/print_cmdline.cpp", + "TestCases/Posix/shared-lib-test.cpp", + "TestCases/Posix/start-deactivated.cpp", + "TestCases/asan_options-help.cpp", + "TestCases/default_options.cpp", + "TestCases/printf-2.c", + "TestCases/sleep_for_debugger.c", + "TestCases/strcasestr-1.c", + "TestCases/strcasestr-2.c", + "TestCases/strstr-1.c", + "TestCases/strstr-2.c", + + # Problems in runtime (e.g. segfault) when using qemu. + "TestCases/Linux/clone_test.cpp", + "TestCases/Linux/interception_malloc_test.cpp", + "TestCases/Linux/interception_test.cpp", + "TestCases/Linux/quarantine_size_mb.cpp", + "TestCases/Linux/segv_read_write.c", + "TestCases/Posix/closed-fds.cpp", + "TestCases/Posix/deep_call_stack.cpp", + "TestCases/Posix/free_hook_realloc.cpp", + "TestCases/Posix/halt_on_error-torture.cpp", + "TestCases/Posix/handle_abort_on_error.cpp", + "TestCases/Posix/no-fd.cpp", + "TestCases/Posix/strndup_oob_test.cpp", + "TestCases/Posix/strndup_oob_test2.cpp", + "TestCases/coverage-disabled.cpp", + "TestCases/debug_double_free.cpp", + "TestCases/debug_report.cpp", + "TestCases/exitcode.cpp", + "TestCases/interception_failure_test.cpp", + "TestCases/interface_test.cpp", + "TestCases/log-path_test.cpp", + "TestCases/malloc-no-intercept.c", + "TestCases/null_deref.cpp", + "TestCases/on_error_callback.cpp", + "TestCases/replaceable_new_delete.cpp", + "TestCases/suppressions-exec-relative-location.cpp", + "TestCases/throw_invoke_test.cpp", ] config.available_features.add("ohos_family") -- Gitee From 34664b0a7fc58ac912164ec1bfa20e1125ef772c Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Thu, 19 Dec 2024 01:51:55 +0300 Subject: [PATCH 07/13] Updated script: added support for -c, -shared, multisource tests --- lit-tests/compiler-rt/asan/lit.site.cfg.py | 72 ------- .../compiler-rt/common/adlt_test_format.py | 200 ++++++++++++++---- 2 files changed, 157 insertions(+), 115 deletions(-) diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index 5e8ae9e..c04cee0 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -29,78 +29,6 @@ unsupported = [ "TestCases/malloc_fill.cpp", "TestCases/realloc.cpp", - # Multiple source files in the test: - "TestCases/Darwin/unset-insert-libraries-on-exec.cpp", - "TestCases/Linux/initialization-bug-any-order.cpp", - "TestCases/Windows/iostream_sbo.cpp", - "TestCases/global-underflow.cpp", - "TestCases/ignorelist.cpp", - "TestCases/init-order-atexit.cpp", - "TestCases/initialization-bug.cpp", - "TestCases/initialization-constexpr.cpp", - "TestCases/initialization-ignorelist.cpp", - "TestCases/initialization-nobug.cpp", - - # Two build steps with `-c`. - # TODO: support in the future. - "TestCases/Darwin/cstring_section.c", - "TestCases/Darwin/empty-section.cpp", - "TestCases/Darwin/haswell-symbolication.cpp", - "TestCases/Darwin/linked-only.cpp", - "TestCases/Darwin/mixing-global-constructors.cpp", - "TestCases/Darwin/odr-lto.cpp", - "TestCases/Linux/activation-options.cpp", - "TestCases/Linux/local_alias.cpp", - "TestCases/Linux/longjmp_chk.c", - "TestCases/Posix/global-registration.c", - "TestCases/Posix/init-order-pthread-create.cpp", - "TestCases/Posix/start-deactivated.cpp", - "TestCases/Windows/dll_and_lib.cpp", - "TestCases/Windows/dll_large_function.cpp", - "TestCases/Windows/seh.cpp", - "TestCases/Windows/unsymbolized.cpp", - "TestCases/coverage-trace-pc.cpp", - - # The output file is a .so file. - # TODO: support in the future. - "TestCases/Linux/activation-options.cpp", - "TestCases/Linux/asan_preload_test-1.cpp", - "TestCases/Linux/dlopen-mixed-c-cxx.c", - "TestCases/Linux/function-sections-are-bad.cpp", - "TestCases/Linux/init-order-dlopen.cpp", - "TestCases/Linux/printf-fortify-1.c", - "TestCases/Linux/printf-fortify-2.c", - "TestCases/Linux/printf-fortify-3.c", - "TestCases/Linux/printf-fortify-4.c", - "TestCases/Linux/printf-fortify-5.c", - "TestCases/Linux/pthread_create_from_constructor.cpp", - "TestCases/Linux/static_tls.cpp", - "TestCases/Posix/asan-symbolize-sanity-test.cpp", - "TestCases/Posix/dlclose-test.cpp", - "TestCases/Posix/shared-lib-test.cpp", - "TestCases/Posix/start-deactivated.cpp", - - # Tests without launch steps (compilation only): - "TestCases/Linux/globals-gc-sections-lld.cpp", - "TestCases/malloc-no-intercept.c", - - # Complex command parsing. - # TODO: support in the future. - "TestCases/Linux/read_binary_name_regtest.c", - - # Tests using -shared libraries: - # TODO: support in the future. - "TestCases/Linux/odr-violation.cpp", - "TestCases/Linux/odr-vtable.cpp", - "TestCases/Linux/odr_c_test.c", - "TestCases/Linux/preinit_test.cpp", - "TestCases/Linux/stress_dtls.c", - "TestCases/Posix/coverage-module-unloaded.cpp", - "TestCases/Posix/coverage-reset.cpp", - "TestCases/Posix/coverage.cpp", - "TestCases/Posix/interception-in-shared-lib-test.cpp", - "TestCases/suppressions-library.cpp", - # Compilation error, clang is used instead of clang++. # "error: ISO C++ forbids forward references to 'enum' types" "TestCases/Linux/ptrace.cpp", diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index bdc09f0..70c0098 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -19,6 +19,25 @@ from tools import shell from config import Config +def get_output_from_cmd(cmd: str) -> tuple[str, str]: + """ + Finding output file and defining its type in the input command. + """ + output = None + output_type = "executable" + + while cmd: + arg = cmd.pop(0) + if arg == "-shared" or arg == "-dynamiclib": + output_type = "shared" + elif arg == "-c": + output_type = "object" + elif arg == "-o": + output = cmd.pop(0) + + return output, output_type + + class AdltTestFormat(ShTest): """ AdltTestFormat class. @@ -106,7 +125,6 @@ class AdltTestFormat(ShTest): Adding additional commands (builds, linking, etc.) to the original command to run tests using ADLT. """ tmpDir, tmpBase = TR.getTempPaths(test) - testExt = tmpBase.split(".")[-1] srcFile = test.getSourcePath() @@ -132,6 +150,15 @@ class AdltTestFormat(ShTest): ) shell(f"python3 {ROOT_DIR}/tools/gen_qemu_env.py -od {tmpDir}") + # To store output files of different commands. + outputHistory = {} + + # For mapping old input files to new ones. + inputsMapping = {} + + # To store ADLT input libraries. + inputLibs = [] + # Updating the script commands. for i in range(len(script)): # Sometimes, a RUN script may contain multiple commands separated by `&&`, @@ -141,56 +168,143 @@ class AdltTestFormat(ShTest): for j in range(len(runCmd)): cmd = runCmd[j] - if f"{srcFile} " in cmd and "clang" in cmd: - # Get filename after `-o`. - outFile = re.split(r" -o ", cmd)[-1].strip() - outFile = outFile.split(" ")[0] - - # Add compilation step with `-c`. - compileOut = f"{outFile}.o" - compileCmd = f"{srcFile} -fPIC -c " - compileCmd = cmd.replace(f"{srcFile} ", compileCmd) - compileCmd = compileCmd.replace(outFile, compileOut) - - croppedCmd = cmd[:] - croppedCmd = re.sub(".*%.*RUN.*\) +", "", croppedCmd) - croppedCmd = re.sub(r" +", " ", croppedCmd) - croppedCmd = re.sub(r"^.*?clang", "clang", croppedCmd) - - # Add object file linking step. - linkOut = f"{outFile}.so" - linkCmd = croppedCmd - linkCmd = linkCmd.replace(outFile, linkOut) - linkCmd = linkCmd.replace( - f"{srcFile} ", - f"-fPIC -Wl,--emit-relocs -shared {compileOut} -Wl,-soname,{linkOut} ", - ) + if not "clang" in cmd: + continue - # Add the lld call with --adlt. - adltOut = f"{linkOut}.adlt" - adltCmd = croppedCmd - adltCmd = adltCmd.split(" ")[0] - adltCmd = f"{adltCmd} --adlt {linkOut} -o {adltOut} --emit-relocs" - adltCmd = adltCmd.replace("clang", "ld.lld") + # Remove the extra from command and add space at the end (for correct replacement). + cmd = re.sub(".*%.*RUN.*\) +", "", cmd) + cmd = re.sub(r" +", " ", cmd) + cmd += " " - # Add wrapper for main. - clangPath = croppedCmd.split(" ")[0].replace("clang++", "clang") - mainOut = f"{outFile}.main.o" - mainCmd = f"{clangPath} {defines} --target=aarch64-linux-ohos -c {SCRIPT_DIR}/main.c -o {mainOut}" + outputName, outputType = get_output_from_cmd(cmd.split(" ")) + if outputName is None: + continue + + outputHistory[outputName] = (outputType, cmd) + + # If the command contains `-c`, we extend it with an additional option. + if outputType == "object": + runCmd[j] = f"{cmd} -fPIC" + continue - # Link the wrapper for main and the test shared library. - linkAllArgs = f"-Wl,--wrap=main --rtlib=compiler-rt -Wl,--emit-relocs {mainOut} {linkOut} " - linkAllCmd = croppedCmd - linkAllCmd = linkAllCmd.replace(f"{srcFile} ", linkAllArgs) + # If the command contains `-shared', we extend it with additional options required for ADLT compatibility. + elif outputType == "shared": + runCmd[j] = ( + f"{cmd} -Wl,--emit-relocs,--no-relax -Wl,-soname,{outputName} " + ) + inputLibs.append(outputName) + continue + + # If the command expects a binary file, the processing is more complicated. + elif outputType == "executable": + outCmd = [] + + # Get a list of all input files (*.cpp, *.c, .o, .so) from the command. + cmdWithoutOutput = cmd.replace(f" {outputName} ", " ") + inputFiles = [ + s.strip() + for s in re.findall(r" \/\S+\.(?:cpp|o|so|c)", cmdWithoutOutput) + ] + + # Now we need to process each file separately. + for inFile in inputFiles: + name = inFile.split("/")[-1] + + # If it's a library, we'll remember it for ADLT. + if name.endswith(".so"): + if inFile not in inputFiles: + inputLibs.append(inFile) + continue + + # If it's an object file, we need to do some additional linking. + elif name.endswith(".o"): + # For linking, we will reuse the command that was for compiling to an object file. + _, compCmd = outputHistory[inFile] + compCmd += " " + + srcFile = re.findall(r" \S+\.(?:c|cpp) ", compCmd)[ + 0 + ].strip() + + linkOut = f"{inFile}.so" + linkCmd = compCmd.replace( + f" -o {inFile} ", f" -o {linkOut} " + ) + linkCmd = linkCmd.replace(f" {srcFile} ", f" {inFile} ") + linkCmd = f"{linkCmd} -fPIC -Wl,--emit-relocs -shared -Wl,-soname,{linkOut}" + linkCmd = linkCmd.replace(" -c ", " ") + + outCmd.append(linkCmd) + inputLibs.append(linkOut) + inputsMapping[inFile] = linkOut + continue + + # If it's C/C++ source, we need to compile manually. + elif name.endswith(".cpp") or name.endswith(".c"): + newCmd = f"{cmd} " + # Remove all unnecessary files from command. + for f in inputFiles: + if f != inFile: + newCmd = newCmd.replace(f" {f} ", " ") + + # Add compilation step with `-c`. + compileOut = f"{tmpDir}/{name}.o" + compileCmd = newCmd.replace( + f"{inFile} ", f"{inFile} -fPIC -c " + ) + compileCmd = compileCmd.replace( + f" {outputName}", f" {compileOut}" + ) + outCmd.append(compileCmd) + + # Add object file linking step. + linkOut = f"{compileOut}.so" + linkCmd = newCmd.replace(f" {outputName}", f" {linkOut}") + linkCmd = linkCmd.replace( + f"{inFile} ", + f" -fPIC -Wl,--emit-relocs,--no-relax -shared {compileOut} -Wl,-soname,{linkOut} ", + ) + outCmd.append(linkCmd) + inputLibs.append(linkOut) + inputsMapping[inFile] = linkOut + else: + raise RuntimeError( + f"The file type isn't supported: {inFile}" + ) + + # In the output command update the input files. + for oldFile, newFile in inputsMapping.items(): + cmd = cmd.replace(f" {oldFile} ", f" {newFile} ") + + # Add the lld call with --adlt. + adltInputLibs = " ".join(inputLibs) + adltOut = f"{outputName}.adlt" + adltCmd = ( + f"ld.lld --adlt {adltInputLibs} -o {adltOut} --emit-relocs" + ) + outCmd.append(adltCmd) # For library we need to call adlt_makelinks.py, to set the links. # It's mandatory to pass environment variables, since llvm-lit clears them. - makelinksCmd = f"env SDK_ROOT={Config.SDK_ROOT} LLVM={Config.LLVM} python3 {ROOT_DIR}/tools/adlt_makelinks.py -i {linkOut} -od {tmpDir}/lib -o {adltOut}" + makelinksCmd = f"env SDK_ROOT={Config.SDK_ROOT} LLVM={Config.LLVM} python3 {ROOT_DIR}/tools/adlt_makelinks.py -i {adltInputLibs} -od {tmpDir}/lib -o {adltOut}" + outCmd.append(makelinksCmd) - # Combine all the commands into one and replace. - runCmd[j] = ( - f"{compileCmd} && {linkCmd} && {adltCmd} && {mainCmd} && {linkAllCmd} && {makelinksCmd}" + # Add wrapper for main. + mainOut = f"{outputName}.main.o" + mainCmd = cmd.replace("clang++", "clang") + mainCmd = mainCmd.replace(f" -o {outputName} ", " ") + mainCmd = re.sub(r" \/\S+\.(?:cpp|o|so|c)", " ", mainCmd) + mainCmd = f"{mainCmd} -x c -std=c99 {defines} -o {mainOut} -c {SCRIPT_DIR}/main.c" + outCmd.append(mainCmd) + + cmd = cmd.replace( + " -o ", + f" -Wl,--wrap=main --rtlib=compiler-rt -Wl,--emit-relocs {mainOut} -o ", ) + outCmd.append(cmd) + + # Combine all the commands into one. + runCmd[j] = " && ".join(outCmd) # If there were multiple commands, then update. script[i] = " && ".join(runCmd) -- Gitee From 3e5611fb49fca09662d9cef1f211b42a732a8d14 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 24 Dec 2024 00:24:56 +0300 Subject: [PATCH 08/13] Refactoring --- .../compiler-rt/common/adlt_test_format.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 70c0098..50db0f9 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -171,10 +171,12 @@ class AdltTestFormat(ShTest): if not "clang" in cmd: continue - # Remove the extra from command and add space at the end (for correct replacement). - cmd = re.sub(".*%.*RUN.*\) +", "", cmd) - cmd = re.sub(r" +", " ", cmd) - cmd += " " + # Commands not related to compilation - let's separate them. + clangPos = re.search(r'\S+\/clang', cmd) + leftCmd, cmd = cmd[:clangPos.start()], cmd[clangPos.start():] + + # Add a space at the end for correct replacement. + cmd = f"{cmd} " outputName, outputType = get_output_from_cmd(cmd.split(" ")) if outputName is None: @@ -192,7 +194,6 @@ class AdltTestFormat(ShTest): runCmd[j] = ( f"{cmd} -Wl,--emit-relocs,--no-relax -Wl,-soname,{outputName} " ) - inputLibs.append(outputName) continue # If the command expects a binary file, the processing is more complicated. @@ -212,8 +213,7 @@ class AdltTestFormat(ShTest): # If it's a library, we'll remember it for ADLT. if name.endswith(".so"): - if inFile not in inputFiles: - inputLibs.append(inFile) + inputLibs.append(inFile) continue # If it's an object file, we need to do some additional linking. @@ -306,6 +306,9 @@ class AdltTestFormat(ShTest): # Combine all the commands into one. runCmd[j] = " && ".join(outCmd) + if len(leftCmd) > 0: + runCmd[j] = f"{leftCmd} {runCmd[j]}" + # If there were multiple commands, then update. script[i] = " && ".join(runCmd) -- Gitee From aa9c7190dc6f9ebd3a3347bad5807d2ab3a82cf8 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 24 Dec 2024 01:05:28 +0300 Subject: [PATCH 09/13] Remove extra brackets from cmd and apply black formatter --- lit-tests/compiler-rt/common/adlt_test_format.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 50db0f9..4f97851 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -166,17 +166,20 @@ class AdltTestFormat(ShTest): runCmd = script[i].split("&&") for j in range(len(runCmd)): - cmd = runCmd[j] + # Add a space at the end for correct replacement. + cmd = f"{runCmd[j]} " + + # Some tests contain brackets in commands, it is advisable to remove them so as not to break the structure. + for br in ["(", "{", "}", ")"]: + cmd = cmd.replace(f" {br} ", " ") if not "clang" in cmd: + runCmd[j] = cmd continue # Commands not related to compilation - let's separate them. - clangPos = re.search(r'\S+\/clang', cmd) - leftCmd, cmd = cmd[:clangPos.start()], cmd[clangPos.start():] - - # Add a space at the end for correct replacement. - cmd = f"{cmd} " + clangPos = re.search(r"\S+\/clang", cmd) + leftCmd, cmd = cmd[: clangPos.start()], cmd[clangPos.start() :] outputName, outputType = get_output_from_cmd(cmd.split(" ")) if outputName is None: -- Gitee From 9df6d6174147e3238cadde53287e9fa589f45d78 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Tue, 24 Dec 2024 01:05:55 +0300 Subject: [PATCH 10/13] Disable unsupported tests --- lit-tests/compiler-rt/asan/lit.site.cfg.py | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index c04cee0..e7fc15c 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -36,6 +36,27 @@ unsupported = [ # The test does not contain C/C++ code, it is empty and designed for compilation only. "TestCases/default_ignorelist.cpp", + # Very long test execution time: + "TestCases/Linux/stress_dtls.c", + + # Tests not designed to use shared libraries: + "TestCases/Linux/activation-options.cpp", + "TestCases/Linux/globals-gc-sections-lld.cpp", + "TestCases/Posix/coverage.cpp", + "TestCases/coverage-trace-pc.cpp", + "TestCases/global-underflow.cpp", + "TestCases/initialization-bug.cpp", + + # Tests are not designed to use musl libc: + "TestCases/Linux/init-order-dlopen.cpp", + "TestCases/Linux/printf-fortify-1.c", + "TestCases/Linux/printf-fortify-2.c", + "TestCases/Linux/printf-fortify-3.c", + "TestCases/Linux/printf-fortify-4.c", + + # No %run variable in lit-steps: + "TestCases/Linux/dlopen-mixed-c-cxx.c", + # Tests fail on arm64 host: "TestCases/Linux/function-sections-are-bad.cpp", "TestCases/Linux/initialization-bug-any-order.cpp", @@ -81,6 +102,8 @@ unsupported = [ "TestCases/replaceable_new_delete.cpp", "TestCases/suppressions-exec-relative-location.cpp", "TestCases/throw_invoke_test.cpp", + "TestCases/verbose-log-path_test.cpp", + "TestCases/global-location-nodebug.cpp", ] config.available_features.add("ohos_family") -- Gitee From 508530311f83f522029b7bb96b385aa56dc01e97 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Wed, 25 Dec 2024 22:15:44 +0300 Subject: [PATCH 11/13] Add support for running ubsan tests --- lit-tests/compiler-rt/asan/lit.site.cfg.py | 2 +- .../compiler-rt/common/adlt_test_format.py | 21 +++++++--- lit-tests/compiler-rt/ubsan/lit.site.cfg.py | 39 +++++++++++++++++++ tools/run_lit_sanitizers.py | 2 +- 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 lit-tests/compiler-rt/ubsan/lit.site.cfg.py diff --git a/lit-tests/compiler-rt/asan/lit.site.cfg.py b/lit-tests/compiler-rt/asan/lit.site.cfg.py index e7fc15c..9759612 100644 --- a/lit-tests/compiler-rt/asan/lit.site.cfg.py +++ b/lit-tests/compiler-rt/asan/lit.site.cfg.py @@ -1,5 +1,5 @@ """ -@file adlt.asan.site.cfg.py +@file lit.site.cfg.py @brief The script describes the settings for running asan lit based tests with ADLT. """ diff --git a/lit-tests/compiler-rt/common/adlt_test_format.py b/lit-tests/compiler-rt/common/adlt_test_format.py index 4f97851..1b2ac55 100644 --- a/lit-tests/compiler-rt/common/adlt_test_format.py +++ b/lit-tests/compiler-rt/common/adlt_test_format.py @@ -203,11 +203,13 @@ class AdltTestFormat(ShTest): elif outputType == "executable": outCmd = [] - # Get a list of all input files (*.cpp, *.c, .o, .so) from the command. + # Get a list of all input files (*.cpp, *.c, *.o, *.so, *.m) from the command. cmdWithoutOutput = cmd.replace(f" {outputName} ", " ") inputFiles = [ s.strip() - for s in re.findall(r" \/\S+\.(?:cpp|o|so|c)", cmdWithoutOutput) + for s in re.findall( + r" \/\S+\.(?:cpp|o|so|c|m)", cmdWithoutOutput + ) ] # Now we need to process each file separately. @@ -225,7 +227,7 @@ class AdltTestFormat(ShTest): _, compCmd = outputHistory[inFile] compCmd += " " - srcFile = re.findall(r" \S+\.(?:c|cpp) ", compCmd)[ + srcFile = re.findall(r" \S+\.(?:c|cpp|m) ", compCmd)[ 0 ].strip() @@ -233,6 +235,7 @@ class AdltTestFormat(ShTest): linkCmd = compCmd.replace( f" -o {inFile} ", f" -o {linkOut} " ) + linkCmd = re.sub(r"\-x (c\+\+|c)", " ", linkCmd) linkCmd = linkCmd.replace(f" {srcFile} ", f" {inFile} ") linkCmd = f"{linkCmd} -fPIC -Wl,--emit-relocs -shared -Wl,-soname,{linkOut}" linkCmd = linkCmd.replace(" -c ", " ") @@ -243,7 +246,11 @@ class AdltTestFormat(ShTest): continue # If it's C/C++ source, we need to compile manually. - elif name.endswith(".cpp") or name.endswith(".c"): + elif ( + name.endswith(".cpp") + or name.endswith(".c") + or name.endswith(".m") + ): newCmd = f"{cmd} " # Remove all unnecessary files from command. for f in inputFiles: @@ -262,7 +269,8 @@ class AdltTestFormat(ShTest): # Add object file linking step. linkOut = f"{compileOut}.so" - linkCmd = newCmd.replace(f" {outputName}", f" {linkOut}") + linkCmd = re.sub(r"\-x (c\+\+|c)", " ", newCmd) + linkCmd = linkCmd.replace(f" {outputName}", f" {linkOut}") linkCmd = linkCmd.replace( f"{inFile} ", f" -fPIC -Wl,--emit-relocs,--no-relax -shared {compileOut} -Wl,-soname,{linkOut} ", @@ -296,7 +304,7 @@ class AdltTestFormat(ShTest): mainOut = f"{outputName}.main.o" mainCmd = cmd.replace("clang++", "clang") mainCmd = mainCmd.replace(f" -o {outputName} ", " ") - mainCmd = re.sub(r" \/\S+\.(?:cpp|o|so|c)", " ", mainCmd) + mainCmd = re.sub(r" \/\S+\.(?:cpp|o|so|c|m)", " ", mainCmd) mainCmd = f"{mainCmd} -x c -std=c99 {defines} -o {mainOut} -c {SCRIPT_DIR}/main.c" outCmd.append(mainCmd) @@ -304,6 +312,7 @@ class AdltTestFormat(ShTest): " -o ", f" -Wl,--wrap=main --rtlib=compiler-rt -Wl,--emit-relocs {mainOut} -o ", ) + cmd = re.sub(r"\-x (c\+\+|c)", " ", cmd) outCmd.append(cmd) # Combine all the commands into one. diff --git a/lit-tests/compiler-rt/ubsan/lit.site.cfg.py b/lit-tests/compiler-rt/ubsan/lit.site.cfg.py new file mode 100644 index 0000000..b960f03 --- /dev/null +++ b/lit-tests/compiler-rt/ubsan/lit.site.cfg.py @@ -0,0 +1,39 @@ +""" +@file lit.site.cfg.py + +@brief The script describes the settings for running ubsan lit based tests with ADLT. +""" + +import os +import sys + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +ROOT_DIR = f"{SCRIPT_DIR}/../../../" +UBSAN_DIR = f"{ROOT_DIR}/out/build/lit-tests/compiler-rt/test/ubsan/Standalone-aarch64" + +sys.path.append(f"{SCRIPT_DIR}/../common") + +from adlt_test_format import AdltTestFormat + +unsupported = [ + # Requires changes to the source file: + "TestCases/Integer/suppressions.cpp", + + # Not designed to use shared libraries: + "TestCases/Misc/Linux/diag-stacktrace.cpp", + "TestCases/Misc/Linux/ubsan_options.cpp", + "TestCases/Misc/bounds.cpp", + "TestCases/Misc/monitor.cpp", +] + +config.available_features.add("ohos_family") +config.host_os = "Linux" + +lit_config.load_config( + config, + f"{UBSAN_DIR}/lit.site.cfg.py", +) + +config.test_format = AdltTestFormat(unsupported) +config.test_exec_root = UBSAN_DIR +config.lit_test_times = f"{UBSAN_DIR}/lit_test_times.txt" diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py index 721c96a..ca2e183 100644 --- a/tools/run_lit_sanitizers.py +++ b/tools/run_lit_sanitizers.py @@ -9,7 +9,7 @@ from config import Config from tools import shell # TODO: Support more tests. -supportedTests = ["asan"] +supportedTests = ["asan", "ubsan"] def parseArgs() -> argparse.Namespace: -- Gitee From 872a5ed3ba90cf62e1e49c0702ff8e196b2a93e4 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Fri, 27 Dec 2024 14:35:02 +0300 Subject: [PATCH 12/13] Add support for running tsan tests --- lit-tests/compiler-rt/common/qemu.py | 5 +- lit-tests/compiler-rt/tsan/lit.site.cfg.py | 87 ++++++++++++++++++++++ tools/run_lit_sanitizers.py | 22 ++++-- 3 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 lit-tests/compiler-rt/tsan/lit.site.cfg.py diff --git a/lit-tests/compiler-rt/common/qemu.py b/lit-tests/compiler-rt/common/qemu.py index 70723b6..ca0a6bd 100755 --- a/lit-tests/compiler-rt/common/qemu.py +++ b/lit-tests/compiler-rt/common/qemu.py @@ -10,8 +10,11 @@ import subprocess runFile = sys.argv[1] workingDir = os.path.dirname(runFile) + +envArgs = f"LD_LIBRARY_PATH={workingDir}/lib MUSL_LOG_DISABLE_CONNECT=1" + cmd = ( - f"MUSL_LOG_DISABLE_CONNECT=1 qemu-aarch64-static -L {workingDir} -E -LD_LIBRARY_PATH={workingDir} " + f"{envArgs} qemu-aarch64-static -L {workingDir} -E -LD_LIBRARY_PATH={workingDir} " + " ".join(sys.argv[1:]) ) diff --git a/lit-tests/compiler-rt/tsan/lit.site.cfg.py b/lit-tests/compiler-rt/tsan/lit.site.cfg.py new file mode 100644 index 0000000..31bae76 --- /dev/null +++ b/lit-tests/compiler-rt/tsan/lit.site.cfg.py @@ -0,0 +1,87 @@ +""" +@file lit.site.cfg.py + +@brief The script describes the settings for running tsan lit based tests with ADLT. +""" + +import os +import sys + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +ROOT_DIR = f"{SCRIPT_DIR}/../../../" +TSAN_DIR = f"{ROOT_DIR}/out/build/lit-tests/compiler-rt//test/tsan/AARCH64Config" + +sys.path.append(f"{SCRIPT_DIR}/../common") + +from adlt_test_format import AdltTestFormat + +unsupported = [ + # Very long test execution time: + "Linux/check_preinit.cpp", + "Linux/fork_deadlock.cpp", + "Linux/fork_multithreaded4.cpp", + "Linux/user_fopen.cpp", + "atexit2.cpp", + "atexit4.cpp", + "atexit5.cpp", + "atomic_free.cpp", + "atomic_norace2.cpp" "atomic_norace2.cpp", + "atomic_race.cpp", + "bench_acquire_only.cpp", + "bench_local_mutex.cpp", + "bench_threads.cpp", + "bench_threads.cpp", + "compare_exchange.cpp", + "cond_destruction.cpp", + "force_background_thread.cpp", + "fork_atexit.cpp", + "fork_multithreaded.cpp", + "fork_multithreaded3.cpp", + "free_race3.c", + "signal_block.cpp", + "signal_thread.cpp", + "tls_race.cpp", + "tls_race2.cpp", + "unaligned_race.cpp", + "vfork.cpp", + + # Tests not designed to use shared libraries: + "Linux/user_malloc.cpp", + "cxa_guard_acquire.cpp", + "deadlock_detector_stress_test.cpp", + "debugging.cpp", + "default_options.cpp", + "dlopen_ns.cpp", + "java_symbolization.cpp", + "java_symbolization_legacy.cpp", + "large_malloc_meta.cpp", + "lots_of_threads.c", + + # Problems in runtime (e.g. segfault) when using qemu: + "Linux/clone_setns.cpp", + "fiber_cleanup.cpp", + "mmap_large.cpp", + "mmap_lots.cpp", + "mutex_cycle_long.c", + "signal_handler_longjmp.cpp", + "signal_reset.cpp", + + # Errors in linking. Need to fix sources to fix: + "atexit.cpp", + "global_race.cpp", + "ignore_dlclose.cpp", + "ignore_lib2.cpp", + "libcxx_call_once.cpp", +] + +config.available_features.add("ohos_family") +config.host_os = "Linux" + +lit_config.load_config( + config, + f"{TSAN_DIR}/lit.site.cfg.py", +) + +config.test_format = AdltTestFormat(unsupported) +config.test_exec_root = TSAN_DIR +config.lit_test_times = f"{TSAN_DIR}/lit_test_times.txt" diff --git a/tools/run_lit_sanitizers.py b/tools/run_lit_sanitizers.py index ca2e183..2b21a3c 100644 --- a/tools/run_lit_sanitizers.py +++ b/tools/run_lit_sanitizers.py @@ -9,13 +9,18 @@ from config import Config from tools import shell # TODO: Support more tests. -supportedTests = ["asan", "ubsan"] +supportedTests = ["asan", "ubsan", "tsan"] + +# Some tests require additional libraries to be built, so we need to take this into account. +extraBuildTargets = {"tsan": ["libcxx_tsan_aarch64"]} def parseArgs() -> argparse.Namespace: """ Parsing command line arguments. """ + global supportedTests + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) parser.add_argument( "--test", @@ -40,13 +45,16 @@ def parseArgs() -> argparse.Namespace: return args -def configureCompilerRt(llvmProject: str, llvmInstall: str) -> None: +def configureCompilerRtAndBuild( + llvmProject: str, llvmInstall: str, buildTargets: list = [] +) -> None: """ Configuring a compiler-rt project using CMake to run lit tests. Args: llvmProject (str): Path to llvm project directory. llvmInstall (str): Path to llvm binaries. + buildTargets (list): List of additional targets to build. """ workDir = Config.BUILD_DIR / "lit-tests" / "compiler-rt" shell(f"rm -rf {workDir}") @@ -83,11 +91,13 @@ def configureCompilerRt(llvmProject: str, llvmInstall: str) -> None: -DCOMPILER_RT_TEST_COMPILER="{llvmInstall}/bin/clang" \ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=aarch64-linux-ohos -B{Config.SYSROOT}/lib -L{Config.SYSROOT}/lib -I{Config.SYSROOT}/include" \ -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF \ - -DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON \ """ shell(cmakeCmd) + for target in buildTargets: + shell(f"ninja -C {workDir} {target}") + def run(test: str) -> None: """ @@ -104,7 +114,7 @@ def run(test: str) -> None: def main() -> None: - global supportedTests + global supportedTests, extraBuildTargets args = parseArgs() @@ -115,7 +125,9 @@ def main() -> None: if not args.llvm_project: print("The path to llvm-project is not set! Use --help.") - configureCompilerRt(args.llvm_project, args.llvm_install) + configureCompilerRtAndBuild( + args.llvm_project, args.llvm_install, extraBuildTargets.get(args.test, []) + ) run(args.test) -- Gitee From 50df84d5b2af41dc46e71a7c6d84e7033d57b4c8 Mon Sep 17 00:00:00 2001 From: streshchukvitaly Date: Fri, 27 Dec 2024 14:51:35 +0300 Subject: [PATCH 13/13] Update README.md for compiler-rt lit-tests --- docs/DEBUGGING.md | 3 +++ lit-tests/compiler-rt/README.md | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/docs/DEBUGGING.md b/docs/DEBUGGING.md index f94895f..c9655c7 100644 --- a/docs/DEBUGGING.md +++ b/docs/DEBUGGING.md @@ -35,6 +35,9 @@ ADLT_NO_RELAX=1 ./main.py -cb base -r base # run asan lit-tests from compiler-rt: python3 tools/run_lit_sanitizers.py --test asan --llvm-project $HOME/work/sdk/toolchain/llvm-project/ + +# run ubsan lit-tests from compiler-rt: +python3 tools/run_lit_sanitizers.py --test ubsan --llvm-project $HOME/work/sdk/toolchain/llvm-project/ ``` ### Debugging notes diff --git a/lit-tests/compiler-rt/README.md b/lit-tests/compiler-rt/README.md index 20ed77a..b0212e8 100644 --- a/lit-tests/compiler-rt/README.md +++ b/lit-tests/compiler-rt/README.md @@ -15,6 +15,11 @@ Contents: - `cmake/Platform/OHOS.cmake` - file with CMake configuration for building. - `asan`: - `asan/lit.site.cfg.py` - configuration for running `asan` tests. +- `ubsan`: + - `ubsan/lit.site.cfg.py` - configuration for running `ubsan` tests. +- `tsan`: + - `tsan/lit.site.cfg.py` - configuration for running `tsan` tests. + To add a new test, you need to: -- Gitee