llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libunwind

Author: hu1 (huihui15537226823)

<details>
<summary>Changes</summary>

## Summary

This patch adds OHOS AArch64 support for running the libc++ runtimes test
suite, including libc++, libc++abi, and libunwind.

The main pieces are:

- Add OHOS-specific lit configurations for libc++, libc++abi, and libunwind.
- Add an OHOS executor path for running tests on device through HDC.
- Add an OHOS QEMU user-mode executor, which is easier to use for local and CI
  testing when physical OHOS devices are not available.
- Configure OHOS libc++ builds to use the `__h` ABI namespace by default
  through `LIBCXX_ABI_NAMESPACE=__h`.
- Add `ohos-qemu` / `ohos-hdc` lit features so tests can distinguish QEMU
  user-mode from real-device execution.
- Mark a small number of tests unsupported under `ohos-qemu` where QEMU
  user-mode does not match real OHOS device behavior, such as `/proc`, signal
  unwinding, or very thread-heavy stress tests. These tests remain available for
  HDC/device testing.

## Motivation

This makes it possible to continuously validate OHOS libc++ runtimes support
inside the upstream libc++ CI structure.

The QEMU path is the recommended default for general CI usage because it does
not require dedicated phone/device infrastructure. The HDC path is still
supported for real-device validation when an OHOS device is available.

## Sysroot Requirement

The OHOS QEMU sysroot is expected to be provided by the local machine or CI
agent and passed through `--ohos-qemu-sysroot` or `OHOS_QEMU_SYSROOT`. It is not
vendored into the LLVM source tree.

## Local Testing

A typical full OHOS AArch64 QEMU test run can be launched with:

```bash
cd /home/cdx/hwasan/llvm/llvm-project

unset HDC HDC_UTID HDC_TIMEOUT_SECONDS

export OHOS_SYSROOT=/home/xxx/sysroot/aarch64-linux-ohos
export CC=/home/xxx/llvm/out/llvm23-ohos-toolchain-install/bin/clang
export CXX=/home/xxx/llvm/out/llvm23-ohos-toolchain-install/bin/clang++
export OHOS_LIBCXX_ABI_NAMESPACE=__h

libcxx/utils/ci/run-buildbot \
  --ohos-qemu /usr/bin/qemu-aarch64 \
  --ohos-qemu-sysroot /home/xxx/llvm/out/qemu-sysroot-aarch64-linux-ohos \
  --build-dir /home/xxx/oh1/builds/llvm-ohos-qemu-full-habi \
  ohos-aarch64-full \
  2&gt;&amp;1 | tee /home/xxx/oh1/logs/7.9.log
```

The HDC/device path can also be used by providing `HDC`/device environment
variables and running the `ohos-hdc-aarch64-full` builder.

## Notes

The QEMU executor is intended to provide a convenient and reproducible CI mode.
Some tests are intentionally disabled only for `ohos-qemu` when the failure is
caused by QEMU user-mode behavior rather than libc++/libc++abi/libunwind
correctness on a real OHOS device.


---

Patch is 109.83 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/208390.diff


109 Files Affected:

- (modified) cmake/Modules/GetToolchainDirs.cmake (+23-14) 
- (modified) compiler-rt/cmake/Modules/CompilerRTUtils.cmake (+6-2) 
- (modified) compiler-rt/cmake/builtin-config-ix.cmake (+1-1) 
- (modified) compiler-rt/cmake/crt-config-ix.cmake (+1-1) 
- (modified) compiler-rt/lib/builtins/crtbegin.c (+9) 
- (modified) compiler-rt/lib/builtins/emutls.c (+4-4) 
- (modified) libcxx/CMakeLists.txt (+8-2) 
- (modified) libcxx/cmake/config-ix.cmake (+2) 
- (modified) libcxx/include/__config (+3-2) 
- (modified) libcxx/include/__cxx03/__config (+3-2) 
- (modified) libcxx/include/__cxx03/__locale_dir/locale_base_api.h (+1-1) 
- (modified) libcxx/include/__locale_dir/locale_base_api.h (+1-1) 
- (modified) libcxx/src/include/config_elast.h (+2) 
- (added) libcxx/test/configs/llvm-libc++-ohos.cfg.in (+63) 
- (modified) libcxx/test/extensions/clang/clang_modules_include.gen.py (+3) 
- (modified) 
libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
 (+1) 
