diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 98ade77f0d76336aef56abe4ffdefdfbb1834bb4..a5247bb17cb74cf172223a775f6df2da16cd60e6 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -124,6 +124,7 @@ endif() pythonize_bool(ANDROID) pythonize_bool(OHOS_FAMILY) +pythonize_bool(OHOS_HOST) set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 869d0e233ef34d946260aae60ad71b1cfc4b2121..f3f7153e734004be42ecf471a3fce5bf08dccfbf 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -274,10 +274,14 @@ elif is_ohos_family_mobile(): # FIXME: some tests for hos also need this now, # probably this shouldn't be added for ohos config.available_features.add('android') - compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", "ohos_compile.py") + " " - config.compile_wrapper = compile_wrapper config.substitutions.append( ('%run', "") ) config.substitutions.append( ('%env ', "env ") ) + if config.ohos_host: + compile_wrapper_name = "ohos_host_compile.py" + else: + compile_wrapper_name = "ohos_compile.py" + compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", compile_wrapper_name) + " " + config.compile_wrapper = compile_wrapper tool_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", "ohos_tool.py") + " " tools.append(ToolSubst('llvm-objdump', command=WrapTool('llvm-objdump', tool_wrapper), unresolved='fatal')) # OHOS_LOCAL end @@ -542,14 +546,19 @@ elif config.host_os == 'OHOS': sys.path.append(hdc_imp) import hdc_constants env = os.environ.copy() - config.substitutions.append( ('%device_rundir/', hdc_constants.TMPDIR) ) - prefix = hdc_constants.get_hdc_cmd_prefix() - prefix_str = ' '.join(prefix) - config.substitutions.append(('%push_to_device', "%s file send " % prefix_str) ) - config.substitutions.append(('%adb_shell ', "%s shell " % prefix_str) ) - config.substitutions.append(('%device_rm', "%s shell 'rm ' " % prefix_str) ) - subprocess.check_call(prefix + ['tconn'], env=env) - subprocess.check_call(prefix + ['shell', 'mkdir', '-p', hdc_constants.TMPDIR], env=env) + if config.ohos_host: + config.substitutions.append( ('%device_rundir/', "./") ) + config.substitutions.append( ('%push_to_device', "echo ") ) + config.substitutions.append( ('%adb_shell', "") ) + else: + config.substitutions.append( ('%device_rundir/', hdc_constants.TMPDIR) ) + prefix = hdc_constants.get_hdc_cmd_prefix() + prefix_str = ' '.join(prefix) + config.substitutions.append(('%push_to_device', "%s file send " % prefix_str) ) + config.substitutions.append(('%adb_shell ', "%s shell " % prefix_str) ) + config.substitutions.append(('%device_rm', "%s shell 'rm ' " % prefix_str) ) + subprocess.check_call(prefix + ['tconn'], env=env) + subprocess.check_call(prefix + ['shell', 'mkdir', '-p', hdc_constants.TMPDIR], env=env) # OHOS_LOCAL end else: diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index 1a20461cbf7d83c322b717e8fcf506e00e9b6cae..27a03dc7bc16ce0358f18f95a201406a66614a23 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -43,6 +43,7 @@ set_default("use_thinlto", False) set_default("use_lto", config.use_thinlto) set_default("android", @ANDROID_PYBOOL@) set_default("ohos_family", @OHOS_FAMILY_PYBOOL@) +set_default("ohos_host", @OHOS_HOST_PYBOOL@) set_default("android_api_level", "@ANDROID_API_LEVEL@") set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@") set_default("android_files_to_push", []) 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 23a10f2e1109be3d1d4aeb69104a645a65bedb65..88cdb2d5ff443677a76d657fd483ede471ecca97 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 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import os, subprocess, tempfile +import os, subprocess, tempfile, re import hdc_constants verbose = False @@ -56,3 +56,70 @@ def push_to_device(path): # hdc do not auto create directories on device hdc(['shell', 'mkdir', '-p', os.path.dirname(dst_path)]) hdc(['file', 'send', '-m', path, dst_path], attempts=5, check_stdout='FileTransfer finish') + +def map_path(path, do_push): + if os.path.exists(path): + if do_push: + push_to_device(path) + return host_to_device_path(path) + return path + +def map_list(value, sep, regex, get_path_and_do_push): + def repl(m): + path, do_push = get_path_and_do_push(m) + return map_path(path, do_push) + + opts = value.split(sep) + return sep.join(re.sub(regex, repl, opt) for opt in opts) + +def build_env(do_push=True): + args = [] + 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' 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 + symb_name = '%s_SYMBOLIZER_PATH' % san + args.append('%s=%s' % (symb_name, os.environ.get('LLVM_SYMBOLIZER_PATH', + os.path.join(hdc_constants.TMPDIR,'llvm-symbolizer-aarch64')))) + # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. + 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 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']: + # Map TSan or UBSan suppressions file to device + value = map_list(value, ':', r'(?<=suppressions=)(.+)', lambda m: (m.group(1), do_push)) + elif key == 'LD_LIBRARY_PATH': + # Map LD_LIBRARY_PATH to device + value = map_list(value, ':', r'(.+)', lambda m: (m.group(1), False)) + + args.append('%s="%s"' % (key, value)) + return ' '.join(args) + +def get_output_from_args(args): + output = None + output_type = 'executable' + + while args: + arg = args.pop(0) + if arg == '-shared': + output_type = 'shared' + elif arg == '-c': + output_type = 'object' + elif arg == '-o': + output = args.pop(0) + + return output, output_type \ No newline at end of file diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py index b3f48571588e6d7c0bbce42eaf7b4a7d2962f53a..8e2f92c35284ca264491ed22dcf446b94cc9d4f4 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py @@ -7,27 +7,16 @@ from ohos_common import * here = os.path.abspath(os.path.dirname(sys.argv[0])) hos_run = os.path.join(here, 'ohos_run.py') -output = None -output_type = 'executable' - -args = sys.argv[1:] -append_args = [] -check_trgt = False -while args: - arg = args.pop(0) - if arg == '-shared': - output_type = 'shared' - elif arg == '-c': - output_type = 'object' - elif arg == '-o': - output = args.pop(0) -if hdc_constants.DYN_LINKER: - append_args.append('-Wl,--dynamic-linker=' + hdc_constants.DYN_LINKER) +output, output_type = get_output_from_args(sys.argv[1:]) if output == None: print ("No output file name!") sys.exit(1) +append_args = [] +if hdc_constants.DYN_LINKER: + append_args.append('-Wl,--dynamic-linker=' + hdc_constants.DYN_LINKER) + ret = subprocess.call(sys.argv[1:] + append_args) if ret != 0: diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_compile.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_compile.py new file mode 100755 index 0000000000000000000000000000000000000000..c4dbe0523dde2f1c51721b52023ea062ccb5ecc3 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_compile.py @@ -0,0 +1,30 @@ +#!/bin/env python3 + +import os, sys, subprocess +from ohos_common import * + +here = os.path.abspath(os.path.dirname(sys.argv[0])) +hos_run = os.path.join(here, 'ohos_host_run.py') + +output, output_type = get_output_from_args(sys.argv[1:]) + +if output == None: + print ("No output file name!") + sys.exit(1) + +append_args = [] +if hdc_constants.DYN_LINKER: + append_args.append('-Wl,--dynamic-linker=' + hdc_constants.DYN_LINKER) + +# TODO: Fix adding compiler-rt include +sanitizer_include = os.path.abspath(os.path.join(here, "../../../include/")) +append_args.append('-I' + sanitizer_include) + +ret = subprocess.call(sys.argv[1:] + append_args) + +if ret != 0: + sys.exit(ret) + +if output_type == 'executable': + os.rename(output, output + '.real') + os.symlink(hos_run, output) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_run.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_run.py new file mode 100755 index 0000000000000000000000000000000000000000..3f74ee951b775aec9cb562b031e01c202d99426e --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_host_run.py @@ -0,0 +1,27 @@ +#!/bin/env python3 + +import os, signal, sys, subprocess +from ohos_common import * + +device_binary = sys.argv[0] + '.real' +device_env = build_env(False) +device_args = ' '.join(sys.argv[1:]) # FIXME: escape? + +# Currently OHOS set log_path in UBSAN_OPTIONS +# Tests expects to see output in stdout/stderr and fails when it is not there +# So unset UBSAN_OPTIONS before run tests. +result = subprocess.run(f'unset UBSAN_OPTIONS && {device_env} {device_binary} {device_args}', + shell=True, capture_output=True, text=True, timeout=30) + +sys.stdout.write(result.stdout) +sys.stderr.write(result.stderr) +sys.stdout.flush() +sys.stderr.flush() + +retcode = result.returncode + +# If the device process died with a signal, do abort(). +# Not exactly the same, but good enough to fool "not --crash". +if retcode < 0: + os.kill(os.getpid(), signal.SIGABRT) +sys.exit(retcode) 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 a6e7596d2178f8b47680224fbb1c7ff0556d9036..136d46c3a304610b26fedb9fb7226f052f794cdf 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 @@ -5,59 +5,6 @@ import re from ohos_common import * device_binary = host_to_device_path(sys.argv[0]) - -def map_path(path, do_push): - if os.path.exists(path): - if do_push: - push_to_device(path) - return host_to_device_path(path) - return path - -def map_list(value, sep, regex, get_path_and_do_push): - def repl(m): - path, do_push = get_path_and_do_push(m) - return map_path(path, do_push) - - opts = value.split(sep) - return sep.join(re.sub(regex, repl, opt) for opt in opts) - -def build_env(): - args = [] - 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' 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 - symb_name = '%s_SYMBOLIZER_PATH' % san - args.append('%s=%s' % (symb_name, os.environ.get('LLVM_SYMBOLIZER_PATH', - os.path.join(hdc_constants.TMPDIR,'llvm-symbolizer-aarch64')))) - # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. - 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 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']: - # Map TSan or UBSan suppressions file to device - value = map_list(value, ':', r'(?<=suppressions=)(.+)', lambda m: (m.group(1), True)) - elif key == 'LD_LIBRARY_PATH': - # Map LD_LIBRARY_PATH to device - value = map_list(value, ':', r'(.+)', lambda m: (m.group(1), False)) - - args.append('%s="%s"' % (key, value)) - return ' '.join(args) - device_env = build_env() device_args = ' '.join(sys.argv[1:]) # FIXME: escape? device_stdout = device_binary + '.stdout'