Remove unused code from nativeaot libunwind dependency#128415
Conversation
NativeAOT's llvm-libunwind dependency includes many files that are never compiled or used. This reduces the vendored copy to only what's needed. Removed source files not compiled by NativeAOT (not in llvm-libunwind.cmake): - UnwindLevel1.c (zero-cost exception APIs) - UnwindLevel1-gcc-ext.c (GCC extension APIs) - Unwind-seh.cpp (SEH unwinding) - Unwind-sjlj.c (setjmp/longjmp exceptions) - Unwind-wasm.c (WASM exceptions) - Unwind_AIXExtras.cpp (AIX-specific) Removed directories and files not used in the dotnet build: - test/ (llvm test suite) - docs/ (llvm documentation) - cmake/ (standalone CMake modules) - CMakeLists.txt files (standalone build system) - .clang-format, libunwind.modulemap Removed dead _LIBUNWIND_DISABLE_ZERO_COST_APIS define from NativeAOT CMakeLists.txt - this macro is not referenced anywhere in llvm-libunwind source. The zero-cost API files (UnwindLevel1.c, UnwindLevel1-gcc-ext.c) were never compiled in the first place. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
NativeAOT uses llvm-libunwind's internal C++ classes directly (DwarfInstructions, CompactUnwinder, UnwindCursor, LocalAddressSpace) and does not call any of the public unw_* C API functions defined in libunwind.cpp. Removing it from the build eliminates 20 globally-visible symbols that conflict with platform libunwind on Android NDK r29. The only symbol from libunwind.cpp that NativeAOT references is LocalAddressSpace::sThisAddressSpace (a static singleton). This is now defined directly in UnixNativeCodeManager.cpp. Eliminated symbols: __unw_init_local, __unw_step, __unw_step_stage2, __unw_get_reg, __unw_set_reg, __unw_get_fpreg, __unw_set_fpreg, __unw_get_proc_info, __unw_get_proc_name, __unw_resume, __unw_is_fpreg, __unw_is_signal_frame, __unw_regname, __unw_iterate_dwarf_unwind_cache, __unw_add_dynamic_fde, __unw_remove_dynamic_fde, __unw_add_dynamic_eh_frame_section, __unw_remove_dynamic_eh_frame_section, unw_local_addr_space, and their weak aliases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
The static member LocalAddressSpace::sThisAddressSpace conflicts with the same symbol in Android NDK r29's libunwind.a. Remove the static member declaration from AddressSpace.hpp and switch UnixNativeCodeManager.cpp to use the existing _addressSpace instance from UnwindHelpers.cpp via an extern declaration. Both are instances of the same stateless type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
|
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib |
There was a problem hiding this comment.
Pull request overview
This PR reduces the vendored llvm-libunwind footprint used by NativeAOT and adjusts NativeAOT’s unwinding integration to avoid Android link failures caused by duplicate libunwind symbols.
Changes:
- Removes large portions of upstream
llvm-libunwind(tests/docs/CMake scaffolding and several source files) from the repo. - Stops building
llvm-libunwind/src/libunwind.cppviasrc/native/external/llvm-libunwind.cmakeand switches NativeAOT’s unwind-section discovery to use aLocalAddressSpaceinstance defined inUnwindHelpers.cpp. - Drops an unused NativeAOT CMake definition related to disabling
_Unwind_*-style APIs.
Show a summary per file
| File | Description |
|---|---|
| src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/unwind_leaffunction.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/unw_resume.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/unw_getcontext.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/signal_unwind.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/signal_frame.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/remember_state_leak.pass.sh.s | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/lit.cfg.py | Removed upstream lit “canary” config. |
| src/native/external/llvm-libunwind/test/libunwind_02.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/libunwind_01.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/frameheadercache_test.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/forceunwind.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/floatregister.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/eh_frame_fde_pc_range.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static-mingw.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared-mingw.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in | Removed upstream test config bridge. |
| src/native/external/llvm-libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/configs/apple-libunwind-system.cfg.in | Removed upstream test config. |
| src/native/external/llvm-libunwind/test/CMakeLists.txt | Removed upstream test suite CMake integration. |
| src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/alignment.compile.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/aix_signal_unwind.pass.sh.S | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/aix_runtime_link.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/aarch64_za_unwind.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/test/aarch64_vg_unwind.pass.cpp | Removed upstream libunwind test. |
| src/native/external/llvm-libunwind/src/UnwindLevel1.c | Removed upstream zero-cost EH implementation. |
| src/native/external/llvm-libunwind/src/UnwindLevel1-gcc-ext.c | Removed upstream gcc extension implementation. |
| src/native/external/llvm-libunwind/src/Unwind-wasm.c | Removed upstream wasm EH implementation. |
| src/native/external/llvm-libunwind/src/Unwind-sjlj.c | Removed upstream SJLJ EH implementation. |
| src/native/external/llvm-libunwind/src/Unwind-seh.cpp | Removed upstream SEH EH implementation. |
| src/native/external/llvm-libunwind/src/Unwind_AIXExtras.cpp | Removed upstream AIX extras implementation. |
| src/native/external/llvm-libunwind/src/CMakeLists.txt | Removed upstream libunwind build definition. |
| src/native/external/llvm-libunwind/src/AddressSpace.hpp | Removes LocalAddressSpace::sThisAddressSpace declaration. |
| src/native/external/llvm-libunwind/include/libunwind.modulemap | Removed upstream modulemap. |
| src/native/external/llvm-libunwind/include/CMakeLists.txt | Removed upstream include install CMake. |
| src/native/external/llvm-libunwind/docs/README.txt | Removed upstream docs file. |
| src/native/external/llvm-libunwind/docs/index.rst | Removed upstream docs file. |
| src/native/external/llvm-libunwind/docs/conf.py | Removed upstream docs file. |
| src/native/external/llvm-libunwind/docs/CMakeLists.txt | Removed upstream docs CMake integration. |
| src/native/external/llvm-libunwind/docs/BuildingLibunwind.rst | Removed upstream docs file. |
| src/native/external/llvm-libunwind/CMakeLists.txt | Removed upstream top-level CMake integration. |
| src/native/external/llvm-libunwind/cmake/Modules/HandleLibunwindFlags.cmake | Removed upstream CMake module. |
| src/native/external/llvm-libunwind/cmake/config-ix.cmake | Removed upstream CMake module. |
| src/native/external/llvm-libunwind/.clang-format | Removed upstream formatting config. |
| src/native/external/llvm-libunwind.cmake | Drops src/libunwind.cpp from the NativeAOT libunwind source list. |
| src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp | Switches unwind section discovery to a shared LocalAddressSpace instance. |
| src/coreclr/nativeaot/Runtime/CMakeLists.txt | Removes _LIBUNWIND_DISABLE_ZERO_COST_APIS definition. |
Copilot's findings
- Files reviewed: 52/52 changed files
- Comments generated: 2
| src/Unwind-EHABI.cpp | ||
| src/libunwind.cpp | ||
| ) | ||
|
|
| // Use the LocalAddressSpace instance from UnwindHelpers.cpp instead of | ||
| // the static member LocalAddressSpace::sThisAddressSpace (which was | ||
| // previously defined in libunwind.cpp). This avoids exporting a symbol | ||
| // that conflicts with platform libunwind on Android. | ||
| extern libunwind::LocalAddressSpace _addressSpace; | ||
|
|
1. Guard EHABI zero-cost exception APIs with _LIBUNWIND_DISABLE_ZERO_COST_APIS. Unwind-EHABI.cpp's C++ exception dispatch functions (__aeabi_unwind_cpp_pr*, _Unwind_RaiseException, unwind_phase1/2, etc.) call __unw_step and other public unw_* functions from libunwind.cpp, which is no longer compiled. NativeAOT only uses _Unwind_VRS_Interpret from this file. The guard compiles out the unused dispatch code, avoiding undefined symbol errors on ARM EHABI targets. 2. Replace extern _addressSpace with UnwindHelpers::FindUnwindSections(). Instead of exposing a cross-TU global with a generic name, UnixNativeCodeManager now calls a typed static method on UnwindHelpers which internally uses the file-local LocalAddressSpace instance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
| @@ -1,116 +0,0 @@ | |||
| # HandleLibcxxFlags - A set of macros used to setup the flags used to compile | |||
There was a problem hiding this comment.
We do not mind having some unused code under src/native/external to make the updates easy.
If there are large chunks of code (e.g. tests) that are worth deleting, it needs to be noted in https://github.com/dotnet/runtime/blob/main/src/native/external/llvm-libunwind-version.txt
Example of existing file with exclusions https://github.com/dotnet/runtime/blob/main/src/native/external/zlib-ng-version.txt
Delete the zero-cost exception dispatch functions that NativeAOT does not use: __aeabi_unwind_cpp_pr0/1/2, unwindOneFrame, ProcessDescriptors, unwind_phase1/2, _Unwind_RaiseException, and related helpers. These depend on __unw_step and other public unw_* functions from libunwind.cpp which is no longer compiled. NativeAOT only uses _Unwind_VRS_Interpret (the ARM EHABI bytecode interpreter) and decode_eht_entry from this file. The Descriptor::Format enum is retained as it is referenced by decode_eht_entry. Reduces Unwind-EHABI.cpp from 1,213 to 303 lines. Also removes the _LIBUNWIND_DISABLE_ZERO_COST_APIS define that was re-added in the previous commit, since the code it would have guarded is now deleted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
logAPIs(), logUnwinding(), and logDWARF() are declared in config.h when NDEBUG is not defined and were previously implemented in libunwind.cpp. Since libunwind.cpp is no longer compiled, provide these definitions in UnwindHelpers.cpp to fix undefined symbols in Debug builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Assisted-by: Claude:claude-opus-4.6-1m
Trying another approach for #121172.