- (modified) libcxx/test/selftest/dsl/dsl.sh.py (+5) 
- (modified) libcxx/test/selftest/stdin-is-piped.sh.cpp (+1) 
- (modified) 
libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp
 (+3) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
 (+1-1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
 (+1-1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp
 (+2) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
 (+3) 
- (modified) 
libcxx/test/std/input.output/iostream.format/std.manip/setfill_wchar_max.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/cin.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/clog.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcerr-imbue.sh.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcin-imbue.sh.cpp
 (+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcin.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wclog.sh.cpp 
(+1) 
- (modified) 
libcxx/test/std/input.output/syncstream/osyncstream/thread/several_threads.pass.cpp
 (+2) 
- (modified) 
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp
 (+1) 
- (modified) 
libcxx/test/std/localization/locales/locale/locale.cons/default.pass.cpp (+1) 
- (modified) libcxx/test/std/re/re.traits/transform.pass.cpp (+1) 
- (modified) libcxx/test/std/re/re.traits/transform_primary.pass.cpp (+1) 
- (modified) 
libcxx/test/std/thread/futures/futures.async/thread_create_failure.pass.cpp 
(+1) 
- (modified) libcxx/test/std/thread/thread.jthread/join.deadlock.pass.cpp (+1) 
- (modified) 
libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp 
(+1) 
- (modified) libcxx/test/support/count_new.h (+28) 
- (modified) libcxx/test/support/filesystem_test_helper.h (+3-1) 
- (modified) libcxx/test/support/test_macros.h (+3-1) 
- (modified) libcxx/utils/ci/buildkite-pipeline.yml (+15) 
- (modified) libcxx/utils/ci/run-buildbot (+91) 
- (added) libcxx/utils/ci/vendor/ohos/hdc_run.py (+472) 
- (added) libcxx/utils/ci/vendor/ohos/hdc_run_test.py (+115) 
- (added) libcxx/utils/ci/vendor/ohos/qemu_run.py (+144) 
- (modified) libcxxabi/CMakeLists.txt (+6-1) 
- (added) libcxxabi/test/configs/llvm-libc++abi-ohos.cfg.in (+36) 
- (modified) libcxxabi/test/guard_threaded_test.pass.cpp (+2) 
- (modified) libunwind/CMakeLists.txt (+6-1) 
- (modified) libunwind/src/Registers.hpp (+9-6) 
- (modified) libunwind/test/aarch64_za_unwind.pass.cpp (+7-6) 
- (modified) libunwind/test/bad_unwind_info.pass.cpp (+2) 
- (added) libunwind/test/configs/llvm-libunwind-ohos.cfg.in (+61) 
- (modified) libunwind/test/signal_unwind.pass.cpp (+2) 


``````````diff
diff --git a/cmake/Modules/GetToolchainDirs.cmake 
b/cmake/Modules/GetToolchainDirs.cmake
index 7568734e3f25d..1e8a3e4e015ca 100644
--- a/cmake/Modules/GetToolchainDirs.cmake
+++ b/cmake/Modules/GetToolchainDirs.cmake
@@ -79,7 +79,15 @@ function(get_runtimes_target_libdir_common 
default_target_triple arch variable)
   string(FIND "${default_target_triple}" "-" dash_index)
   string(SUBSTRING "${default_target_triple}" "${dash_index}" -1 triple_suffix)
   string(SUBSTRING "${default_target_triple}" 0 "${dash_index}" triple_cpu)
-  if(ANDROID AND "${arch}" STREQUAL "i386")
+  if("${triple_suffix}" MATCHES "linux-ohos")
+    if("${arch}" STREQUAL "i386")
+      set(target "i686-linux-ohos")
+    elseif("${arch}" MATCHES "^arm")
+      set(target "arm-linux-ohos")
+    else()
+      set(target "${arch}-linux-ohos")
+    endif()
+  elseif(ANDROID AND "${arch}" STREQUAL "i386")
     set(target "i686${triple_suffix}")
   elseif("${arch}" STREQUAL "amd64")
     set(target "x86_64${triple_suffix}")
@@ -125,25 +133,26 @@ function(get_runtimes_target_libdir_common 
default_target_triple arch variable)
   set("${variable}" "${target}" PARENT_SCOPE)
 endfunction()
 
-
-# Corresponds to Clang's ToolChain::getRuntimePath().
-function (get_toolchain_target_dirname outvar)
-  string(FIND "${LLVM_TARGET_TRIPLE}" "-" dash_index)
+function(get_runtimes_target_dirname default_target_triple variable)
+  string(FIND "${default_target_triple}" "-" dash_index)
   if (dash_index EQUAL "-1")
-    # This means LLVM_TARGET_TRIPLE is not set and we cannot derive the dirname
-    # from it. The proper behavior here would be to emit an error since we have
-    # no target we can build for. However, compiler-rt uses
-    # COMPILER_RT_DEFAULT_TARGET_TRIPLE instead and ignores LLVM_TARGET_TRIPLE.
-    # To not break the build when building only compiler-rt, we skip the triple
-    # subdirectory.
     set(target "")
   else ()
-    string(SUBSTRING "${LLVM_TARGET_TRIPLE}" 0 "${dash_index}" triple_cpu)
+    string(SUBSTRING "${default_target_triple}" 0 "${dash_index}" triple_cpu)
     set(arch "${triple_cpu}")
     if("${arch}" MATCHES "^i.86$")
       set(arch "i386")
     endif()
-    get_runtimes_target_libdir_common("${LLVM_TARGET_TRIPLE}" "${arch}" target)
-  endif ()
+    get_runtimes_target_libdir_common("${default_target_triple}" "${arch}" 
target)
+  endif()
+  set("${variable}" "${target}" PARENT_SCOPE)
+endfunction()
+
+
+# Corresponds to Clang's ToolChain::getRuntimePath().
+function (get_toolchain_target_dirname outvar)
+  # If LLVM_TARGET_TRIPLE is unset, this intentionally returns an empty
+  # directory to preserve the historical compiler-rt-only behavior.
+  get_runtimes_target_dirname("${LLVM_TARGET_TRIPLE}" target)
   set("${outvar}" "${target}" PARENT_SCOPE)
 endfunction()
diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake 
b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
index 75216ed704bce..af55b2166de60 100644
--- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
@@ -491,8 +491,12 @@ endfunction()
 
 function(get_compiler_rt_target arch variable)
   if(COMPILER_RT_DEFAULT_TARGET_ONLY)
-    # Use exact spelling when building only for the target specified to CMake.
-    set(target "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}")
+    if(CMAKE_SYSTEM_NAME STREQUAL "OHOS")
+      get_runtimes_target_libdir_common("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" 
"${arch}" target)
+    else()
+      # Use exact spelling when building only for the target specified to 
CMake.
+      set(target "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}")
+    endif()
   else()
     get_runtimes_target_libdir_common("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" 
"${arch}" target)
   endif()
diff --git a/compiler-rt/cmake/builtin-config-ix.cmake 
b/compiler-rt/cmake/builtin-config-ix.cmake
index 528268da729fb..90d9e451ff109 100644
--- a/compiler-rt/cmake/builtin-config-ix.cmake
+++ b/compiler-rt/cmake/builtin-config-ix.cmake
@@ -297,7 +297,7 @@ else()
   endforeach()
 endif()
 
-if(OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER AND NOT
+if(OS_NAME MATCHES "Linux|SerenityOS|OHOS" AND NOT LLVM_USE_SANITIZER AND NOT
    COMPILER_RT_GPU_BUILD)
   set(COMPILER_RT_HAS_CRT TRUE)
 else()
diff --git a/compiler-rt/cmake/crt-config-ix.cmake 
b/compiler-rt/cmake/crt-config-ix.cmake
index ebc7d671e74ee..64112f1636b09 100644
--- a/compiler-rt/cmake/crt-config-ix.cmake
+++ b/compiler-rt/cmake/crt-config-ix.cmake
@@ -47,7 +47,7 @@ if(NOT APPLE)
   message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}")
 endif()
 
-if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|SerenityOS" AND NOT 
LLVM_USE_SANITIZER)
+if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|SerenityOS|OHOS" AND NOT 
LLVM_USE_SANITIZER)
   set(COMPILER_RT_HAS_CRT TRUE)
 else()
   set(COMPILER_RT_HAS_CRT FALSE)
diff --git a/compiler-rt/lib/builtins/crtbegin.c 
b/compiler-rt/lib/builtins/crtbegin.c
index 74becdbe5dd0e..381a69fac4664 100644
--- a/compiler-rt/lib/builtins/crtbegin.c
+++ b/compiler-rt/lib/builtins/crtbegin.c
@@ -36,6 +36,10 @@ extern fp __CTOR_LIST_END__[];
 
 extern void __cxa_finalize(void *) __attribute__((weak));
 
+#if defined(__OHOS__)
+extern void __at_fini() __attribute__((weak));
+#endif
+
 static void __attribute__((used)) __do_init(void) {
   static _Bool __initialized;
   if (__builtin_expect(__initialized, 0))
@@ -114,6 +118,11 @@ static void __attribute__((used)) __do_fini(void) {
     return;
   __finalized = 1;
 
+#if defined(__OHOS__)
+  if (__at_fini)
+    __at_fini();
+#endif
+
   if (__cxa_finalize)
     __cxa_finalize(__dso_handle);
 
diff --git a/compiler-rt/lib/builtins/emutls.c 
b/compiler-rt/lib/builtins/emutls.c
index a8a5d7c0749a8..2d15d8e249f43 100644
--- a/compiler-rt/lib/builtins/emutls.c
+++ b/compiler-rt/lib/builtins/emutls.c
@@ -12,7 +12,7 @@
 
 #include "int_lib.h"
 
-#ifdef __BIONIC__
+#if defined(__BIONIC__) || defined(__OHOS__)
 // There are 4 pthread key cleanup rounds on Bionic. Delay emutls deallocation
 // to round 2. We need to delay deallocation because:
 //  - Android versions older than M lack __cxa_thread_atexit_impl, so apps
@@ -51,7 +51,7 @@ static void emutls_shutdown(emutls_address_array *array);
 
 static pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t emutls_pthread_key;
-#ifdef __BIONIC__
+#if defined(__BIONIC__) || defined(__OHOS__)
 static bool emutls_key_created = false;
 #endif
 
@@ -401,8 +401,8 @@ void *__emutls_get_address(__emutls_control *control) {
   return array->data[index];
 }
 
-#ifdef __BIONIC__
-// Called by Bionic on dlclose to delete the emutls pthread key.
+#if defined(__BIONIC__) || defined(__OHOS__)
+// Called by Bionic/OHOS on dlclose to delete the emutls pthread key.
 __attribute__((visibility("hidden"))) void __emutls_unregister_key(void) {
   if (emutls_key_created) {
     pthread_key_delete(emutls_pthread_key);
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 845240d1b894c..9a1af0ced8965 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -277,7 +277,8 @@ option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
 # or we don't have any ABI library.
 if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY
     OR NOT LIBCXX_ENABLE_SHARED
-    OR LIBCXX_CXX_ABI STREQUAL "none")
+    OR LIBCXX_CXX_ABI STREQUAL "none"
+    OR CMAKE_SYSTEM_NAME STREQUAL "OHOS")
   set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF)
 elseif((UNIX OR FUCHSIA) AND NOT APPLE)
   set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON)
@@ -450,7 +451,12 @@ set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output 
name for the static lib
 
 # TODO: Use common runtimes infrastructure for output and install paths
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
-  set(LIBCXX_TARGET_SUBDIR ${LLVM_DEFAULT_TARGET_TRIPLE})
+  if(CMAKE_SYSTEM_NAME STREQUAL "OHOS")
+    include(GetToolchainDirs)
+    get_runtimes_target_dirname("${LLVM_DEFAULT_TARGET_TRIPLE}" 
LIBCXX_TARGET_SUBDIR)
+  else()
+    set(LIBCXX_TARGET_SUBDIR ${LLVM_DEFAULT_TARGET_TRIPLE})
+  endif()
   if(LIBCXX_LIBDIR_SUBDIR)
     string(APPEND LIBCXX_TARGET_SUBDIR /${LIBCXX_LIBDIR_SUBDIR})
   endif()
diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake
index 270d80575adcf..e0e5a3c3094d2 100644
--- a/libcxx/cmake/config-ix.cmake
+++ b/libcxx/cmake/config-ix.cmake
@@ -126,6 +126,8 @@ elseif(PICOLIBC)
   set(LIBCXX_HAS_PTHREAD_LIB NO)
   set(LIBCXX_HAS_RT_LIB NO)
   set(LIBCXX_HAS_ATOMIC_LIB NO)
+elseif(OHOS)
+  set(LIBCXX_HAS_ATOMIC_LIB NO)
 else()
   check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
   check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
diff --git a/libcxx/include/__config b/libcxx/include/__config
index fdd0558fbec6f..c7da0ec54447c 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -292,7 +292,8 @@ typedef __char32_t char32_t;
         defined(__APPLE__) ||                                                  
                                        \
         defined(__MVS__) ||                                                    
                                        \
         defined(_AIX) ||                                                       
                                        \
-        defined(__EMSCRIPTEN__)
+        defined(__EMSCRIPTEN__) ||                                             
                                        \
+        defined(__OHOS_FAMILY__)
 // clang-format on
 #      undef _LIBCPP_HAS_THREAD_API_PTHREAD
 #      define _LIBCPP_HAS_THREAD_API_PTHREAD 1
@@ -371,7 +372,7 @@ typedef __char32_t char32_t;
 #  endif
 
 #  if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || 
defined(__wasi__) ||                        \
-      _LIBCPP_HAS_MUSL_LIBC || defined(__OpenBSD__) || _LIBCPP_LIBC_LLVM_LIBC
+      _LIBCPP_HAS_MUSL_LIBC || defined(__OpenBSD__) || _LIBCPP_LIBC_LLVM_LIBC 
|| defined(__OHOS_FAMILY__)
 #    define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
 #  endif
 
diff --git a/libcxx/include/__cxx03/__config b/libcxx/include/__cxx03/__config
index 27c26084da4b1..d9078a4ddf0d0 100644
--- a/libcxx/include/__cxx03/__config
+++ b/libcxx/include/__cxx03/__config
@@ -680,7 +680,8 @@ typedef __char32_t char32_t;
         defined(__APPLE__) ||                                                  
                                        \
         defined(__MVS__) ||                                                    
                                        \
         defined(_AIX) ||                                                       
                                        \
-        defined(__EMSCRIPTEN__)
+        defined(__EMSCRIPTEN__) ||                                             
                                        \
+        defined(__OHOS_FAMILY__)
 // clang-format on
 #      define _LIBCPP_HAS_THREAD_API_PTHREAD
 #    elif defined(__Fuchsia__)
@@ -753,7 +754,7 @@ typedef __char32_t char32_t;
 #  endif
 
 #  if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || 
defined(__wasi__) ||                        \
-      defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__)
+      defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || 
defined(__OHOS_FAMILY__)
 #    define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
 #  endif
 
diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h 
b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
index 3dbce825bc76c..a107aeeae5da4 100644
--- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h
@@ -23,7 +23,7 @@
 #  include <__cxx03/__locale_dir/locale_base_api/openbsd.h>
 #elif defined(__Fuchsia__)
 #  include <__cxx03/__locale_dir/locale_base_api/fuchsia.h>
-#elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC)
+#elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || 
defined(__OHOS_FAMILY__)
 #  include <__cxx03/__locale_dir/locale_base_api/musl.h>
 #elif defined(__APPLE__) || defined(__FreeBSD__)
 #  include <__cxx03/xlocale.h>
diff --git a/libcxx/include/__locale_dir/locale_base_api.h 
b/libcxx/include/__locale_dir/locale_base_api.h
index e1e60e18fd7c6..7dbbbd0b11654 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -120,7 +120,7 @@
 #    include <__locale_dir/support/fuchsia.h>
 #  elif _LIBCPP_LIBC_LLVM_LIBC
 #    include <__locale_dir/support/llvm_libc.h>
-#  elif defined(__linux__)
+#  elif defined(__linux__) || defined(__OHOS_FAMILY__)
 #    include <__locale_dir/support/linux.h>
 #  elif _LIBCPP_LIBC_NEWLIB
 #    include <__locale_dir/support/newlib.h>
diff --git a/libcxx/src/include/config_elast.h 
b/libcxx/src/include/config_elast.h
index daec2429de8eb..328a77d9934a5 100644
--- a/libcxx/src/include/config_elast.h
+++ b/libcxx/src/include/config_elast.h
@@ -43,6 +43,8 @@
 #  define _LIBCPP_ELAST (_sys_nerr - 1)
 #elif defined(_AIX)
 #  define _LIBCPP_ELAST 127
+#elif defined(__OHOS_FAMILY__)
+// No _LIBCPP_ELAST needed on OHOS
 #else
 // Warn here so that the person doing the libcxx port has an easier time:
 #  warning ELAST for this platform not yet implemented
diff --git a/libcxx/test/configs/llvm-libc++-ohos.cfg.in 
b/libcxx/test/configs/llvm-libc++-ohos.cfg.in
new file mode 100644
index 0000000000000..3be1c267ede2a
--- /dev/null
+++ b/libcxx/test/configs/llvm-libc++-ohos.cfg.in
@@ -0,0 +1,63 @@
+# This testing configuration handles running the test suite against LLVM's
+# libc++ using HDC or QEMU on OHOS.
+
+lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg')
+
+config.substitutions.append(('%{flags}',
+    ('--sysroot @CMAKE_SYSROOT@ ' if '@CMAKE_SYSROOT@' else '') + '-pthread'
+))
+config.substitutions.append(('%{compile_flags}',
+    '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I 
%{libcxx-dir}/test/support '
+    '-DTEST_HAS_NO_RELIABLE_LIBRARY_INTERNAL_ALLOCATIONS'
+))
+config.substitutions.append(('%{link_flags}',
+    # Link libc++abi/libunwind directly: lld won't resolve libc++'s transitive
+    # DT_NEEDED entries when building the test executable.
+    '-nostdlib++ -L %{lib-dir} -l@LIBCXX_SHARED_OUTPUT_NAME@ -lc++abi -lunwind'
+))
+config.substitutions.append(('%{exec}',
+    '%{executor} --execdir %{temp} -- '
+))
+
+import os, site
+site.addsitedir(os.path.join('@LIBCXX_SOURCE_DIR@', 'utils'))
+import libcxx.test.params, libcxx.test.config
+
+executor_kind = lit_config.params.get(
+    'executor_kind', getattr(config, 'executor_kind', 'ohos-hdc')
+)
+if executor_kind not in ('ohos-hdc', 'ohos-qemu'):
+    lit_config.fatal(f'unsupported OHOS executor_kind: {executor_kind}')
+
+config.available_features.add('LIBCXX-OHOS-FIXME')
+config.available_features.add(executor_kind)
+config.available_features.add('platform-has-nonportable-locales')
+config.available_features.add('platform-has-unreliable-new-delete-interposition')
+config.available_features.add('pthread-join-self-deadlocks')
+
+if executor_kind == 'ohos-hdc':
+    config.available_features.add('executor-has-no-stdin')
+    config.available_features.add('executor-merges-stderr-into-stdout')
+    config.available_features.add('executor-runs-as-root')
+
+libcxx.test.config.configure(
+    libcxx.test.params.DEFAULT_PARAMETERS,
+    libcxx.test.features.DEFAULT_FEATURES,
+    config,
+    lit_config
+)
+
+# The generic libc++ hardening-mode feature probe executes a target binary via
+# %{exec}. On OHOS/HDC that probe can fail for runner reasons even though the
+# configured libc++ headers still expose the selected hardening mode. Preserve
+# the configured mode so UNSUPPORTED/REQUIRES annotations remain stable.
+detected_hardening_features = [
+    feature for feature in config.available_features
+    if feature.startswith('libcpp-hardening-mode=')
+]
+configured_hardening_mode = '@LIBCXX_HARDENING_MODE@'
+if (
+    not detected_hardening_features and
+    configured_hardening_mode in ('none', 'fast', 'extensive', 'debug')
+):
+    
config.available_features.add(f'libcpp-hardening-mode={configured_hardening_mode}')
diff --git a/libcxx/test/extensions/clang/clang_modules_include.gen.py 
b/libcxx/test/extensions/clang/clang_modules_include.gen.py
index ed058cd908511..88aa51c4dd080 100644
--- a/libcxx/test/extensions/clang/clang_modules_include.gen.py
+++ b/libcxx/test/extensions/clang/clang_modules_include.gen.py
@@ -24,6 +24,9 @@
 # The Android headers don't appear to be compatible with modules yet
 # UNSUPPORTED: LIBCXX-ANDROID-FIXME
 
+# The OHOS headers don't appear to be compatible with modules yet
+# UNSUPPORTED: LIBCXX-OHOS-FIXME
+
 # TODO: Investigate this failure
 # UNSUPPORTED: LIBCXX-FREEBSD-FIXME
 
diff --git 
a/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
 
b/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
index 6e59b8256ffe7..a98402b5917b6 100644
--- 
a/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
+++ 
b/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
@@ -12,6 +12,7 @@
 // for facets, as it uses __sso_allocator<facet*, N>. It would fail if new
 // facets have been added (using install()) but N hasn't been adjusted to
 // account for them.
+// UNSUPPORTED: platform-has-unreliable-new-delete-interposition
 
 #include <cassert>
 
diff --git a/libcxx/test/selftest/dsl/dsl.sh.py 
b/libcxx/test/selftest/dsl/dsl.sh.py
index f93ccc747d661..fbbacb0c8d979 100644
--- a/libcxx/test/selftest/dsl/dsl.sh.py
+++ b/libcxx/test/selftest/dsl/dsl.sh.py
@@ -9,6 +9,11 @@
 # With picolibc, test_program_stderr_is_not_conflated_with_stdout fails
 # because stdout & stderr are treated as the same.
 # XFAIL: LIBCXX-PICOLIBC-FIXME
+#
+# The OHOS HDC executor currently merges remote stderr into host stdout, and
+# OHOS locale probing accepts some intentionally bogus locale names.
+# UNSUPPORTED: executor-merges-stderr-into-stdout
+# UNSUPPORTED: platform-has-nonportable-locales
 
 # Investigate why this is failing with LLVM libc.
 # XFAIL: LLVM-LIBC-FIXME
diff --git a/libcxx/test/selftest/stdin-is-piped.sh.cpp 
b/libcxx/test/selftest/stdin-is-piped.sh.cpp
index ffd10631c6a67..1e1b8d1bd0317 100644
--- a/libcxx/test/selftest/stdin-is-piped.sh.cpp
+++ b/libcxx/test/selftest/stdin-is-piped.sh.cpp
@@ -7,6 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 // Make sure that the executor pipes standard input to the test-executable 
being run.
+// UNSUPPORTED: executor-has-no-stdin
 
 // RUN: %{build}
 // RUN: echo "abc" | %{exec} %t.exe
diff --git 
a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp
 
b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp
index 43233decf1b34..fd6abca7c4fe1 100644
--- 
a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp
+++ 
b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp
@@ -6,6 +6,9 @@
 //
 
//===----------------------------------------------------------------------===//
 
+// OHOS qemu-user does not match device fd ownership/signal behavior here.
+// UNSUPPORTED: ohos-qemu
+
 // <fstream>
 
 // basic_filebuf<charT,traits>* close();
diff --git 
a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
 
b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
index a1a37012369d4..d1c2316dec112 100644
--- 
a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
+++ 
b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
@@ -8,6 +8,7 @@
 
 // REQUIRES: can-create-symlinks
 // UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: executor-runs-as-root
 
 // <filesystem>
 
diff --git 
a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
 
b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
index ba14af1240d4b..d4e23a9a3c6b6 100644
--- 
a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
+++ 
b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp
@@ -8,6 +8,7 @@
 
 // REQUIRES: can-create-symlinks
 // UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED:...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/208390
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to