From 564f130305fa44d8e14613219243bcd8b3356943 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 4 Apr 2024 13:27:12 +0200 Subject: [PATCH 01/23] Begin migration from https://github.com/xamarin/xamarin-android/pull/8800 --- .gitmodules | 4 + Configuration.props | 4 + Xamarin.Android.sln | 2 + build-tools/cmake/xa_common.cmake | 144 ++++++- build-tools/cmake/xa_macros.cmake | 3 +- build-tools/cmake/xa_preamble.cmake | 7 + build-tools/scripts/cmake-android.props | 6 + .../scripts/generate-pinvoke-tables.sh | 3 +- external/libunwind | 1 + .../Android.Runtime/RuntimeNativeMethods.cs | 15 + src/libunwind-xamarin/CMakeLists.txt | 395 ++++++++++++++++++ src/libunwind-xamarin/config.h.in | 21 + .../fixes/aarch64/Gos-linux.c | 145 +++++++ .../libunwind-xamarin.csproj | 15 + .../libunwind-xamarin.targets | 54 +++ src/monodroid/CMakeLists.txt | 212 ++++------ src/monodroid/jni/cpp-util.hh | 12 +- src/monodroid/jni/generate-pinvoke-tables.cc | 1 + src/monodroid/jni/monodroid-glue-internal.hh | 29 ++ src/monodroid/jni/monodroid-tracing.cc | 89 ++++ src/monodroid/jni/pinvoke-override-api.cc | 9 + src/monodroid/jni/pinvoke-tables.include | 4 +- src/monodroid/jni/shared-constants.hh | 13 + src/monodroid/monodroid.csproj | 5 +- src/monodroid/monodroid.targets | 18 +- src/native/CMakeLists.txt | 17 + .../jni => native/shared}/cxx-abi/string.cc | 0 .../shared}/cxx-abi/terminate.cc | 0 .../jni => native/shared}/helpers.cc | 0 .../jni => native/shared}/helpers.hh | 2 +- .../jni => native/shared}/new_delete.cc | 2 + .../jni => native/shared}/platform-compat.hh | 0 src/native/tracing/native-tracing.cc | 336 +++++++++++++++ src/native/tracing/native-tracing.hh | 46 ++ 34 files changed, 1472 insertions(+), 142 deletions(-) create mode 100644 build-tools/cmake/xa_preamble.cmake create mode 100644 build-tools/scripts/cmake-android.props create mode 160000 external/libunwind create mode 100644 src/libunwind-xamarin/CMakeLists.txt create mode 100644 src/libunwind-xamarin/config.h.in create mode 100644 src/libunwind-xamarin/fixes/aarch64/Gos-linux.c create mode 100644 src/libunwind-xamarin/libunwind-xamarin.csproj create mode 100644 src/libunwind-xamarin/libunwind-xamarin.targets create mode 100644 src/monodroid/jni/monodroid-tracing.cc create mode 100644 src/native/CMakeLists.txt rename src/{monodroid/jni => native/shared}/cxx-abi/string.cc (100%) rename src/{monodroid/jni => native/shared}/cxx-abi/terminate.cc (100%) rename src/{monodroid/jni => native/shared}/helpers.cc (100%) rename src/{monodroid/jni => native/shared}/helpers.hh (97%) rename src/{monodroid/jni => native/shared}/new_delete.cc (97%) rename src/{monodroid/jni => native/shared}/platform-compat.hh (100%) create mode 100644 src/native/tracing/native-tracing.cc create mode 100644 src/native/tracing/native-tracing.hh diff --git a/.gitmodules b/.gitmodules index 20bbd195b37..ac10c71f961 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,7 @@ [submodule "external/constexpr-xxh3"] path = external/constexpr-xxh3 url = https://github.com/chys87/constexpr-xxh3.git +[submodule "external/libunwind"] + path = external/libunwind + url = https://github.com/libunwind/libunwind.git + branch = master diff --git a/Configuration.props b/Configuration.props index 1a467652e80..0890b5b7103 100644 --- a/Configuration.props +++ b/Configuration.props @@ -104,6 +104,8 @@ True $(MSBuildThisFileDirectory)external\opentk $(MSBuildThisFileDirectory)external\sqlite + $(MSBuildThisFileDirectory)external\libunwind + $(BootstrapOutputDirectory)\libunwind $(MSBuildThisFileDirectory) $(MSBuildThisFileDirectory)src-ThirdParty\ armeabi-v7a;x86 @@ -144,6 +146,8 @@ $([System.IO.Path]::GetFullPath ('$(JavaInteropSourceDirectory)')) $([System.IO.Path]::GetFullPath ('$(MonoSourceDirectory)')) $([System.IO.Path]::GetFullPath ('$(SqliteSourceDirectory)')) + $([System.IO.Path]::GetFullPath ('$(LibUnwindSourceDirectory)')) + $([System.IO.Path]::GetFullPath ('$(LibUnwindGeneratedHeadersDirectory)')) $([System.IO.Path]::GetFullPath ('$(OpenTKSourceDirectory)')) net8.0 diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln index c85d197a5aa..b46ca2898aa 100644 --- a/Xamarin.Android.sln +++ b/Xamarin.Android.sln @@ -47,6 +47,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Diagnost EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Cecil", "external\Java.Interop\src\Java.Interop.Tools.Cecil\Java.Interop.Tools.Cecil.csproj", "{D48EE8D0-0A0A-4493-AEF5-DAF5F8CF86AD}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libunwind", "src\libunwind-xamarin\libunwind-xamarin.csproj", "{F8E4961B-C427-47F9-92D6-0BEB5B76B3D7}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "monodroid", "src\monodroid\monodroid.csproj", "{53EE4C57-1C03-405A-8243-8DA539546C88}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}" diff --git a/build-tools/cmake/xa_common.cmake b/build-tools/cmake/xa_common.cmake index d732318eb05..250473e2633 100644 --- a/build-tools/cmake/xa_common.cmake +++ b/build-tools/cmake/xa_common.cmake @@ -1 +1,143 @@ -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +include("${CMAKE_ANDROID_NDK}/build/cmake/abis.cmake") + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(DEBUG_BUILD True) +else() + set(DEBUG_BUILD False) +endif() + +set(XA_NO_INLINE "$ENV{XA_NO_INLINE}") +if(XA_NO_INLINE) + set(DONT_INLINE_DEFAULT ON) +else() + set(DONT_INLINE_DEFAULT OFF) +endif() + +set(XA_NO_STRIP "$ENV{XA_NO_STRIP}") +if(XA_NO_STRIP OR DEBUG_BUILD) + set(STRIP_DEBUG_DEFAULT OFF) +endif() + +option(ENABLE_CLANG_ASAN "Enable the clang AddressSanitizer support" OFF) +option(ENABLE_CLANG_UBSAN "Enable the clang UndefinedBehaviorSanitizer support" OFF) + +if(ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) + set(STRIP_DEBUG_DEFAULT OFF) + set(ANALYZERS_ENABLED ON) +else() + if(NOT XA_NO_STRIP) + set(STRIP_DEBUG_DEFAULT ON) + endif() + set(ANALYZERS_ENABLED OFF) +endif() + +option(COMPILER_DIAG_COLOR "Show compiler diagnostics/errors in color" ON) +option(STRIP_DEBUG "Strip debugging information when linking" ${STRIP_DEBUG_DEFAULT}) +option(DISABLE_DEBUG "Disable the built-in debugging code" OFF) +option(USE_CCACHE "Use ccache, if found, to speed up recompilation" ON) +option(DONT_INLINE "Do not inline any functions which are usually inlined, to get better stack traces" ${DONT_INLINE_DEFAULT}) + +if(USE_CCACHE) + if(CMAKE_CXX_COMPILER MATCHES "/ccache/") + message(STATUS "ccache: compiler already uses ccache") + else() + find_program(CCACHE ccache) + if(CCACHE) + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE}") + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE}") + message(STATUS "ccache: compiler will be lauched with ${CCACHE}") + endif() + endif() +endif() + +if(ANDROID_STL STREQUAL none) + set(USES_LIBSTDCPP False) +else() + set(USES_LIBSTDCPP True) +endif() + +# +# General config +# +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux) + set(IS_LINUX True) +else() + set(IS_LINUX False) +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) + set(IS_MACOS True) +else() + set(IS_MACOS False) +endif() + +set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}") +include("${XA_BUILD_DIR}/xa_build_configuration.cmake") + +# +# Paths +# +if(ANDROID_ABI MATCHES "^arm64-v8a") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM64}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_arm64-v8a_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^armeabi-v7a") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_armeabi-v7a_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^x86_64") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86_64}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_64_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^x86") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_TRIPLE}") +else() + message(FATAL "${ANDROID_ABI} is not supported for .NET 6+ builds") +endif() + +file(REAL_PATH "../../" REPO_ROOT_DIR) +set(EXTERNAL_DIR "${REPO_ROOT_DIR}/external") +set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") +set(SHARED_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/shared") +set(TRACING_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/tracing") +# +# Include directories +# +include_directories(SYSTEM ${CMAKE_SYSROOT}/usr/include/c++/v1/) +include_directories(SYSTEM "${NET_RUNTIME_DIR}/native/include/mono-2.0") +include_directories("${JAVA_INTEROP_SRC_PATH}") +include_directories("${SHARED_SOURCES_DIR}") +include_directories("${TRACING_SOURCES_DIR}") + +# +# Compiler defines +# +add_compile_definitions(XA_VERSION="${XA_VERSION}") +add_compile_definitions(_REENTRANT) +add_compile_definitions(PLATFORM_ANDROID) + +if(DEBUG_BUILD AND NOT DISABLE_DEBUG) + add_compile_definitions(DEBUG) +endif() + +if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") + add_compile_definitions(ANDROID64) +endif() + +if (ANDROID_NDK_MAJOR LESS 20) + add_compile_definitions(__ANDROID_API_Q__=29) +endif() + +# +# Shared sources +# +set(XA_SHARED_SOURCES + ${SHARED_SOURCES_DIR}/helpers.cc + ${SHARED_SOURCES_DIR}/new_delete.cc +) diff --git a/build-tools/cmake/xa_macros.cmake b/build-tools/cmake/xa_macros.cmake index df23bdedcd0..69759acf363 100644 --- a/build-tools/cmake/xa_macros.cmake +++ b/build-tools/cmake/xa_macros.cmake @@ -200,7 +200,8 @@ function(xa_common_prepare) -fstack-protector-strong -fstrict-return -fno-strict-aliasing - -ffunction-sections + -fno-function-sections + -fno-data-sections -funswitch-loops -Wa,-noexecstack -fPIC diff --git a/build-tools/cmake/xa_preamble.cmake b/build-tools/cmake/xa_preamble.cmake new file mode 100644 index 00000000000..d28fc5e10c4 --- /dev/null +++ b/build-tools/cmake/xa_preamble.cmake @@ -0,0 +1,7 @@ +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12) + +# +# Read product version +# +file(STRINGS "../../Directory.Build.props" XA_PRODUCT_VERSION_XML REGEX "^[ \t]*(.*)") +string(REGEX REPLACE "^[ \t]*(.*)" "\\1" XA_VERSION "${XA_PRODUCT_VERSION_XML}") diff --git a/build-tools/scripts/cmake-android.props b/build-tools/scripts/cmake-android.props new file mode 100644 index 00000000000..6335db11af8 --- /dev/null +++ b/build-tools/scripts/cmake-android.props @@ -0,0 +1,6 @@ + + + + <_CmakeAndroidFlags>--debug-output -GNinja -DCMAKE_MAKE_PROGRAM="$(NinjaPath)" -DXA_BUILD_CONFIGURATION=$(Configuration) -DXA_LIB_TOP_DIR=$(MicrosoftAndroidSdkOutDir) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DMONO_PATH="$(MonoSourceFullPath)" -DANDROID_STL="none" -DANDROID_CPP_FEATURES="no-rtti no-exceptions" -DANDROID_TOOLCHAIN=clang -DCMAKE_TOOLCHAIN_FILE="$(AndroidNdkDirectory)/build/cmake/android.toolchain.cmake" -DANDROID_NDK=$(AndroidNdkDirectory) + + diff --git a/build-tools/scripts/generate-pinvoke-tables.sh b/build-tools/scripts/generate-pinvoke-tables.sh index e0136d126f1..a63853f8562 100755 --- a/build-tools/scripts/generate-pinvoke-tables.sh +++ b/build-tools/scripts/generate-pinvoke-tables.sh @@ -9,6 +9,7 @@ TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include" GENERATED_FILE="${TARGET_FILE}.generated" DIFF_FILE="${TARGET_FILE}.diff" EXTERNAL_DIR="${MY_DIR}/../../external/" +NATIVE_DIR="${MY_DIR}/../../src/native" function die() { @@ -63,7 +64,7 @@ case ${HOST} in *) die Unsupported OS ;; esac -${COMPILER} -O2 -std=c++20 -I${EXTERNAL_DIR} -I${EXTERNAL_DIR}/constexpr-xxh3 "${GENERATOR_SOURCE}" -o "${GENERATOR_BINARY}" +${COMPILER} -O2 -std=c++20 -I${EXTERNAL_DIR} -I${EXTERNAL_DIR}/constexpr-xxh3 -I${NATIVE_DIR}/shared "${GENERATOR_SOURCE}" -o "${GENERATOR_BINARY}" "${GENERATOR_BINARY}" "${GENERATED_FILE}" FILES_DIFFER="no" diff --git a/external/libunwind b/external/libunwind new file mode 160000 index 00000000000..3705baed4dd --- /dev/null +++ b/external/libunwind @@ -0,0 +1 @@ +Subproject commit 3705baed4ddb5a98138d16dd2effcaeaa7e72db5 diff --git a/src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs b/src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs index a0c936c59ff..da635032800 100644 --- a/src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs +++ b/src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs @@ -6,8 +6,23 @@ namespace Android.Runtime { + // Values must be identical to those in src/monodroid/jni/monodroid-glue-internal.hh + [Flags] + enum TraceKind : uint + { + Java = 0x01, + Managed = 0x02, + Native = 0x04, + Signals = 0x08, + + All = Java | Managed | Native | Signals, + } + internal static class RuntimeNativeMethods { + [DllImport (RuntimeConstants.InternalDllName, CallingConvention = CallingConvention.Cdecl)] + internal extern static void monodroid_log_traces (TraceKind kind, string first_line); + [DllImport (RuntimeConstants.InternalDllName, CallingConvention = CallingConvention.Cdecl)] internal extern static void monodroid_log (LogLevel level, LogCategories category, string message); diff --git a/src/libunwind-xamarin/CMakeLists.txt b/src/libunwind-xamarin/CMakeLists.txt new file mode 100644 index 00000000000..02ad008d774 --- /dev/null +++ b/src/libunwind-xamarin/CMakeLists.txt @@ -0,0 +1,395 @@ +cmake_minimum_required(VERSION 3.19) + +# +# MUST be included before project()! +# +include("../../build-tools/cmake/xa_preamble.cmake") + +if(NOT DEFINED LIBUNWIND_LIBRARY_NAME) + message(FATAL_ERROR "Please set the LIBUNWIND_LIBRARY_NAME variable on command line (-DLIBUNWIND_LIBRARY_NAME=base_library_name)") +endif() + +if(NOT DEFINED LIBUNWIND_SOURCE_DIR) + message(FATAL_ERROR "Please set the LIBUNWIND_SOURCE_DIR variable on command line (-DLIBUNWIND_SOURCE_DIR=source_dir_path)") +endif() + +if(NOT DEFINED LIBUNWIND_OUTPUT_DIR) + message(FATAL_ERROR "Please set the LIBUNWIND_OUTPUT_DIR variable on command line (-DLIBUNWIND_OUTPUT_DIR=output_dir_path)") +endif() + +if(NOT DEFINED LIBUNWIND_HEADERS_OUTPUT_DIR) + message(FATAL_ERROR "Please set the LIBUNWIND_HEADERS_OUTPUT_DIR variable on command line (-DLIBUNWIND_HEADERS_OUTPUT_DIR=output_dir_path)") +endif() + +# +# Read libunwind version +# +set(CONFIGURE_AC "${LIBUNWIND_SOURCE_DIR}/configure.ac") +file(STRINGS "${CONFIGURE_AC}" UNWIND_MAJOR_VERSION_AC REGEX "^[ \t]*define[ \t]*\\([ \t]*pkg_major,[ \t]*(.*)\\)") +file(STRINGS "${CONFIGURE_AC}" UNWIND_MINOR_VERSION_AC REGEX "^[ \t]*define[ \t]*\\([ \t]*pkg_minor,[ \t]*(.*)\\)") +file(STRINGS "${CONFIGURE_AC}" UNWIND_EXTRA_VERSION_AC REGEX "^[ \t]*define[ \t]*\\([ \t]*pkg_extra,[ \t]*(.*)\\)") +string(REGEX REPLACE "^[ \t]*define[ \t]*\\([ \t]*pkg_major,[ \t]*(.*)\\)" "\\1" UNWIND_MAJOR_VERSION "${UNWIND_MAJOR_VERSION_AC}") +string(REGEX REPLACE "^[ \t]*define[ \t]*\\([ \t]*pkg_minor,[ \t]*(.*)\\)" "\\1" UNWIND_MINOR_VERSION "${UNWIND_MINOR_VERSION_AC}") +string(REGEX REPLACE "^[ \t]*define[ \t]*\\([ \t]*pkg_extra,[ \t]*(.*)\\)" "\\1" UNWIND_EXTRA_VERSION "${UNWIND_EXTRA_VERSION_AC}") + +set(PKG_MAJOR "${UNWIND_MAJOR_VERSION}") +set(PKG_MINOR "${UNWIND_MINOR_VERSION}") +set(PKG_EXTRA "${UNWIND_EXTRA_VERSION}") +set(PACKAGE_STRING "libunwind-xamarin") +set(PACKAGE_BUGREPORT "") + +message(STATUS "Major: ${PKG_MAJOR}; Minor: ${PKG_MINOR}; Extra: ${PKG_EXTRA}") + +project( + libunwind-xamarin +# VERSION "${PKG_MAJOR}.${PKG_MINOR}.${PKG_EXTRA}" + LANGUAGES C ASM +) + +# +# MUST be included after project()! +# +include("../../build-tools/cmake/xa_common.cmake") + +include(CheckCSourceCompiles) +include(CheckIncludeFiles) +include(CheckSymbolExists) +include("../../build-tools/cmake/xa_macros.cmake") + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) + +if(CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a) + set(TARGET_AARCH64 TRUE) + set(arch aarch64) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a) + set(TARGET_ARM TRUE) + set(arch arm) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86_64) + set(TARGET_AMD64 TRUE) + set(arch x86_64) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86) + set(TARGET_X86 TRUE) + set(arch x86) +else() + message(FATAL_ERROR "Unsupported Android ABI ${CMAKE_ANDROID_ARCH_ABI}") +endif() + +set(DSO_SYMBOL_VISIBILITY "hidden") +xa_common_prepare() + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + list(APPEND LOCAL_COMPILER_ARGS -g -fno-omit-frame-pointer) +else() + list(APPEND LOCAL_COMPILER_ARGS -s -fomit-frame-pointer) + add_compile_definitions(NDEBUG) +endif() +list(APPEND LOCAL_COMPILER_ARGS + ${XA_DEFAULT_SYMBOL_VISIBILITY} + -fno-asynchronous-unwind-tables + -fno-unwind-tables +) + +xa_check_c_flags(XA_C_FLAGS "${LOCAL_COMPILER_ARGS}") +xa_check_c_linker_flags(XA_C_LINKER_FLAGS "${LOCAL_COMPILER_ARGS}") + +add_compile_options(${XA_C_FLAGS}) +add_link_options(${XA_C_LINKER_FLAGS}) + +add_compile_definitions(HAVE_CONFIG_H) +add_compile_definitions(_GNU_SOURCE) +add_compile_definitions(UNW_LOCAL_ONLY) # we don't need remote unwinding + +# Detect include files +set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) + +set(HAVE_ASM_VSYSCALL_H True) +#check_include_files(asm/vsyscall.h HAVE_ASM_VSYSCALL_H) +check_include_files(byteswap.h HAVE_BYTESWAP_H) +check_include_files(elf.h HAVE_ELF_H) +check_include_files(endian.h HAVE_ENDIAN_H) +check_include_files(link.h HAVE_LINK_H) +check_include_files(sys/endian.h HAVE_SYS_ENDIAN_H) +check_include_files(sys/link.h HAVE_SYS_LINK_H) +check_include_files(sys/param.h HAVE_SYS_PARAM_H) +check_include_files(sys/syscall.h HAVE_SYS_SYSCALL_H) + +# Detect functions +check_symbol_exists(mincore "sys/mman.h" HAVE_MINCORE) +check_symbol_exists(pipe2 "fcntl.h;unistd.h" HAVE_PIPE2) + +# TODO: consider enabling zlib + +configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) +configure_file(${LIBUNWIND_SOURCE_DIR}/include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) +configure_file(${LIBUNWIND_SOURCE_DIR}/include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) +configure_file(${LIBUNWIND_SOURCE_DIR}/include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) + +# The files are nearly identical, the only difference is name of the header included when remote-only libunwind is used +# We don't use it, but we still copy files to separate directories in order to avoid locking issues during parallel builds +set(HEADERS_DIR ${LIBUNWIND_HEADERS_OUTPUT_DIR}/${CMAKE_ANDROID_ARCH_ABI}) + +file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h DESTINATION ${HEADERS_DIR}) +file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h DESTINATION ${HEADERS_DIR}) +file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h DESTINATION ${HEADERS_DIR}/tdep/) + +include_directories(${LIBUNWIND_SOURCE_DIR}/include/tdep) +include_directories(${LIBUNWIND_SOURCE_DIR}/include) +include_directories(${LIBUNWIND_SOURCE_DIR}/src) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/tdep) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) + +if(TARGET_ARM) + # Ensure that the remote and local unwind code can reside in the same binary without name clashing + add_definitions("-Darm_search_unwind_table=UNW_OBJ(arm_search_unwind_table)") + # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension + #TODO: possibly not needed? add_definitions(-Dasm=__asm__) + # The arm sources include ex_tables.h from include/tdep-arm without going through a redirection + # in include/tdep like it works for similar files on other architectures. So we need to add + # the include/tdep-arm to include directories + include_directories(${LIBUNWIND_SOURCE_DIR}/include/tdep-arm) +elseif(TARGET_AARCH64) + # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension + #TODO: possibly not needed? add_definitions(-Dasm=__asm__) +endif() + +set(SOURCES_DIR ${LIBUNWIND_SOURCE_DIR}/src) + +set(LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/dwarf/Gexpr.c + ${SOURCES_DIR}/dwarf/Gfde.c + ${SOURCES_DIR}/dwarf/Gfind_proc_info-lsb.c + ${SOURCES_DIR}/dwarf/Gfind_unwind_table.c + ${SOURCES_DIR}/dwarf/Gget_proc_info_in_range.c + ${SOURCES_DIR}/dwarf/Gparser.c + ${SOURCES_DIR}/dwarf/Gpe.c + ${SOURCES_DIR}/dwarf/Lexpr.c + ${SOURCES_DIR}/dwarf/Lfde.c + ${SOURCES_DIR}/dwarf/Lfind_proc_info-lsb.c + ${SOURCES_DIR}/dwarf/Lfind_unwind_table.c + ${SOURCES_DIR}/dwarf/Lget_proc_info_in_range.c + ${SOURCES_DIR}/dwarf/Lparser.c + ${SOURCES_DIR}/dwarf/Lpe.c + ${SOURCES_DIR}/dwarf/global.c + ${SOURCES_DIR}/elfxx.c + ${SOURCES_DIR}/mi/Gaddress_validator.c + ${SOURCES_DIR}/mi/Gdestroy_addr_space.c + ${SOURCES_DIR}/mi/Gdyn-extract.c +# ${SOURCES_DIR}/mi/Gdyn-remote.c + ${SOURCES_DIR}/mi/Gfind_dynamic_proc_info.c + ${SOURCES_DIR}/mi/Gget_elf_filename.c + ${SOURCES_DIR}/mi/Gget_fpreg.c + ${SOURCES_DIR}/mi/Gget_proc_info_by_ip.c + ${SOURCES_DIR}/mi/Gget_proc_name.c + ${SOURCES_DIR}/mi/Gget_reg.c + ${SOURCES_DIR}/mi/Gput_dynamic_unwind_info.c + ${SOURCES_DIR}/mi/Gset_cache_size.c + ${SOURCES_DIR}/mi/Gset_caching_policy.c + ${SOURCES_DIR}/mi/Gset_fpreg.c + ${SOURCES_DIR}/mi/Gset_iterate_phdr_function.c + ${SOURCES_DIR}/mi/Gset_reg.c + ${SOURCES_DIR}/mi/Ldestroy_addr_space.c + ${SOURCES_DIR}/mi/Ldyn-extract.c + ${SOURCES_DIR}/mi/Lfind_dynamic_proc_info.c + ${SOURCES_DIR}/mi/Lget_accessors.c + ${SOURCES_DIR}/mi/Lget_elf_filename.c + ${SOURCES_DIR}/mi/Lget_fpreg.c + ${SOURCES_DIR}/mi/Lget_proc_info_by_ip.c + ${SOURCES_DIR}/mi/Lget_proc_name.c + ${SOURCES_DIR}/mi/Lget_reg.c + ${SOURCES_DIR}/mi/Lput_dynamic_unwind_info.c + ${SOURCES_DIR}/mi/Lset_cache_size.c + ${SOURCES_DIR}/mi/Lset_caching_policy.c + ${SOURCES_DIR}/mi/Lset_fpreg.c + ${SOURCES_DIR}/mi/Lset_iterate_phdr_function.c + ${SOURCES_DIR}/mi/Lset_reg.c + ${SOURCES_DIR}/mi/backtrace.c + ${SOURCES_DIR}/mi/dyn-cancel.c + ${SOURCES_DIR}/mi/dyn-info-list.c + ${SOURCES_DIR}/mi/dyn-register.c + ${SOURCES_DIR}/mi/flush_cache.c + ${SOURCES_DIR}/mi/init.c + ${SOURCES_DIR}/mi/mempool.c + ${SOURCES_DIR}/mi/strerror.c + ${SOURCES_DIR}/os-linux.c +) + +if(TARGET_AMD64 OR TARGET_AARCH64) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/elf64.c + ) +endif() + +if(TARGET_X86 OR TARGET_ARM) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/elf32.c + ) +endif() + +if(TARGET_X86) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/x86/Gapply_reg_state.c + ${SOURCES_DIR}/x86/Gcreate_addr_space.c + ${SOURCES_DIR}/x86/Gget_proc_info.c + ${SOURCES_DIR}/x86/Gget_save_loc.c + ${SOURCES_DIR}/x86/Gglobal.c + ${SOURCES_DIR}/x86/Ginit.c + ${SOURCES_DIR}/x86/Ginit_local.c + ${SOURCES_DIR}/x86/Ginit_remote.c + ${SOURCES_DIR}/x86/Gos-linux.c + ${SOURCES_DIR}/x86/Greg_states_iterate.c + ${SOURCES_DIR}/x86/Gregs.c + ${SOURCES_DIR}/x86/Gresume.c + ${SOURCES_DIR}/x86/Gstep.c + ${SOURCES_DIR}/x86/Lapply_reg_state.c + ${SOURCES_DIR}/x86/Lcreate_addr_space.c + ${SOURCES_DIR}/x86/Lget_proc_info.c + ${SOURCES_DIR}/x86/Lget_save_loc.c + ${SOURCES_DIR}/x86/Lglobal.c + ${SOURCES_DIR}/x86/Linit.c + ${SOURCES_DIR}/x86/Linit_local.c + ${SOURCES_DIR}/x86/Linit_remote.c + ${SOURCES_DIR}/x86/Los-linux.c + ${SOURCES_DIR}/x86/Lreg_states_iterate.c + ${SOURCES_DIR}/x86/Lregs.c + ${SOURCES_DIR}/x86/Lresume.c + ${SOURCES_DIR}/x86/Lstep.c + ${SOURCES_DIR}/x86/getcontext-linux.S + ${SOURCES_DIR}/x86/is_fpreg.c + ${SOURCES_DIR}/x86/regname.c + ) +endif(TARGET_X86) + +if(TARGET_AMD64) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/x86_64/Gapply_reg_state.c + ${SOURCES_DIR}/x86_64/Gcreate_addr_space.c + ${SOURCES_DIR}/x86_64/Gget_proc_info.c + ${SOURCES_DIR}/x86_64/Gget_save_loc.c + ${SOURCES_DIR}/x86_64/Gglobal.c + ${SOURCES_DIR}/x86_64/Ginit.c + ${SOURCES_DIR}/x86_64/Ginit_local.c + ${SOURCES_DIR}/x86_64/Ginit_remote.c + ${SOURCES_DIR}/x86_64/Gos-linux.c + ${SOURCES_DIR}/x86_64/Greg_states_iterate.c + ${SOURCES_DIR}/x86_64/Gregs.c + ${SOURCES_DIR}/x86_64/Gresume.c + ${SOURCES_DIR}/x86_64/Gstash_frame.c + ${SOURCES_DIR}/x86_64/Gstep.c + ${SOURCES_DIR}/x86_64/Gtrace.c + ${SOURCES_DIR}/x86_64/Lapply_reg_state.c + ${SOURCES_DIR}/x86_64/Lcreate_addr_space.c + ${SOURCES_DIR}/x86_64/Lget_proc_info.c + ${SOURCES_DIR}/x86_64/Lget_save_loc.c + ${SOURCES_DIR}/x86_64/Lglobal.c + ${SOURCES_DIR}/x86_64/Linit.c + ${SOURCES_DIR}/x86_64/Linit_local.c + ${SOURCES_DIR}/x86_64/Linit_remote.c + ${SOURCES_DIR}/x86_64/Los-linux.c + ${SOURCES_DIR}/x86_64/Lreg_states_iterate.c + ${SOURCES_DIR}/x86_64/Lregs.c + ${SOURCES_DIR}/x86_64/Lresume.c + ${SOURCES_DIR}/x86_64/Lstash_frame.c + ${SOURCES_DIR}/x86_64/Lstep.c + ${SOURCES_DIR}/x86_64/Ltrace.c + ${SOURCES_DIR}/x86_64/getcontext.S + ${SOURCES_DIR}/x86_64/is_fpreg.c + ${SOURCES_DIR}/x86_64/regname.c + ${SOURCES_DIR}/x86_64/setcontext.S + ) +endif() + +if(TARGET_ARM) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/arm/Gapply_reg_state.c + ${SOURCES_DIR}/arm/Gcreate_addr_space.c + ${SOURCES_DIR}/arm/Gex_tables.c + ${SOURCES_DIR}/arm/Gget_proc_info.c + ${SOURCES_DIR}/arm/Gget_save_loc.c + ${SOURCES_DIR}/arm/Gglobal.c + ${SOURCES_DIR}/arm/Ginit.c + ${SOURCES_DIR}/arm/Ginit_local.c + ${SOURCES_DIR}/arm/Ginit_remote.c + ${SOURCES_DIR}/arm/Gos-linux.c + ${SOURCES_DIR}/arm/Greg_states_iterate.c + ${SOURCES_DIR}/arm/Gregs.c + ${SOURCES_DIR}/arm/Gresume.c + ${SOURCES_DIR}/arm/Gstash_frame.c + ${SOURCES_DIR}/arm/Gstep.c + ${SOURCES_DIR}/arm/Gtrace.c + ${SOURCES_DIR}/arm/Lapply_reg_state.c + ${SOURCES_DIR}/arm/Lcreate_addr_space.c + ${SOURCES_DIR}/arm/Lex_tables.c + ${SOURCES_DIR}/arm/Lget_proc_info.c + ${SOURCES_DIR}/arm/Lget_save_loc.c + ${SOURCES_DIR}/arm/Lglobal.c + ${SOURCES_DIR}/arm/Linit.c + ${SOURCES_DIR}/arm/Linit_local.c + ${SOURCES_DIR}/arm/Linit_remote.c + ${SOURCES_DIR}/arm/Los-linux.c + ${SOURCES_DIR}/arm/Lreg_states_iterate.c + ${SOURCES_DIR}/arm/Lregs.c + ${SOURCES_DIR}/arm/Lresume.c + ${SOURCES_DIR}/arm/Lstash_frame.c + ${SOURCES_DIR}/arm/Lstep.c + ${SOURCES_DIR}/arm/Ltrace.c + ${SOURCES_DIR}/arm/getcontext.S + ${SOURCES_DIR}/arm/is_fpreg.c + ${SOURCES_DIR}/arm/regname.c + ) +endif() + +if(TARGET_AARCH64) + list(APPEND LIBUNWIND_XAMARIN_SOURCES + ${SOURCES_DIR}/aarch64/Gapply_reg_state.c + ${SOURCES_DIR}/aarch64/Gcreate_addr_space.c + ${SOURCES_DIR}/aarch64/Gget_proc_info.c + ${SOURCES_DIR}/aarch64/Gget_save_loc.c + ${SOURCES_DIR}/aarch64/Gglobal.c + ${SOURCES_DIR}/aarch64/Ginit.c + ${SOURCES_DIR}/aarch64/Ginit_local.c + ${SOURCES_DIR}/aarch64/Ginit_remote.c + ${SOURCES_DIR}/aarch64/Gis_signal_frame.c + + # Use local version with partial revert of https://github.com/libunwind/libunwind/pull/503 + # until https://github.com/libunwind/libunwind/issues/702 is fixed + # ${SOURCES_DIR}/aarch64/Gos-linux.c + fixes/aarch64/Gos-linux.c + + ${SOURCES_DIR}/aarch64/Greg_states_iterate.c + ${SOURCES_DIR}/aarch64/Gregs.c + ${SOURCES_DIR}/aarch64/Gresume.c + ${SOURCES_DIR}/aarch64/Gstash_frame.c + ${SOURCES_DIR}/aarch64/Gstep.c + ${SOURCES_DIR}/aarch64/Gtrace.c + ${SOURCES_DIR}/aarch64/Lapply_reg_state.c + ${SOURCES_DIR}/aarch64/Lcreate_addr_space.c + ${SOURCES_DIR}/aarch64/Lget_proc_info.c + ${SOURCES_DIR}/aarch64/Lget_save_loc.c + ${SOURCES_DIR}/aarch64/Lglobal.c + ${SOURCES_DIR}/aarch64/Linit.c + ${SOURCES_DIR}/aarch64/Linit_local.c + ${SOURCES_DIR}/aarch64/Linit_remote.c + ${SOURCES_DIR}/aarch64/Lis_signal_frame.c + ${SOURCES_DIR}/aarch64/Lreg_states_iterate.c + ${SOURCES_DIR}/aarch64/Lregs.c + ${SOURCES_DIR}/aarch64/Lresume.c + ${SOURCES_DIR}/aarch64/Lstash_frame.c + ${SOURCES_DIR}/aarch64/Lstep.c + ${SOURCES_DIR}/aarch64/Ltrace.c + ${SOURCES_DIR}/aarch64/getcontext.S + ${SOURCES_DIR}/aarch64/is_fpreg.c + ${SOURCES_DIR}/aarch64/regname.c + ) +endif() + +add_library(${LIBUNWIND_LIBRARY_NAME} + STATIC + ${LIBUNWIND_XAMARIN_SOURCES} +) + +target_link_options( + ${LIBUNWIND_LIBRARY_NAME} + PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} +) diff --git a/src/libunwind-xamarin/config.h.in b/src/libunwind-xamarin/config.h.in new file mode 100644 index 00000000000..52656bb9740 --- /dev/null +++ b/src/libunwind-xamarin/config.h.in @@ -0,0 +1,21 @@ +#if !defined (__LIBUNWIND_CONFIG_H) +#define __LIBUNWIND_CONFIG_H + +#cmakedefine01 HAVE_ELF_H +#cmakedefine01 HAVE_ENDIAN_H +#cmakedefine01 HAVE_ASM_VSYSCALL_H +#cmakedefine01 HAVE_BYTESWAP_H +#cmakedefine01 HAVE_ELF_H +#cmakedefine01 HAVE_ENDIAN_H +#cmakedefine01 HAVE_LINK_H +#cmakedefine01 HAVE_SYS_ENDIAN_H +#cmakedefine01 HAVE_SYS_LINK_H +#cmakedefine01 HAVE_SYS_PARAM_H +#cmakedefine01 HAVE_SYS_SYSCALL_H +#cmakedefine01 HAVE_MINCORE +#cmakedefine01 HAVE_PIPE2 + +#define PACKAGE_STRING "@PACKAGE_STRING@" +#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +#endif // ndef __LIBUNWIND_CONFIG_H diff --git a/src/libunwind-xamarin/fixes/aarch64/Gos-linux.c b/src/libunwind-xamarin/fixes/aarch64/Gos-linux.c new file mode 100644 index 00000000000..fd9f266427c --- /dev/null +++ b/src/libunwind-xamarin/fixes/aarch64/Gos-linux.c @@ -0,0 +1,145 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 CodeSourcery + Copyright (C) 2011-2013 Linaro Limited + Copyright (C) 2012 Tommi Rantala + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +//#include "unwind_i.h" +#include "../../../../external/libunwind/src/aarch64/unwind_i.h" +#ifndef UNW_REMOTE_ONLY + +HIDDEN int +aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + unw_tdep_context_t *uc = c->uc; + + if (c->sigcontext_format == AARCH64_SCF_NONE) + { + /* Since there are no signals involved here we restore EH and non scratch + registers only. */ + unsigned long regs[24]; + regs[0] = uc->uc_mcontext.regs[0]; + regs[1] = uc->uc_mcontext.regs[1]; + regs[2] = uc->uc_mcontext.regs[2]; + regs[3] = uc->uc_mcontext.regs[3]; + regs[4] = uc->uc_mcontext.regs[19]; + regs[5] = uc->uc_mcontext.regs[20]; + regs[6] = uc->uc_mcontext.regs[21]; + regs[7] = uc->uc_mcontext.regs[22]; + regs[8] = uc->uc_mcontext.regs[23]; + regs[9] = uc->uc_mcontext.regs[24]; + regs[10] = uc->uc_mcontext.regs[25]; + regs[11] = uc->uc_mcontext.regs[26]; + regs[12] = uc->uc_mcontext.regs[27]; + regs[13] = uc->uc_mcontext.regs[28]; + regs[14] = uc->uc_mcontext.regs[29]; /* FP */ + regs[15] = uc->uc_mcontext.regs[30]; /* LR */ + regs[16] = GET_FPCTX(uc)->vregs[8]; + regs[17] = GET_FPCTX(uc)->vregs[9]; + regs[18] = GET_FPCTX(uc)->vregs[10]; + regs[19] = GET_FPCTX(uc)->vregs[11]; + regs[20] = GET_FPCTX(uc)->vregs[12]; + regs[21] = GET_FPCTX(uc)->vregs[13]; + regs[22] = GET_FPCTX(uc)->vregs[14]; + regs[23] = GET_FPCTX(uc)->vregs[15]; + unsigned long sp = uc->uc_mcontext.sp; + + struct regs_overlay { + char x[sizeof(regs)]; + }; + + __asm__ __volatile__ ( + "mov x4, %0\n" + "mov x5, %1\n" + "ldp x0, x1, [x4]\n" + "ldp x2, x3, [x4,16]\n" + "ldp x19, x20, [x4,32]\n" + "ldp x21, x22, [x4,48]\n" + "ldp x23, x24, [x4,64]\n" + "ldp x25, x26, [x4,80]\n" + "ldp x27, x28, [x4,96]\n" + "ldp x29, x30, [x4,112]\n" + "ldp d8, d9, [x4,128]\n" + "ldp d10, d11, [x4,144]\n" + "ldp d12, d13, [x4,160]\n" + "ldp d14, d15, [x4,176]\n" + "mov sp, x5\n" + "ret \n" + : + : "r" (regs), + "r" (sp), + "m" (*(struct regs_overlay *)regs) + ); + } + else + { + struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; + + if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; + if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; + if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; + if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; + + sc->regs[4] = uc->uc_mcontext.regs[4]; + sc->regs[5] = uc->uc_mcontext.regs[5]; + sc->regs[6] = uc->uc_mcontext.regs[6]; + sc->regs[7] = uc->uc_mcontext.regs[7]; + sc->regs[8] = uc->uc_mcontext.regs[8]; + sc->regs[9] = uc->uc_mcontext.regs[9]; + sc->regs[10] = uc->uc_mcontext.regs[10]; + sc->regs[11] = uc->uc_mcontext.regs[11]; + sc->regs[12] = uc->uc_mcontext.regs[12]; + sc->regs[13] = uc->uc_mcontext.regs[13]; + sc->regs[14] = uc->uc_mcontext.regs[14]; + sc->regs[15] = uc->uc_mcontext.regs[15]; + sc->regs[16] = uc->uc_mcontext.regs[16]; + sc->regs[17] = uc->uc_mcontext.regs[17]; + sc->regs[18] = uc->uc_mcontext.regs[18]; + sc->regs[19] = uc->uc_mcontext.regs[19]; + sc->regs[20] = uc->uc_mcontext.regs[20]; + sc->regs[21] = uc->uc_mcontext.regs[21]; + sc->regs[22] = uc->uc_mcontext.regs[22]; + sc->regs[23] = uc->uc_mcontext.regs[23]; + sc->regs[24] = uc->uc_mcontext.regs[24]; + sc->regs[25] = uc->uc_mcontext.regs[25]; + sc->regs[26] = uc->uc_mcontext.regs[26]; + sc->regs[27] = uc->uc_mcontext.regs[27]; + sc->regs[28] = uc->uc_mcontext.regs[28]; + sc->regs[29] = uc->uc_mcontext.regs[29]; + sc->regs[30] = uc->uc_mcontext.regs[30]; + sc->sp = uc->uc_mcontext.sp; + sc->pc = uc->uc_mcontext.pc; + sc->pstate = uc->uc_mcontext.pstate; + + __asm__ __volatile__ ( + "mov sp, %0\n" + "ret %1\n" + : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) + ); + } + unreachable(); + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/libunwind-xamarin/libunwind-xamarin.csproj b/src/libunwind-xamarin/libunwind-xamarin.csproj new file mode 100644 index 00000000000..b7aba4a3cfb --- /dev/null +++ b/src/libunwind-xamarin/libunwind-xamarin.csproj @@ -0,0 +1,15 @@ + + + Exe + netstandard2.0 + False + + + + + + $(MicrosoftAndroidSdkOutDir)lib + + + + diff --git a/src/libunwind-xamarin/libunwind-xamarin.targets b/src/libunwind-xamarin/libunwind-xamarin.targets new file mode 100644 index 00000000000..3b989aec4aa --- /dev/null +++ b/src/libunwind-xamarin/libunwind-xamarin.targets @@ -0,0 +1,54 @@ + + + + + + + <_LibUnwindBaseLibName>unwind_xamarin + <_LibUnwindLibName>lib$(_LibUnwindBaseLibName).a + <_LibUnwindHeadersOutputDir>$(LibUnwindGeneratedHeadersFullPath) + + + + + + + + <_ConfigureLibUnwindCommands + Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + $(_CmakeAndroidFlags) -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_BUILD_TYPE=$(Configuration) -DLIBUNWIND_SOURCE_DIR="$(LibUnwindSourceFullPath)" -DLIBUNWIND_LIBRARY_NAME="$(_LibUnwindBaseLibName)" -DLIBUNWIND_OUTPUT_DIR="@(AndroidSupportedTargetJitAbi->'$(OutputPath)/%(AndroidRID)')" -DLIBUNWIND_HEADERS_OUTPUT_DIR="$(_LibUnwindHeadersOutputDir)" $(MSBuildThisFileDirectory) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.Identity)-$(Configuration) + + + + + + + + + + + <_BuildLibUnwindCommands + Include="@(AndroidSupportedTargetJitAbi)"> + $(NinjaPath) + -v + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.Identity)-$(Configuration) + + + + + + + + + + + diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index 469a4ef5fca..a82cddea564 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -1,15 +1,9 @@ -cmake_minimum_required(VERSION 3.18.1) +cmake_minimum_required(VERSION 3.19) # # MUST be included before project()! # -include("../../build-tools/cmake/xa_common.cmake") - -# -# Read product version -# -file(STRINGS "../../Directory.Build.props" XA_PRODUCT_VERSION_XML REGEX "^[ \t]*(.*)") -string(REGEX REPLACE "^[ \t]*(.*)" "\\1" XA_VERSION "${XA_PRODUCT_VERSION_XML}") +include("../../build-tools/cmake/xa_preamble.cmake") project( monodroid @@ -17,76 +11,14 @@ project( DESCRIPTION "Xamarin.Android native runtime" HOMEPAGE_URL "https://github.com/xamarin/xamarin-android" LANGUAGES CXX C - ) - -option(COMPILER_DIAG_COLOR "Show compiler diagnostics/errors in color" ON) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_C_EXTENSIONS OFF) - -if(CMAKE_BUILD_TYPE STREQUAL Debug) - set(DEBUG_BUILD True) -else() - set(DEBUG_BUILD False) -endif() - -set(XA_NO_INLINE "$ENV{XA_NO_INLINE}") -if(XA_NO_INLINE) - set(DONT_INLINE_DEFAULT ON) -else() - set(DONT_INLINE_DEFAULT OFF) -endif() - -set(XA_NO_STRIP "$ENV{XA_NO_STRIP}") -if(XA_NO_STRIP OR DEBUG_BUILD) - set(STRIP_DEBUG_DEFAULT OFF) -endif() - -option(ENABLE_CLANG_ASAN "Enable the clang AddressSanitizer support" OFF) -option(ENABLE_CLANG_UBSAN "Enable the clang UndefinedBehaviorSanitizer support" OFF) +) -if(ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) - # ASAN and UBSAN always require the debug symbols to be left in the binary - set(STRIP_DEBUG_DEFAULT OFF) - set(ANALYZERS_ENABLED ON) -else() - if(NOT XA_NO_STRIP) - set(STRIP_DEBUG_DEFAULT ON) - endif() - set(ANALYZERS_ENABLED OFF) -endif() +# +# MUST be included after project()! +# +include("../../build-tools/cmake/xa_common.cmake") option(ENABLE_TIMING "Build with timing support" OFF) -option(STRIP_DEBUG "Strip debugging information when linking" ${STRIP_DEBUG_DEFAULT}) -option(DISABLE_DEBUG "Disable the built-in debugging code" OFF) -option(USE_CCACHE "Use ccache, if found, to speed up recompilation" ON) -option(DONT_INLINE "Do not inline any functions which are usually inlined, to get better stack traces" ${DONT_INLINE_DEFAULT}) - -if(USE_CCACHE) - if(CMAKE_CXX_COMPILER MATCHES "/ccache/") - message(STATUS "ccache: compiler already uses ccache") - else() - find_program(CCACHE ccache) - if(CCACHE) - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE}") - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE}") - message(STATUS "ccache: compiler will be lauched with ${CCACHE}") - endif() - endif() -endif() - - - -if(ANDROID_STL STREQUAL none) - set(USES_LIBSTDCPP False) -else() - set(USES_LIBSTDCPP True) -endif() # Environment checks @@ -112,53 +44,30 @@ if(NOT DEFINED XA_LIB_TOP_DIR) message(FATAL_ERROR "Please set the XA_LIB_TOP_DIR variable on command line (-DXA_LIB_TOP_DIR=path)") endif() +if(NOT DEFINED LIBUNWIND_SOURCE_DIR) + message(FATAL_ERROR "Please set the LIBUNWIND_SOURCE_DIR on command line (-DLIBUNWIND_SOURCE_DIR=path)") +endif() + +if(NOT DEFINED LIBUNWIND_HEADERS_DIR) + message(FATAL_ERROR "Please set the LIBUNWIND_HEADERS_DIR on command line (-DLIBUNWIND_HEADERS_DIR=path)") +endif() + # Needed modules include(CheckIncludeFile) include(CheckCXXSymbolExists) -# General config - -if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux) - set(IS_LINUX True) -else() - set(IS_LINUX False) -endif() - -if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) - set(IS_MACOS True) -else() - set(IS_MACOS False) -endif() - # Paths -set(EXTERNAL_DIR "../../external") -set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/jni) -set(BIONIC_SOURCES_DIR "../../src-ThirdParty/bionic") +set(BIONIC_SOURCES_DIR "${REPO_ROOT_DIR}/src-ThirdParty/bionic") set(LZ4_SRC_DIR "${EXTERNAL_DIR}/lz4/lib") set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR}) -set(XA_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/${XA_BUILD_CONFIGURATION}") -set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}") +set(XA_BIN_DIR "${REPO_ROOT_DIR}/bin/${XA_BUILD_CONFIGURATION}") set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map") set(XXHASH_DIR "${EXTERNAL_DIR}/xxHash") set(CONSTEXPR_XXH3_DIR "${EXTERNAL_DIR}/constexpr-xxh3") -include("${XA_BUILD_DIR}/xa_build_configuration.cmake") - -if(ANDROID_ABI MATCHES "^arm64-v8a") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM64}") -elseif(ANDROID_ABI MATCHES "^armeabi-v7a") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM}") -elseif(ANDROID_ABI MATCHES "^x86_64") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86_64}") -elseif(ANDROID_ABI MATCHES "^x86") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86}") -else() - message(FATAL "${ANDROID_ABI} is not supported for .NET 6+ builds") -endif() - set(LZ4_SOURCES "${LZ4_SRC_DIR}/lz4.c" ) @@ -171,9 +80,8 @@ include_directories(${EXTERNAL_DIR}) # much about them, we can just as well avoid cluttered build output. include_directories(SYSTEM ${CONSTEXPR_XXH3_DIR}) include_directories(SYSTEM ${ROBIN_MAP_DIR}/include) -include_directories(SYSTEM ${CMAKE_SYSROOT}/usr/include/c++/v1/) include_directories(SYSTEM ${LZ4_INCLUDE_DIR}) -include_directories(SYSTEM "${NET_RUNTIME_DIR}/native/include/mono-2.0") + include_directories("jni") include_directories("${XA_BIN_DIR}/include") include_directories("${XA_BIN_DIR}/include/${ANDROID_ABI}/eglib") @@ -182,7 +90,6 @@ include_directories("${XA_BIN_DIR}/include/${ANDROID_ABI}/eglib") include_directories("../../bin/${CONFIGURATION}/include") include_directories("../../bin/${CONFIGURATION}/include/${ANDROID_ABI}/eglib") include_directories("${MONO_PATH}/mono/eglib") -include_directories("${JAVA_INTEROP_SRC_PATH}") # Common preparation code include("../../build-tools/cmake/xa_macros.cmake") @@ -192,10 +99,8 @@ xa_macos_prepare_arm64() # Compiler defines -add_compile_definitions(XA_VERSION="${XA_VERSION}") add_compile_definitions(TSL_NO_EXCEPTIONS) add_compile_definitions(HAVE_CONFIG_H) -add_compile_definitions(_REENTRANT) add_compile_definitions(JI_DLL_EXPORT) add_compile_definitions(MONO_DLL_EXPORT) add_compile_definitions(NET) @@ -214,15 +119,6 @@ if (ENABLE_TIMING) endif() add_compile_definitions(HAVE_LZ4) -add_compile_definitions(PLATFORM_ANDROID) - -if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") - add_compile_definitions(ANDROID64) -endif() - -if (ANDROID_NDK_MAJOR LESS 20) - add_compile_definitions(__ANDROID_API_Q__=29) -endif() # Compiler and linker flags set(LINK_LIBS @@ -376,6 +272,7 @@ endif() set(XAMARIN_INTERNAL_API_LIB xa-internal-api${CHECKED_BUILD_INFIX}) set(XAMARIN_DEBUG_APP_HELPER_LIB xamarin-debug-app-helper${CHECKED_BUILD_INFIX}) set(XAMARIN_APP_STUB_LIB xamarin-app) +set(XAMARIN_NATIVE_TRACING_LIB xamarin-native-tracing) string(TOLOWER ${CMAKE_BUILD_TYPE} XAMARIN_MONO_ANDROID_SUFFIX) set(XAMARIN_MONO_ANDROID_LIB "mono-android${CHECKED_BUILD_INFIX}.${XAMARIN_MONO_ANDROID_SUFFIX}") @@ -387,6 +284,7 @@ set(XAMARIN_MONODROID_SOURCES ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc ${JAVA_INTEROP_SRC_PATH}/java-interop.cc ${LZ4_SOURCES} + ${XA_SHARED_SOURCES} ${SOURCES_DIR}/android-system.cc ${SOURCES_DIR}/basic-android-system.cc ${SOURCES_DIR}/basic-utilities.cc @@ -396,14 +294,13 @@ set(XAMARIN_MONODROID_SOURCES ${SOURCES_DIR}/embedded-assemblies-zip.cc ${SOURCES_DIR}/embedded-assemblies.cc ${SOURCES_DIR}/globals.cc - ${SOURCES_DIR}/helpers.cc ${SOURCES_DIR}/jni-remapping.cc ${SOURCES_DIR}/logger.cc ${SOURCES_DIR}/mono-log-adapter.cc ${SOURCES_DIR}/monodroid-glue.cc ${SOURCES_DIR}/monodroid-networkinfo.cc + ${SOURCES_DIR}/monodroid-tracing.cc ${SOURCES_DIR}/monovm-properties.cc - ${SOURCES_DIR}/new_delete.cc ${SOURCES_DIR}/osbridge.cc ${SOURCES_DIR}/pinvoke-override-api.cc ${SOURCES_DIR}/shared-constants.cc @@ -422,11 +319,18 @@ endif() if(NOT USES_LIBSTDCPP) list(APPEND XAMARIN_MONODROID_SOURCES ${BIONIC_SOURCES_DIR}/cxa_guard.cc - ${SOURCES_DIR}/cxx-abi/string.cc - ${SOURCES_DIR}/cxx-abi/terminate.cc + ${SHARED_SOURCES_DIR}/cxx-abi/string.cc + ${SHARED_SOURCES_DIR}/cxx-abi/terminate.cc ) endif() +set(NATIVE_TRACING_SOURCES + ${SHARED_SOURCES_DIR}/cxx-abi/string.cc +# ${SHARED_SOURCES_DIR}/cxx-abi/terminate.cc + ${TRACING_SOURCES_DIR}/native-tracing.cc + ${XA_SHARED_SOURCES} +) + set(XAMARIN_APP_STUB_SOURCES ${SOURCES_DIR}/application_dso_stub.cc ) @@ -436,9 +340,8 @@ set(XAMARIN_DEBUG_APP_HELPER_SOURCES ${SOURCES_DIR}/basic-utilities.cc ${SOURCES_DIR}/cpu-arch-detect.cc ${SOURCES_DIR}/debug-app-helper.cc - ${SOURCES_DIR}/helpers.cc - ${SOURCES_DIR}/new_delete.cc ${SOURCES_DIR}/shared-constants.cc + ${XA_SHARED_SOURCES} ) set(XAMARIN_STUB_LIB_SOURCES @@ -503,6 +406,52 @@ add_library( SHARED ${XAMARIN_MONODROID_SOURCES} ) +if(NOT DEBUG_BUILD) + set(CPP_ABI_PATH ${CMAKE_SYSROOT}/usr/lib/${SYSROOT_ABI_LIB_DIR}/${TOOLCHAIN_TRIPLE}/libc++abi.a) + + add_library( + ${XAMARIN_NATIVE_TRACING_LIB} + SHARED ${NATIVE_TRACING_SOURCES} + ) + + target_include_directories( + ${XAMARIN_NATIVE_TRACING_LIB} BEFORE + PRIVATE + ${LIBUNWIND_SOURCE_DIR}/include + ${LIBUNWIND_HEADERS_DIR}/${CMAKE_ANDROID_ARCH_ABI} + ${NDK_CXX_LIBCPPABI_SOURCE_PATH}/include + ) + + target_compile_options( + ${XAMARIN_NATIVE_TRACING_LIB} + PRIVATE + # Avoid the 'warning: dynamic exception specifications are deprecated' warning from libc++ headers + -Wno-deprecated-dynamic-exception-spec + ${XA_DEFAULT_SYMBOL_VISIBILITY} + # Prevent genration of the .eh_frame section (we don't use exceptions and don't need it) + -fno-asynchronous-unwind-tables + ) + + target_link_options( + ${XAMARIN_NATIVE_TRACING_LIB} + PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} + ) + + target_link_libraries( + ${XAMARIN_NATIVE_TRACING_LIB} + PRIVATE + -llog + ${CPP_ABI_PATH} + ${XA_LIBRARY_OUTPUT_DIRECTORY}/libunwind_xamarin.a + ) + + target_compile_definitions( + ${XAMARIN_NATIVE_TRACING_LIB} + PRIVATE + XAMARIN_TRACING + ) +endif() + # Ugly, but this is the only way to change LZ4 symbols visibility without modifying lz4.h set(LZ4_VISIBILITY_OPTS "-DLZ4LIB_VISIBILITY=__attribute__ ((visibility (\"hidden\")))") @@ -511,6 +460,13 @@ target_compile_options( PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} "${LZ4_VISIBILITY_OPTS}" ) +target_include_directories( + ${XAMARIN_MONO_ANDROID_LIB} BEFORE + PRIVATE + ${LIBUNWIND_SOURCE_DIR}/include + ${LIBUNWIND_HEADERS_DIR}/${CMAKE_ANDROID_ARCH_ABI} +) + set(DEBUG_HELPER_LINK_LIBS "-ldl") target_link_options( diff --git a/src/monodroid/jni/cpp-util.hh b/src/monodroid/jni/cpp-util.hh index 8f50149eb33..66dddc1d325 100644 --- a/src/monodroid/jni/cpp-util.hh +++ b/src/monodroid/jni/cpp-util.hh @@ -43,9 +43,19 @@ namespace xamarin::android template struct CDeleter final { + using UnderlyingType = std::remove_cv_t; + void operator() (T* p) { - std::free (p); + UnderlyingType *ptr; + + if constexpr (std::is_const_v) { + ptr = const_cast*> (p); + } else { + ptr = p; + } + + std::free (reinterpret_cast(ptr)); } }; diff --git a/src/monodroid/jni/generate-pinvoke-tables.cc b/src/monodroid/jni/generate-pinvoke-tables.cc index bcc9bce2acf..c29358d1e5b 100644 --- a/src/monodroid/jni/generate-pinvoke-tables.cc +++ b/src/monodroid/jni/generate-pinvoke-tables.cc @@ -61,6 +61,7 @@ const std::vector internal_pinvoke_names = { "_monodroid_gref_log_delete", "_monodroid_gref_log_new", "monodroid_log", + "monodroid_log_traces", "_monodroid_lookup_replacement_type", "_monodroid_lookup_replacement_method_info", "_monodroid_lref_log_delete", diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/monodroid/jni/monodroid-glue-internal.hh index abd3401671c..a8245495dd4 100644 --- a/src/monodroid/jni/monodroid-glue-internal.hh +++ b/src/monodroid/jni/monodroid-glue-internal.hh @@ -64,6 +64,15 @@ namespace xamarin::android::internal } }; + // Values must be identical to those in src/Mono.Android/Android.Runtime/RuntimeNativeMethods.cs + enum class TraceKind : uint32_t + { + Java = 0x01, + Managed = 0x02, + Native = 0x04, + Signals = 0x08, + }; + class MonodroidRuntime { using pinvoke_api_map = tsl::robin_map< @@ -146,6 +155,9 @@ namespace xamarin::android::internal static constexpr std::string_view mono_component_diagnostics_tracing_name { "libmono-component-diagnostics_tracing.so" }; static constexpr hash_t mono_component_diagnostics_tracing_hash = xxhash::hash (mono_component_diagnostics_tracing_name); + static constexpr std::string_view xamarin_native_tracing_name { "libxamarin-native-tracing.so" }; + static constexpr hash_t xamarin_native_tracing_name_hash = xxhash::hash (xamarin_native_tracing_name); + public: static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; @@ -190,6 +202,7 @@ namespace xamarin::android::internal void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException); char* get_java_class_name_for_TypeManager (jclass klass); + void log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept; private: static void mono_log_handler (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data); @@ -209,6 +222,22 @@ namespace xamarin::android::internal static PinvokeEntry* find_pinvoke_address (hash_t hash, const PinvokeEntry *entries, size_t entry_count) noexcept; static void* handle_other_pinvoke_request (const char *library_name, hash_t library_name_hash, const char *entrypoint_name, hash_t entrypoint_name_hash) noexcept; static void* monodroid_pinvoke_override (const char *library_name, const char *entrypoint_name); + + template + static void load_symbol (void *handle, const char *name, TFunc*& fnptr) noexcept + { + char *err = nullptr; + void *symptr = monodroid_dlsym (handle, name, &err, nullptr); + + if (symptr == nullptr) { + log_warn (LOG_DEFAULT, "Failed to load symbol '%s' library with handle %p. %s", name, handle, err == nullptr ? "Unknown error" : err); + fnptr = nullptr; + return; + } + + fnptr = reinterpret_cast(symptr); + } + static void* monodroid_dlopen_ignore_component_or_load (hash_t hash, const char *name, int flags, char **err) noexcept; static void* monodroid_dlopen (const char *name, int flags, char **err) noexcept; static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data) noexcept; diff --git a/src/monodroid/jni/monodroid-tracing.cc b/src/monodroid/jni/monodroid-tracing.cc new file mode 100644 index 00000000000..7f85117ae27 --- /dev/null +++ b/src/monodroid/jni/monodroid-tracing.cc @@ -0,0 +1,89 @@ +#include +#include + +#include "java-interop-logger.h" +#include "mono/utils/details/mono-dl-fallback-types.h" +#include "monodroid-glue-internal.hh" +#include "native-tracing.hh" +#include "cppcompat.hh" +#include + +using namespace xamarin::android::internal; + +static decltype(xa_get_native_backtrace)* _xa_get_native_backtrace; +static decltype(xa_get_managed_backtrace)* _xa_get_managed_backtrace; +static decltype(xa_get_java_backtrace)* _xa_get_java_backtrace; +static decltype(xa_get_interesting_signal_handlers)* _xa_get_interesting_signal_handlers; +static bool tracing_init_done; + +static std::mutex tracing_init_lock {}; + +void +MonodroidRuntime::log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept +{ + if (!tracing_init_done) { + std::lock_guard lock (tracing_init_lock); + + char *err = nullptr; + void *handle = monodroid_dlopen (xamarin_native_tracing_name.data (), MONO_DL_EAGER, &err, nullptr); + if (handle == nullptr) { + log_warn (LOG_DEFAULT, "Failed to load native tracing library '%s'. %s", xamarin_native_tracing_name, err == nullptr ? "Unknown error" : err); + } else { + load_symbol (handle, "xa_get_native_backtrace", _xa_get_native_backtrace); + load_symbol (handle, "xa_get_managed_backtrace", _xa_get_managed_backtrace); + load_symbol (handle, "xa_get_java_backtrace", _xa_get_java_backtrace); + load_symbol (handle, "xa_get_interesting_signal_handlers", _xa_get_interesting_signal_handlers); + } + + tracing_init_done = true; + } + + std::string trace; + if (first_line != nullptr) { + trace.append (first_line); + trace.append ("\n"); + } + + bool need_newline = false; + auto add_trace = [&] (c_unique_ptr const& data, const char *banner) -> void { + if (need_newline) { + trace.append ("\n "); + } else { + trace.append (" "); + } + + trace.append (banner); + if (!data) { + trace.append (": unavailable"); + } else { + trace.append (":\n"); + trace.append (data.get ()); + trace.append ("\n"); + } + need_newline = true; + }; + + if ((kind & TraceKind::Native) == TraceKind::Native) { + c_unique_ptr native { _xa_get_native_backtrace != nullptr ? _xa_get_native_backtrace () : nullptr }; + add_trace (native, "Native stacktrace"); + } + + if ((kind & TraceKind::Java) == TraceKind::Java && env != nullptr) { + c_unique_ptr java { _xa_get_java_backtrace != nullptr ?_xa_get_java_backtrace (env) : nullptr }; + add_trace (java, "Java stacktrace"); + } + + if ((kind & TraceKind::Managed) == TraceKind::Managed) { + c_unique_ptr managed { _xa_get_managed_backtrace != nullptr ? _xa_get_managed_backtrace () : nullptr }; + add_trace (managed, "Managed stacktrace"); + } + + if ((kind & TraceKind::Signals) == TraceKind::Signals) { + c_unique_ptr signals { _xa_get_interesting_signal_handlers != nullptr ? _xa_get_interesting_signal_handlers () : nullptr }; + add_trace (signals, "Signal handlers"); + } + + // Use this call because it is slightly faster (doesn't need to parse the format) and it doesn't truncate longer + // strings (like the stack traces we've just produced), unlike __android_log_vprint used by our `log_*` functions + __android_log_write (ANDROID_LOG_INFO, SharedConstants::LOG_CATEGORY_NAME_MONODROID.data (), trace.c_str ()); +} diff --git a/src/monodroid/jni/pinvoke-override-api.cc b/src/monodroid/jni/pinvoke-override-api.cc index 94232f60045..09710484807 100644 --- a/src/monodroid/jni/pinvoke-override-api.cc +++ b/src/monodroid/jni/pinvoke-override-api.cc @@ -363,6 +363,15 @@ _monodroid_lookup_replacement_method_info (const char *jniSourceType, const char return JniRemapping::lookup_replacement_method_info (jniSourceType, jniMethodName, jniMethodSignature); } +static void +monodroid_log_traces (uint32_t kind, const char *first_line) +{ + JNIEnv *env = osBridge.ensure_jnienv (); + auto tk = static_cast(kind); + + monodroidRuntime.log_traces (env, tk, first_line); +} + #include "pinvoke-tables.include" MonodroidRuntime::pinvoke_library_map MonodroidRuntime::other_pinvoke_map (MonodroidRuntime::LIBRARY_MAP_INITIAL_BUCKET_COUNT); diff --git a/src/monodroid/jni/pinvoke-tables.include b/src/monodroid/jni/pinvoke-tables.include index 1f3c479095c..e358a4d848f 100644 --- a/src/monodroid/jni/pinvoke-tables.include +++ b/src/monodroid/jni/pinvoke-tables.include @@ -18,6 +18,7 @@ static PinvokeEntry internal_pinvokes[] = { {0x2fbe68718cf2510d, "_monodroid_get_identity_hash_code", reinterpret_cast(&_monodroid_get_identity_hash_code)}, {0x3ade4348ac8ce0fa, "_monodroid_freeifaddrs", reinterpret_cast(&_monodroid_freeifaddrs)}, {0x3b2467e7eadd4a6a, "_monodroid_lref_log_new", reinterpret_cast(&_monodroid_lref_log_new)}, + {0x3b8097af56b5361f, "monodroid_log_traces", reinterpret_cast(&monodroid_log_traces)}, {0x3c5532ecdab53f89, "set_world_accessable", reinterpret_cast(&set_world_accessable)}, {0x423c8f539a2c56d2, "_monodroid_lookup_replacement_type", reinterpret_cast(&_monodroid_lookup_replacement_type)}, {0x4b1956138764939a, "_monodroid_gref_log_new", reinterpret_cast(&_monodroid_gref_log_new)}, @@ -540,6 +541,7 @@ static PinvokeEntry internal_pinvokes[] = { {0xd78c749d, "monodroid_get_log_categories", reinterpret_cast(&monodroid_get_log_categories)}, {0xd91f3619, "create_public_directory", reinterpret_cast(&create_public_directory)}, {0xe215a17c, "_monodroid_weak_gref_delete", reinterpret_cast(&_monodroid_weak_gref_delete)}, + {0xe4c3ee19, "monodroid_log_traces", reinterpret_cast(&monodroid_log_traces)}, {0xe7e77ca5, "_monodroid_gref_log", reinterpret_cast(&_monodroid_gref_log)}, {0xea2184e3, "_monodroid_gc_wait_for_bridge_processing", reinterpret_cast(&_monodroid_gc_wait_for_bridge_processing)}, {0xf4079b4a, "monodroid_dylib_mono_new", reinterpret_cast(&monodroid_dylib_mono_new)}, @@ -989,5 +991,5 @@ constexpr hash_t system_io_compression_native_library_hash = 0xafe3142c; constexpr hash_t system_security_cryptography_native_android_library_hash = 0x93625cd; #endif -constexpr size_t internal_pinvokes_count = 49; +constexpr size_t internal_pinvokes_count = 50; constexpr size_t dotnet_pinvokes_count = 428; diff --git a/src/monodroid/jni/shared-constants.hh b/src/monodroid/jni/shared-constants.hh index 2c706ae2df7..1ecdbcf90e5 100644 --- a/src/monodroid/jni/shared-constants.hh +++ b/src/monodroid/jni/shared-constants.hh @@ -83,6 +83,19 @@ namespace xamarin::android::internal // Documented in NDK's comments static constexpr size_t MAX_LOGCAT_MESSAGE_LENGTH = 1023; + + static constexpr std::string_view LOG_CATEGORY_NAME_NONE { "*none*" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID { "monodroid" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_ASSEMBLY { "monodroid-assembly" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_DEBUG { "monodroid-debug" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_GC { "monodroid-gc" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_GREF { "monodroid-gref" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_LREF { "monodroid-lref" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_TIMING { "monodroid-timing" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_BUNDLE { "monodroid-bundle" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_NETWORK { "monodroid-network" }; + static constexpr std::string_view LOG_CATEGORY_NAME_MONODROID_NETLINK { "monodroid-netlink" }; + static constexpr std::string_view LOG_CATEGORY_NAME_ERROR { "*error*" }; }; } #endif // __SHARED_CONSTANTS_HH diff --git a/src/monodroid/monodroid.csproj b/src/monodroid/monodroid.csproj index c4dbc2d7b5c..100496fe8fc 100644 --- a/src/monodroid/monodroid.csproj +++ b/src/monodroid/monodroid.csproj @@ -6,7 +6,7 @@ Exe false - + @@ -14,8 +14,9 @@ - + + diff --git a/src/monodroid/monodroid.targets b/src/monodroid/monodroid.targets index ed667e7fc44..7d0c3010bbf 100644 --- a/src/monodroid/monodroid.targets +++ b/src/monodroid/monodroid.targets @@ -1,6 +1,7 @@ + @@ -74,43 +75,48 @@ DependsOnTargets="_ConfigureRuntimesInputs" Inputs="@(_ConfigureRuntimesInputs)" Outputs="@(_ConfigureRuntimesOutputs)"> + + + + <_CmakeLibUnwind>-DLIBUNWIND_SOURCE_DIR="$(LibUnwindSourceDirectory)" -DLIBUNWIND_HEADERS_DIR="$(LibUnwindGeneratedHeadersDirectory)" <_NoInline Condition=" '$(DoNotInlineMonodroid)' == 'true' ">-DDONT_INLINE=ON <_NoStrip Condition=" '$(DoNotStripMonodroid)' == 'true' ">-DSTRIP_DEBUG=OFF <_CmakeAndroidFlags>$(_NoInline) $(_NoStrip) --debug-output -GNinja -DCMAKE_MAKE_PROGRAM="$(NinjaPath)" -DXA_BUILD_CONFIGURATION=$(Configuration) -DXA_LIB_TOP_DIR=$(MicrosoftAndroidSdkOutDir) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DMONO_PATH="$(MonoSourceFullPath)" -DANDROID_STL="none" -DANDROID_CPP_FEATURES="no-rtti no-exceptions" -DANDROID_TOOLCHAIN=clang -DCMAKE_TOOLCHAIN_FILE="$(AndroidNdkDirectory)/build/cmake/android.toolchain.cmake" -DANDROID_NDK=$(AndroidNdkDirectory) + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Debug <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Release <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> $(CmakePath) - $(_CmakeAndroidFlags) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" + $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Release diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt new file mode 100644 index 00000000000..b7a0a0daee3 --- /dev/null +++ b/src/native/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.19) + +# +# MUST be included before project()! +# +include("../../build-tools/cmake/xa_preamble.cmake") + +project( + native-libs + VERSION ${XA_VERSION} + LANGUAGES CXX +) + +# +# MUST be included after project()! +# +include("../../build-tools/cmake/xa_common.cmake") diff --git a/src/monodroid/jni/cxx-abi/string.cc b/src/native/shared/cxx-abi/string.cc similarity index 100% rename from src/monodroid/jni/cxx-abi/string.cc rename to src/native/shared/cxx-abi/string.cc diff --git a/src/monodroid/jni/cxx-abi/terminate.cc b/src/native/shared/cxx-abi/terminate.cc similarity index 100% rename from src/monodroid/jni/cxx-abi/terminate.cc rename to src/native/shared/cxx-abi/terminate.cc diff --git a/src/monodroid/jni/helpers.cc b/src/native/shared/helpers.cc similarity index 100% rename from src/monodroid/jni/helpers.cc rename to src/native/shared/helpers.cc diff --git a/src/monodroid/jni/helpers.hh b/src/native/shared/helpers.hh similarity index 97% rename from src/monodroid/jni/helpers.hh rename to src/native/shared/helpers.hh index 88d4904e92d..fe5b03ecda1 100644 --- a/src/monodroid/jni/helpers.hh +++ b/src/native/shared/helpers.hh @@ -12,7 +12,7 @@ namespace xamarin::android #define ADD_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::add_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) #define MULTIPLY_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::multiply_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) - class Helpers + class [[gnu::visibility("hidden")]] Helpers { public: template diff --git a/src/monodroid/jni/new_delete.cc b/src/native/shared/new_delete.cc similarity index 97% rename from src/monodroid/jni/new_delete.cc rename to src/native/shared/new_delete.cc index 074dfe35610..dcd3eb1d20d 100644 --- a/src/monodroid/jni/new_delete.cc +++ b/src/native/shared/new_delete.cc @@ -22,7 +22,9 @@ operator new (size_t size) { void* p = do_alloc (size); if (p == nullptr) { +#if !defined (XAMARIN_TRACING) log_fatal (LOG_DEFAULT, "Out of memory in the `new` operator"); +#endif xamarin::android::Helpers::abort_application (); } diff --git a/src/monodroid/jni/platform-compat.hh b/src/native/shared/platform-compat.hh similarity index 100% rename from src/monodroid/jni/platform-compat.hh rename to src/native/shared/platform-compat.hh diff --git a/src/native/tracing/native-tracing.cc b/src/native/tracing/native-tracing.cc new file mode 100644 index 00000000000..5b69cda234a --- /dev/null +++ b/src/native/tracing/native-tracing.cc @@ -0,0 +1,336 @@ +#include +#include +#include + +#include +#include + +#include + +#include "native-tracing.hh" +#include "shared-constants.hh" +#include "cppcompat.hh" + +constexpr int PRIORITY = ANDROID_LOG_INFO; + +static void append_frame_number (std::string &trace, size_t count) noexcept; +static unw_word_t adjust_address (unw_word_t addr) noexcept; +static void init_jni (JNIEnv *env) noexcept; + +// java.lang.Thread +static jclass java_lang_Thread; +static jmethodID java_lang_Thread_currentThread; +static jmethodID java_lang_Thread_getStackTrace; + +// java.lang.StackTraceElement +static jclass java_lang_StackTraceElement; +static jmethodID java_lang_StackTraceElement_toString; + +static std::mutex java_init_lock; + +const char* xa_get_managed_backtrace () noexcept +{ + std::string trace { "TODO: implement" }; + + return strdup (trace.c_str ()); +} + +const char* xa_get_native_backtrace () noexcept +{ + constexpr int FRAME_OFFSET_WIDTH = sizeof(uintptr_t) * 2; + + unw_cursor_t cursor; + unw_context_t uc; + unw_word_t ip; + unw_word_t offp; + std::array name_buf; + std::array num_buf; // Enough for text representation of a decimal 64-bit integer + some possible + // additions (sign, padding, punctuation etc) + const char *symbol_name; + Dl_info info; + + unw_getcontext (&uc); + unw_init_local (&cursor, &uc); + + size_t frame_counter = 0; + + std::string trace; + while (unw_step (&cursor) > 0) { + if (!trace.empty ()) { + trace.append ("\n"); + } + + unw_get_reg (&cursor, UNW_REG_IP, &ip); + ip = adjust_address (ip); + + auto ptr = reinterpret_cast(ip); + const char *fname = nullptr; + const void *symptr = nullptr; + unw_word_t frame_offset = 0; + bool info_valid = false; + + if (dladdr (ptr, &info) != 0) { + if (info.dli_fname != nullptr) { + fname = info.dli_fname; + } + symptr = info.dli_sname; + frame_offset = ip - reinterpret_cast(info.dli_fbase); + info_valid = true; + } else { + frame_offset = ip; + } + + append_frame_number (trace, frame_counter++); + + std::snprintf (num_buf.data (), num_buf.size (), "%0*zx (", FRAME_OFFSET_WIDTH, frame_offset); + trace.append (num_buf.data ()); + std::snprintf (num_buf.data (), num_buf.size (), "%p) ", ptr); + trace.append (num_buf.data ()); + + // TODO: consider searching /proc/self/maps for the beginning of the corresponding region to calculate the + // correct offset (like done in bionic stack trace) + trace.append (fname != nullptr ? fname : "[anonymous]"); + + bool symbol_name_allocated = false; + offp = 0; + if (unw_get_proc_name (&cursor, name_buf.data (), name_buf.size (), &offp) == 0) { + symbol_name = name_buf.data (); + } else if (info_valid && info.dli_sname != nullptr) { + symbol_name = info.dli_sname; + } else { + symbol_name = nullptr; + } + offp = adjust_address (offp); + + if (symbol_name != nullptr) { + char *demangled_symbol_name; + int demangle_status; + + // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#demangler + demangled_symbol_name = abi::__cxa_demangle (symbol_name, nullptr, nullptr, &demangle_status); + symbol_name_allocated = demangle_status == 0 && demangled_symbol_name != nullptr; + if (symbol_name_allocated) { + symbol_name = demangled_symbol_name; + } + } + + if (symbol_name != nullptr) { + trace.append (" "); + trace.append (symbol_name); + if (offp != 0) { + trace.append (" + "); + std::snprintf (num_buf.data (), num_buf.size (), "%zu", offp); + trace.append (num_buf.data ()); + } + } + + if (symptr != nullptr) { + trace.append (" (symaddr: "); + std::snprintf (num_buf.data (), num_buf.size (), "%p", symptr); + trace.append (num_buf.data ()); + trace.append (")"); + } + + if (symbol_name_allocated && symbol_name != nullptr) { + std::free (reinterpret_cast(const_cast(symbol_name))); + } + } + + return strdup (trace.c_str ()); +} + +const char* xa_get_java_backtrace (JNIEnv *env) noexcept +{ + init_jni (env); + + // TODO: error handling + jobject current_thread = env->CallStaticObjectMethod (java_lang_Thread, java_lang_Thread_currentThread); + auto stack_trace_array = static_cast(env->CallNonvirtualObjectMethod (current_thread, java_lang_Thread, java_lang_Thread_getStackTrace)); + jsize nframes = env->GetArrayLength (stack_trace_array); + std::string trace; + + for (jsize i = 0; i < nframes; i++) { + jobject frame = env->GetObjectArrayElement (stack_trace_array, i); + auto frame_desc_java = static_cast(env->CallObjectMethod (frame, java_lang_StackTraceElement_toString)); + const char *frame_desc = env->GetStringUTFChars (frame_desc_java, nullptr); + + if (!trace.empty ()) { + trace.append ("\n"); + } + + append_frame_number (trace, i); + trace.append (frame_desc); + env->ReleaseStringUTFChars (frame_desc_java, frame_desc); + } + + return strdup (trace.c_str ()); +} + +[[gnu::always_inline]] +unw_word_t adjust_address (unw_word_t addr) noexcept +{ + // This is what bionic does, let's do the same so that our backtrace addresses match bionic output + // Code copied verbatim from + // https://android.googlesource.com/platform/bionic/+/refs/tags/android-13.0.0_r37/libc/bionic/execinfo.cpp#50 + if (addr != 0) { +#if defined (__arm__) + // If the address is suspiciously low, do nothing to avoid a segfault trying + // to access this memory. + if (addr >= 4096) { + // Check bits [15:11] of the first halfword assuming the instruction + // is 32 bits long. If the bits are any of these values, then our + // assumption was correct: + // b11101 + // b11110 + // b11111 + // Otherwise, this is a 16 bit instruction. + uint16_t value = (*reinterpret_cast(addr - 2)) >> 11; + if (value == 0x1f || value == 0x1e || value == 0x1d) { + return addr - 4; + } + + return addr - 2; + } +#elif defined (__aarch64__) + // All instructions are 4 bytes long, skip back one instruction. + return addr - 4; +#elif defined (__i386__) || defined (__x86_64__) + // It's difficult to decode exactly where the previous instruction is, + // so subtract 1 to estimate where the instruction lives. + return addr - 1; +#endif + } + + return addr; +} + +const char* xa_get_interesting_signal_handlers () noexcept +{ + constexpr char SA_SIGNAL[] = "signal"; + constexpr char SA_SIGACTION[] = "sigaction"; + constexpr char SIG_IGNORED[] = "[ignored]"; + + std::array num_buf; + Dl_info info; + struct sigaction cur_sa; + std::string trace; + + for (int i = 0; i < _NSIG; i++) { + if (sigaction (i, nullptr, &cur_sa) != 0) { + continue; // ignore + } + + void *handler; + const char *installed_with; + if (cur_sa.sa_flags & SA_SIGINFO) { + handler = reinterpret_cast(cur_sa.sa_sigaction); + installed_with = SA_SIGACTION; + } else { + handler = reinterpret_cast(cur_sa.sa_handler); + installed_with = SA_SIGNAL; + } + + if (handler == SIG_DFL) { + continue; + } + + if (!trace.empty ()) { + trace.append ("\n"); + } + + const char *symbol_name = nullptr; + const char *file_name = nullptr; + if (handler == SIG_IGN) { + symbol_name = SIG_IGNORED; + } else { + if (dladdr (handler, &info) != 0) { + symbol_name = info.dli_sname; + file_name = info.dli_fname; + } + } + + trace.append (" "); + trace.append (strsignal (i)); + trace.append (" ("); + std::snprintf (num_buf.data (), num_buf.size (), "%d", i); + trace.append (num_buf.data ()); + trace.append ("), with "); + trace.append (installed_with); + trace.append (": "); + + if (file_name != nullptr) { + trace.append (file_name); + trace.append (" "); + } + + if (symbol_name == nullptr) { + std::snprintf (num_buf.data (), num_buf.size (), "%p", handler); + trace.append (num_buf.data ()); + } else { + trace.append (symbol_name); + } + } + + return strdup (trace.c_str ()); +} + +[[gnu::always_inline]] +void append_frame_number (std::string &trace, size_t count) noexcept +{ + std::array num_buf; // Enough for text representation of a decimal 64-bit integer + some possible + // additions (sign, padding, punctuation etc) + trace.append (" #"); + std::snprintf (num_buf.data (), num_buf.size (), "%-3zu: ", count); + trace.append (num_buf.data ()); +} + +void init_jni (JNIEnv *env) noexcept +{ + // We might be called more than once, ignore all but the first call + if (java_lang_Thread != nullptr) { + return; + } + + std::lock_guard lock (java_init_lock); + + java_lang_Thread = to_gref (env, env->FindClass ("java/lang/Thread")); + java_lang_Thread_currentThread = env->GetStaticMethodID (java_lang_Thread, "currentThread", "()Ljava/lang/Thread;"); + java_lang_Thread_getStackTrace = env->GetMethodID (java_lang_Thread, "getStackTrace", "()[Ljava/lang/StackTraceElement;"); + java_lang_StackTraceElement = to_gref (env, env->FindClass ("java/lang/StackTraceElement")); + java_lang_StackTraceElement_toString = env->GetMethodID (java_lang_StackTraceElement, "toString", "()Ljava/lang/String;"); + + // We check for the Java exception and possible null pointers only here, since all the calls JNI before the last one + // would do the exception check for us. + if (env->ExceptionOccurred ()) { + env->ExceptionDescribe (); + env->ExceptionClear (); + xamarin::android::Helpers::abort_application (); + } + + bool all_found = assert_valid_jni_pointer (java_lang_Thread, "class", "java.lang.Thread"); + all_found &= assert_valid_jni_pointer (java_lang_Thread_currentThread, "method", "java.lang.Thread.currentThread ()"); + all_found &= assert_valid_jni_pointer (java_lang_Thread_getStackTrace, "method", "java.lang.Thread.getStackTrace ()"); + all_found &= assert_valid_jni_pointer (java_lang_Thread, "class", "java.lang.StackTraceElement"); + all_found &= assert_valid_jni_pointer (java_lang_Thread_currentThread, "method", "java.lang.StackTraceElement.toString ()"); + + if (!all_found) { + xamarin::android::Helpers::abort_application (); + } +} + +bool assert_valid_jni_pointer (void *o, const char *missing_kind, const char *missing_name) noexcept +{ + if (o != nullptr) { + return true; + } + + __android_log_print ( + PRIORITY, + xamarin::android::internal::SharedConstants::LOG_CATEGORY_NAME_MONODROID_ASSEMBLY.data (), + "missing Java %s: %s", + missing_kind, + missing_name + ); + + return false; +} diff --git a/src/native/tracing/native-tracing.hh b/src/native/tracing/native-tracing.hh new file mode 100644 index 00000000000..6f08e7273b3 --- /dev/null +++ b/src/native/tracing/native-tracing.hh @@ -0,0 +1,46 @@ +#if !defined (__NATIVE_TRACING_HH) +#define __NATIVE_TRACING_HH + +#include +#include +#include + +#define UNW_LOCAL_ONLY +#include + +// Public API must not expose any types that are part of libc++ - we don't know what version of the +// library (if any) is used by the application we're embedded in. +// +// For the same reason, we cannot return memory allocated with the `new` operator - the implementation +// used by the application's C++ code might be incompatible. For this reason, any dynamically allocated +// memory we return to the caller is allocated with the libc's `malloc` +// +extern "C" { + [[gnu::visibility("default")]] + const char* xa_get_native_backtrace () noexcept; + + [[gnu::visibility("default")]] + const char* xa_get_java_backtrace (JNIEnv *env) noexcept; + + [[gnu::visibility("default")]] + const char* xa_get_managed_backtrace () noexcept; + + [[gnu::visibility("default")]] + const char* xa_get_interesting_signal_handlers () noexcept; +} + +template +[[gnu::always_inline]] +inline TJavaPointer to_gref (JNIEnv *env, TJavaPointer lref) noexcept +{ + if (lref == nullptr) { + return nullptr; + } + + auto ret = static_cast (env->NewGlobalRef (lref)); + env->DeleteLocalRef (lref); + return ret; +} + +bool assert_valid_jni_pointer (void *o, const char *missing_kind, const char *missing_name) noexcept; +#endif // ndef __NATIVE_TRACING_HH From 8554fed17f22ed5f8e450345a3f103bd204a107c Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 5 Apr 2024 09:43:01 +0000 Subject: [PATCH 02/23] Bumps LLVM to v18.1.3 and XA utils version to 8.0.0 (#8852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: https://discourse.llvm.org/t/llvm-18-1-0-released/77448 Changes: https://discourse.llvm.org/t/llvm-18-1-1-released/77540 Changes: https://discourse.llvm.org/t/18-1-2-released/77821 Changes: https://discourse.llvm.org/t/18-1-3-released/78136 Changes interesting for us: * AArch64 backend * Added support for Cortex-A520, Cortex-A720 and Cortex-X4 CPUs. * Assembler/disassembler support has been added for 2023 architecture extensions. * Support has been added for Stack Clash Protection. During function frame creation and dynamic stack allocations, the compiler will issue memory accesses at regular intervals so that a guard area at the top of the stack can’t be skipped over. * x86 backend * The i128 type now matches GCC and clang’s __int128 type. This mainly benefits external projects such as Rust which aim to be binary compatible with C, but also fixes code generation where LLVM already assumed that the type matched and called into libgcc helper functions. **Full Changelog**: https://github.com/xamarin/xamarin-android-binutils/compare/L_17.0.6-7.2.1...L_18.1.3-8.0.0 --- build-tools/installers/unix-binutils.projitems | 4 +++- .../xaprepare/xaprepare/ConfigAndData/Configurables.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build-tools/installers/unix-binutils.projitems b/build-tools/installers/unix-binutils.projitems index b1df3153b61..519c1daed2b 100644 --- a/build-tools/installers/unix-binutils.projitems +++ b/build-tools/installers/unix-binutils.projitems @@ -1,7 +1,7 @@ - <_LlvmLibExtension Condition=" '$(HostOS)' == 'Linux' ">so.17 + <_LlvmLibExtension Condition=" '$(HostOS)' == 'Linux' ">so.18.1 <_LlvmLibExtension Condition=" '$(HostOS)' == 'Darwin' ">dylib @@ -62,8 +62,10 @@ <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMDebugInfoPDB.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMDemangle.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMExtensions.$(_LlvmLibExtension)" /> + <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMFrontendOffloading.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMFrontendOpenMP.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMGlobalISel.$(_LlvmLibExtension)" /> + <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMHipStdPar.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMInstCombine.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMInstrumentation.$(_LlvmLibExtension)" /> <_BinUtilsFilesUnixSign Include="$(MicrosoftAndroidSdkOutDir)$(HostOS)\binutils\lib\libLLVMipo.$(_LlvmLibExtension)" /> diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs index 89c29ba32c5..cc349751b43 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs @@ -15,7 +15,7 @@ namespace Xamarin.Android.Prepare // partial class Configurables { - const string BinutilsVersion = "L_17.0.6-7.2.1"; + const string BinutilsVersion = "L_18.1.3-8.0.0"; const string MicrosoftOpenJDK17Version = "17.0.8"; const string MicrosoftOpenJDK17Release = "17.0.8.7"; From 42e199ae437e45d2539b52a04505e9425f030d81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:54:31 -1000 Subject: [PATCH 03/23] Bump external/Java.Interop from `651de42` to `e1c7832` (#8836) Bumps [external/Java.Interop](https://github.com/xamarin/java.interop) from `651de42` to `e1c7832`. - [Commits](https://github.com/xamarin/java.interop/compare/651de42732d194cee5a45fae45feda37706a8c16...e1c78326fbe2679cd90854c15d31f0fba7b796b6) --- updated-dependencies: - dependency-name: external/Java.Interop dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- external/Java.Interop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/Java.Interop b/external/Java.Interop index 651de42732d..e1c78326fbe 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 651de42732d194cee5a45fae45feda37706a8c16 +Subproject commit e1c78326fbe2679cd90854c15d31f0fba7b796b6 From b9b057166c3b7a87ef87c018047929b7768747eb Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Mon, 8 Apr 2024 23:59:06 -0700 Subject: [PATCH 04/23] [ci] Update dependabot ignore list (#8864) Updates the list of submodules that dependabot ignores when checking for updates. Repos which are no longer valid have been removed and recently added xxhash repos have been added to this list. --- .github/dependabot.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9c3f02fab8f..1661447e8ee 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,10 +14,8 @@ updates: schedule: interval: "daily" ignore: - - dependency-name: "external/apksig" + - dependency-name: "external/constexpr-xxh3" - dependency-name: "external/debugger-libs" - dependency-name: "external/lz4" - - dependency-name: "external/nrefactory" - - dependency-name: "external/opentk" - dependency-name: "external/robin-map" - - dependency-name: "external/sqlite" + - dependency-name: "external/xxHash" From 842d3c3228bcf808fbee517795a22b72b6cbfc83 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 11 Apr 2024 16:28:23 +0200 Subject: [PATCH 05/23] Update apkdesc files --- .../BuildReleaseArm64SimpleDotNet.apkdesc | 28 +++--- .../BuildReleaseArm64XFormsDotNet.apkdesc | 90 +++++++++---------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index f72d4cc5633..aa48fb18d6c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -11,31 +11,31 @@ "Size": 1027 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 64234 + "Size": 64238 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { - "Size": 91668 + "Size": 91590 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5222 + "Size": 5318 }, "lib/arm64-v8a/lib_System.Console.dll.so": { - "Size": 6548 + "Size": 6543 }, "lib/arm64-v8a/lib_System.Linq.dll.so": { - "Size": 8483 + "Size": 8520 }, "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { - "Size": 566421 + "Size": 566145 }, "lib/arm64-v8a/lib_System.Runtime.dll.so": { - "Size": 2552 + "Size": 2545 }, "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { - "Size": 4025 + "Size": 4017 }, "lib/arm64-v8a/lib_UnnamedProject.dll.so": { - "Size": 2934 + "Size": 2932 }, "lib/arm64-v8a/libarc.bin.so": { "Size": 1512 @@ -44,10 +44,10 @@ "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 354064 + "Size": 481952 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3132992 + "Size": 3135328 }, "lib/arm64-v8a/libSystem.Globalization.Native.so": { "Size": 67248 @@ -62,10 +62,10 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 12656 + "Size": 12696 }, "META-INF/BNDLTOOL.RSA": { - "Size": 1221 + "Size": 1223 }, "META-INF/BNDLTOOL.SF": { "Size": 3266 @@ -98,5 +98,5 @@ "Size": 1904 } }, - "PackageSize": 2689557 + "PackageSize": 2738709 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc index 2d232c645fb..979456f1439 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc @@ -38,127 +38,127 @@ "Size": 8090 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 72397 + "Size": 72398 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { - "Size": 458327 + "Size": 458239 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5222 + "Size": 5318 }, "lib/arm64-v8a/lib_mscorlib.dll.so": { - "Size": 3998 + "Size": 3991 }, "lib/arm64-v8a/lib_netstandard.dll.so": { - "Size": 5631 + "Size": 5625 }, "lib/arm64-v8a/lib_System.Collections.Concurrent.dll.so": { - "Size": 11520 + "Size": 11517 }, "lib/arm64-v8a/lib_System.Collections.dll.so": { - "Size": 15413 + "Size": 15409 }, "lib/arm64-v8a/lib_System.Collections.NonGeneric.dll.so": { - "Size": 7441 + "Size": 7436 }, "lib/arm64-v8a/lib_System.ComponentModel.dll.so": { - "Size": 1941 + "Size": 1934 }, "lib/arm64-v8a/lib_System.ComponentModel.Primitives.dll.so": { - "Size": 2555 + "Size": 2548 }, "lib/arm64-v8a/lib_System.ComponentModel.TypeConverter.dll.so": { - "Size": 6089 + "Size": 6082 }, "lib/arm64-v8a/lib_System.Console.dll.so": { - "Size": 6580 + "Size": 6575 }, "lib/arm64-v8a/lib_System.Core.dll.so": { - "Size": 1976 + "Size": 1968 }, "lib/arm64-v8a/lib_System.Diagnostics.DiagnosticSource.dll.so": { - "Size": 9065 + "Size": 9057 }, "lib/arm64-v8a/lib_System.Diagnostics.TraceSource.dll.so": { - "Size": 6552 + "Size": 6543 }, "lib/arm64-v8a/lib_System.dll.so": { - "Size": 2331 + "Size": 2323 }, "lib/arm64-v8a/lib_System.Drawing.dll.so": { - "Size": 1937 + "Size": 1931 }, "lib/arm64-v8a/lib_System.Drawing.Primitives.dll.so": { - "Size": 11968 + "Size": 11963 }, "lib/arm64-v8a/lib_System.IO.Compression.Brotli.dll.so": { - "Size": 11190 + "Size": 11184 }, "lib/arm64-v8a/lib_System.IO.Compression.dll.so": { - "Size": 15864 + "Size": 15861 }, "lib/arm64-v8a/lib_System.IO.IsolatedStorage.dll.so": { - "Size": 9897 + "Size": 9893 }, "lib/arm64-v8a/lib_System.Linq.dll.so": { - "Size": 20166 + "Size": 20208 }, "lib/arm64-v8a/lib_System.Linq.Expressions.dll.so": { - "Size": 164751 + "Size": 164627 }, "lib/arm64-v8a/lib_System.Net.Http.dll.so": { - "Size": 67559 + "Size": 68134 }, "lib/arm64-v8a/lib_System.Net.Primitives.dll.so": { - "Size": 22242 + "Size": 22237 }, "lib/arm64-v8a/lib_System.Net.Requests.dll.so": { - "Size": 3594 + "Size": 3587 }, "lib/arm64-v8a/lib_System.ObjectModel.dll.so": { - "Size": 8566 + "Size": 8561 }, "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { - "Size": 872867 + "Size": 872591 }, "lib/arm64-v8a/lib_System.Private.DataContractSerialization.dll.so": { - "Size": 193446 + "Size": 193451 }, "lib/arm64-v8a/lib_System.Private.Uri.dll.so": { - "Size": 42910 + "Size": 42906 }, "lib/arm64-v8a/lib_System.Private.Xml.dll.so": { - "Size": 216089 + "Size": 215939 }, "lib/arm64-v8a/lib_System.Private.Xml.Linq.dll.so": { - "Size": 16631 + "Size": 16624 }, "lib/arm64-v8a/lib_System.Runtime.dll.so": { - "Size": 2709 + "Size": 2701 }, "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { - "Size": 4025 + "Size": 4017 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.dll.so": { - "Size": 1865 + "Size": 1858 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.Formatters.dll.so": { - "Size": 2484 + "Size": 2478 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.Primitives.dll.so": { - "Size": 3758 + "Size": 3751 }, "lib/arm64-v8a/lib_System.Security.Cryptography.dll.so": { - "Size": 8102 + "Size": 8095 }, "lib/arm64-v8a/lib_System.Text.RegularExpressions.dll.so": { - "Size": 161398 + "Size": 161223 }, "lib/arm64-v8a/lib_System.Xml.dll.so": { - "Size": 1760 + "Size": 1753 }, "lib/arm64-v8a/lib_System.Xml.Linq.dll.so": { - "Size": 1776 + "Size": 1769 }, "lib/arm64-v8a/lib_UnnamedProject.dll.so": { "Size": 5007 @@ -239,10 +239,10 @@ "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 354064 + "Size": 481952 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3132992 + "Size": 3135328 }, "lib/arm64-v8a/libSystem.Globalization.Native.so": { "Size": 67248 @@ -257,7 +257,7 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 118880 + "Size": 118920 }, "META-INF/androidx.activity_activity.version": { "Size": 6 @@ -2480,5 +2480,5 @@ "Size": 812848 } }, - "PackageSize": 10218536 + "PackageSize": 10267688 } \ No newline at end of file From 9cf8516772c225f9dd1dd0a524ed2aadacf7aa8c Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 11 Apr 2024 22:08:45 +0200 Subject: [PATCH 06/23] [WIP] Migration to new native sources layout Build is broken atm --- .../Microsoft.Android.Runtime.proj | 2 + src/native/CMakeLists.txt | 137 +++++++- src/native/CMakePresets.json | 309 ++++++++++++++++++ src/native/CMakeUserPresets.json | 47 +++ src/{monodroid => native}/libstub/stub.cc | 0 .../libunwind}/CMakeLists.txt | 0 .../libunwind}/config.h.in | 0 .../libunwind}/fixes/aarch64/Gos-linux.c | 0 .../libunwind}/libunwind-xamarin.csproj | 0 .../libunwind}/libunwind-xamarin.targets | 0 src/{ => native}/monodroid/.gitignore | 0 src/{ => native}/monodroid/CMakeLists.txt | 0 src/{ => native}/monodroid/config.xml | 0 src/{ => native}/monodroid/jni/.gitignore | 0 src/{ => native}/monodroid/jni/TODO.md | 0 .../monodroid/jni/android-system.cc | 0 .../monodroid/jni/android-system.hh | 0 .../monodroid/jni/application_dso_stub.cc | 0 .../monodroid/jni/basic-android-system.cc | 0 .../monodroid/jni/basic-android-system.hh | 0 .../monodroid/jni/basic-utilities.cc | 0 .../monodroid/jni/basic-utilities.hh | 0 src/{ => native}/monodroid/jni/build-info.hh | 0 src/{ => native}/monodroid/jni/config.h | 0 src/{ => native}/monodroid/jni/cpp-util.hh | 0 src/{ => native}/monodroid/jni/cppcompat.hh | 0 .../monodroid/jni/cpu-arch-detect.cc | 0 src/{ => native}/monodroid/jni/cpu-arch.hh | 0 .../monodroid/jni/debug-app-helper.cc | 0 .../monodroid/jni/debug-app-helper.hh | 0 .../monodroid/jni/debug-constants.cc | 0 src/{ => native}/monodroid/jni/debug.cc | 0 src/{ => native}/monodroid/jni/debug.hh | 0 .../monodroid/jni/designer-assemblies.cc | 0 .../monodroid/jni/designer-assemblies.hh | 0 .../monodroid/jni/embedded-assemblies-zip.cc | 0 .../monodroid/jni/embedded-assemblies.cc | 0 .../monodroid/jni/embedded-assemblies.hh | 0 .../monodroid/jni/generate-pinvoke-tables.cc | 0 src/{ => native}/monodroid/jni/globals.cc | 0 src/{ => native}/monodroid/jni/globals.hh | 0 .../monodroid/jni/host-config.h.in | 0 .../monodroid/jni/internal-pinvoke-api.cc | 0 .../monodroid/jni/jni-remapping.cc | 0 .../monodroid/jni/jni-remapping.hh | 0 .../monodroid/jni/jni-wrappers.hh | 0 src/{ => native}/monodroid/jni/logger.cc | 0 src/{ => native}/monodroid/jni/logger.hh | 0 .../monodroid/jni/mono-image-loader.hh | 0 .../monodroid/jni/mono-log-adapter.cc | 0 .../monodroid/jni/mono_android_Runtime.h | 0 .../monodroid/jni/monodroid-glue-designer.cc | 0 .../monodroid/jni/monodroid-glue-internal.hh | 0 .../monodroid/jni/monodroid-glue.cc | 0 .../monodroid/jni/monodroid-glue.hh | 0 .../monodroid/jni/monodroid-networkinfo.cc | 0 .../monodroid/jni/monodroid-tracing.cc | 0 src/{ => native}/monodroid/jni/monodroid.h | 0 src/{ => native}/monodroid/jni/monodroid.x | Bin .../monodroid/jni/monovm-properties.cc | 0 .../monodroid/jni/monovm-properties.hh | 0 src/{ => native}/monodroid/jni/osbridge.cc | 0 src/{ => native}/monodroid/jni/osbridge.hh | 0 .../monodroid/jni/pinvoke-override-api.cc | 0 .../monodroid/jni/pinvoke-tables.include | 0 src/{ => native}/monodroid/jni/search.hh | 0 .../monodroid/jni/shared-constants.cc | 0 .../monodroid/jni/shared-constants.hh | 0 .../monodroid/jni/startup-aware-lock.hh | 0 src/{ => native}/monodroid/jni/strings.hh | 0 src/{ => native}/monodroid/jni/timezones.cc | 0 .../monodroid/jni/timing-internal.cc | 0 .../monodroid/jni/timing-internal.hh | 0 src/{ => native}/monodroid/jni/timing.hh | 0 src/{ => native}/monodroid/jni/util.cc | 0 src/{ => native}/monodroid/jni/util.hh | 0 src/{ => native}/monodroid/jni/win32/jni_md.h | 0 .../monodroid/jni/xa-internal-api-impl.hh | 0 .../monodroid/jni/xa-internal-api.cc | 0 .../monodroid/jni/xa-internal-api.hh | 0 .../jni/xamarin-android-app-context.cc | 0 src/{ => native}/monodroid/jni/xamarin-app.hh | 0 .../monodroid/jni/xamarin_getifaddrs.cc | 0 .../monodroid/jni/xamarin_getifaddrs.h | 0 src/{ => native}/monodroid/jni/xxhash.hh | 0 src/{ => native}/monodroid/machine.config.xml | 0 src/{ => native}/monodroid/monodroid.csproj | 0 src/{ => native}/monodroid/monodroid.targets | 0 88 files changed, 488 insertions(+), 7 deletions(-) create mode 100644 src/native/CMakePresets.json create mode 100644 src/native/CMakeUserPresets.json rename src/{monodroid => native}/libstub/stub.cc (100%) rename src/{libunwind-xamarin => native/libunwind}/CMakeLists.txt (100%) rename src/{libunwind-xamarin => native/libunwind}/config.h.in (100%) rename src/{libunwind-xamarin => native/libunwind}/fixes/aarch64/Gos-linux.c (100%) rename src/{libunwind-xamarin => native/libunwind}/libunwind-xamarin.csproj (100%) rename src/{libunwind-xamarin => native/libunwind}/libunwind-xamarin.targets (100%) rename src/{ => native}/monodroid/.gitignore (100%) rename src/{ => native}/monodroid/CMakeLists.txt (100%) rename src/{ => native}/monodroid/config.xml (100%) rename src/{ => native}/monodroid/jni/.gitignore (100%) rename src/{ => native}/monodroid/jni/TODO.md (100%) rename src/{ => native}/monodroid/jni/android-system.cc (100%) rename src/{ => native}/monodroid/jni/android-system.hh (100%) rename src/{ => native}/monodroid/jni/application_dso_stub.cc (100%) rename src/{ => native}/monodroid/jni/basic-android-system.cc (100%) rename src/{ => native}/monodroid/jni/basic-android-system.hh (100%) rename src/{ => native}/monodroid/jni/basic-utilities.cc (100%) rename src/{ => native}/monodroid/jni/basic-utilities.hh (100%) rename src/{ => native}/monodroid/jni/build-info.hh (100%) rename src/{ => native}/monodroid/jni/config.h (100%) rename src/{ => native}/monodroid/jni/cpp-util.hh (100%) rename src/{ => native}/monodroid/jni/cppcompat.hh (100%) rename src/{ => native}/monodroid/jni/cpu-arch-detect.cc (100%) rename src/{ => native}/monodroid/jni/cpu-arch.hh (100%) rename src/{ => native}/monodroid/jni/debug-app-helper.cc (100%) rename src/{ => native}/monodroid/jni/debug-app-helper.hh (100%) rename src/{ => native}/monodroid/jni/debug-constants.cc (100%) rename src/{ => native}/monodroid/jni/debug.cc (100%) rename src/{ => native}/monodroid/jni/debug.hh (100%) rename src/{ => native}/monodroid/jni/designer-assemblies.cc (100%) rename src/{ => native}/monodroid/jni/designer-assemblies.hh (100%) rename src/{ => native}/monodroid/jni/embedded-assemblies-zip.cc (100%) rename src/{ => native}/monodroid/jni/embedded-assemblies.cc (100%) rename src/{ => native}/monodroid/jni/embedded-assemblies.hh (100%) rename src/{ => native}/monodroid/jni/generate-pinvoke-tables.cc (100%) rename src/{ => native}/monodroid/jni/globals.cc (100%) rename src/{ => native}/monodroid/jni/globals.hh (100%) rename src/{ => native}/monodroid/jni/host-config.h.in (100%) rename src/{ => native}/monodroid/jni/internal-pinvoke-api.cc (100%) rename src/{ => native}/monodroid/jni/jni-remapping.cc (100%) rename src/{ => native}/monodroid/jni/jni-remapping.hh (100%) rename src/{ => native}/monodroid/jni/jni-wrappers.hh (100%) rename src/{ => native}/monodroid/jni/logger.cc (100%) rename src/{ => native}/monodroid/jni/logger.hh (100%) rename src/{ => native}/monodroid/jni/mono-image-loader.hh (100%) rename src/{ => native}/monodroid/jni/mono-log-adapter.cc (100%) rename src/{ => native}/monodroid/jni/mono_android_Runtime.h (100%) rename src/{ => native}/monodroid/jni/monodroid-glue-designer.cc (100%) rename src/{ => native}/monodroid/jni/monodroid-glue-internal.hh (100%) rename src/{ => native}/monodroid/jni/monodroid-glue.cc (100%) rename src/{ => native}/monodroid/jni/monodroid-glue.hh (100%) rename src/{ => native}/monodroid/jni/monodroid-networkinfo.cc (100%) rename src/{ => native}/monodroid/jni/monodroid-tracing.cc (100%) rename src/{ => native}/monodroid/jni/monodroid.h (100%) rename src/{ => native}/monodroid/jni/monodroid.x (100%) rename src/{ => native}/monodroid/jni/monovm-properties.cc (100%) rename src/{ => native}/monodroid/jni/monovm-properties.hh (100%) rename src/{ => native}/monodroid/jni/osbridge.cc (100%) rename src/{ => native}/monodroid/jni/osbridge.hh (100%) rename src/{ => native}/monodroid/jni/pinvoke-override-api.cc (100%) rename src/{ => native}/monodroid/jni/pinvoke-tables.include (100%) rename src/{ => native}/monodroid/jni/search.hh (100%) rename src/{ => native}/monodroid/jni/shared-constants.cc (100%) rename src/{ => native}/monodroid/jni/shared-constants.hh (100%) rename src/{ => native}/monodroid/jni/startup-aware-lock.hh (100%) rename src/{ => native}/monodroid/jni/strings.hh (100%) rename src/{ => native}/monodroid/jni/timezones.cc (100%) rename src/{ => native}/monodroid/jni/timing-internal.cc (100%) rename src/{ => native}/monodroid/jni/timing-internal.hh (100%) rename src/{ => native}/monodroid/jni/timing.hh (100%) rename src/{ => native}/monodroid/jni/util.cc (100%) rename src/{ => native}/monodroid/jni/util.hh (100%) rename src/{ => native}/monodroid/jni/win32/jni_md.h (100%) rename src/{ => native}/monodroid/jni/xa-internal-api-impl.hh (100%) rename src/{ => native}/monodroid/jni/xa-internal-api.cc (100%) rename src/{ => native}/monodroid/jni/xa-internal-api.hh (100%) rename src/{ => native}/monodroid/jni/xamarin-android-app-context.cc (100%) rename src/{ => native}/monodroid/jni/xamarin-app.hh (100%) rename src/{ => native}/monodroid/jni/xamarin_getifaddrs.cc (100%) rename src/{ => native}/monodroid/jni/xamarin_getifaddrs.h (100%) rename src/{ => native}/monodroid/jni/xxhash.hh (100%) rename src/{ => native}/monodroid/machine.config.xml (100%) rename src/{ => native}/monodroid/monodroid.csproj (100%) rename src/{ => native}/monodroid/monodroid.targets (100%) diff --git a/build-tools/create-packs/Microsoft.Android.Runtime.proj b/build-tools/create-packs/Microsoft.Android.Runtime.proj index 8982eb6f911..6ccb3fa4847 100644 --- a/build-tools/create-packs/Microsoft.Android.Runtime.proj +++ b/build-tools/create-packs/Microsoft.Android.Runtime.proj @@ -41,6 +41,8 @@ projects that use the Microsoft.Android framework in .NET 6+. <_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libmono-android.debug.so" /> <_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libmono-android.release.so" /> <_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libxamarin-debug-app-helper.so" /> + <_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libxamarin-native-tracing.so" /> + <_AndroidRuntimePackAssets Include="$(MicrosoftAndroidSdkOutDir)lib\$(AndroidRID)\libunwind_xamarin.a" /> diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index b7a0a0daee3..58f8e95f3d9 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -1,17 +1,140 @@ -cmake_minimum_required(VERSION 3.19) +cmake_minimum_required(VERSION 3.21) # -# MUST be included before project()! +# Read product version # -include("../../build-tools/cmake/xa_preamble.cmake") +file(STRINGS "../../Directory.Build.props" XA_PRODUCT_VERSION_XML REGEX "^[ \t]*(.*)") +string(REGEX REPLACE "^[ \t]*(.*)" "\\1" XA_VERSION "${XA_PRODUCT_VERSION_XML}") project( - native-libs + android-native-bits VERSION ${XA_VERSION} - LANGUAGES CXX + DESCRIPTION "Xamarin.Android native runtime" + HOMEPAGE_URL "https://github.com/xamarin/xamarin-android" + LANGUAGES CXX C ) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +include("${CMAKE_ANDROID_NDK}/build/cmake/abis.cmake") + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(DEBUG_BUILD True) +else() + set(DEBUG_BUILD False) +endif() + +set(XA_NO_INLINE "$ENV{XA_NO_INLINE}") +if(XA_NO_INLINE) + set(DONT_INLINE_DEFAULT ON) +else() + set(DONT_INLINE_DEFAULT OFF) +endif() + +set(XA_NO_STRIP "$ENV{XA_NO_STRIP}") +if(XA_NO_STRIP OR DEBUG_BUILD) + set(STRIP_DEBUG_DEFAULT OFF) +endif() + +option(ENABLE_CLANG_ASAN "Enable the clang AddressSanitizer support" OFF) +option(ENABLE_CLANG_UBSAN "Enable the clang UndefinedBehaviorSanitizer support" OFF) + +if(ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) + set(STRIP_DEBUG_DEFAULT OFF) + set(ANALYZERS_ENABLED ON) +else() + if(NOT XA_NO_STRIP) + set(STRIP_DEBUG_DEFAULT ON) + endif() + set(ANALYZERS_ENABLED OFF) +endif() + +option(COMPILER_DIAG_COLOR "Show compiler diagnostics/errors in color" ON) +option(STRIP_DEBUG "Strip debugging information when linking" ${STRIP_DEBUG_DEFAULT}) +option(DISABLE_DEBUG "Disable the built-in debugging code" OFF) +option(USE_CCACHE "Use ccache, if found, to speed up recompilation" ON) +option(DONT_INLINE "Do not inline any functions which are usually inlined, to get better stack traces" ${DONT_INLINE_DEFAULT}) + +if(USE_CCACHE) + if(CMAKE_CXX_COMPILER MATCHES "/ccache/") + message(STATUS "ccache: compiler already uses ccache") + else() + find_program(CCACHE ccache) + if(CCACHE) + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE}") + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE}") + message(STATUS "ccache: compiler will be lauched with ${CCACHE}") + endif() + endif() +endif() + +if(ANDROID_STL STREQUAL none) + set(USES_LIBSTDCPP False) +else() + set(USES_LIBSTDCPP True) +endif() + +# +# Needed modules +# +include(CheckIncludeFile) +include(CheckCXXSymbolExists) + +# +# General config +# +set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}") +include("${XA_BUILD_DIR}/xa_build_configuration.cmake") + # -# MUST be included after project()! +# Paths +# +if(ANDROID_ABI MATCHES "^arm64-v8a") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM64}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_arm64-v8a_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^armeabi-v7a") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_armeabi-v7a_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^x86_64") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86_64}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_64_TRIPLE}") +elseif(ANDROID_ABI MATCHES "^x86") + set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86}") + set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_TRIPLE}") +else() + message(FATAL "${ANDROID_ABI} is not supported for .NET 6+ builds") +endif() + +file(REAL_PATH "../../../" REPO_ROOT_DIR) +set(EXTERNAL_DIR "${REPO_ROOT_DIR}/external") +set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") +set(SHARED_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/shared") +set(TRACING_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/tracing") + # -include("../../build-tools/cmake/xa_common.cmake") +# Include directories +# +include_directories(SYSTEM ${CMAKE_SYSROOT}/usr/include/c++/v1/) +include_directories(SYSTEM "${NET_RUNTIME_DIR}/native/include/mono-2.0") +include_directories("${JAVA_INTEROP_SRC_PATH}") + +# +# Compiler defines +# +add_compile_definitions(XA_VERSION="${XA_VERSION}") +add_compile_definitions(_REENTRANT) +add_compile_definitions(PLATFORM_ANDROID) + +if(DEBUG_BUILD AND NOT DISABLE_DEBUG) + add_compile_definitions(DEBUG) +endif() + +if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") + add_compile_definitions(ANDROID64) +endif() diff --git a/src/native/CMakePresets.json b/src/native/CMakePresets.json new file mode 100644 index 00000000000..a841c345e63 --- /dev/null +++ b/src/native/CMakePresets.json @@ -0,0 +1,309 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 21, + "patch": 0 + }, + + "configurePresets": { + { + "name": "common", + "hidden": true, + "generator": "Ninja", + "debug": true, + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "ANDROID_TOOLCHAIN": "clang" + } + }, + + { + "name": "common-debug", + "hidden": "true", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "XA_BUILD_CONFIGURATION": "Debug" + } + }, + + { + "name": "common-release", + "hidden": "true", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "XA_BUILD_CONFIGURATION": "Release" + } + }, + + { + "name": "default-common", + "hidden": true, + "inherits": "common", + "cacheVariables": { + "ANDROID_STL": "none", + "ANDROID_CPP_FEATURES": "no-rtti no-exceptions" + } + }, + + { + "name": "analyzers-common", + "hidden": true, + "inherits": "common", + "cacheVariables": { + "ANDROID_STL": "c++_static", + "ANDROID_CPP_FEATURES": "rtti exceptions" + } + }, + + { + "name": "default-debug", + "hidden": true, + "inherits": ["default-common", "common-debug"] + }, + + { + "name": "default-release", + "hidden": true, + "inherits": ["default-common", "common-release"] + }, + + { + "name": "analyzers-debug", + "hidden": true, + "inherits": ["analyzers-common", "common-debug"] + }, + + { + "name": "analyzers-release", + "hidden": true, + "inherits": ["analyzers-common", "common-release"] + }, + + { + "name": "common-armeabi-v7a", + "hidden": true, + "cacheVariables": { + "ANDROID_ABI": "armeabi-v7a", + "ANDROID_RID": "android-arm" + } + }, + + { + "name": "common-arm64-v8a", + "hidden": true, + "cacheVariables": { + "ANDROID_ABI": "arm64-v8a", + "ANDROID_RID": "android-arm64" + } + }, + + { + "name": "common-x86", + "hidden": true, + "cacheVariables": { + "ANDROID_ABI": "x86", + "ANDROID_RID": "android-x86" + } + }, + + { + "name": "common-x86_64", + "hidden": true, + "cacheVariables": { + "ANDROID_ABI": "x86_64", + "ANDROID_RID": "android-x64" + } + }, + + { + "name": "asan-common", + "hidden": true, + "cacheVariables": { + "ENABLE_CLANG_ASAN": "ON" + } + }, + + { + "name": "ubsan-common", + "hidden": true, + "cacheVariables": { + "ENABLE_CLANG_UBSAN": "ON" + } + }, + + { + "name": "default-debug-armeabi-v7a", + "inherits": ["default-common", "common-debug", "common-armeabi-v7a"] + }, + + { + "name": "default-release-armeabi-v7a", + "inherits": ["default-common", "common-release", "common-armeabi-v7a"] + }, + + { + "name": "analyzers-debug-armeabi-v7a", + "hidden": true, + "inherits": ["analyzers-common", "common-debug", "common-armeabi-v7a"] + }, + + { + "name": "analyzers-release-armeabi-v7a", + "hidden": true, + "inherits": ["analyzers-common", "common-release", "common-armeabi-v7a"] + }, + + { + "name": "asan-release-armeabi-v7a", + "inherits": ["analyzers-release-armeabi-v7a", "asan-common"] + }, + + { + "name": "asan-debug-armeabi-v7a", + "inherits": ["analyzers-debug-armeabi-v7a", "asan-common"] + }, + + { + "name": "ubsan-release-armeabi-v7a", + "inherits": ["analyzers-release-armeabi-v7a", "ubsan-common"] + }, + + { + "name": "ubsan-debug-armeabi-v7a", + "inherits": ["analyzers-debug-armeabi-v7a", "ubsan-common"] + }, + + + + { + "name": "default-debug-arm64-v8a", + "inherits": ["default-common", "common-debug", "common-arm64-v8a"] + }, + + { + "name": "default-release-arm64-v8a", + "inherits": ["default-common", "common-release", "common-arm64-v8a"] + }, + + { + "name": "analyzers-debug-arm64-v8a", + "hidden": true, + "inherits": ["analyzers-common", "common-debug", "common-arm64-v8a"] + }, + + { + "name": "analyzers-release-arm64-v8a", + "hidden": true, + "inherits": ["analyzers-common", "common-release", "common-arm64-v8a"] + }, + + { + "name": "asan-release-arm64-v8a", + "inherits": ["analyzers-release-arm64-v8a", "asan-common"] + }, + + { + "name": "asan-debug-arm64-v8a", + "inherits": ["analyzers-debug-arm64-v8a", "asan-common"] + }, + + { + "name": "ubsan-release-arm64-v8a", + "inherits": ["analyzers-release-arm64-v8a", "ubsan-common"] + }, + + { + "name": "ubsan-debug-arm64-v8a", + "inherits": ["analyzers-debug-arm64-v8a", "ubsan-common"] + }, + + + + { + "name": "default-debug-x86", + "inherits": ["default-common", "common-debug", "common-x86"] + }, + + { + "name": "default-release-x86", + "inherits": ["default-common", "common-release", "common-x86"] + }, + + { + "name": "analyzers-debug-x86", + "hidden": true, + "inherits": ["analyzers-common", "common-debug", "common-x86"] + }, + + { + "name": "analyzers-release-x86", + "hidden": true, + "inherits": ["analyzers-common", "common-release", "common-x86"] + }, + + { + "name": "asan-release-x86", + "inherits": ["analyzers-release-x86", "asan-common"] + }, + + { + "name": "asan-debug-x86", + "inherits": ["analyzers-debug-x86", "asan-common"] + }, + + { + "name": "ubsan-release-x86", + "inherits": ["analyzers-release-x86", "ubsan-common"] + }, + + { + "name": "ubsan-debug-x86", + "inherits": ["analyzers-debug-x86", "ubsan-common"] + }, + + + + { + "name": "default-debug-x86_64", + "inherits": ["default-common", "common-debug", "common-x86_64"] + }, + + { + "name": "default-release-x86_64", + "inherits": ["default-common", "common-release", "common-x86_64"] + }, + + { + "name": "analyzers-debug-x86_64", + "hidden": true, + "inherits": ["analyzers-common", "common-debug", "common-x86_64"] + }, + + { + "name": "analyzers-release-x86_64", + "hidden": true, + "inherits": ["analyzers-common", "common-release", "common-x86_64"] + }, + + { + "name": "asan-release-x86_64", + "inherits": ["analyzers-release-x86_64", "asan-common"] + }, + + { + "name": "asan-debug-x86_64", + "inherits": ["analyzers-debug-x86_64", "asan-common"] + }, + + { + "name": "ubsan-release-x86_64", + "inherits": ["analyzers-release-x86_64", "ubsan-common"] + }, + + { + "name": "ubsan-debug-x86_64", + "inherits": ["analyzers-debug-x86_64", "ubsan-common"] + } + } +} diff --git a/src/native/CMakeUserPresets.json b/src/native/CMakeUserPresets.json new file mode 100644 index 00000000000..bf93c770157 --- /dev/null +++ b/src/native/CMakeUserPresets.json @@ -0,0 +1,47 @@ +{ + "version": 3, + "configurePresets": { + { + "name": "common", + "toolchainFile": "@AndroidCmakeToolchainFile@", + "cacheVariables": { + "ANDROID_NDK": "@AndroidNdkDirectory@", + "CMAKE_MAKE_PROGRAM": "@NinjaPath@", + "XA_LIB_TOP_DIR": "@MicrosoftAndroidSdkOutDir@", + "OUTPUT_PATH": "@OutputPath@" + } + }, + + { + "name": "common-armeabi-v7a", + "cacheVariables": { + "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_Arm@", + "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_Arm@" + } + }, + + { + "name": "common-arm64-v8a", + "cacheVariables": { + "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_Arm64@", + "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_Arm64@" + } + }, + + { + "name": "common-x86", + "cacheVariables": { + "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_X86@", + "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_X86@" + } + }, + + { + "name": "common-x86_64", + "cacheVariables": { + "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_X86_64@", + "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_X86_64@" + } + } + } +} diff --git a/src/monodroid/libstub/stub.cc b/src/native/libstub/stub.cc similarity index 100% rename from src/monodroid/libstub/stub.cc rename to src/native/libstub/stub.cc diff --git a/src/libunwind-xamarin/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt similarity index 100% rename from src/libunwind-xamarin/CMakeLists.txt rename to src/native/libunwind/CMakeLists.txt diff --git a/src/libunwind-xamarin/config.h.in b/src/native/libunwind/config.h.in similarity index 100% rename from src/libunwind-xamarin/config.h.in rename to src/native/libunwind/config.h.in diff --git a/src/libunwind-xamarin/fixes/aarch64/Gos-linux.c b/src/native/libunwind/fixes/aarch64/Gos-linux.c similarity index 100% rename from src/libunwind-xamarin/fixes/aarch64/Gos-linux.c rename to src/native/libunwind/fixes/aarch64/Gos-linux.c diff --git a/src/libunwind-xamarin/libunwind-xamarin.csproj b/src/native/libunwind/libunwind-xamarin.csproj similarity index 100% rename from src/libunwind-xamarin/libunwind-xamarin.csproj rename to src/native/libunwind/libunwind-xamarin.csproj diff --git a/src/libunwind-xamarin/libunwind-xamarin.targets b/src/native/libunwind/libunwind-xamarin.targets similarity index 100% rename from src/libunwind-xamarin/libunwind-xamarin.targets rename to src/native/libunwind/libunwind-xamarin.targets diff --git a/src/monodroid/.gitignore b/src/native/monodroid/.gitignore similarity index 100% rename from src/monodroid/.gitignore rename to src/native/monodroid/.gitignore diff --git a/src/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt similarity index 100% rename from src/monodroid/CMakeLists.txt rename to src/native/monodroid/CMakeLists.txt diff --git a/src/monodroid/config.xml b/src/native/monodroid/config.xml similarity index 100% rename from src/monodroid/config.xml rename to src/native/monodroid/config.xml diff --git a/src/monodroid/jni/.gitignore b/src/native/monodroid/jni/.gitignore similarity index 100% rename from src/monodroid/jni/.gitignore rename to src/native/monodroid/jni/.gitignore diff --git a/src/monodroid/jni/TODO.md b/src/native/monodroid/jni/TODO.md similarity index 100% rename from src/monodroid/jni/TODO.md rename to src/native/monodroid/jni/TODO.md diff --git a/src/monodroid/jni/android-system.cc b/src/native/monodroid/jni/android-system.cc similarity index 100% rename from src/monodroid/jni/android-system.cc rename to src/native/monodroid/jni/android-system.cc diff --git a/src/monodroid/jni/android-system.hh b/src/native/monodroid/jni/android-system.hh similarity index 100% rename from src/monodroid/jni/android-system.hh rename to src/native/monodroid/jni/android-system.hh diff --git a/src/monodroid/jni/application_dso_stub.cc b/src/native/monodroid/jni/application_dso_stub.cc similarity index 100% rename from src/monodroid/jni/application_dso_stub.cc rename to src/native/monodroid/jni/application_dso_stub.cc diff --git a/src/monodroid/jni/basic-android-system.cc b/src/native/monodroid/jni/basic-android-system.cc similarity index 100% rename from src/monodroid/jni/basic-android-system.cc rename to src/native/monodroid/jni/basic-android-system.cc diff --git a/src/monodroid/jni/basic-android-system.hh b/src/native/monodroid/jni/basic-android-system.hh similarity index 100% rename from src/monodroid/jni/basic-android-system.hh rename to src/native/monodroid/jni/basic-android-system.hh diff --git a/src/monodroid/jni/basic-utilities.cc b/src/native/monodroid/jni/basic-utilities.cc similarity index 100% rename from src/monodroid/jni/basic-utilities.cc rename to src/native/monodroid/jni/basic-utilities.cc diff --git a/src/monodroid/jni/basic-utilities.hh b/src/native/monodroid/jni/basic-utilities.hh similarity index 100% rename from src/monodroid/jni/basic-utilities.hh rename to src/native/monodroid/jni/basic-utilities.hh diff --git a/src/monodroid/jni/build-info.hh b/src/native/monodroid/jni/build-info.hh similarity index 100% rename from src/monodroid/jni/build-info.hh rename to src/native/monodroid/jni/build-info.hh diff --git a/src/monodroid/jni/config.h b/src/native/monodroid/jni/config.h similarity index 100% rename from src/monodroid/jni/config.h rename to src/native/monodroid/jni/config.h diff --git a/src/monodroid/jni/cpp-util.hh b/src/native/monodroid/jni/cpp-util.hh similarity index 100% rename from src/monodroid/jni/cpp-util.hh rename to src/native/monodroid/jni/cpp-util.hh diff --git a/src/monodroid/jni/cppcompat.hh b/src/native/monodroid/jni/cppcompat.hh similarity index 100% rename from src/monodroid/jni/cppcompat.hh rename to src/native/monodroid/jni/cppcompat.hh diff --git a/src/monodroid/jni/cpu-arch-detect.cc b/src/native/monodroid/jni/cpu-arch-detect.cc similarity index 100% rename from src/monodroid/jni/cpu-arch-detect.cc rename to src/native/monodroid/jni/cpu-arch-detect.cc diff --git a/src/monodroid/jni/cpu-arch.hh b/src/native/monodroid/jni/cpu-arch.hh similarity index 100% rename from src/monodroid/jni/cpu-arch.hh rename to src/native/monodroid/jni/cpu-arch.hh diff --git a/src/monodroid/jni/debug-app-helper.cc b/src/native/monodroid/jni/debug-app-helper.cc similarity index 100% rename from src/monodroid/jni/debug-app-helper.cc rename to src/native/monodroid/jni/debug-app-helper.cc diff --git a/src/monodroid/jni/debug-app-helper.hh b/src/native/monodroid/jni/debug-app-helper.hh similarity index 100% rename from src/monodroid/jni/debug-app-helper.hh rename to src/native/monodroid/jni/debug-app-helper.hh diff --git a/src/monodroid/jni/debug-constants.cc b/src/native/monodroid/jni/debug-constants.cc similarity index 100% rename from src/monodroid/jni/debug-constants.cc rename to src/native/monodroid/jni/debug-constants.cc diff --git a/src/monodroid/jni/debug.cc b/src/native/monodroid/jni/debug.cc similarity index 100% rename from src/monodroid/jni/debug.cc rename to src/native/monodroid/jni/debug.cc diff --git a/src/monodroid/jni/debug.hh b/src/native/monodroid/jni/debug.hh similarity index 100% rename from src/monodroid/jni/debug.hh rename to src/native/monodroid/jni/debug.hh diff --git a/src/monodroid/jni/designer-assemblies.cc b/src/native/monodroid/jni/designer-assemblies.cc similarity index 100% rename from src/monodroid/jni/designer-assemblies.cc rename to src/native/monodroid/jni/designer-assemblies.cc diff --git a/src/monodroid/jni/designer-assemblies.hh b/src/native/monodroid/jni/designer-assemblies.hh similarity index 100% rename from src/monodroid/jni/designer-assemblies.hh rename to src/native/monodroid/jni/designer-assemblies.hh diff --git a/src/monodroid/jni/embedded-assemblies-zip.cc b/src/native/monodroid/jni/embedded-assemblies-zip.cc similarity index 100% rename from src/monodroid/jni/embedded-assemblies-zip.cc rename to src/native/monodroid/jni/embedded-assemblies-zip.cc diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/native/monodroid/jni/embedded-assemblies.cc similarity index 100% rename from src/monodroid/jni/embedded-assemblies.cc rename to src/native/monodroid/jni/embedded-assemblies.cc diff --git a/src/monodroid/jni/embedded-assemblies.hh b/src/native/monodroid/jni/embedded-assemblies.hh similarity index 100% rename from src/monodroid/jni/embedded-assemblies.hh rename to src/native/monodroid/jni/embedded-assemblies.hh diff --git a/src/monodroid/jni/generate-pinvoke-tables.cc b/src/native/monodroid/jni/generate-pinvoke-tables.cc similarity index 100% rename from src/monodroid/jni/generate-pinvoke-tables.cc rename to src/native/monodroid/jni/generate-pinvoke-tables.cc diff --git a/src/monodroid/jni/globals.cc b/src/native/monodroid/jni/globals.cc similarity index 100% rename from src/monodroid/jni/globals.cc rename to src/native/monodroid/jni/globals.cc diff --git a/src/monodroid/jni/globals.hh b/src/native/monodroid/jni/globals.hh similarity index 100% rename from src/monodroid/jni/globals.hh rename to src/native/monodroid/jni/globals.hh diff --git a/src/monodroid/jni/host-config.h.in b/src/native/monodroid/jni/host-config.h.in similarity index 100% rename from src/monodroid/jni/host-config.h.in rename to src/native/monodroid/jni/host-config.h.in diff --git a/src/monodroid/jni/internal-pinvoke-api.cc b/src/native/monodroid/jni/internal-pinvoke-api.cc similarity index 100% rename from src/monodroid/jni/internal-pinvoke-api.cc rename to src/native/monodroid/jni/internal-pinvoke-api.cc diff --git a/src/monodroid/jni/jni-remapping.cc b/src/native/monodroid/jni/jni-remapping.cc similarity index 100% rename from src/monodroid/jni/jni-remapping.cc rename to src/native/monodroid/jni/jni-remapping.cc diff --git a/src/monodroid/jni/jni-remapping.hh b/src/native/monodroid/jni/jni-remapping.hh similarity index 100% rename from src/monodroid/jni/jni-remapping.hh rename to src/native/monodroid/jni/jni-remapping.hh diff --git a/src/monodroid/jni/jni-wrappers.hh b/src/native/monodroid/jni/jni-wrappers.hh similarity index 100% rename from src/monodroid/jni/jni-wrappers.hh rename to src/native/monodroid/jni/jni-wrappers.hh diff --git a/src/monodroid/jni/logger.cc b/src/native/monodroid/jni/logger.cc similarity index 100% rename from src/monodroid/jni/logger.cc rename to src/native/monodroid/jni/logger.cc diff --git a/src/monodroid/jni/logger.hh b/src/native/monodroid/jni/logger.hh similarity index 100% rename from src/monodroid/jni/logger.hh rename to src/native/monodroid/jni/logger.hh diff --git a/src/monodroid/jni/mono-image-loader.hh b/src/native/monodroid/jni/mono-image-loader.hh similarity index 100% rename from src/monodroid/jni/mono-image-loader.hh rename to src/native/monodroid/jni/mono-image-loader.hh diff --git a/src/monodroid/jni/mono-log-adapter.cc b/src/native/monodroid/jni/mono-log-adapter.cc similarity index 100% rename from src/monodroid/jni/mono-log-adapter.cc rename to src/native/monodroid/jni/mono-log-adapter.cc diff --git a/src/monodroid/jni/mono_android_Runtime.h b/src/native/monodroid/jni/mono_android_Runtime.h similarity index 100% rename from src/monodroid/jni/mono_android_Runtime.h rename to src/native/monodroid/jni/mono_android_Runtime.h diff --git a/src/monodroid/jni/monodroid-glue-designer.cc b/src/native/monodroid/jni/monodroid-glue-designer.cc similarity index 100% rename from src/monodroid/jni/monodroid-glue-designer.cc rename to src/native/monodroid/jni/monodroid-glue-designer.cc diff --git a/src/monodroid/jni/monodroid-glue-internal.hh b/src/native/monodroid/jni/monodroid-glue-internal.hh similarity index 100% rename from src/monodroid/jni/monodroid-glue-internal.hh rename to src/native/monodroid/jni/monodroid-glue-internal.hh diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/native/monodroid/jni/monodroid-glue.cc similarity index 100% rename from src/monodroid/jni/monodroid-glue.cc rename to src/native/monodroid/jni/monodroid-glue.cc diff --git a/src/monodroid/jni/monodroid-glue.hh b/src/native/monodroid/jni/monodroid-glue.hh similarity index 100% rename from src/monodroid/jni/monodroid-glue.hh rename to src/native/monodroid/jni/monodroid-glue.hh diff --git a/src/monodroid/jni/monodroid-networkinfo.cc b/src/native/monodroid/jni/monodroid-networkinfo.cc similarity index 100% rename from src/monodroid/jni/monodroid-networkinfo.cc rename to src/native/monodroid/jni/monodroid-networkinfo.cc diff --git a/src/monodroid/jni/monodroid-tracing.cc b/src/native/monodroid/jni/monodroid-tracing.cc similarity index 100% rename from src/monodroid/jni/monodroid-tracing.cc rename to src/native/monodroid/jni/monodroid-tracing.cc diff --git a/src/monodroid/jni/monodroid.h b/src/native/monodroid/jni/monodroid.h similarity index 100% rename from src/monodroid/jni/monodroid.h rename to src/native/monodroid/jni/monodroid.h diff --git a/src/monodroid/jni/monodroid.x b/src/native/monodroid/jni/monodroid.x similarity index 100% rename from src/monodroid/jni/monodroid.x rename to src/native/monodroid/jni/monodroid.x diff --git a/src/monodroid/jni/monovm-properties.cc b/src/native/monodroid/jni/monovm-properties.cc similarity index 100% rename from src/monodroid/jni/monovm-properties.cc rename to src/native/monodroid/jni/monovm-properties.cc diff --git a/src/monodroid/jni/monovm-properties.hh b/src/native/monodroid/jni/monovm-properties.hh similarity index 100% rename from src/monodroid/jni/monovm-properties.hh rename to src/native/monodroid/jni/monovm-properties.hh diff --git a/src/monodroid/jni/osbridge.cc b/src/native/monodroid/jni/osbridge.cc similarity index 100% rename from src/monodroid/jni/osbridge.cc rename to src/native/monodroid/jni/osbridge.cc diff --git a/src/monodroid/jni/osbridge.hh b/src/native/monodroid/jni/osbridge.hh similarity index 100% rename from src/monodroid/jni/osbridge.hh rename to src/native/monodroid/jni/osbridge.hh diff --git a/src/monodroid/jni/pinvoke-override-api.cc b/src/native/monodroid/jni/pinvoke-override-api.cc similarity index 100% rename from src/monodroid/jni/pinvoke-override-api.cc rename to src/native/monodroid/jni/pinvoke-override-api.cc diff --git a/src/monodroid/jni/pinvoke-tables.include b/src/native/monodroid/jni/pinvoke-tables.include similarity index 100% rename from src/monodroid/jni/pinvoke-tables.include rename to src/native/monodroid/jni/pinvoke-tables.include diff --git a/src/monodroid/jni/search.hh b/src/native/monodroid/jni/search.hh similarity index 100% rename from src/monodroid/jni/search.hh rename to src/native/monodroid/jni/search.hh diff --git a/src/monodroid/jni/shared-constants.cc b/src/native/monodroid/jni/shared-constants.cc similarity index 100% rename from src/monodroid/jni/shared-constants.cc rename to src/native/monodroid/jni/shared-constants.cc diff --git a/src/monodroid/jni/shared-constants.hh b/src/native/monodroid/jni/shared-constants.hh similarity index 100% rename from src/monodroid/jni/shared-constants.hh rename to src/native/monodroid/jni/shared-constants.hh diff --git a/src/monodroid/jni/startup-aware-lock.hh b/src/native/monodroid/jni/startup-aware-lock.hh similarity index 100% rename from src/monodroid/jni/startup-aware-lock.hh rename to src/native/monodroid/jni/startup-aware-lock.hh diff --git a/src/monodroid/jni/strings.hh b/src/native/monodroid/jni/strings.hh similarity index 100% rename from src/monodroid/jni/strings.hh rename to src/native/monodroid/jni/strings.hh diff --git a/src/monodroid/jni/timezones.cc b/src/native/monodroid/jni/timezones.cc similarity index 100% rename from src/monodroid/jni/timezones.cc rename to src/native/monodroid/jni/timezones.cc diff --git a/src/monodroid/jni/timing-internal.cc b/src/native/monodroid/jni/timing-internal.cc similarity index 100% rename from src/monodroid/jni/timing-internal.cc rename to src/native/monodroid/jni/timing-internal.cc diff --git a/src/monodroid/jni/timing-internal.hh b/src/native/monodroid/jni/timing-internal.hh similarity index 100% rename from src/monodroid/jni/timing-internal.hh rename to src/native/monodroid/jni/timing-internal.hh diff --git a/src/monodroid/jni/timing.hh b/src/native/monodroid/jni/timing.hh similarity index 100% rename from src/monodroid/jni/timing.hh rename to src/native/monodroid/jni/timing.hh diff --git a/src/monodroid/jni/util.cc b/src/native/monodroid/jni/util.cc similarity index 100% rename from src/monodroid/jni/util.cc rename to src/native/monodroid/jni/util.cc diff --git a/src/monodroid/jni/util.hh b/src/native/monodroid/jni/util.hh similarity index 100% rename from src/monodroid/jni/util.hh rename to src/native/monodroid/jni/util.hh diff --git a/src/monodroid/jni/win32/jni_md.h b/src/native/monodroid/jni/win32/jni_md.h similarity index 100% rename from src/monodroid/jni/win32/jni_md.h rename to src/native/monodroid/jni/win32/jni_md.h diff --git a/src/monodroid/jni/xa-internal-api-impl.hh b/src/native/monodroid/jni/xa-internal-api-impl.hh similarity index 100% rename from src/monodroid/jni/xa-internal-api-impl.hh rename to src/native/monodroid/jni/xa-internal-api-impl.hh diff --git a/src/monodroid/jni/xa-internal-api.cc b/src/native/monodroid/jni/xa-internal-api.cc similarity index 100% rename from src/monodroid/jni/xa-internal-api.cc rename to src/native/monodroid/jni/xa-internal-api.cc diff --git a/src/monodroid/jni/xa-internal-api.hh b/src/native/monodroid/jni/xa-internal-api.hh similarity index 100% rename from src/monodroid/jni/xa-internal-api.hh rename to src/native/monodroid/jni/xa-internal-api.hh diff --git a/src/monodroid/jni/xamarin-android-app-context.cc b/src/native/monodroid/jni/xamarin-android-app-context.cc similarity index 100% rename from src/monodroid/jni/xamarin-android-app-context.cc rename to src/native/monodroid/jni/xamarin-android-app-context.cc diff --git a/src/monodroid/jni/xamarin-app.hh b/src/native/monodroid/jni/xamarin-app.hh similarity index 100% rename from src/monodroid/jni/xamarin-app.hh rename to src/native/monodroid/jni/xamarin-app.hh diff --git a/src/monodroid/jni/xamarin_getifaddrs.cc b/src/native/monodroid/jni/xamarin_getifaddrs.cc similarity index 100% rename from src/monodroid/jni/xamarin_getifaddrs.cc rename to src/native/monodroid/jni/xamarin_getifaddrs.cc diff --git a/src/monodroid/jni/xamarin_getifaddrs.h b/src/native/monodroid/jni/xamarin_getifaddrs.h similarity index 100% rename from src/monodroid/jni/xamarin_getifaddrs.h rename to src/native/monodroid/jni/xamarin_getifaddrs.h diff --git a/src/monodroid/jni/xxhash.hh b/src/native/monodroid/jni/xxhash.hh similarity index 100% rename from src/monodroid/jni/xxhash.hh rename to src/native/monodroid/jni/xxhash.hh diff --git a/src/monodroid/machine.config.xml b/src/native/monodroid/machine.config.xml similarity index 100% rename from src/monodroid/machine.config.xml rename to src/native/monodroid/machine.config.xml diff --git a/src/monodroid/monodroid.csproj b/src/native/monodroid/monodroid.csproj similarity index 100% rename from src/monodroid/monodroid.csproj rename to src/native/monodroid/monodroid.csproj diff --git a/src/monodroid/monodroid.targets b/src/native/monodroid/monodroid.targets similarity index 100% rename from src/monodroid/monodroid.targets rename to src/native/monodroid/monodroid.targets From 37c2108076d0795a0fa1cd1147317311db9e0d2a Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 12 Apr 2024 12:33:39 +0200 Subject: [PATCH 07/23] [WIP] xaprepare generates cmake presets Neither runtime nor other native libraries are built yet --- Xamarin.Android.sln | 4 +- .../xaprepare/ConfigAndData/Configurables.cs | 1 + .../xaprepare/Steps/Step_GenerateFiles.cs | 26 ++++++++++ src/native/.gitignore | 2 + src/native/CMakeLists.txt | 1 + ...CMakePresets.json => CMakePresets.json.in} | 34 ++++++++++---- src/native/CMakeUserPresets.json | 47 ------------------- src/native/native.csproj | 22 +++++++++ 8 files changed, 77 insertions(+), 60 deletions(-) create mode 100644 src/native/.gitignore rename src/native/{CMakePresets.json => CMakePresets.json.in} (86%) delete mode 100644 src/native/CMakeUserPresets.json create mode 100644 src/native/native.csproj diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln index b46ca2898aa..eaf3ea4fb2e 100644 --- a/Xamarin.Android.sln +++ b/Xamarin.Android.sln @@ -47,9 +47,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Diagnost EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Cecil", "external\Java.Interop\src\Java.Interop.Tools.Cecil\Java.Interop.Tools.Cecil.csproj", "{D48EE8D0-0A0A-4493-AEF5-DAF5F8CF86AD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "libunwind", "src\libunwind-xamarin\libunwind-xamarin.csproj", "{F8E4961B-C427-47F9-92D6-0BEB5B76B3D7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "monodroid", "src\monodroid\monodroid.csproj", "{53EE4C57-1C03-405A-8243-8DA539546C88}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "native", "src\native\native.csproj", "{53EE4C57-1C03-405A-8243-8DA539546C88}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}" EndProject diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs index 3cebe494ddb..3d51c65bb7d 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs @@ -206,6 +206,7 @@ public static partial class Paths public static readonly string ExternalGitDepsFilePath = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, ".external"); public static readonly string ExternalGitDepsDestDir = ExternalDir; public static readonly string ExternalXamarinAndroidToolsSln = Path.Combine (ExternalDir, "xamarin-android-tools", "Xamarin.Android.Tools.sln"); + public static readonly string NativeSourcesDir = Path.Combine (BuildPaths.XamarinAndroidSourceRoot, "src", "native"); // Dynamic locations used throughout the code public static string ExternalJavaInteropDir => GetCachedPath (ref externalJavaInteropDir, () => ctx.Properties.GetRequiredValue (KnownProperties.JavaInteropFullPath)); diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs b/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs index aaa16fb9225..e4f7d26b610 100644 --- a/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs +++ b/build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs @@ -57,6 +57,7 @@ protected override async Task Execute (Context context) Get_SourceLink_Json (context), Get_Configuration_Generated_Props (context), Get_Cmake_XA_Build_Configuration (context), + Get_Cmake_Presets (context), }; } else { return new List { @@ -64,6 +65,7 @@ protected override async Task Execute (Context context) Get_Configuration_OperatingSystem_props (context), Get_Configuration_Generated_Props (context), Get_Cmake_XA_Build_Configuration (context), + Get_Cmake_Presets (context), Get_Ndk_projitems (context), Get_XABuildConfig_cs (context), Get_Omnisharp_Json (context), @@ -105,6 +107,30 @@ GeneratedFile Get_Cmake_XA_Build_Configuration (Context context) ); } + GeneratedFile Get_Cmake_Presets (Context context) + { + const string OutputFileName = "CMakePresets.json"; + + Properties props = context.Properties; + var replacements = new Dictionary (StringComparer.Ordinal) { + { "@AndroidNdkDirectory@", Utilities.EscapePathSeparators (props.GetRequiredValue (KnownProperties.AndroidNdkDirectory)) }, + { "@NinjaPath@", Utilities.EscapePathSeparators (props.GetRequiredValue (KnownProperties.NinjaPath)) }, + { "@MicrosoftAndroidSdkOutDir@", Utilities.EscapePathSeparators (props.GetRequiredValue (KnownProperties.MicrosoftAndroidSdkOutDir)) }, + { "@OutputPath@", Utilities.EscapePathSeparators (Path.Combine (props.GetRequiredValue (KnownProperties.MicrosoftAndroidSdkOutDir), "lib")) }, + { "@NDK_ARMEABI_V7_API_NET@", BuildAndroidPlatforms.NdkMinimumAPI.ToString () }, + { "@NDK_ARM64_V8A_API_NET@", BuildAndroidPlatforms.NdkMinimumAPI.ToString () }, + { "@NDK_X86_API_NET@", BuildAndroidPlatforms.NdkMinimumAPI.ToString () }, + { "@NDK_X86_64_API_NET@", BuildAndroidPlatforms.NdkMinimumAPI.ToString () }, + { "@XA_BUILD_CONFIGURATION@", context.Configuration }, + }; + + return new GeneratedPlaceholdersFile ( + replacements, + Path.Combine (Configurables.Paths.NativeSourcesDir, $"{OutputFileName}.in"), + Path.Combine (Configurables.Paths.NativeSourcesDir, OutputFileName) + ); + } + GeneratedFile Get_Configuration_Generated_Props (Context context) { const string OutputFileName = "Configuration.Generated.props"; diff --git a/src/native/.gitignore b/src/native/.gitignore new file mode 100644 index 00000000000..34d21e62347 --- /dev/null +++ b/src/native/.gitignore @@ -0,0 +1,2 @@ +CMakeUserPresets.json +CMakePresets.json diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 58f8e95f3d9..494aac9e49e 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -111,6 +111,7 @@ else() message(FATAL "${ANDROID_ABI} is not supported for .NET 6+ builds") endif() + file(REAL_PATH "../../../" REPO_ROOT_DIR) set(EXTERNAL_DIR "${REPO_ROOT_DIR}/external") set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") diff --git a/src/native/CMakePresets.json b/src/native/CMakePresets.json.in similarity index 86% rename from src/native/CMakePresets.json rename to src/native/CMakePresets.json.in index a841c345e63..51ae5802202 100644 --- a/src/native/CMakePresets.json +++ b/src/native/CMakePresets.json.in @@ -6,33 +6,39 @@ "patch": 0 }, - "configurePresets": { + "configurePresets": [ { "name": "common", "hidden": true, "generator": "Ninja", - "debug": true, + "debug": { + "output": true + }, + "toolchainFile": "@AndroidNdkDirectory@/build/cmake/android.toolchain.cmake", "cacheVariables": { + "ANDROID_NDK": "@AndroidNdkDirectory@", + "ANDROID_TOOLCHAIN": "clang", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", - "ANDROID_TOOLCHAIN": "clang" + "CMAKE_MAKE_PROGRAM": "@NinjaPath@", + "OUTPUT_PATH": "@OutputPath@", + "XA_LIB_TOP_DIR": "@MicrosoftAndroidSdkOutDir@", + "XA_BUILD_CONFIGURATION": "@XA_BUILD_CONFIGURATION@" } }, { "name": "common-debug", - "hidden": "true", + "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "XA_BUILD_CONFIGURATION": "Debug" + "CMAKE_BUILD_TYPE": "Debug" } }, { "name": "common-release", - "hidden": "true", + "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "XA_BUILD_CONFIGURATION": "Release" + "CMAKE_BUILD_TYPE": "Release" } }, @@ -85,6 +91,8 @@ "hidden": true, "cacheVariables": { "ANDROID_ABI": "armeabi-v7a", + "ANDROID_NATIVE_API_LEVEL": "@NDK_ARMEABI_V7_API_NET@", + "ANDROID_PLATFORM": "android-@NDK_ARMEABI_V7_API_NET@", "ANDROID_RID": "android-arm" } }, @@ -94,6 +102,8 @@ "hidden": true, "cacheVariables": { "ANDROID_ABI": "arm64-v8a", + "ANDROID_NATIVE_API_LEVEL": "@NDK_ARM64_V8A_API_NET@", + "ANDROID_PLATFORM": "android-@NDK_ARM64_V8A_API_NET@", "ANDROID_RID": "android-arm64" } }, @@ -103,6 +113,8 @@ "hidden": true, "cacheVariables": { "ANDROID_ABI": "x86", + "ANDROID_NATIVE_API_LEVEL": "@NDK_X86_API_NET@", + "ANDROID_PLATFORM": "android-@NDK_X86_API_NET@", "ANDROID_RID": "android-x86" } }, @@ -112,6 +124,8 @@ "hidden": true, "cacheVariables": { "ANDROID_ABI": "x86_64", + "ANDROID_NATIVE_API_LEVEL": "@NDK_X86_64_API_NET@", + "ANDROID_PLATFORM": "android-@NDK_X86_64_API_NET@", "ANDROID_RID": "android-x64" } }, @@ -305,5 +319,5 @@ "name": "ubsan-debug-x86_64", "inherits": ["analyzers-debug-x86_64", "ubsan-common"] } - } + ] } diff --git a/src/native/CMakeUserPresets.json b/src/native/CMakeUserPresets.json deleted file mode 100644 index bf93c770157..00000000000 --- a/src/native/CMakeUserPresets.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": 3, - "configurePresets": { - { - "name": "common", - "toolchainFile": "@AndroidCmakeToolchainFile@", - "cacheVariables": { - "ANDROID_NDK": "@AndroidNdkDirectory@", - "CMAKE_MAKE_PROGRAM": "@NinjaPath@", - "XA_LIB_TOP_DIR": "@MicrosoftAndroidSdkOutDir@", - "OUTPUT_PATH": "@OutputPath@" - } - }, - - { - "name": "common-armeabi-v7a", - "cacheVariables": { - "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_Arm@", - "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_Arm@" - } - }, - - { - "name": "common-arm64-v8a", - "cacheVariables": { - "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_Arm64@", - "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_Arm64@" - } - }, - - { - "name": "common-x86", - "cacheVariables": { - "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_X86@", - "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_X86@" - } - }, - - { - "name": "common-x86_64", - "cacheVariables": { - "ANDROID_NATIVE_API_LEVEL": "@AndroidNdkApiLevel_X86_64@", - "ANDROID_PLATFORM": "android-@AndroidNdkApiLevel_X86_64@" - } - } - } -} diff --git a/src/native/native.csproj b/src/native/native.csproj new file mode 100644 index 00000000000..38b77115100 --- /dev/null +++ b/src/native/native.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + Debug + AnyCPU + Exe + false + + + + + + $(MicrosoftAndroidSdkOutDir)lib\ + + + + + + + + From eb0628fd943d35b10fccd8f574dc7daa6a4bbf80 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 12 Apr 2024 19:29:53 +0200 Subject: [PATCH 08/23] [WIP] cmake stuff Some libs build already. monodroid still not built. --- external/libunwind | 2 +- src/native/CMakeLists.txt | 304 ++++++++++++++++++++++++++-- src/native/libstub/CMakeLists.txt | 44 ++++ src/native/libunwind/CMakeLists.txt | 157 +++++++------- src/native/native.targets | 199 ++++++++++++++++++ src/native/shared/CMakeLists.txt | 45 ++++ src/native/shared/helpers.hh | 2 +- 7 files changed, 651 insertions(+), 102 deletions(-) create mode 100644 src/native/libstub/CMakeLists.txt create mode 100644 src/native/native.targets create mode 100644 src/native/shared/CMakeLists.txt diff --git a/external/libunwind b/external/libunwind index 3705baed4dd..9cc4d98b22a 160000 --- a/external/libunwind +++ b/external/libunwind @@ -1 +1 @@ -Subproject commit 3705baed4ddb5a98138d16dd2effcaeaa7e72db5 +Subproject commit 9cc4d98b22ae57bc1d8c253988feb85d4298a634 diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 494aac9e49e..9d465d16ba6 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -11,9 +11,27 @@ project( VERSION ${XA_VERSION} DESCRIPTION "Xamarin.Android native runtime" HOMEPAGE_URL "https://github.com/xamarin/xamarin-android" - LANGUAGES CXX C + LANGUAGES CXX C ASM ) +# +# Sanity checks +# +macro(ensure_variable_set VARNAME) + if(NOT ${VARNAME}) + message(FATAL_ERROR "Variable ${VARNAME} not set. Please set it either on command line with -D${VARNAME}=value or in the presets file") + endif() +endmacro() + +ensure_variable_set(ANDROID_ABI) +ensure_variable_set(CMAKE_ANDROID_NDK) +ensure_variable_set(OUTPUT_PATH) +ensure_variable_set(XA_BUILD_CONFIGURATION) +ensure_variable_set(XA_LIB_TOP_DIR) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_PATH}/${ANDROID_RID}" CACHE PATH "" FORCE) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_PATH}/${ANDROID_RID}" CACHE PATH "" FORCE) + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -83,8 +101,11 @@ endif() # # Needed modules # -include(CheckIncludeFile) -include(CheckCXXSymbolExists) +# include(CheckIncludeFile) +# include(CheckCXXSymbolExists) +include(CheckCXXCompilerFlag) +include(CheckCCompilerFlag) +include(CheckLinkerFlag) # # General config @@ -112,30 +133,285 @@ else() endif() -file(REAL_PATH "../../../" REPO_ROOT_DIR) +file(REAL_PATH "../../" REPO_ROOT_DIR) set(EXTERNAL_DIR "${REPO_ROOT_DIR}/external") set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") -set(SHARED_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/shared") -set(TRACING_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/tracing") +set(LIBUNWIND_SOURCE_DIR "${EXTERNAL_DIR}/libunwind") + # # Include directories # -include_directories(SYSTEM ${CMAKE_SYSROOT}/usr/include/c++/v1/) -include_directories(SYSTEM "${NET_RUNTIME_DIR}/native/include/mono-2.0") -include_directories("${JAVA_INTEROP_SRC_PATH}") +set(SYSROOT_CXX_INCLUDE_DIR ${CMAKE_SYSROOT}/usr/include/c++/v1) +set(MONO_RUNTIME_INCLUDE_DIR ${NET_RUNTIME_DIR}/native/include/mono-2.0) +set(JAVA_INTEROP_INCLUDE_DIR ${JAVA_INTEROP_SRC_PATH}) # # Compiler defines # -add_compile_definitions(XA_VERSION="${XA_VERSION}") -add_compile_definitions(_REENTRANT) -add_compile_definitions(PLATFORM_ANDROID) +macro(xa_add_compile_definitions TARGET) + target_compile_definitions( + ${TARGET} + PRIVATE + XA_VERSION="${XA_VERSION}" + _REENTRANT + PLATFORM_ANDROID + ) + + if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") + target_compile_definitions( + ${TARGET} + PRIVATE + ANDROID64 + ) + endif() +endmacro() if(DEBUG_BUILD AND NOT DISABLE_DEBUG) add_compile_definitions(DEBUG) endif() -if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") - add_compile_definitions(ANDROID64) +if(NOT DEBUG_BUILD) + add_compile_definitions(RELEASE NDEBUG) endif() + +# +# Compiler argument macros +# +macro(_compiler_has_arg _lang _arg) + string(REGEX REPLACE "-|,|=" "_" _arg_name ${_arg}) + string(TOUPPER "${_lang}" _lang_upper) + + cmake_language(CALL check_${_lang}_compiler_flag "${_arg}" HAS_${_arg_name}_${_lang_upper}) + if(HAS_${_arg_name}_${_lang_upper}) + set(COMPILER_ARG_FOUND True) + else() + set(COMPILER_ARG_FOUND False) + endif() +endmacro() + +macro(cxx_compiler_has_arg _arg) + _compiler_has_arg(cxx ${_arg}) +endmacro() + +macro(c_compiler_has_arg _arg) + _compiler_has_arg(c ${_arg}) +endmacro() + +macro(_linker_has_arg _lang _arg) + string(REGEX REPLACE "-|,|=" "_" _arg_name ${_arg}) + string(TOUPPER "${_lang}" _lang_upper) + + check_linker_flag(${_lang} "${_arg}" HAS_${_arg_name}_LINKER_${_lang_upper}) + if(HAS_${_arg_name}_LINKER_${_lang_upper}) + set(LINKER_ARG_FOUND True) + else() + set(LINKER_ARG_FOUND False) + endif() +endmacro() + +macro(cxx_linker_has_arg _arg) + _linker_has_arg(CXX ${_arg}) +endmacro() + +macro(c_linker_has_arg _arg) + _linker_has_arg(C ${_arg}) +endmacro() + +macro(xa_check_c_args VARNAME _CHECK_ARGS) + set(_CHECKED_ARGS "") + + foreach(arg ${_CHECK_ARGS}) + c_compiler_has_arg(${arg}) + if(COMPILER_ARG_FOUND) + list(APPEND _CHECKED_ARGS "${arg}") + endif() + endforeach() + + set(${VARNAME} "${_CHECKED_ARGS}") +endmacro() + +macro(xa_check_cxx_args VARNAME _CHECK_ARGS) + set(_CHECKED_ARGS "") + + foreach(arg ${_CHECK_ARGS}) + cxx_compiler_has_arg(${arg}) + if(COMPILER_ARG_FOUND) + list(APPEND _CHECKED_ARGS "${arg}") + endif() + endforeach() + + set(${VARNAME} "${_CHECKED_ARGS}") +endmacro() + +macro(xa_check_c_linker_args VARNAME _CHECK_ARGS) + set(_CHECKED_ARGS "") + + foreach(arg ${_CHECK_ARGS}) + c_linker_has_arg(${arg}) + if(LINKER_ARG_FOUND) + list(APPEND _CHECKED_ARGS "${arg}") + endif() + endforeach() + + set(${VARNAME} "${_CHECKED_ARGS}") +endmacro() + +macro(xa_check_cxx_linker_args VARNAME _CHECK_ARGS) + set(_CHECKED_ARGS "") + + foreach(arg ${_CHECK_ARGS}) + cxx_linker_has_arg(${arg}) + if(LINKER_ARG_FOUND) + list(APPEND _CHECKED_ARGS "${arg}") + endif() + endforeach() + + set(${VARNAME} "${_CHECKED_ARGS}") +endmacro() + +# +# Compiler args +# +set(CMAKE_CXX_VISIBILITY_PRESET "hidden") +set(CMAKE_C_VISIBILITY_PRESET "hidden") + +# +# Common flags are used when building all external +# and our own code +# +set(POTENTIAL_COMMON_COMPILER_ARGS + -fstack-protector-strong + -fstrict-return + -fno-strict-aliasing + -fno-function-sections + -fno-data-sections + -funswitch-loops + -Wa,-noexecstack + -fPIC + -g + -O2 +) + +set(POTENTIAL_COMMON_LINKER_ARGS + -fstack-protector-strong + LINKER:-fstrict-return + LINKER:-z,now + LINKER:-z,relro + LINKER:-z,noexecstack + LINKER:--no-undefined + LINKER:--export-dynamic +) + +# Add some options to increase security. They may mildly affect performance but they won't be big, because the features are +# assisted by the hardware. +if((CMAKE_ANDROID_ARCH_ABI STREQUAL "x86") OR (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")) + # -fcf-protection=full: Enable control flow protection to counter Return Oriented Programming (ROP) and Jump Oriented Programming (JOP) attacks on many x86 architectures + list(APPEND POTENTIAL_COMMON_COMPILER_ARGS + -fcf-protection=full + ) +endif() + +if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + # -mbranch-protection=standard: Enable branch protection to counter Return Oriented Programming (ROP) and Jump Oriented Programming (JOP) attacks on AArch64 + # In clang -mbranch-protection=standard is equivalent to -mbranch-protection=bti+pac-ret and invokes the AArch64 Branch Target Identification (BTI) and Pointer Authentication using key A (pac-ret) + list(APPEND POTENTIAL_COMMON_COMPILER_ARGS + -mbranch-protection=standard + ) +endif() + +if(COMPILER_DIAG_COLOR) + list(APPEND POTENTIAL_COMMON_COMPILER_ARGS + -fdiagnostics-color=always + -fcolor-diagnostics + ) +endif() + +if(STRIP_DEBUG) + list(APPEND POTENTIAL_COMMON_LINKER_ARGS LINKER:-S) +else() + # When not stripping symbols, we likely want to have precise stack traces, so + # we won't omit frame pointers + list(APPEND POTENTIAL_COMMON_COMPILER_ARGS + -fno-omit-frame-pointer + -fno-limit-debug-info + ) +endif() + +# +# Flags to use only when building our code +# +set(POTENTIAL_XA_COMMON_COMPILER_ARGS + -Wall + -Wconversion + -Wdeprecated + -Wduplicated-branches + -Wduplicated-cond + -Werror=format-security + -Werror=return-type + -Wextra + -Wformat-security + -Wformat=2 + -Wno-format-nonliteral + -Wimplicit-fallthrough + -Wmisleading-indentation + -Wnull-dereference + -Wpointer-arith + -Wshadow + -Wsign-compare + -Wtrampolines + -Wuninitialized + -fstrict-flex-arrays=3 +) + +if (ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) + list(APPEND POTENTIAL_XA_COMMON_COMPILER_ARGS + -fno-omit-frame-pointer + -fno-optimize-sibling-calls + ) +endif() + +unset(SANITIZER_FLAGS) +if (ENABLE_CLANG_ASAN) + set(SANITIZER_FLAGS -fsanitize=address) + set(CHECKED_BUILD_INFIX "-checked+asan") +elseif(ENABLE_CLANG_UBSAN) + set(SANITIZER_FLAGS -fsanitize=undefined) + set(CHECKED_BUILD_INFIX "-checked+ubsan") +endif() + +if(SANITIZER_FLAGS) + message(STATUS) + message(STATUS "Got sanitizer: ${SANITIZER_FLAGS}") + message(STATUS) + + list(APPEND POTENTIAL_XA_COMMON_COMPILER_ARGS ${SANITIZER_FLAGS}) + list(APPEND POTENTIAL_XA_COMMON_LINKER_ARGS ${SANITIZER_FLAGS}) + list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${SANITIZER_FLAGS}) +endif() + +message(STATUS) +message(STATUS "Checking support for common compiler and linker args") +message(STATUS) +xa_check_cxx_args(COMMON_CXX_ARGS "${POTENTIAL_COMMON_COMPILER_ARGS}") +xa_check_c_args(COMMON_C_ARGS "${POTENTIAL_COMMON_COMPILER_ARGS}") +xa_check_cxx_linker_args(COMMON_CXX_LINKER_ARGS "${POTENTIAL_COMMON_LINKER_ARGS}") +xa_check_c_linker_args(COMMON_C_LINKER_ARGS "${POTENTIAL_COMMON_LINKER_ARGS}") + +message(STATUS) +message(STATUS "Checking support for XA common compiler and linker args") +message(STATUS) +xa_check_cxx_args(XA_COMMON_CXX_ARGS "${POTENTIAL_XA_COMMON_COMPILER_ARGS}") +xa_check_c_args(XA_COMMON_C_ARGS "${POTENTIAL_XA_COMMON_COMPILER_ARGS}") +xa_check_cxx_linker_args(XA_COMMON_CXX_LINKER_ARGS "${POTENTIAL_XA_COMMON_LINKER_ARGS}") +xa_check_c_linker_args(XA_COMMON_C_LINKER_ARGS "${POTENTIAL_XA_COMMON_LINKER_ARGS}") + +add_compile_options("$<$:${COMMON_CXX_ARGS}>") +add_compile_options("$<$:${COMMON_C_ARGS}>") + +add_link_options("$<$:${COMMON_CXX_LINKER_ARGS}>") +add_link_options("$<$:${COMMON_C_LINKER_ARGS}>") + +add_subdirectory(libstub) +add_subdirectory(shared) +add_subdirectory(libunwind) diff --git a/src/native/libstub/CMakeLists.txt b/src/native/libstub/CMakeLists.txt new file mode 100644 index 00000000000..16dc744ee95 --- /dev/null +++ b/src/native/libstub/CMakeLists.txt @@ -0,0 +1,44 @@ +set(XA_LIBRARY_STUBS_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/libstubs/${ANDROID_RID}") + +set(XAMARIN_STUB_LIB_SOURCES + stub.cc +) + +macro(xa_add_stub_library _libname) + if(NOT ANALYZERS_ENABLED) + add_library( + ${_libname} + SHARED ${XAMARIN_STUB_LIB_SOURCES} + ) + + string(TOUPPER ${_libname} _libname_uc) + target_compile_definitions( + ${_libname} + PRIVATE STUB_LIB_NAME=lib${_libname} IN_LIB${_libname_uc} + ) + xa_add_compile_definitions(${_libname}) + + target_compile_options( + ${_libname} + PRIVATE ${XA_COMMON_CXX_ARGS} -nostdlib -fno-exceptions -fno-rtti + ) + + target_link_options( + ${_libname} + PRIVATE ${XA_COMMON_CXX_LINKER_ARGS} -nostdlib -fno-exceptions -fno-rtti + ) + + set_target_properties( + ${_libname} + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${XA_LIBRARY_STUBS_OUTPUT_DIRECTORY}" + ) + endif() +endmacro() + +xa_add_stub_library(c) +xa_add_stub_library(m) + +# These two are used by the marshal methods tracing library when linking libxamarin-app.so +xa_add_stub_library(log) +xa_add_stub_library(dl) diff --git a/src/native/libunwind/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt index 02ad008d774..11ffeda2095 100644 --- a/src/native/libunwind/CMakeLists.txt +++ b/src/native/libunwind/CMakeLists.txt @@ -1,25 +1,6 @@ -cmake_minimum_required(VERSION 3.19) - -# -# MUST be included before project()! -# -include("../../build-tools/cmake/xa_preamble.cmake") - -if(NOT DEFINED LIBUNWIND_LIBRARY_NAME) - message(FATAL_ERROR "Please set the LIBUNWIND_LIBRARY_NAME variable on command line (-DLIBUNWIND_LIBRARY_NAME=base_library_name)") -endif() - -if(NOT DEFINED LIBUNWIND_SOURCE_DIR) - message(FATAL_ERROR "Please set the LIBUNWIND_SOURCE_DIR variable on command line (-DLIBUNWIND_SOURCE_DIR=source_dir_path)") -endif() - -if(NOT DEFINED LIBUNWIND_OUTPUT_DIR) - message(FATAL_ERROR "Please set the LIBUNWIND_OUTPUT_DIR variable on command line (-DLIBUNWIND_OUTPUT_DIR=output_dir_path)") -endif() - -if(NOT DEFINED LIBUNWIND_HEADERS_OUTPUT_DIR) - message(FATAL_ERROR "Please set the LIBUNWIND_HEADERS_OUTPUT_DIR variable on command line (-DLIBUNWIND_HEADERS_OUTPUT_DIR=output_dir_path)") -endif() +ensure_variable_set(LIBUNWIND_SOURCE_DIR) +set(LIB_NAME unwind-xamarin) +set(LIB_ALIAS xa::unwind) # # Read libunwind version @@ -38,27 +19,11 @@ set(PKG_EXTRA "${UNWIND_EXTRA_VERSION}") set(PACKAGE_STRING "libunwind-xamarin") set(PACKAGE_BUGREPORT "") -message(STATUS "Major: ${PKG_MAJOR}; Minor: ${PKG_MINOR}; Extra: ${PKG_EXTRA}") - -project( - libunwind-xamarin -# VERSION "${PKG_MAJOR}.${PKG_MINOR}.${PKG_EXTRA}" - LANGUAGES C ASM -) - -# -# MUST be included after project()! -# -include("../../build-tools/cmake/xa_common.cmake") +message(STATUS "libunwind version: ${PKG_MAJOR}.${PKG_MINOR}.${PKG_EXTRA}") include(CheckCSourceCompiles) include(CheckIncludeFiles) include(CheckSymbolExists) -include("../../build-tools/cmake/xa_macros.cmake") - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBUNWIND_OUTPUT_DIR}) if(CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a) set(TARGET_AARCH64 TRUE) @@ -76,30 +41,19 @@ else() message(FATAL_ERROR "Unsupported Android ABI ${CMAKE_ANDROID_ARCH_ABI}") endif() -set(DSO_SYMBOL_VISIBILITY "hidden") -xa_common_prepare() - -if(CMAKE_BUILD_TYPE STREQUAL Debug) - list(APPEND LOCAL_COMPILER_ARGS -g -fno-omit-frame-pointer) +if(IS_DEBUG) + list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS -g -fno-omit-frame-pointer) else() - list(APPEND LOCAL_COMPILER_ARGS -s -fomit-frame-pointer) + list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS -fomit-frame-pointer) add_compile_definitions(NDEBUG) endif() -list(APPEND LOCAL_COMPILER_ARGS - ${XA_DEFAULT_SYMBOL_VISIBILITY} +list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS -fno-asynchronous-unwind-tables -fno-unwind-tables + -Wno-macro-redefined ) -xa_check_c_flags(XA_C_FLAGS "${LOCAL_COMPILER_ARGS}") -xa_check_c_linker_flags(XA_C_LINKER_FLAGS "${LOCAL_COMPILER_ARGS}") - -add_compile_options(${XA_C_FLAGS}) -add_link_options(${XA_C_LINKER_FLAGS}) - -add_compile_definitions(HAVE_CONFIG_H) -add_compile_definitions(_GNU_SOURCE) -add_compile_definitions(UNW_LOCAL_ONLY) # we don't need remote unwinding +xa_check_c_args(LIBUNWIND_C_ARGS "${POTENTIAL_LOCAL_COMPILER_ARGS}") # Detect include files set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) @@ -126,34 +80,6 @@ configure_file(${LIBUNWIND_SOURCE_DIR}/include/libunwind-common.h.in ${CMAKE_CUR configure_file(${LIBUNWIND_SOURCE_DIR}/include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) configure_file(${LIBUNWIND_SOURCE_DIR}/include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) -# The files are nearly identical, the only difference is name of the header included when remote-only libunwind is used -# We don't use it, but we still copy files to separate directories in order to avoid locking issues during parallel builds -set(HEADERS_DIR ${LIBUNWIND_HEADERS_OUTPUT_DIR}/${CMAKE_ANDROID_ARCH_ABI}) - -file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h DESTINATION ${HEADERS_DIR}) -file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h DESTINATION ${HEADERS_DIR}) -file(COPY ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h DESTINATION ${HEADERS_DIR}/tdep/) - -include_directories(${LIBUNWIND_SOURCE_DIR}/include/tdep) -include_directories(${LIBUNWIND_SOURCE_DIR}/include) -include_directories(${LIBUNWIND_SOURCE_DIR}/src) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/tdep) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) - -if(TARGET_ARM) - # Ensure that the remote and local unwind code can reside in the same binary without name clashing - add_definitions("-Darm_search_unwind_table=UNW_OBJ(arm_search_unwind_table)") - # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension - #TODO: possibly not needed? add_definitions(-Dasm=__asm__) - # The arm sources include ex_tables.h from include/tdep-arm without going through a redirection - # in include/tdep like it works for similar files on other architectures. So we need to add - # the include/tdep-arm to include directories - include_directories(${LIBUNWIND_SOURCE_DIR}/include/tdep-arm) -elseif(TARGET_AARCH64) - # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension - #TODO: possibly not needed? add_definitions(-Dasm=__asm__) -endif() - set(SOURCES_DIR ${LIBUNWIND_SOURCE_DIR}/src) set(LIBUNWIND_XAMARIN_SOURCES @@ -384,12 +310,71 @@ if(TARGET_AARCH64) ) endif() -add_library(${LIBUNWIND_LIBRARY_NAME} +add_library( + ${LIB_NAME} STATIC ${LIBUNWIND_XAMARIN_SOURCES} ) +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" + "$" + "$" + "$" +) + +if(TARGET_ARM) + # Ensure that the remote and local unwind code can reside in the same binary without name clashing + target_compile_definitions( + ${LIB_NAME} + PRIVATE + "arm_search_unwind_table=UNW_OBJ(arm_search_unwind_table)" + ) + + # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension + #TODO: possibly not needed? add_definitions(-Dasm=__asm__) + # The arm sources include ex_tables.h from include/tdep-arm without going through a redirection + # in include/tdep like it works for similar files on other architectures. So we need to add + # the include/tdep-arm to include directories + target_include_directories( + ${LIB_NAME} + PRIVATE + ${LIBUNWIND_SOURCE_DIR}/include/tdep-arm + ) +elseif(TARGET_AARCH64) + # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension + #TODO: possibly not needed? add_definitions(-Dasm=__asm__) +endif() + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${COMMON_C_ARGS} ${LIBUNWIND_C_ARGS} +) + +target_include_directories( + ${LIB_NAME} + PRIVATE + ${LIBUNWIND_SOURCE_DIR}/src +) + target_link_options( - ${LIBUNWIND_LIBRARY_NAME} + ${LIB_NAME} PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} ) + +target_compile_definitions( + ${LIB_NAME} + PUBLIC + UNW_LOCAL_ONLY +) + +target_compile_definitions( + ${LIB_NAME} + PRIVATE + HAVE_CONFIG_H _GNU_SOURCE +) diff --git a/src/native/native.targets b/src/native/native.targets new file mode 100644 index 00000000000..97394fd5c65 --- /dev/null +++ b/src/native/native.targets @@ -0,0 +1,199 @@ + + + + + + + + + <_ConfigureRuntimesInputs Include="CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="libstub\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="libunwind\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="monodroid\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="shared\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="tracing\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Debug\CMakeCache.txt')" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Release\CMakeCache.txt')" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Debug" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Release" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Release" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + + + + + + <_NoInline Condition=" '$(DoNotInlineMonodroid)' == 'true' ">-DDONT_INLINE=ON + <_NoStrip Condition=" '$(DoNotStripMonodroid)' == 'true' ">-DSTRIP_DEBUG=OFF + + <_CmakeAndroidFlags>$(_NoInline) $(_NoStrip) "$(MSBuildThisFileDirectory)" + + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset default-debug-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset default-release-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release + + + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset asan-debug-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset asan-release-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Release + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset ubsan-debug-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Debug + + + <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> + $(CmakePath) + --preset ubsan-release-%(AndroidSupportedTargetJitAbi.Identity) $(_CmakeAndroidFlags) + $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Release + + + + + + + + + + + + <_MonoDroidSources Include="jni\*.cc;jni\*.h;jni\*.hh;jni\**\*.c;" /> + + + + + + <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Debug\CMakeCache.txt')" /> + <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Release\CMakeCache.txt')" /> + <_BuildAndroidRuntimesInputs Include="@(_MonoDroidSources)" /> + <_BuildAndroidRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" /> + <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android.debug.so')" /> + <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android.release.so')" /> + <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\Debug\libxamarin-app.so')" /> + <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\Release\libxamarin-app.so')" /> + + + <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+ubsan.debug.so')" /> + <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+asan.debug.so')" /> + <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+asan.release.so')" /> + <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+ubsan.release.so')" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ArmRuntimePackFiles Include="$(OutputPath)\android-arm\*.*" /> + <_Arm64RuntimePackFiles Include="$(OutputPath)\android-arm64\*.*" /> + <_x86RuntimePackFiles Include="$(OutputPath)\android-x86\*.*" /> + <_x64RuntimePackFiles Include="$(OutputPath)\android-x64\*.*" /> + + + + + + + + diff --git a/src/native/shared/CMakeLists.txt b/src/native/shared/CMakeLists.txt new file mode 100644 index 00000000000..54620d837ac --- /dev/null +++ b/src/native/shared/CMakeLists.txt @@ -0,0 +1,45 @@ +set(LIB_NAME xa-shared-bits) +set(LIB_ALIAS xa::shared) + +set(XA_SHARED_SOURCES + cxx-abi/string.cc + cxx-abi/terminate.cc + helpers.cc + new_delete.cc +) + +add_library( + ${LIB_NAME} + STATIC + ${XA_SHARED_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" + "$" +) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} +) + +set_target_properties( + ${LIB_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/shared/helpers.hh b/src/native/shared/helpers.hh index fe5b03ecda1..40eff78eaca 100644 --- a/src/native/shared/helpers.hh +++ b/src/native/shared/helpers.hh @@ -4,7 +4,7 @@ #include #include -#include "java-interop-util.h" +#include #include "platform-compat.hh" namespace xamarin::android From 5756ecded4319ab5e8fc8a1a37bdea691f65e1bd Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 15 Apr 2024 22:31:20 +0200 Subject: [PATCH 09/23] Refactoring + cleanup continue --- src/native/CMakeLists.txt | 4 +- src/native/libunwind/CMakeLists.txt | 5 + src/native/monodroid/CMakeLists.txt | 69 +-- src/native/monodroid/jni/android-system.hh | 139 ------ .../monodroid/jni/basic-android-system.cc | 109 ----- .../monodroid/jni/basic-android-system.hh | 110 ----- src/native/monodroid/jni/basic-utilities.hh | 343 --------------- src/native/monodroid/jni/debug.hh | 16 - src/native/monodroid/jni/monodroid-glue.cc | 10 +- src/native/monodroid/jni/osbridge.cc | 6 - src/native/monodroid/jni/runtime-util.cc | 20 + src/native/monodroid/jni/runtime-util.hh | 13 + src/native/monodroid/jni/timing.cc | 11 + src/native/monodroid/jni/util.cc | 188 -------- src/native/monodroid/jni/util.hh | 110 ----- src/native/runtime-base/CMakeLists.txt | 60 +++ .../jni => runtime-base}/android-system.cc | 209 ++++++--- src/native/runtime-base/android-system.hh | 233 ++++++++++ .../jni => runtime-base}/cpu-arch-detect.cc | 0 .../jni => runtime-base}/cpu-arch.hh | 2 - .../jni => runtime-base}/jni-wrappers.hh | 0 .../{monodroid/jni => runtime-base}/logger.cc | 26 +- .../{monodroid/jni => runtime-base}/logger.hh | 0 .../jni => runtime-base}/shared-constants.cc | 0 .../jni => runtime-base}/shared-constants.hh | 15 + .../jni => runtime-base}/strings.hh | 0 .../util.cc} | 188 +++++++- src/native/runtime-base/util.hh | 405 ++++++++++++++++++ src/native/shared/CMakeLists.txt | 5 + .../{monodroid/jni => shared}/cpp-util.hh | 0 .../{monodroid/jni => shared}/xxhash.hh | 0 src/native/xamarin-app-stub/CMakeLists.txt | 47 ++ .../application_dso_stub.cc | 0 .../jni => xamarin-app-stub}/xamarin-app.hh | 2 +- 34 files changed, 1166 insertions(+), 1179 deletions(-) delete mode 100644 src/native/monodroid/jni/android-system.hh delete mode 100644 src/native/monodroid/jni/basic-android-system.cc delete mode 100644 src/native/monodroid/jni/basic-android-system.hh delete mode 100644 src/native/monodroid/jni/basic-utilities.hh create mode 100644 src/native/monodroid/jni/runtime-util.cc create mode 100644 src/native/monodroid/jni/runtime-util.hh create mode 100644 src/native/monodroid/jni/timing.cc delete mode 100644 src/native/monodroid/jni/util.cc delete mode 100644 src/native/monodroid/jni/util.hh create mode 100644 src/native/runtime-base/CMakeLists.txt rename src/native/{monodroid/jni => runtime-base}/android-system.cc (70%) create mode 100644 src/native/runtime-base/android-system.hh rename src/native/{monodroid/jni => runtime-base}/cpu-arch-detect.cc (100%) rename src/native/{monodroid/jni => runtime-base}/cpu-arch.hh (95%) rename src/native/{monodroid/jni => runtime-base}/jni-wrappers.hh (100%) rename src/native/{monodroid/jni => runtime-base}/logger.cc (92%) rename src/native/{monodroid/jni => runtime-base}/logger.hh (100%) rename src/native/{monodroid/jni => runtime-base}/shared-constants.cc (100%) rename src/native/{monodroid/jni => runtime-base}/shared-constants.hh (81%) rename src/native/{monodroid/jni => runtime-base}/strings.hh (100%) rename src/native/{monodroid/jni/basic-utilities.cc => runtime-base/util.cc} (50%) create mode 100644 src/native/runtime-base/util.hh rename src/native/{monodroid/jni => shared}/cpp-util.hh (100%) rename src/native/{monodroid/jni => shared}/xxhash.hh (100%) create mode 100644 src/native/xamarin-app-stub/CMakeLists.txt rename src/native/{monodroid/jni => xamarin-app-stub}/application_dso_stub.cc (100%) rename src/native/{monodroid/jni => xamarin-app-stub}/xamarin-app.hh (99%) diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 9d465d16ba6..7a35a5133f8 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -413,5 +413,7 @@ add_link_options("$<$:${COMMON_CXX_LINKER_ARGS}>") add_link_options("$<$:${COMMON_C_LINKER_ARGS}>") add_subdirectory(libstub) -add_subdirectory(shared) add_subdirectory(libunwind) +add_subdirectory(shared) +add_subdirectory(xamarin-app-stub) +add_subdirectory(runtime-base) diff --git a/src/native/libunwind/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt index 11ffeda2095..cfdb3408d9c 100644 --- a/src/native/libunwind/CMakeLists.txt +++ b/src/native/libunwind/CMakeLists.txt @@ -50,7 +50,12 @@ endif() list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS -fno-asynchronous-unwind-tables -fno-unwind-tables + + # Turn off some warnings, as we can't do much about them here... + -Wno-absolute-value + -Wno-incompatible-pointer-types -Wno-macro-redefined + -Wno-single-bit-bitfield-constant-conversion ) xa_check_c_args(LIBUNWIND_C_ARGS "${POTENTIAL_LOCAL_COMPILER_ARGS}") diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index a82cddea564..1f312c8bf7e 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -22,12 +22,6 @@ option(ENABLE_TIMING "Build with timing support" OFF) # Environment checks -if(NOT DEFINED MONO_PATH) - message(FATAL_ERROR "Please set the MONO_PATH variable on command line (-DMONO_PATH=PATH)") -else() - string(REPLACE "\\" "/" MONO_PATH ${MONO_PATH}) -endif() - if(NOT DEFINED CONFIGURATION) message(FATAL_ERROR "Please set the CONFIGURATION variable on command line (-DCONFIGURATION=name)") endif() @@ -63,10 +57,7 @@ set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/jni) set(BIONIC_SOURCES_DIR "${REPO_ROOT_DIR}/src-ThirdParty/bionic") set(LZ4_SRC_DIR "${EXTERNAL_DIR}/lz4/lib") set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR}) -set(XA_BIN_DIR "${REPO_ROOT_DIR}/bin/${XA_BUILD_CONFIGURATION}") set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map") -set(XXHASH_DIR "${EXTERNAL_DIR}/xxHash") -set(CONSTEXPR_XXH3_DIR "${EXTERNAL_DIR}/constexpr-xxh3") set(LZ4_SOURCES "${LZ4_SRC_DIR}/lz4.c" @@ -81,21 +72,8 @@ include_directories(${EXTERNAL_DIR}) include_directories(SYSTEM ${CONSTEXPR_XXH3_DIR}) include_directories(SYSTEM ${ROBIN_MAP_DIR}/include) include_directories(SYSTEM ${LZ4_INCLUDE_DIR}) - include_directories("jni") -include_directories("${XA_BIN_DIR}/include") -include_directories("${XA_BIN_DIR}/include/${ANDROID_ABI}/eglib") - -# This is to allow "release" builds with Debug build type and vice versa -include_directories("../../bin/${CONFIGURATION}/include") -include_directories("../../bin/${CONFIGURATION}/include/${ANDROID_ABI}/eglib") -include_directories("${MONO_PATH}/mono/eglib") - -# Common preparation code -include("../../build-tools/cmake/xa_macros.cmake") -xa_common_prepare() -xa_macos_prepare_arm64() # Compiler defines @@ -285,9 +263,6 @@ set(XAMARIN_MONODROID_SOURCES ${JAVA_INTEROP_SRC_PATH}/java-interop.cc ${LZ4_SOURCES} ${XA_SHARED_SOURCES} - ${SOURCES_DIR}/android-system.cc - ${SOURCES_DIR}/basic-android-system.cc - ${SOURCES_DIR}/basic-utilities.cc ${SOURCES_DIR}/cpu-arch-detect.cc ${SOURCES_DIR}/debug-constants.cc ${SOURCES_DIR}/debug.cc @@ -303,10 +278,10 @@ set(XAMARIN_MONODROID_SOURCES ${SOURCES_DIR}/monovm-properties.cc ${SOURCES_DIR}/osbridge.cc ${SOURCES_DIR}/pinvoke-override-api.cc + ${SOURCES_DIR}/runtime-util.cc ${SOURCES_DIR}/shared-constants.cc ${SOURCES_DIR}/timezones.cc ${SOURCES_DIR}/timing-internal.cc - ${SOURCES_DIR}/util.cc ${SOURCES_DIR}/xamarin_getifaddrs.cc ) @@ -476,43 +451,5 @@ target_link_options( target_link_libraries( ${XAMARIN_MONO_ANDROID_LIB} - ${LINK_LIBS} xamarin-app - ) - -if(NOT ANALYZERS_ENABLED) - macro(xa_add_stub_library _libname) - add_library( - ${_libname} - SHARED ${XAMARIN_STUB_LIB_SOURCES} - ) - - string(TOUPPER ${_libname} _libname_uc) - target_compile_definitions( - ${_libname} - PRIVATE STUB_LIB_NAME=lib${_libname} IN_LIB${_libname_uc} - ) - - target_compile_options( - ${_libname} - PRIVATE -nostdlib -fno-exceptions -fno-rtti - ) - - target_link_options( - ${_libname} - PRIVATE -nostdlib -fno-exceptions -fno-rtti - ) - - set_target_properties( - ${_libname} - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${XA_LIBRARY_STUBS_OUTPUT_DIRECTORY}" - ) - endmacro() - - xa_add_stub_library(c) - xa_add_stub_library(m) - - # These two are used by the marshal methods tracing library when linking libxamarin-app.so - xa_add_stub_library(log) - xa_add_stub_library(dl) -endif() + ${LINK_LIBS} xa::xamarin-app +) diff --git a/src/native/monodroid/jni/android-system.hh b/src/native/monodroid/jni/android-system.hh deleted file mode 100644 index 1b62b8c74ab..00000000000 --- a/src/native/monodroid/jni/android-system.hh +++ /dev/null @@ -1,139 +0,0 @@ -// Dear Emacs, this is a -*- C++ -*- header -#ifndef __ANDROID_SYSTEM_H -#define __ANDROID_SYSTEM_H - -#include -#include - -#include -#include - -#include -#include - -#include "xamarin-app.hh" -#include "basic-android-system.hh" -#include "strings.hh" - -#include - -static inline constexpr size_t PROPERTY_VALUE_BUFFER_LEN = PROP_VALUE_MAX + 1; - -namespace xamarin::android { - class jstring_wrapper; - class jstring_array_wrapper; -} - -namespace xamarin::android::internal -{ -#if defined (DEBUG) - struct BundledProperty; -#endif - - class AndroidSystem : public BasicAndroidSystem - { - private: -#if defined (DEBUG) - static constexpr std::string_view OVERRIDE_ENVIRONMENT_FILE_NAME { "environment" }; - static constexpr uint32_t OVERRIDE_ENVIRONMENT_FILE_HEADER_SIZE = 22; - static BundledProperty *bundled_properties; -#endif - - public: - void setup_environment (); - void setup_process_args (jstring_array_wrapper &runtimeApks); - void create_update_dir (char *override_dir); - int monodroid_get_system_property (const char *name, char **value); - int monodroid_get_system_property (const char *name, dynamic_local_string& value); - - int monodroid_get_system_property (std::string_view const& name, char **value) noexcept - { - return monodroid_get_system_property (name.data (), value); - } - - int monodroid_get_system_property (std::string_view const& name, dynamic_local_string& value) noexcept - { - return monodroid_get_system_property (name.data (), value); - } - - size_t monodroid_get_system_property_from_overrides (const char *name, char ** value); - char* get_bundled_app (JNIEnv *env, jstring dir); - int count_override_assemblies (); - long get_gref_gc_threshold (); - void* load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check); - void* load_dso_from_any_directories (const char *name, unsigned int dl_flags); - bool get_full_dso_path_on_disk (const char *dso_name, dynamic_local_string& path); - - long get_max_gref_count () const - { - return max_gref_count; - } - - void init_max_gref_count () - { - max_gref_count = get_max_gref_count_from_system (); - } - - bool is_assembly_preload_enabled () const - { - return application_config.uses_assembly_preload; - } - - bool is_mono_llvm_enabled () const - { - return application_config.uses_mono_llvm; - } - - bool is_mono_aot_enabled () const - { - return application_config.uses_mono_aot; - } - - MonoAotMode get_mono_aot_mode () const - { - return aotMode; - } - - bool is_interpreter_enabled () const - { - return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; - } - - // Hack, see comment for `aot_mode_last_is_interpreter` at the bottom of the class declaration - bool is_aot_mode_last_really_interpreter_mode () const - { - return false; - } - - void set_running_in_emulator (bool yesno) - { - running_in_emulator = yesno; - } - - private: -#if defined (DEBUG) - void add_system_property (const char *name, const char *value); - void setup_environment (const char *name, const char *value); - void setup_environment_from_override_file (const char *path); - BundledProperty* lookup_system_property (const char *name); -#endif - const char* lookup_system_property (const char *name, size_t &value_len); - long get_max_gref_count_from_system (); - void setup_process_args_apk (const char *apk, size_t index, size_t apk_count, void *user_data); - int _monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len); -#if defined (DEBUG) - size_t _monodroid_get_system_property_from_file (const char *path, char **value); -#endif - bool get_full_dso_path (const char *base_dir, const char *dso_path, dynamic_local_string& path); - void* load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags); - void* load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags); - void* load_dso_from_override_dirs (const char *name, unsigned int dl_flags); - bool get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, dynamic_local_string& path); - - private: - long max_gref_count = 0; - MonoAotMode aotMode = MonoAotMode::MONO_AOT_MODE_NONE; - bool running_in_emulator = false; - }; -} -#endif // !__ANDROID_SYSTEM_H diff --git a/src/native/monodroid/jni/basic-android-system.cc b/src/native/monodroid/jni/basic-android-system.cc deleted file mode 100644 index e9dbbac2d0e..00000000000 --- a/src/native/monodroid/jni/basic-android-system.cc +++ /dev/null @@ -1,109 +0,0 @@ -#include "basic-android-system.hh" -#include "cpp-util.hh" -#include "globals.hh" - -using namespace xamarin::android; -using namespace xamarin::android::internal; - -void -BasicAndroidSystem::detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept -{ - // appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX] points to the native library directory - std::unique_ptr libmonodroid_path {utils.path_combine (appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr (), "libmonodroid.so")}; - log_debug (LOG_ASSEMBLY, "Checking if libmonodroid was unpacked to %s", libmonodroid_path.get ()); - if (!utils.file_exists (libmonodroid_path.get ())) { - log_debug (LOG_ASSEMBLY, "%s not found, assuming application/android:extractNativeLibs == false", libmonodroid_path.get ()); - set_embedded_dso_mode_enabled (true); - } else { - log_debug (LOG_ASSEMBLY, "Native libs extracted to %s, assuming application/android:extractNativeLibs == true", appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); - set_embedded_dso_mode_enabled (false); - } -} - -void -BasicAndroidSystem::setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks) -{ - if (!is_embedded_dso_mode_enabled ()) { - log_debug (LOG_DEFAULT, "Setting up for DSO lookup in app data directories"); - - BasicAndroidSystem::app_lib_directories = std::span (single_app_lib_directory); - BasicAndroidSystem::app_lib_directories [0] = utils.strdup_new (appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); - log_debug (LOG_ASSEMBLY, "Added filesystem DSO lookup location: %s", appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); - } else { - log_debug (LOG_DEFAULT, "Setting up for DSO lookup directly in the APK"); - - if (have_split_apks) { - // If split apks are used, then we will have just a single app library directory. Don't allocate any memory - // dynamically in this case - BasicAndroidSystem::app_lib_directories = std::span (single_app_lib_directory); - } else { - size_t app_lib_directories_size = have_split_apks ? 1 : runtimeApks.get_length (); - BasicAndroidSystem::app_lib_directories = std::span (new const char*[app_lib_directories_size], app_lib_directories_size); - } - - unsigned short built_for_cpu = 0, running_on_cpu = 0; - unsigned char is64bit = 0; - _monodroid_detect_cpu_and_architecture (&built_for_cpu, &running_on_cpu, &is64bit); - setup_apk_directories (running_on_cpu, runtimeApks, have_split_apks); - } -} - -void -BasicAndroidSystem::for_each_apk (jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data) -{ - size_t apksLength = runtimeApks.get_length (); - for (size_t i = 0; i < apksLength; ++i) { - jstring_wrapper &e = runtimeApks [i]; - - (this->*handler) (e.get_cstr (), i, apksLength, user_data); - } -} - -force_inline void -BasicAndroidSystem::add_apk_libdir (const char *apk, size_t &index, const char *abi) noexcept -{ - abort_unless (index < app_lib_directories.size (), "Index out of range"); - app_lib_directories [index] = utils.string_concat (apk, "!/lib/", abi); - log_debug (LOG_ASSEMBLY, "Added APK DSO lookup location: %s", app_lib_directories[index]); - index++; -} - -force_inline void -BasicAndroidSystem::setup_apk_directories (unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks, bool have_split_apks) noexcept -{ - const char *abi = android_abi_names [running_on_cpu]; - size_t number_of_added_directories = 0; - - for (size_t i = 0; i < runtimeApks.get_length (); ++i) { - jstring_wrapper &e = runtimeApks [i]; - const char *apk = e.get_cstr (); - - if (have_split_apks) { - if (utils.ends_with (apk, SharedConstants::split_config_abi_apk_name)) { - add_apk_libdir (apk, number_of_added_directories, abi); - break; - } - } else { - add_apk_libdir (apk, number_of_added_directories, abi); - } - } - - if (app_lib_directories.size () == number_of_added_directories) [[likely]] { - return; - } - - abort_unless (number_of_added_directories > 0, "At least a single application lib directory must be added"); - app_lib_directories = app_lib_directories.subspan (0, number_of_added_directories); -} - -char* -BasicAndroidSystem::determine_primary_override_dir (jstring_wrapper &home) -{ - dynamic_local_string name { home.get_cstr () }; - name.append ("/") - .append (SharedConstants::OVERRIDE_DIRECTORY_NAME) - .append ("/") - .append (SharedConstants::android_lib_abi); - - return utils.strdup_new (name.get ()); -} diff --git a/src/native/monodroid/jni/basic-android-system.hh b/src/native/monodroid/jni/basic-android-system.hh deleted file mode 100644 index 9b6f1bc851f..00000000000 --- a/src/native/monodroid/jni/basic-android-system.hh +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef __BASIC_ANDROID_SYSTEM_HH -#define __BASIC_ANDROID_SYSTEM_HH - -#include -#include -#include -#include -#include - -#include "cpu-arch.hh" -#include "jni-wrappers.hh" - -namespace xamarin::android::internal -{ - class BasicAndroidSystem - { - protected: - using ForEachApkHandler = void (BasicAndroidSystem::*) (const char *apk, size_t index, size_t apk_count, void *user_data); - - private: -#if defined (__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc99-designator" -#endif - // Values correspond to the CPU_KIND_* macros - static constexpr const char* android_abi_names[CPU_KIND_X86_64+1] = { - [0] = "unknown", - [CPU_KIND_ARM] = "armeabi-v7a", - [CPU_KIND_ARM64] = "arm64-v8a", - [CPU_KIND_MIPS] = "mips", - [CPU_KIND_X86] = "x86", - [CPU_KIND_X86_64] = "x86_64", - }; -#if defined (__clang__) -#pragma clang diagnostic pop -#endif - static constexpr size_t ANDROID_ABI_NAMES_SIZE = sizeof(android_abi_names) / sizeof (android_abi_names[0]); - - public: -#ifdef ANDROID64 - static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib64" }; -#else - static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib" }; -#endif - - inline static std::array override_dirs{}; - - // This optimizes things a little bit. The array is allocated at build time, so we pay no cost for its - // allocation and at run time it allows us to skip dynamic memory allocation. - inline static std::array single_app_lib_directory{}; - inline static std::span app_lib_directories; - - public: - void setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks); - - void set_override_dir (uint32_t index, const char* dir) - { - if (index >= override_dirs.size ()) - return; - - override_dirs [index] = const_cast (dir); - } - - bool is_embedded_dso_mode_enabled () const - { - return embedded_dso_mode_enabled; - } - - void detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept; - - char *get_runtime_libdir () const - { - return runtime_libdir; - } - - void set_runtime_libdir (char *dir) - { - runtime_libdir = dir; - } - - char *get_primary_override_dir () const - { - return primary_override_dir; - } - - void set_primary_override_dir (jstring_wrapper& home) - { - primary_override_dir = determine_primary_override_dir (home); - } - - protected: - void for_each_apk (jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data); - - private: - void add_apk_libdir (const char *apk, size_t &index, const char *abi) noexcept; - void setup_apk_directories (unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks, bool have_split_apks) noexcept; - char* determine_primary_override_dir (jstring_wrapper &home); - - void set_embedded_dso_mode_enabled (bool yesno) noexcept - { - embedded_dso_mode_enabled = yesno; - } - - private: - bool embedded_dso_mode_enabled = false; - char *runtime_libdir = nullptr; - char *primary_override_dir = nullptr; - }; -} -#endif // !__BASIC_ANDROID_SYSTEM_HH diff --git a/src/native/monodroid/jni/basic-utilities.hh b/src/native/monodroid/jni/basic-utilities.hh deleted file mode 100644 index 51a42741ed0..00000000000 --- a/src/native/monodroid/jni/basic-utilities.hh +++ /dev/null @@ -1,343 +0,0 @@ -#ifndef __BASIC_UTILITIES_HH -#define __BASIC_UTILITIES_HH - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "java-interop-util.h" -#include "helpers.hh" -#include "cpp-util.hh" -#include "strings.hh" - -namespace xamarin::android -{ - class BasicUtilities - { - public: - FILE *monodroid_fopen (const char* filename, const char* mode); - int monodroid_dirent_hasextension (dirent *e, const char *extension); - void monodroid_strfreev (char **str_array); - char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); - char *monodroid_strdup_printf (const char *format, ...); - char *monodroid_strdup_vprintf (const char *format, va_list vargs); - char* path_combine (const char *path1, const char *path2); - void create_public_directory (const char *dir); - int create_directory (const char *pathname, mode_t mode); - void set_world_accessable (const char *path); - void set_user_executable (const char *path); - bool file_exists (const char *file); - bool directory_exists (const char *directory); - bool file_copy (const char *to, const char *from); - - static std::optional get_file_size_at (int dirfd, const char *file_name) noexcept - { - struct stat sbuf; - if (fstatat (dirfd, file_name, &sbuf, 0) == -1) { - log_warn (LOG_ASSEMBLY, "Failed to stat file '%s': %s", file_name, std::strerror (errno)); - return {}; - } - - return static_cast(sbuf.st_size); - } - - static std::optional open_file_ro_at (int dirfd, const char *file_name) noexcept - { - int fd = openat (dirfd, file_name, O_RDONLY); - if (fd < 0) { - log_error (LOG_ASSEMBLY, "Failed to open file '%s' for reading: %s", file_name, std::strerror (errno)); - return {}; - } - - return fd; - } - - // Make sure that `buf` has enough space! This is by design, the methods are supposed to be fast. - template - void path_combine (TBuffer& buf, const char* path1, const char* path2) noexcept - { - path_combine (buf, path1, path1 == nullptr ? 0 : strlen (path1), path2, path2 == nullptr ? 0 : strlen (path2)); - } - - // internal::static_local_string - template - void path_combine (TBuffer& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept - { - abort_unless (path1 != nullptr || path2 != nullptr, "At least one path must be a valid pointer"); - - if (path1 == nullptr) { - buf.append_c (path2); - return; - } - - if (path2 == nullptr) { - buf.append_c (path1); - return; - } - - buf.append (path1, path1_len); - buf.append ("/"); - buf.append (path2, path2_len); - } - - template - void path_combine (internal::static_local_string& buf, const char* path1, const char* path2) noexcept - { - path_combine (buf, path1, path2); - } - - template - void path_combine (internal::static_local_string& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept - { - path_combine (buf, path1, path1_len, path2, path2_len); - } - - template - void path_combine (internal::dynamic_local_string& buf, const char* path1, const char* path2) noexcept - { - path_combine (buf, path1, path2); - } - - template - void path_combine (internal::dynamic_local_string& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept - { - path_combine (buf, path1, path1_len, path2, path2_len); - } - - char* path_combine (const char *path1, std::string_view const& path2) noexcept - { - return path_combine (path1, path2.data ()); - } - - bool ends_with_slow (const char *str, const char *end) - { - char *p = const_cast (strstr (str, end)); - return p != nullptr && p [strlen (end)] == '\0'; - } - - template - bool ends_with (internal::dynamic_local_string const& str, std::string_view const& sv) const noexcept - { - if (str.length () < sv.length ()) { - return false; - } - - return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; - } - - template - bool ends_with (internal::dynamic_local_string& str, std::string_view const& sv) const noexcept - { - return ends_with(static_cast const&>(str), sv); - } - - bool ends_with (const char *str, std::string_view const& sv) const noexcept - { - size_t len = strlen (str); - if (len < sv.length ()) { - return false; - } - - return memcmp (str + len - sv.length (), sv.data (), sv.length ()) == 0; - } - - template - bool ends_with (const char *str, const char (&end)[N]) - { - char *p = const_cast (strstr (str, end)); - return p != nullptr && p [N - 1] == '\0'; - } - - template - bool ends_with (const char *str, std::array const& end) const noexcept - { - char *p = const_cast (strstr (str, end.data ())); - return p != nullptr && p [N - 1] == '\0'; - } - - template - bool ends_with (const char *str, helper_char_array const& end) const noexcept - { - char *p = const_cast (strstr (str, end.data ())); - return p != nullptr && p [N - 1] == '\0'; - } - - template - bool ends_with (internal::string_base const& str, const char (&end)[N]) const noexcept - { - constexpr size_t end_length = N - 1; - - size_t len = str.length (); - if (len < end_length) [[unlikely]] { - return false; - } - - return memcmp (str.get () + len - end_length, end, end_length) == 0; - } - - template - bool ends_with (internal::string_base const& str, std::array const& end) const noexcept - { - constexpr size_t end_length = N - 1; - - size_t len = str.length (); - if (len < end_length) [[unlikely]] { - return false; - } - - return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; - } - - template - bool ends_with (internal::string_base const& str, helper_char_array const& end) const noexcept - { - constexpr size_t end_length = N - 1; - - size_t len = str.length (); - if (len < end_length) [[unlikely]] { - return false; - } - - return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; - } - - template - const TChar* find_last (internal::string_base const& str, const char ch) const noexcept - { - if (str.empty ()) { - return nullptr; - } - - for (size_t i = str.length (); i > 0; i--) { - const size_t index = i - 1; - if (str[index] == ch) { - return str.get () + index; - } - } - - return nullptr; - } - - void *xmalloc (size_t size) - { - return ::xmalloc (size); - } - - void *xrealloc (void *ptr, size_t size) - { - return ::xrealloc (ptr, size); - } - - void *xcalloc (size_t nmemb, size_t size) - { - return ::xcalloc (nmemb, size); - } - - char *strdup_new (const char* s, size_t len) - { - if (len == 0 || s == nullptr) [[unlikely]] { - return nullptr; - } - - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, len, 1); - auto ret = new char[alloc_size]; - memcpy (ret, s, len); - ret[len] = '\0'; - - return ret; - } - - char *strdup_new (const char* s) - { - if (s == nullptr) [[unlikely]] { - return nullptr; - } - - return strdup_new (s, strlen (s)); - } - - template - char *strdup_new (internal::dynamic_local_string const& buf) noexcept - { - return strdup_new (buf.get (), buf.length ()); - } - - char *strdup_new (xamarin::android::internal::string_segment const& s, size_t from_index = 0) noexcept - { - if (from_index >= s.length ()) { - return nullptr; - } - - return strdup_new (s.start () + from_index, s.length () - from_index); - } - - template - char* string_concat (const char *s1, const CharType* s2, Strings... strings) - { - assert_char_type (); - - size_t len = calculate_length (s1, s2, strings...); - - char *ret = new char [len + 1]; - *ret = '\0'; - - concatenate_strings_into (len, ret, s1, s2, strings...); - - return ret; - } - - bool is_path_rooted (const char *path); - - template - size_t calculate_length (const CharType* s) - { - return strlen (s); - } - - template - size_t calculate_length (const CharType* s1, Strings... strings) - { - assert_char_type (); - - return strlen (s1) + calculate_length (strings...); - } - - protected: - template - void concatenate_strings_into ([[maybe_unused]] size_t len, [[maybe_unused]] char *dest) - {} - - template - void concatenate_strings_into (size_t len, char *dest, const CharType* s1, Strings... strings) - { - assert_char_type (); - - strcat (dest, s1); - concatenate_strings_into (len, dest, strings...); - } - - int make_directory (const char *path, [[maybe_unused]] mode_t mode) - { - return ::mkdir (path, mode); - } - - private: - template - static constexpr void assert_char_type () - { - static_assert (std::is_same_v, "CharType must be an 8-bit character type"); - } - }; -} -#endif // !__BASIC_UTILITIES_HH diff --git a/src/native/monodroid/jni/debug.hh b/src/native/monodroid/jni/debug.hh index 9eafaa05624..4eef337b3f0 100644 --- a/src/native/monodroid/jni/debug.hh +++ b/src/native/monodroid/jni/debug.hh @@ -29,22 +29,6 @@ namespace xamarin::android private: static inline constexpr std::string_view INITIALIZER_NAME { "mono_profiler_init" }; - public: - /* Android property containing connection information, set by XS */ - static inline constexpr std::string_view DEBUG_MONO_CONNECT_PROPERTY { "debug.mono.connect" }; - static inline constexpr std::string_view DEBUG_MONO_DEBUG_PROPERTY { "debug.mono.debug" }; - static inline constexpr std::string_view DEBUG_MONO_ENV_PROPERTY { "debug.mono.env" }; - static inline constexpr std::string_view DEBUG_MONO_EXTRA_PROPERTY { "debug.mono.extra" }; - static inline constexpr std::string_view DEBUG_MONO_GC_PROPERTY { "debug.mono.gc" }; - static inline constexpr std::string_view DEBUG_MONO_GDB_PROPERTY { "debug.mono.gdb" }; - static inline constexpr std::string_view DEBUG_MONO_LOG_PROPERTY { "debug.mono.log" }; - static inline constexpr std::string_view DEBUG_MONO_MAX_GREFC { "debug.mono.max_grefc" }; - static inline constexpr std::string_view DEBUG_MONO_PROFILE_PROPERTY { "debug.mono.profile" }; - static inline constexpr std::string_view DEBUG_MONO_RUNTIME_ARGS_PROPERTY { "debug.mono.runtime_args" }; - static inline constexpr std::string_view DEBUG_MONO_SOFT_BREAKPOINTS { "debug.mono.soft_breakpoints" }; - static inline constexpr std::string_view DEBUG_MONO_TRACE_PROPERTY { "debug.mono.trace" }; - static inline constexpr std::string_view DEBUG_MONO_WREF_PROPERTY { "debug.mono.wref" }; - public: explicit Debug () {} diff --git a/src/native/monodroid/jni/monodroid-glue.cc b/src/native/monodroid/jni/monodroid-glue.cc index 1de65c5c46d..53fbdc7b721 100644 --- a/src/native/monodroid/jni/monodroid-glue.cc +++ b/src/native/monodroid/jni/monodroid-glue.cc @@ -64,6 +64,7 @@ #include "startup-aware-lock.hh" #include "timing-internal.hh" #include "search.hh" +#include "runtime-util.hh" //#include "xamarin_getifaddrs.h" @@ -794,7 +795,7 @@ MonodroidRuntime::LocalRefsAreIndirect (JNIEnv *env, jclass runtimeClass, int ve return 0; } - java_System = utils.get_class_from_runtime_field(env, runtimeClass, "java_lang_System", true); + java_System = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "java_lang_System", true); java_System_identityHashCode = env->GetStaticMethodID (java_System, "identityHashCode", "(Ljava/lang/Object;)I"); return 1; @@ -878,7 +879,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec log_info (LOG_GC, "GREF GC Threshold: %i", init.grefGcThreshold); - init.grefClass = utils.get_class_from_runtime_field (env, runtimeClass, "java_lang_Class", true); + init.grefClass = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "java_lang_Class", true); Class_getName = env->GetMethodID (init.grefClass, "getName", "()Ljava/lang/String;"); init.Class_forName = env->GetStaticMethodID (init.grefClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); @@ -941,7 +942,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec env->DeleteLocalRef (lrefLoaderClass); init.grefLoader = env->NewGlobalRef (loader); - init.grefIGCUserPeer = utils.get_class_from_runtime_field (env, runtimeClass, "mono_android_IGCUserPeer", true); + init.grefIGCUserPeer = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "mono_android_IGCUserPeer", true); osBridge.initialize_on_runtime_init (env, runtimeClass); @@ -1607,7 +1608,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl androidSystem.detect_embedded_dso_mode (applicationDirs); androidSystem.set_running_in_emulator (isEmulator); - java_TimeZone = utils.get_class_from_runtime_field (env, klass, "java_util_TimeZone", true); + java_TimeZone = RuntimeUtil::get_class_from_runtime_field (env, klass, "java_util_TimeZone", true); utils.monodroid_store_package_name (application_config.android_package_name); @@ -1738,6 +1739,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM *vm, void *reserved) { + Util::initialize (); return monodroidRuntime.Java_JNI_OnLoad (vm, reserved); } diff --git a/src/native/monodroid/jni/osbridge.cc b/src/native/monodroid/jni/osbridge.cc index dc8d50db6d3..50e3d560b92 100644 --- a/src/native/monodroid/jni/osbridge.cc +++ b/src/native/monodroid/jni/osbridge.cc @@ -18,12 +18,6 @@ #include "globals.hh" #include "osbridge.hh" -// These two must stay here until JavaInterop is converted to C++ -FILE *gref_log; -FILE *lref_log; -bool gref_to_logcat; -bool lref_to_logcat; - using namespace xamarin::android; using namespace xamarin::android::internal; diff --git a/src/native/monodroid/jni/runtime-util.cc b/src/native/monodroid/jni/runtime-util.cc new file mode 100644 index 00000000000..0fc8edc4482 --- /dev/null +++ b/src/native/monodroid/jni/runtime-util.cc @@ -0,0 +1,20 @@ +#include "globals.hh" +#include "runtime-util.hh" + +using namespace xamarin::android::internal; + +jclass +RuntimeUtil::get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref) +{ + static constexpr char java_lang_class_sig[] = "Ljava/lang/Class;"; + + jfieldID fieldID = env->GetStaticFieldID (runtime, name, java_lang_class_sig); + if (fieldID == nullptr) + return nullptr; + + jobject field = env->GetStaticObjectField (runtime, fieldID); + if (field == nullptr) + return nullptr; + + return reinterpret_cast (make_gref ? osBridge.lref_to_gref (env, field) : field); +} diff --git a/src/native/monodroid/jni/runtime-util.hh b/src/native/monodroid/jni/runtime-util.hh new file mode 100644 index 00000000000..8e6a39b4195 --- /dev/null +++ b/src/native/monodroid/jni/runtime-util.hh @@ -0,0 +1,13 @@ +#if !defined(RUNTIME_UTIL_HH) +#define RUNTIME_UTIL_HH + +#include + +namespace xamarin::android::internal { + class RuntimeUtil + { + public: + static jclass get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref); + }; +} +#endif // ndef RUNTIME_UTIL_HH diff --git a/src/native/monodroid/jni/timing.cc b/src/native/monodroid/jni/timing.cc new file mode 100644 index 00000000000..ec48972850b --- /dev/null +++ b/src/native/monodroid/jni/timing.cc @@ -0,0 +1,11 @@ +#include "timing-internal.hh" + +void timing_point::mark () +{ + FastTiming::get_time (sec, ns); +} + +timing_diff::timing_diff (const timing_period &period) +{ + FastTiming::calculate_interval (period.start, period.end, *this); +} diff --git a/src/native/monodroid/jni/util.cc b/src/native/monodroid/jni/util.cc deleted file mode 100644 index b7bcdd805b5..00000000000 --- a/src/native/monodroid/jni/util.cc +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef HAVE_BSD_STRING_H -#include -#endif - -#include -#include -#include - -#include "util.hh" -#include "globals.hh" -#include "timing-internal.hh" - -using namespace xamarin::android; -using namespace xamarin::android::internal; - -void timing_point::mark () -{ - FastTiming::get_time (sec, ns); -} - -timing_diff::timing_diff (const timing_period &period) -{ - FastTiming::calculate_interval (period.start, period.end, *this); -} - -Util::Util () -{ - page_size = getpagesize (); -} - -int -Util::send_uninterrupted (int fd, void *buf, size_t len) -{ - ssize_t res; - - do { - res = send (fd, buf, len, 0); - } while (res == -1 && errno == EINTR); - - return static_cast(res) == len; -} - -ssize_t -Util::recv_uninterrupted (int fd, void *buf, size_t len) -{ - using nbytes_type = size_t; - - ssize_t res; - size_t total = 0; - int flags = 0; - nbytes_type nbytes; - - do { - nbytes = static_cast(len - total); - res = recv (fd, (char *) buf + total, nbytes, flags); - - if (res > 0) - total += static_cast(res); - } while ((res > 0 && total < len) || (res == -1 && errno == EINTR)); - - return static_cast(total); -} - -template -inline void -Util::package_hash_to_hex (IdxType /* idx */) -{ - package_property_suffix[sizeof (package_property_suffix) / sizeof (char) - 1] = 0x00; -} - -template -inline void -Util::package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices) -{ - package_property_suffix [idx] = hex_chars [(hash & (0xF0000000 >> idx * 4)) >> ((7 - idx) * 4)]; - package_hash_to_hex (hash, indices...); -} - -void -Util::monodroid_store_package_name (const char *name) -{ - if (!name || *name == '\0') - return; - - /* Android properties can be at most 32 bytes long (!) and so we mustn't append the package name - * as-is since it will most likely generate conflicts (packages tend to be named - * com.mycompany.app), so we simply generate a hash code and use that instead. We treat the name - * as a stream of bytes assumming it's an ASCII string using a simplified version of the hash - * algorithm used by BCL's String.GetHashCode () - */ - const char *ch = name; - uint32_t hash = 0; - while (*ch) - hash = (hash << 5) - (hash + static_cast(*ch++)); - - // In C++14 or newer we could use std::index_sequence, but in C++11 it's a bit too much ado - // for this simple case, so a manual sequence it is. - // - // And yes, I know it could be done in a simple loop or in even simpler 8 lines of code, but - // that would be boring, wouldn't it? :) - package_hash_to_hex (hash, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u); - log_debug (LOG_DEFAULT, "Generated hash 0x%s for package name %s", package_property_suffix, name); -} - -MonoAssembly* -Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename) -{ - MonoImageOpenStatus status; - MonoAssemblyName *aname = mono_assembly_name_new (basename); - MonoAssembly *assm = mono_assembly_load_full_alc (alc_handle, aname, nullptr, &status); - - mono_assembly_name_free (aname); - - if (assm == nullptr || status != MonoImageOpenStatus::MONO_IMAGE_OK) { - log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); - Helpers::abort_application (); - } - return assm; -} - -MonoAssembly * -Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) -{ - MonoAssembly *assm; - MonoAssemblyName *aname; - MonoImageOpenStatus status; - - aname = mono_assembly_name_new (basename); - MonoDomain *current = get_current_domain (); - - if (domain != current) { - mono_domain_set (domain, FALSE); - assm = mono_assembly_load_full (aname, nullptr, &status, 0); - mono_domain_set (current, FALSE); - } else { - assm = mono_assembly_load_full (aname, nullptr, &status, 0); - } - - mono_assembly_name_free (aname); - - if (!assm) { - log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); - Helpers::abort_application (); - } - return assm; -} - -MonoClass* -Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const char* assembly, const char *_namespace, const char *type) -{ - MonoClass *result; - MonoAssemblyName *aname = mono_assembly_name_new (assembly); - MonoAssembly *assm = mono_assembly_loaded (aname); - if (assm != nullptr) { - MonoImage *image = mono_assembly_get_image (assm); - result = mono_class_from_name (image, _namespace, type); - } else - result = nullptr; - - mono_assembly_name_free (aname); - return result; -} - -jclass -Util::get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref) -{ - static constexpr char java_lang_class_sig[] = "Ljava/lang/Class;"; - - jfieldID fieldID = env->GetStaticFieldID (runtime, name, java_lang_class_sig); - if (fieldID == nullptr) - return nullptr; - - jobject field = env->GetStaticObjectField (runtime, fieldID); - if (field == nullptr) - return nullptr; - - return reinterpret_cast (make_gref ? osBridge.lref_to_gref (env, field) : field); -} diff --git a/src/native/monodroid/jni/util.hh b/src/native/monodroid/jni/util.hh deleted file mode 100644 index d402a01484e..00000000000 --- a/src/native/monodroid/jni/util.hh +++ /dev/null @@ -1,110 +0,0 @@ -// This is a -*- C++ -*- header -#ifndef __MONODROID_UTIL_H__ -#define __MONODROID_UTIL_H__ - -#ifndef TRUE -#ifdef __cplusplus -static inline constexpr int TRUE = 1; -#else -#define TRUE 1 -#endif // __cplusplus -#endif - -#ifndef FALSE -#ifdef __cplusplus -static inline constexpr int FALSE = 0; -#else -#define FALSE 0 -#endif // __cplusplus -#endif - -#include -#include -#include -#include -#include -#ifdef HAVE_BSD_STRING_H -#include -#endif -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "monodroid.h" -#include "jni-wrappers.hh" -#ifdef __cplusplus -#include "basic-utilities.hh" -#endif - -#include "java-interop-util.h" -#include "logger.hh" - -#ifdef __cplusplus -namespace xamarin::android -{ - class Util : public BasicUtilities - { - static constexpr std::array hex_chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - static constexpr uint32_t ms_in_nsec = 1000000ULL; - - public: - Util (); - - int monodroid_getpagesize () const noexcept - { - return page_size; - } - - void monodroid_store_package_name (const char *name); - MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); - MonoAssembly *monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename); - MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); - int send_uninterrupted (int fd, void *buf, size_t len); - ssize_t recv_uninterrupted (int fd, void *buf, size_t len); - jclass get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref = false); - - static bool should_log (LogCategories category) noexcept - { - return (log_categories & category) != 0; - } - - MonoDomain *get_current_domain (bool attach_thread_if_needed = true) const noexcept - { - MonoDomain *ret = mono_domain_get (); - if (ret != nullptr) { - return ret; - } - - // It's likely that we got a nullptr because the current thread isn't attached (see - // https://github.com/xamarin/xamarin-android/issues/6211), so we need to attach the thread to the root - // domain - ret = mono_get_root_domain (); - if (attach_thread_if_needed) { - mono_thread_attach (ret); - } - - return ret; - } - - private: - template - void package_hash_to_hex (IdxType idx); - - template - void package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices); - - private: - char package_property_suffix[9]; - int page_size; - }; -} -#endif // __cplusplus -#endif /* __MONODROID_UTIL_H__ */ diff --git a/src/native/runtime-base/CMakeLists.txt b/src/native/runtime-base/CMakeLists.txt new file mode 100644 index 00000000000..a10a50da582 --- /dev/null +++ b/src/native/runtime-base/CMakeLists.txt @@ -0,0 +1,60 @@ +set(LIB_NAME runtime-base) +set(LIB_ALIAS xa::runtime-base) + +set(XA_RUNTIME_BASE_SOURCES + android-system.cc + cpu-arch-detect.cc + logger.cc + shared-constants.cc + util.cc +) + +list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS + -ffunction-sections + -fdata-sections +) + +xa_check_c_args(RUNTIME_BASE_CXX_ARGS "${POTENTIAL_LOCAL_COMPILER_ARGS}") + +add_library( + ${LIB_NAME} + STATIC + ${XA_RUNTIME_BASE_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} + ${RUNTIME_BASE_CXX_ARGS} +) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" +) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_link_libraries( + ${LIB_NAME} + PRIVATE + xa::shared + xa::xamarin-app +) + +set_target_properties( + ${LIB_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/monodroid/jni/android-system.cc b/src/native/runtime-base/android-system.cc similarity index 70% rename from src/native/monodroid/jni/android-system.cc rename to src/native/runtime-base/android-system.cc index fce00bae049..c6643b7e19f 100644 --- a/src/native/monodroid/jni/android-system.cc +++ b/src/native/runtime-base/android-system.cc @@ -3,13 +3,27 @@ #include #include -#include "globals.hh" +#include + #include "android-system.hh" -#include "jni-wrappers.hh" -#include "xamarin-app.hh" #include "cpp-util.hh" #include "java-interop-dlfcn.h" #include "java-interop.h" +#include "jni-wrappers.hh" +#include "shared-constants.hh" +#include "strings.hh" +#include "util.hh" +#include "xamarin-app.hh" + +using namespace microsoft::java_interop; +using namespace xamarin::android::internal; +using namespace xamarin::android; + +// These two must stay here until JavaInterop is converted to C++ +FILE *gref_log; +FILE *lref_log; +bool gref_to_logcat; +bool lref_to_logcat; #if defined (DEBUG) namespace xamarin::android::internal { @@ -20,17 +34,11 @@ namespace xamarin::android::internal { struct BundledProperty *next; }; } -#endif // DEBUG - -using namespace microsoft::java_interop; -using namespace xamarin::android; -using namespace xamarin::android::internal; -#if defined (DEBUG) BundledProperty *AndroidSystem::bundled_properties = nullptr; BundledProperty* -AndroidSystem::lookup_system_property (const char *name) +AndroidSystem::lookup_system_property (const char *name) noexcept { for (BundledProperty *p = bundled_properties; p != nullptr; p = p->next) { if (strcmp (p->name, name) == 0) { @@ -42,7 +50,7 @@ AndroidSystem::lookup_system_property (const char *name) #endif // DEBUG const char* -AndroidSystem::lookup_system_property (const char *name, size_t &value_len) +AndroidSystem::lookup_system_property (const char *name, size_t &value_len) noexcept { value_len = 0; #if defined (DEBUG) @@ -85,7 +93,7 @@ AndroidSystem::lookup_system_property (const char *name, size_t &value_len) #if defined (DEBUG) void -AndroidSystem::add_system_property (const char *name, const char *value) +AndroidSystem::add_system_property (const char *name, const char *value) noexcept { BundledProperty* p = lookup_system_property (name); if (p != nullptr) { @@ -122,7 +130,7 @@ AndroidSystem::add_system_property (const char *name, const char *value) #endif // DEBUG int -AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len) +AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len) noexcept { if (name == nullptr || sp_value == nullptr) return -1; @@ -145,7 +153,7 @@ AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value } int -AndroidSystem::monodroid_get_system_property (const char *name, dynamic_local_string& value) +AndroidSystem::monodroid_get_system_property (const char *name, dynamic_local_string& value) noexcept { int len = _monodroid__system_property_get (name, value.get (), value.size ()); if (len > 0) { @@ -164,7 +172,7 @@ AndroidSystem::monodroid_get_system_property (const char *name, dynamic_local_st } int -AndroidSystem::monodroid_get_system_property (const char *name, char **value) +AndroidSystem::monodroid_get_system_property (const char *name, char **value) noexcept { if (value) *value = nullptr; @@ -196,12 +204,12 @@ AndroidSystem::monodroid_get_system_property (const char *name, char **value) #if defined (DEBUG) size_t -AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char **value) +AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char **value) noexcept { if (value != nullptr) *value = nullptr; - FILE* fp = utils.monodroid_fopen (path, "r"); + FILE* fp = Util::monodroid_fopen (path, "r"); if (fp == nullptr) return 0; @@ -233,7 +241,7 @@ AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char #endif // def DEBUG size_t -AndroidSystem::monodroid_get_system_property_from_overrides ([[maybe_unused]] const char *name, [[maybe_unused]] char ** value) +AndroidSystem::monodroid_get_system_property_from_overrides ([[maybe_unused]] const char *name, [[maybe_unused]] char ** value) noexcept { #if defined (DEBUG) for (const char *od : override_dirs) { @@ -241,7 +249,7 @@ AndroidSystem::monodroid_get_system_property_from_overrides ([[maybe_unused]] co continue; } - std::unique_ptr override_file {utils.path_combine (od, name)}; + std::unique_ptr override_file {Util::path_combine (od, name)}; log_info (LOG_DEFAULT, "Trying to get property from %s", override_file.get ()); size_t result = _monodroid_get_system_property_from_file (override_file.get (), value); if (result == 0 || value == nullptr || (*value) == nullptr || **value == '\0') { @@ -256,7 +264,7 @@ AndroidSystem::monodroid_get_system_property_from_overrides ([[maybe_unused]] co // TODO: review this. Do we really have to create the dir in release? void -AndroidSystem::create_update_dir (char *override_dir) +AndroidSystem::create_update_dir (char *override_dir) noexcept { #if defined (RELEASE) /* @@ -266,23 +274,23 @@ AndroidSystem::create_update_dir (char *override_dir) * However, if any logging is enabled (which should _not_ happen with * pre-loaded apps!), we need the .__override__ directory... */ - if (log_categories == 0 && monodroid_get_system_property (Debug::DEBUG_MONO_PROFILE_PROPERTY, nullptr) == 0) { + if (log_categories == 0 && monodroid_get_system_property (SharedConstants::DEBUG_MONO_PROFILE_PROPERTY, nullptr) == 0) { return; } #endif // def RELEASE override_dirs [0] = override_dir; - utils.create_public_directory (override_dir); + Util::create_public_directory (override_dir); log_warn (LOG_DEFAULT, "Creating public update directory: `%s`", override_dir); } bool -AndroidSystem::get_full_dso_path (const char *base_dir, const char *dso_path, dynamic_local_string& path) +AndroidSystem::get_full_dso_path (const char *base_dir, const char *dso_path, dynamic_local_string& path) noexcept { if (dso_path == nullptr) return false; - if (base_dir == nullptr || utils.is_path_rooted (dso_path)) + if (base_dir == nullptr || Util::is_path_rooted (dso_path)) return const_cast(dso_path); // Absolute path or no base path, can't do much with it path.assign_c (base_dir) @@ -293,27 +301,27 @@ AndroidSystem::get_full_dso_path (const char *base_dir, const char *dso_path, dy } void* -AndroidSystem::load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check) +AndroidSystem::load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check) noexcept { if (path == nullptr || *path == '\0') return nullptr; log_info (LOG_ASSEMBLY, "Trying to load shared library '%s'", path); - if (!skip_exists_check && !is_embedded_dso_mode_enabled () && !utils.file_exists (path)) { + if (!skip_exists_check && !is_embedded_dso_mode_enabled () && !Util::file_exists (path)) { log_info (LOG_ASSEMBLY, "Shared library '%s' not found", path); return nullptr; } char *error = nullptr; void *handle = java_interop_lib_load (path, dl_flags, &error); - if (handle == nullptr && utils.should_log (LOG_ASSEMBLY)) + if (handle == nullptr && Util::should_log (LOG_ASSEMBLY)) log_info_nocheck (LOG_ASSEMBLY, "Failed to load shared library '%s'. %s", path, error); java_interop_free (error); return handle; } void* -AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags) +AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags) noexcept { abort_if_invalid_pointer_argument (directories); if (dso_name == nullptr) @@ -333,13 +341,13 @@ AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t nu } void* -AndroidSystem::load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags) +AndroidSystem::load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags) noexcept { return load_dso_from_specified_dirs (app_lib_directories.data (), app_lib_directories.size (), name, dl_flags); } void* -AndroidSystem::load_dso_from_override_dirs ([[maybe_unused]] const char *name, [[maybe_unused]] unsigned int dl_flags) +AndroidSystem::load_dso_from_override_dirs ([[maybe_unused]] const char *name, [[maybe_unused]] unsigned int dl_flags) noexcept { #ifdef RELEASE return nullptr; @@ -349,7 +357,7 @@ AndroidSystem::load_dso_from_override_dirs ([[maybe_unused]] const char *name, [ } void* -AndroidSystem::load_dso_from_any_directories (const char *name, unsigned int dl_flags) +AndroidSystem::load_dso_from_any_directories (const char *name, unsigned int dl_flags) noexcept { void *handle = load_dso_from_override_dirs (name, dl_flags); if (handle == nullptr) @@ -358,16 +366,16 @@ AndroidSystem::load_dso_from_any_directories (const char *name, unsigned int dl_ } bool -AndroidSystem::get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, dynamic_local_string& path) +AndroidSystem::get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, dynamic_local_string& path) noexcept { - if (get_full_dso_path (base_dir, dso_name, path) && utils.file_exists (path.get ())) + if (get_full_dso_path (base_dir, dso_name, path) && Util::file_exists (path.get ())) return true; return false; } bool -AndroidSystem::get_full_dso_path_on_disk (const char *dso_name, dynamic_local_string& path) +AndroidSystem::get_full_dso_path_on_disk (const char *dso_name, dynamic_local_string& path) noexcept { if (is_embedded_dso_mode_enabled ()) return false; @@ -390,7 +398,7 @@ AndroidSystem::get_full_dso_path_on_disk (const char *dso_name, dynamic_local_st } int -AndroidSystem::count_override_assemblies (void) +AndroidSystem::count_override_assemblies (void) noexcept { int c = 0; @@ -398,14 +406,14 @@ AndroidSystem::count_override_assemblies (void) DIR *dir; dirent *e; - if (dir_path == nullptr || !utils.directory_exists (dir_path)) + if (dir_path == nullptr || !Util::directory_exists (dir_path)) continue; if ((dir = ::opendir (dir_path)) == nullptr) continue; while ((e = ::readdir (dir)) != nullptr && e) { - if (utils.monodroid_dirent_hasextension (e, ".dll")) + if (Util::monodroid_dirent_hasextension (e, ".dll")) ++c; } ::closedir (dir); @@ -415,7 +423,7 @@ AndroidSystem::count_override_assemblies (void) } long -AndroidSystem::get_max_gref_count_from_system (void) +AndroidSystem::get_max_gref_count_from_system (void) noexcept { long max; @@ -426,7 +434,7 @@ AndroidSystem::get_max_gref_count_from_system (void) } dynamic_local_string override; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_MAX_GREFC, override) > 0) { + if (monodroid_get_system_property (SharedConstants::DEBUG_MONO_MAX_GREFC, override) > 0) { char *e; max = strtol (override.get (), &e, 10); switch (*e) { @@ -442,7 +450,7 @@ AndroidSystem::get_max_gref_count_from_system (void) if (max < 0) max = std::numeric_limits::max (); if (*e) { - log_warn (LOG_GC, "Unsupported '%s' value '%s'.", Debug::DEBUG_MONO_MAX_GREFC.data (), override.get ()); + log_warn (LOG_GC, "Unsupported '%s' value '%s'.", SharedConstants::DEBUG_MONO_MAX_GREFC.data (), override.get ()); } log_warn (LOG_GC, "Overriding max JNI Global Reference count to %i", max); } @@ -450,7 +458,7 @@ AndroidSystem::get_max_gref_count_from_system (void) } long -AndroidSystem::get_gref_gc_threshold () +AndroidSystem::get_gref_gc_threshold () noexcept { if (max_gref_count == std::numeric_limits::max ()) return max_gref_count; @@ -459,7 +467,7 @@ AndroidSystem::get_gref_gc_threshold () #if defined (DEBUG) void -AndroidSystem::setup_environment (const char *name, const char *value) +AndroidSystem::setup_environment (const char *name, const char *value) noexcept { if (name == nullptr || *name == '\0') return; @@ -478,7 +486,7 @@ AndroidSystem::setup_environment (const char *name, const char *value) } void -AndroidSystem::setup_environment_from_override_file (const char *path) +AndroidSystem::setup_environment_from_override_file (const char *path) noexcept { using read_count_type = size_t; @@ -568,7 +576,7 @@ AndroidSystem::setup_environment_from_override_file (const char *path) #endif // def DEBUG void -AndroidSystem::setup_environment () +AndroidSystem::setup_environment () noexcept { if (is_mono_aot_enabled () && *mono_aot_mode_name != '\0') { switch (mono_aot_mode_name [0]) { @@ -632,8 +640,8 @@ AndroidSystem::setup_environment () #if defined (DEBUG) // TODO: for debug read from file in the override directory named `environment` for (const char *od : override_dirs) { - std::unique_ptr env_override_file {utils.path_combine (od, OVERRIDE_ENVIRONMENT_FILE_NAME.data ())}; - if (utils.file_exists (env_override_file.get ())) { + std::unique_ptr env_override_file {Util::path_combine (od, OVERRIDE_ENVIRONMENT_FILE_NAME.data ())}; + if (Util::file_exists (env_override_file.get ())) { setup_environment_from_override_file (env_override_file.get ()); } } @@ -641,7 +649,7 @@ AndroidSystem::setup_environment () } void -AndroidSystem::setup_process_args_apk (const char *apk, size_t index, size_t apk_count, [[maybe_unused]] void *user_data) +AndroidSystem::setup_process_args_apk (const char *apk, size_t index, size_t apk_count, [[maybe_unused]] void *user_data) noexcept { if (apk == nullptr || index != apk_count - 1) return; @@ -651,7 +659,110 @@ AndroidSystem::setup_process_args_apk (const char *apk, size_t index, size_t apk } void -AndroidSystem::setup_process_args (jstring_array_wrapper &runtimeApks) +AndroidSystem::setup_process_args (jstring_array_wrapper &runtimeApks) noexcept +{ + for_each_apk (runtimeApks, static_cast (&AndroidSystem::setup_process_args_apk), nullptr); +} + +void +AndroidSystem::detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept +{ + // appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX] points to the native library directory + std::unique_ptr libmonodroid_path {Util::path_combine (appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr (), "libmonodroid.so")}; + log_debug (LOG_ASSEMBLY, "Checking if libmonodroid was unpacked to %s", libmonodroid_path.get ()); + if (!Util::file_exists (libmonodroid_path.get ())) { + log_debug (LOG_ASSEMBLY, "%s not found, assuming application/android:extractNativeLibs == false", libmonodroid_path.get ()); + set_embedded_dso_mode_enabled (true); + } else { + log_debug (LOG_ASSEMBLY, "Native libs extracted to %s, assuming application/android:extractNativeLibs == true", appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); + set_embedded_dso_mode_enabled (false); + } +} + +void +AndroidSystem::setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks) noexcept +{ + if (!is_embedded_dso_mode_enabled ()) { + log_debug (LOG_DEFAULT, "Setting up for DSO lookup in app data directories"); + + AndroidSystem::app_lib_directories = std::span (single_app_lib_directory); + AndroidSystem::app_lib_directories [0] = Util::strdup_new (appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); + log_debug (LOG_ASSEMBLY, "Added filesystem DSO lookup location: %s", appDirs[SharedConstants::APP_DIRS_DATA_DIR_INDEX].get_cstr ()); + } else { + log_debug (LOG_DEFAULT, "Setting up for DSO lookup directly in the APK"); + + if (have_split_apks) { + // If split apks are used, then we will have just a single app library directory. Don't allocate any memory + // dynamically in this case + AndroidSystem::app_lib_directories = std::span (single_app_lib_directory); + } else { + size_t app_lib_directories_size = have_split_apks ? 1 : runtimeApks.get_length (); + AndroidSystem::app_lib_directories = std::span (new const char*[app_lib_directories_size], app_lib_directories_size); + } + + unsigned short built_for_cpu = 0, running_on_cpu = 0; + unsigned char is64bit = 0; + _monodroid_detect_cpu_and_architecture (&built_for_cpu, &running_on_cpu, &is64bit); + setup_apk_directories (running_on_cpu, runtimeApks, have_split_apks); + } +} + +void +AndroidSystem::for_each_apk (jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data) noexcept +{ + size_t apksLength = runtimeApks.get_length (); + for (size_t i = 0; i < apksLength; ++i) { + jstring_wrapper &e = runtimeApks [i]; + + (handler) (e.get_cstr (), i, apksLength, user_data); + } +} + +force_inline void +AndroidSystem::add_apk_libdir (const char *apk, size_t &index, const char *abi) noexcept +{ + abort_unless (index < app_lib_directories.size (), "Index out of range"); + app_lib_directories [index] = Util::string_concat (apk, "!/lib/", abi); + log_debug (LOG_ASSEMBLY, "Added APK DSO lookup location: %s", app_lib_directories[index]); + index++; +} + +force_inline void +AndroidSystem::setup_apk_directories (unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks, bool have_split_apks) noexcept { - for_each_apk (runtimeApks, static_cast (&AndroidSystem::setup_process_args_apk), nullptr); + const char *abi = android_abi_names [running_on_cpu]; + size_t number_of_added_directories = 0; + + for (size_t i = 0; i < runtimeApks.get_length (); ++i) { + jstring_wrapper &e = runtimeApks [i]; + const char *apk = e.get_cstr (); + + if (have_split_apks) { + if (Util::ends_with (apk, SharedConstants::split_config_abi_apk_name)) { + add_apk_libdir (apk, number_of_added_directories, abi); + break; + } + } else { + add_apk_libdir (apk, number_of_added_directories, abi); + } + } + + if (app_lib_directories.size () == number_of_added_directories) [[likely]] { + return; + } + + abort_unless (number_of_added_directories > 0, "At least a single application lib directory must be added"); + app_lib_directories = app_lib_directories.subspan (0, number_of_added_directories); +} + +char* +AndroidSystem::determine_primary_override_dir (jstring_wrapper &home) noexcept +{ + dynamic_local_string name { home.get_cstr () }; + name.append ("/") + .append (SharedConstants::OVERRIDE_DIRECTORY_NAME) + .append ("/") + .append (SharedConstants::android_lib_abi); + + return Util::strdup_new (name.get ()); } diff --git a/src/native/runtime-base/android-system.hh b/src/native/runtime-base/android-system.hh new file mode 100644 index 00000000000..f100c6ff028 --- /dev/null +++ b/src/native/runtime-base/android-system.hh @@ -0,0 +1,233 @@ +#ifndef ANDROID_SYSTEM_HH +#define ANDROID_SYSTEM_HH + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "xamarin-app.hh" +#include "cpu-arch.hh" +#include "jni-wrappers.hh" +#include "strings.hh" + +static inline constexpr size_t PROPERTY_VALUE_BUFFER_LEN = PROP_VALUE_MAX + 1; + +extern FILE *gref_log; +extern FILE *lref_log; +extern bool gref_to_logcat; +extern bool lref_to_logcat; + +namespace xamarin::android { + class jstring_wrapper; + class jstring_array_wrapper; +} + +namespace xamarin::android::internal { +#if defined (DEBUG) + struct BundledProperty; +#endif + + class AndroidSystem + { + protected: + using ForEachApkHandler = void (*) (const char *apk, size_t index, size_t apk_count, void *user_data); + + private: +#if defined (__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc99-designator" +#endif + // Values correspond to the CPU_KIND_* macros + static constexpr const char* android_abi_names[CPU_KIND_X86_64+1] = { + [0] = "unknown", + [CPU_KIND_ARM] = "armeabi-v7a", + [CPU_KIND_ARM64] = "arm64-v8a", + [CPU_KIND_MIPS] = "mips", + [CPU_KIND_X86] = "x86", + [CPU_KIND_X86_64] = "x86_64", + }; +#if defined (__clang__) +#pragma clang diagnostic pop +#endif + static constexpr size_t ANDROID_ABI_NAMES_SIZE = sizeof(android_abi_names) / sizeof (android_abi_names[0]); + +#if defined (DEBUG) + static constexpr std::string_view OVERRIDE_ENVIRONMENT_FILE_NAME { "environment" }; + static constexpr uint32_t OVERRIDE_ENVIRONMENT_FILE_HEADER_SIZE = 22; + static BundledProperty *bundled_properties; +#endif + + public: +#ifdef ANDROID64 + static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib64" }; +#else + static constexpr std::string_view SYSTEM_LIB_PATH { "/system/lib" }; +#endif + + inline static std::array override_dirs{}; + + // This optimizes things a little bit. The array is allocated at build time, so we pay no cost for its + // allocation and at run time it allows us to skip dynamic memory allocation. + inline static std::array single_app_lib_directory{}; + inline static std::span app_lib_directories; + + public: + static void setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks) noexcept; + + static size_t monodroid_get_system_property_from_overrides (const char *name, char ** value) noexcept; + static char* get_bundled_app (JNIEnv *env, jstring dir) noexcept; + static int count_override_assemblies () noexcept; + static long get_gref_gc_threshold () noexcept; + static void* load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check) noexcept; + static void* load_dso_from_any_directories (const char *name, unsigned int dl_flags) noexcept; + static bool get_full_dso_path_on_disk (const char *dso_name, dynamic_local_string& path) noexcept; + static void setup_environment () noexcept; + static void setup_process_args (jstring_array_wrapper &runtimeApks) noexcept; + static void create_update_dir (char *override_dir) noexcept; + static int monodroid_get_system_property (const char *name, char **value) noexcept; + static int monodroid_get_system_property (const char *name, dynamic_local_string &value) noexcept; + + static int monodroid_get_system_property (std::string_view const& name, char **value) noexcept + { + return monodroid_get_system_property (name.data (), value); + } + + static int monodroid_get_system_property (std::string_view const& name, dynamic_local_string& value) noexcept + { + return monodroid_get_system_property (name.data (), value); + } + + static void set_override_dir (uint32_t index, const char* dir) noexcept + { + if (index >= override_dirs.size ()) + return; + + override_dirs [index] = const_cast (dir); + } + + static bool is_embedded_dso_mode_enabled () noexcept + { + return embedded_dso_mode_enabled; + } + + static void detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept; + + static char *get_runtime_libdir () noexcept + { + return runtime_libdir; + } + + static void set_runtime_libdir (char *dir) noexcept + { + runtime_libdir = dir; + } + + static char *get_primary_override_dir () noexcept + { + return primary_override_dir; + } + + static void set_primary_override_dir (jstring_wrapper& home) noexcept + { + primary_override_dir = determine_primary_override_dir (home); + } + + static long get_max_gref_count () noexcept + { + return max_gref_count; + } + + static void init_max_gref_count () noexcept + { + max_gref_count = get_max_gref_count_from_system (); + } + + static bool is_assembly_preload_enabled () noexcept + { + return application_config.uses_assembly_preload; + } + + static bool is_mono_llvm_enabled () noexcept + { + return application_config.uses_mono_llvm; + } + + static bool is_mono_aot_enabled () noexcept + { + return application_config.uses_mono_aot; + } + + static MonoAotMode get_mono_aot_mode () noexcept + { + return aotMode; + } + + static bool is_interpreter_enabled () noexcept + { + return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; + } + + // Hack, see comment for `aot_mode_last_is_interpreter` at the bottom of the class declaration + static bool is_aot_mode_last_really_interpreter_mode () noexcept + { + return false; + } + + static void set_running_in_emulator (bool yesno) noexcept + { + running_in_emulator = yesno; + } + + protected: + static void for_each_apk (jstring_array_wrapper &runtimeApks, ForEachApkHandler handler, void *user_data) noexcept; + + private: +#if defined (DEBUG) + static void add_system_property (const char *name, const char *value) noexcept; + static void setup_environment (const char *name, const char *value) noexcept; + static void setup_environment_from_override_file (const char *path) noexcept; + static BundledProperty* lookup_system_property (const char *name) noexcept; +#endif + static const char* lookup_system_property (const char *name, size_t &value_len) noexcept; + static long get_max_gref_count_from_system () noexcept; + static void setup_process_args_apk (const char *apk, size_t index, size_t apk_count, void *user_data) noexcept; + static int _monodroid__system_property_get (const char *name, char *sp_value, size_t sp_value_len) noexcept; +#if defined (DEBUG) + static size_t _monodroid_get_system_property_from_file (const char *path, char **value) noexcept; +#endif + static bool get_full_dso_path (const char *base_dir, const char *dso_path, dynamic_local_string& path) noexcept; + static void* load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags) noexcept; + static void* load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags) noexcept; + static void* load_dso_from_override_dirs (const char *name, unsigned int dl_flags) noexcept; + static bool get_existing_dso_path_on_disk (const char *base_dir, const char *dso_name, dynamic_local_string& path) noexcept; + + private: + static void add_apk_libdir (const char *apk, size_t &index, const char *abi) noexcept; + static void setup_apk_directories (unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks, bool have_split_apks) noexcept; + static char* determine_primary_override_dir (jstring_wrapper &home) noexcept; + + static void set_embedded_dso_mode_enabled (bool yesno) noexcept + { + embedded_dso_mode_enabled = yesno; + } + + private: + static inline bool embedded_dso_mode_enabled = false; + static inline char *runtime_libdir = nullptr; + static inline char *primary_override_dir = nullptr; + static inline long max_gref_count = 0; + static inline MonoAotMode aotMode = MonoAotMode::MONO_AOT_MODE_NONE; + static inline bool running_in_emulator = false; + }; +} +#endif // !ANDROID_SYSTEM_HH diff --git a/src/native/monodroid/jni/cpu-arch-detect.cc b/src/native/runtime-base/cpu-arch-detect.cc similarity index 100% rename from src/native/monodroid/jni/cpu-arch-detect.cc rename to src/native/runtime-base/cpu-arch-detect.cc diff --git a/src/native/monodroid/jni/cpu-arch.hh b/src/native/runtime-base/cpu-arch.hh similarity index 95% rename from src/native/monodroid/jni/cpu-arch.hh rename to src/native/runtime-base/cpu-arch.hh index 29c210d47f4..de0e9cf93d5 100644 --- a/src/native/monodroid/jni/cpu-arch.hh +++ b/src/native/runtime-base/cpu-arch.hh @@ -1,8 +1,6 @@ #ifndef __CPU_ARCH_H #define __CPU_ARCH_H -#include - #define CPU_KIND_UNKNOWN ((unsigned short)0) #define CPU_KIND_ARM ((unsigned short)1) #define CPU_KIND_ARM64 ((unsigned short)2) diff --git a/src/native/monodroid/jni/jni-wrappers.hh b/src/native/runtime-base/jni-wrappers.hh similarity index 100% rename from src/native/monodroid/jni/jni-wrappers.hh rename to src/native/runtime-base/jni-wrappers.hh diff --git a/src/native/monodroid/jni/logger.cc b/src/native/runtime-base/logger.cc similarity index 92% rename from src/native/monodroid/jni/logger.cc rename to src/native/runtime-base/logger.cc index 581d633df99..db3c4fc47ca 100644 --- a/src/native/monodroid/jni/logger.cc +++ b/src/native/runtime-base/logger.cc @@ -7,14 +7,12 @@ #include #include +#include +#include "android-system.hh" #include "logger.hh" - -#include "monodroid.h" -#include "monodroid-glue.hh" -#include "debug.hh" +#include "shared-constants.hh" #include "util.hh" -#include "globals.hh" #undef DO_LOG #define DO_LOG(_level_,_category_,_format_,_args_) \ @@ -67,17 +65,17 @@ open_file (LogCategories category, const char *path, const char *override_dir, c } if (!path) { - utils.create_public_directory (override_dir); - p = utils.path_combine (override_dir, filename); + Util::create_public_directory (override_dir); + p = Util::path_combine (override_dir, filename); path = p; } unlink (path); - f = utils.monodroid_fopen (path, "a"); + f = Util::monodroid_fopen (path, "a"); if (f) { - utils.set_world_accessable (path); + Util::set_world_accessable (path); } else { log_warn (category, "Could not open path '%s' for logging: %s", path, strerror (errno)); } @@ -132,7 +130,7 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) log_timing_categories = LOG_TIMING_DEFAULT; dynamic_local_string value; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_LOG_PROPERTY, value) == 0) + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_LOG_PROPERTY, value) == 0) return; string_segment param; @@ -182,7 +180,7 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) constexpr std::string_view CAT_GREF_EQUALS { "gref=" }; if (set_category (CAT_GREF_EQUALS, param, LOG_GREF, true /* arg_starts_with_name */)) { - gref_file = utils.strdup_new (param, CAT_GREF_EQUALS.length ()); + gref_file = Util::strdup_new (param, CAT_GREF_EQUALS.length ()); continue; } @@ -198,7 +196,7 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) constexpr std::string_view CAT_LREF_EQUALS { "lref=" }; if (set_category (CAT_LREF_EQUALS, param, LOG_LREF, true /* arg_starts_with_name */)) { - lref_file = utils.strdup_new (param, CAT_LREF_EQUALS.length ()); + lref_file = Util::strdup_new (param, CAT_LREF_EQUALS.length ()); continue; } @@ -226,13 +224,13 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) constexpr std::string_view MONO_LOG_MASK_ARG { "mono_log_mask=" }; if (param.starts_with (MONO_LOG_MASK_ARG)) { - mono_log_mask = utils.strdup_new (param, MONO_LOG_MASK_ARG.length ()); + mono_log_mask = Util::strdup_new (param, MONO_LOG_MASK_ARG.length ()); continue; } constexpr std::string_view MONO_LOG_LEVEL_ARG { "mono_log_level=" }; if (param.starts_with (MONO_LOG_LEVEL_ARG)) { - mono_log_level = utils.strdup_new (param, MONO_LOG_LEVEL_ARG.length ()); + mono_log_level = Util::strdup_new (param, MONO_LOG_LEVEL_ARG.length ()); continue; } diff --git a/src/native/monodroid/jni/logger.hh b/src/native/runtime-base/logger.hh similarity index 100% rename from src/native/monodroid/jni/logger.hh rename to src/native/runtime-base/logger.hh diff --git a/src/native/monodroid/jni/shared-constants.cc b/src/native/runtime-base/shared-constants.cc similarity index 100% rename from src/native/monodroid/jni/shared-constants.cc rename to src/native/runtime-base/shared-constants.cc diff --git a/src/native/monodroid/jni/shared-constants.hh b/src/native/runtime-base/shared-constants.hh similarity index 81% rename from src/native/monodroid/jni/shared-constants.hh rename to src/native/runtime-base/shared-constants.hh index 1ecdbcf90e5..bc8461f59f0 100644 --- a/src/native/monodroid/jni/shared-constants.hh +++ b/src/native/runtime-base/shared-constants.hh @@ -46,6 +46,21 @@ namespace xamarin::android::internal static constexpr std::string_view MONO_SGEN_ARCH_SO { "libmonosgen-" __BITNESS__ "-2.0.so" }; static constexpr std::string_view OVERRIDE_DIRECTORY_NAME { ".__override__" }; + /* Android property containing connection information, set by XS */ + static inline constexpr std::string_view DEBUG_MONO_CONNECT_PROPERTY { "debug.mono.connect" }; + static inline constexpr std::string_view DEBUG_MONO_DEBUG_PROPERTY { "debug.mono.debug" }; + static inline constexpr std::string_view DEBUG_MONO_ENV_PROPERTY { "debug.mono.env" }; + static inline constexpr std::string_view DEBUG_MONO_EXTRA_PROPERTY { "debug.mono.extra" }; + static inline constexpr std::string_view DEBUG_MONO_GC_PROPERTY { "debug.mono.gc" }; + static inline constexpr std::string_view DEBUG_MONO_GDB_PROPERTY { "debug.mono.gdb" }; + static inline constexpr std::string_view DEBUG_MONO_LOG_PROPERTY { "debug.mono.log" }; + static inline constexpr std::string_view DEBUG_MONO_MAX_GREFC { "debug.mono.max_grefc" }; + static inline constexpr std::string_view DEBUG_MONO_PROFILE_PROPERTY { "debug.mono.profile" }; + static inline constexpr std::string_view DEBUG_MONO_RUNTIME_ARGS_PROPERTY { "debug.mono.runtime_args" }; + static inline constexpr std::string_view DEBUG_MONO_SOFT_BREAKPOINTS { "debug.mono.soft_breakpoints" }; + static inline constexpr std::string_view DEBUG_MONO_TRACE_PROPERTY { "debug.mono.trace" }; + static inline constexpr std::string_view DEBUG_MONO_WREF_PROPERTY { "debug.mono.wref" }; + #if __arm__ static constexpr std::string_view android_abi { "armeabi_v7a" }; static constexpr std::string_view android_lib_abi { "armeabi-v7a" }; diff --git a/src/native/monodroid/jni/strings.hh b/src/native/runtime-base/strings.hh similarity index 100% rename from src/native/monodroid/jni/strings.hh rename to src/native/runtime-base/strings.hh diff --git a/src/native/monodroid/jni/basic-utilities.cc b/src/native/runtime-base/util.cc similarity index 50% rename from src/native/monodroid/jni/basic-utilities.cc rename to src/native/runtime-base/util.cc index bfe10dfa922..a5ff68f04a8 100644 --- a/src/native/monodroid/jni/basic-utilities.cc +++ b/src/native/runtime-base/util.cc @@ -1,15 +1,161 @@ #include -#include #include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include -#include "basic-utilities.hh" -#include "logger.hh" -#include "cpp-util.hh" +#include "util.hh" using namespace xamarin::android; +void Util::initialize () noexcept +{ + page_size = getpagesize (); +} + +int +Util::send_uninterrupted (int fd, void *buf, size_t len) +{ + ssize_t res; + + do { + res = send (fd, buf, len, 0); + } while (res == -1 && errno == EINTR); + + return static_cast(res) == len; +} + +ssize_t +Util::recv_uninterrupted (int fd, void *buf, size_t len) +{ + using nbytes_type = size_t; + + ssize_t res; + size_t total = 0; + int flags = 0; + nbytes_type nbytes; + + do { + nbytes = static_cast(len - total); + res = recv (fd, (char *) buf + total, nbytes, flags); + + if (res > 0) + total += static_cast(res); + } while ((res > 0 && total < len) || (res == -1 && errno == EINTR)); + + return static_cast(total); +} + +template +inline void +Util::package_hash_to_hex (IdxType /* idx */) +{ + package_property_suffix[sizeof (package_property_suffix) / sizeof (char) - 1] = 0x00; +} + +template +inline void +Util::package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices) +{ + package_property_suffix [idx] = hex_chars [(hash & (0xF0000000 >> idx * 4)) >> ((7 - idx) * 4)]; + package_hash_to_hex (hash, indices...); +} + +void +Util::monodroid_store_package_name (const char *name) +{ + if (!name || *name == '\0') + return; + + /* Android properties can be at most 32 bytes long (!) and so we mustn't append the package name + * as-is since it will most likely generate conflicts (packages tend to be named + * com.mycompany.app), so we simply generate a hash code and use that instead. We treat the name + * as a stream of bytes assumming it's an ASCII string using a simplified version of the hash + * algorithm used by BCL's String.GetHashCode () + */ + const char *ch = name; + uint32_t hash = 0; + while (*ch) + hash = (hash << 5) - (hash + static_cast(*ch++)); + + // In C++14 or newer we could use std::index_sequence, but in C++11 it's a bit too much ado + // for this simple case, so a manual sequence it is. + // + // And yes, I know it could be done in a simple loop or in even simpler 8 lines of code, but + // that would be boring, wouldn't it? :) + package_hash_to_hex (hash, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u); + log_debug (LOG_DEFAULT, "Generated hash 0x%s for package name %s", package_property_suffix, name); +} + +MonoAssembly* +Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename) +{ + MonoImageOpenStatus status; + MonoAssemblyName *aname = mono_assembly_name_new (basename); + MonoAssembly *assm = mono_assembly_load_full_alc (alc_handle, aname, nullptr, &status); + + mono_assembly_name_free (aname); + + if (assm == nullptr || status != MonoImageOpenStatus::MONO_IMAGE_OK) { + log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); + Helpers::abort_application (); + } + return assm; +} + +MonoAssembly * +Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) +{ + MonoAssembly *assm; + MonoAssemblyName *aname; + MonoImageOpenStatus status; + + aname = mono_assembly_name_new (basename); + MonoDomain *current = get_current_domain (); + + if (domain != current) { + mono_domain_set (domain, FALSE); + assm = mono_assembly_load_full (aname, nullptr, &status, 0); + mono_domain_set (current, FALSE); + } else { + assm = mono_assembly_load_full (aname, nullptr, &status, 0); + } + + mono_assembly_name_free (aname); + + if (!assm) { + log_fatal (LOG_DEFAULT, "Unable to find assembly '%s'.", basename); + Helpers::abort_application (); + } + return assm; +} + +MonoClass* +Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const char* assembly, const char *_namespace, const char *type) +{ + MonoClass *result; + MonoAssemblyName *aname = mono_assembly_name_new (assembly); + MonoAssembly *assm = mono_assembly_loaded (aname); + if (assm != nullptr) { + MonoImage *image = mono_assembly_get_image (assm); + result = mono_class_from_name (image, _namespace, type); + } else + result = nullptr; + + mono_assembly_name_free (aname); + return result; +} + char* -BasicUtilities::path_combine (const char *path1, const char *path2) +Util::path_combine (const char *path1, const char *path2) { // Don't let erroneous nullptr parameters situation propagate abort_unless (path1 != nullptr || path2 != nullptr, "At least one path must be a valid pointer"); @@ -31,7 +177,7 @@ BasicUtilities::path_combine (const char *path1, const char *path2) } void -BasicUtilities::create_public_directory (const char *dir) +Util::create_public_directory (const char *dir) { mode_t m = umask (0); int ret = mkdir (dir, 0777); @@ -42,7 +188,7 @@ BasicUtilities::create_public_directory (const char *dir) } int -BasicUtilities::create_directory (const char *pathname, mode_t mode) +Util::create_directory (const char *pathname, mode_t mode) { if (mode <= 0) mode = DEFAULT_DIRECTORY_MODE; @@ -76,7 +222,7 @@ BasicUtilities::create_directory (const char *pathname, mode_t mode) } void -BasicUtilities::set_world_accessable ([[maybe_unused]] const char *path) +Util::set_world_accessable ([[maybe_unused]] const char *path) { int r; do { @@ -89,7 +235,7 @@ BasicUtilities::set_world_accessable ([[maybe_unused]] const char *path) } void -BasicUtilities::set_user_executable ([[maybe_unused]] const char *path) +Util::set_user_executable ([[maybe_unused]] const char *path) { int r; do { @@ -102,7 +248,7 @@ BasicUtilities::set_user_executable ([[maybe_unused]] const char *path) } bool -BasicUtilities::file_exists (const char *file) +Util::file_exists (const char *file) { struct stat s; if (::stat (file, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG) @@ -111,7 +257,7 @@ BasicUtilities::file_exists (const char *file) } bool -BasicUtilities::directory_exists (const char *directory) +Util::directory_exists (const char *directory) { if (directory == nullptr) { return false; @@ -124,15 +270,15 @@ BasicUtilities::directory_exists (const char *directory) } bool -BasicUtilities::file_copy (const char *to, const char *from) +Util::file_copy (const char *to, const char *from) { if (to == nullptr || *to == '\0') { - log_error (LOG_DEFAULT, "BasicUtilities::file_copy: `to` parameter must not be null or empty"); + log_error (LOG_DEFAULT, "Util::file_copy: `to` parameter must not be null or empty"); return false; } if (from == nullptr || *from == '\0') { - log_error (LOG_DEFAULT, "BasicUtilities::file_copy: `from` parameter must not be null or empty"); + log_error (LOG_DEFAULT, "Util::file_copy: `from` parameter must not be null or empty"); return false; } @@ -165,7 +311,7 @@ BasicUtilities::file_copy (const char *to, const char *from) } bool -BasicUtilities::is_path_rooted (const char *path) +Util::is_path_rooted (const char *path) noexcept { if (path == nullptr) { return false; @@ -175,7 +321,7 @@ BasicUtilities::is_path_rooted (const char *path) } FILE * -BasicUtilities::monodroid_fopen (const char *filename, const char *mode) +Util::monodroid_fopen (const char *filename, const char *mode) { FILE *ret; @@ -192,13 +338,13 @@ BasicUtilities::monodroid_fopen (const char *filename, const char *mode) } int -BasicUtilities::monodroid_dirent_hasextension (dirent *e, const char *extension) +Util::monodroid_dirent_hasextension (dirent *e, const char *extension) { return ends_with_slow (e->d_name, extension); } void -BasicUtilities::monodroid_strfreev (char **str_array) +Util::monodroid_strfreev (char **str_array) { char **orig = str_array; if (str_array == nullptr) { @@ -213,7 +359,7 @@ BasicUtilities::monodroid_strfreev (char **str_array) } char ** -BasicUtilities::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) +Util::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) { if (str == nullptr || *str == '\0') { return static_cast(xcalloc (sizeof(char*), 1)); @@ -286,7 +432,7 @@ BasicUtilities::monodroid_strsplit (const char *str, const char *delimiter, size } char * -BasicUtilities::monodroid_strdup_printf (const char *format, ...) +Util::monodroid_strdup_printf (const char *format, ...) { va_list args; @@ -298,7 +444,7 @@ BasicUtilities::monodroid_strdup_printf (const char *format, ...) } char* -BasicUtilities::monodroid_strdup_vprintf (const char *format, va_list vargs) +Util::monodroid_strdup_vprintf (const char *format, va_list vargs) { char *ret = nullptr; int n = vasprintf (&ret, format, vargs); diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh new file mode 100644 index 00000000000..49c230e5bf0 --- /dev/null +++ b/src/native/runtime-base/util.hh @@ -0,0 +1,405 @@ +// This is a -*- C++ -*- header +#ifndef __MONODROID_UTIL_H__ +#define __MONODROID_UTIL_H__ + +#ifndef TRUE +#ifdef __cplusplus +static inline constexpr int TRUE = 1; +#else +#define TRUE 1 +#endif // __cplusplus +#endif + +#ifndef FALSE +#ifdef __cplusplus +static inline constexpr int FALSE = 0; +#else +#define FALSE 0 +#endif // __cplusplus +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "jni-wrappers.hh" +#include "java-interop-util.h" +#include "logger.hh" +#include "strings.hh" + +#ifdef __cplusplus +namespace xamarin::android +{ + class Util + { + static constexpr std::array hex_chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + static constexpr uint32_t ms_in_nsec = 1000000ULL; + + public: + static void initialize () noexcept; + + static int monodroid_getpagesize () noexcept + { + return page_size; + } + + static void monodroid_store_package_name (const char *name); + static MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); + static MonoAssembly *monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename); + static MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); + static int send_uninterrupted (int fd, void *buf, size_t len); + static ssize_t recv_uninterrupted (int fd, void *buf, size_t len); + static FILE *monodroid_fopen (const char* filename, const char* mode); + static int monodroid_dirent_hasextension (dirent *e, const char *extension); + static void monodroid_strfreev (char **str_array); + static char **monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens); + static char *monodroid_strdup_printf (const char *format, ...); + static char *monodroid_strdup_vprintf (const char *format, va_list vargs); + static char* path_combine (const char *path1, const char *path2); + static void create_public_directory (const char *dir); + static int create_directory (const char *pathname, mode_t mode); + static void set_world_accessable (const char *path); + static void set_user_executable (const char *path); + static bool file_exists (const char *file); + static bool directory_exists (const char *directory); + static bool file_copy (const char *to, const char *from); + + static std::optional get_file_size_at (int dirfd, const char *file_name) noexcept + { + struct stat sbuf; + if (fstatat (dirfd, file_name, &sbuf, 0) == -1) { + log_warn (LOG_ASSEMBLY, "Failed to stat file '%s': %s", file_name, std::strerror (errno)); + return std::nullopt; + } + + return static_cast(sbuf.st_size); + } + + static std::optional open_file_ro_at (int dirfd, const char *file_name) noexcept + { + int fd = openat (dirfd, file_name, O_RDONLY); + if (fd < 0) { + log_error (LOG_ASSEMBLY, "Failed to open file '%s' for reading: %s", file_name, std::strerror (errno)); + return std::nullopt; + } + + return fd; + } + + // Make sure that `buf` has enough space! This is by design, the methods are supposed to be fast. + template + static void path_combine (TBuffer& buf, const char* path1, const char* path2) noexcept + { + path_combine (buf, path1, path1 == nullptr ? 0 : strlen (path1), path2, path2 == nullptr ? 0 : strlen (path2)); + } + + // internal::static_local_string + template + static void path_combine (TBuffer& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept + { + abort_unless (path1 != nullptr || path2 != nullptr, "At least one path must be a valid pointer"); + + if (path1 == nullptr) { + buf.append_c (path2); + return; + } + + if (path2 == nullptr) { + buf.append_c (path1); + return; + } + + buf.append (path1, path1_len); + buf.append ("/"); + buf.append (path2, path2_len); + } + + template + static void path_combine (internal::static_local_string& buf, const char* path1, const char* path2) noexcept + { + path_combine (buf, path1, path2); + } + + template + static void path_combine (internal::static_local_string& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept + { + path_combine (buf, path1, path1_len, path2, path2_len); + } + + template + static void path_combine (internal::dynamic_local_string& buf, const char* path1, const char* path2) noexcept + { + path_combine (buf, path1, path2); + } + + template + static void path_combine (internal::dynamic_local_string& buf, const char* path1, size_t path1_len, const char* path2, size_t path2_len) noexcept + { + path_combine (buf, path1, path1_len, path2, path2_len); + } + + static char* path_combine (const char *path1, std::string_view const& path2) noexcept + { + return path_combine (path1, path2.data ()); + } + + static bool ends_with_slow (const char *str, const char *end) noexcept + { + char *p = const_cast (strstr (str, end)); + return p != nullptr && p [strlen (end)] == '\0'; + } + + template + static bool ends_with (internal::dynamic_local_string& str, std::string_view const& sv) noexcept + { + return ends_with(static_cast const&>(str), sv); + } + + bool ends_with (const char *str, std::string_view const& sv) const noexcept + { + size_t len = strlen (str); + if (len < sv.length ()) { + return false; + } + + return memcmp (str + len - sv.length (), sv.data (), sv.length ()) == 0; + } + + template + static bool ends_with (const char *str, const char (&end)[N]) + { + char *p = const_cast (strstr (str, end)); + return p != nullptr && p [N - 1] == '\0'; + } + + template + static bool ends_with (const char *str, std::array const& end) noexcept + { + char *p = const_cast (strstr (str, end.data ())); + return p != nullptr && p [N - 1] == '\0'; + } + + template + static bool ends_with (const char *str, helper_char_array const& end) noexcept + { + char *p = const_cast (strstr (str, end.data ())); + return p != nullptr && p [N - 1] == '\0'; + } + + template + static bool ends_with (internal::string_base const& str, const char (&end)[N]) noexcept + { + constexpr size_t end_length = N - 1; + + size_t len = str.length (); + if (len < end_length) [[unlikely]] { + return false; + } + + return memcmp (str.get () + len - end_length, end, end_length) == 0; + } + + template + static bool ends_with (internal::string_base const& str, std::array const& end) noexcept + { + constexpr size_t end_length = N - 1; + + size_t len = str.length (); + if (len < end_length) [[unlikely]] { + return false; + } + + return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; + } + + template + static bool ends_with (internal::string_base const& str, helper_char_array const& end) noexcept + { + constexpr size_t end_length = N - 1; + + size_t len = str.length (); + if (len < end_length) [[unlikely]] { + return false; + } + + return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; + } + + template + static const TChar* find_last (internal::string_base const& str, const char ch) noexcept + { + if (str.empty ()) { + return nullptr; + } + + for (size_t i = str.length (); i > 0; i--) { + const size_t index = i - 1; + if (str[index] == ch) { + return str.get () + index; + } + } + + return nullptr; + } + + static void *xmalloc (size_t size) noexcept + { + return ::xmalloc (size); + } + + static void *xrealloc (void *ptr, size_t size) noexcept + { + return ::xrealloc (ptr, size); + } + + static void *xcalloc (size_t nmemb, size_t size) noexcept + { + return ::xcalloc (nmemb, size); + } + + static char *strdup_new (const char* s, size_t len) noexcept + { + if (len == 0 || s == nullptr) [[unlikely]] { + return nullptr; + } + + size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, len, 1); + auto ret = new char[alloc_size]; + memcpy (ret, s, len); + ret[len] = '\0'; + + return ret; + } + + static char *strdup_new (const char* s) noexcept + { + if (s == nullptr) [[unlikely]] { + return nullptr; + } + + return strdup_new (s, strlen (s)); + } + + template + static char *strdup_new (internal::dynamic_local_string const& buf) noexcept + { + return strdup_new (buf.get (), buf.length ()); + } + + static char *strdup_new (xamarin::android::internal::string_segment const& s, size_t from_index = 0) noexcept + { + if (from_index >= s.length ()) { + return nullptr; + } + + return strdup_new (s.start () + from_index, s.length () - from_index); + } + + template + static char* string_concat (const char *s1, const CharType* s2, Strings... strings) noexcept + { + assert_char_type (); + + size_t len = calculate_length (s1, s2, strings...); + + char *ret = new char [len + 1]; + *ret = '\0'; + + concatenate_strings_into (len, ret, s1, s2, strings...); + + return ret; + } + + static bool is_path_rooted (const char *path) noexcept; + + template + static size_t calculate_length (const CharType* s) noexcept + { + return strlen (s); + } + + template + static size_t calculate_length (const CharType* s1, Strings... strings) noexcept + { + assert_char_type (); + + return strlen (s1) + calculate_length (strings...); + } + + static bool should_log (LogCategories category) noexcept + { + return (log_categories & category) != 0; + } + + static MonoDomain *get_current_domain (bool attach_thread_if_needed = true) noexcept + { + MonoDomain *ret = mono_domain_get (); + if (ret != nullptr) { + return ret; + } + + // It's likely that we got a nullptr because the current thread isn't attached (see + // https://github.com/xamarin/xamarin-android/issues/6211), so we need to attach the thread to the root + // domain + ret = mono_get_root_domain (); + if (attach_thread_if_needed) { + mono_thread_attach (ret); + } + + return ret; + } + + protected: + template + static constexpr void concatenate_strings_into ([[maybe_unused]] size_t len, [[maybe_unused]] char *dest) noexcept + {} + + template + static constexpr void concatenate_strings_into (size_t len, char *dest, const CharType* s1, Strings... strings) noexcept + { + assert_char_type (); + + strcat (dest, s1); + concatenate_strings_into (len, dest, strings...); + } + + static int make_directory (const char *path, [[maybe_unused]] mode_t mode) noexcept + { + return ::mkdir (path, mode); + } + + private: + template + static void package_hash_to_hex (IdxType idx); + + template + static void package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices); + + template + static constexpr void assert_char_type () + { + static_assert (std::is_same_v, "CharType must be an 8-bit character type"); + } + + private: + static char package_property_suffix[9]; + static inline int page_size; + }; +} +#endif // __cplusplus +#endif /* __MONODROID_UTIL_H__ */ diff --git a/src/native/shared/CMakeLists.txt b/src/native/shared/CMakeLists.txt index 54620d837ac..0dcfce8bbe3 100644 --- a/src/native/shared/CMakeLists.txt +++ b/src/native/shared/CMakeLists.txt @@ -8,6 +8,9 @@ set(XA_SHARED_SOURCES new_delete.cc ) +set(XXHASH_DIR "${EXTERNAL_DIR}/xxHash") +set(CONSTEXPR_XXH3_DIR "${EXTERNAL_DIR}/constexpr-xxh3") + add_library( ${LIB_NAME} STATIC @@ -21,6 +24,8 @@ target_include_directories( PUBLIC "$" "$" + "$" + "$" ) target_include_directories( diff --git a/src/native/monodroid/jni/cpp-util.hh b/src/native/shared/cpp-util.hh similarity index 100% rename from src/native/monodroid/jni/cpp-util.hh rename to src/native/shared/cpp-util.hh diff --git a/src/native/monodroid/jni/xxhash.hh b/src/native/shared/xxhash.hh similarity index 100% rename from src/native/monodroid/jni/xxhash.hh rename to src/native/shared/xxhash.hh diff --git a/src/native/xamarin-app-stub/CMakeLists.txt b/src/native/xamarin-app-stub/CMakeLists.txt new file mode 100644 index 00000000000..ff40ebcc227 --- /dev/null +++ b/src/native/xamarin-app-stub/CMakeLists.txt @@ -0,0 +1,47 @@ +set(LIB_NAME xamarin-app) +set(LIB_ALIAS xa::xamarin-app) + +set(XAMARIN_APP_SOURCES + application_dso_stub.cc +) + +add_library( + ${LIB_NAME} + SHARED + ${XAMARIN_APP_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" +) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} +) + +target_link_libraries( + ${LIB_NAME} + PRIVATE + xa::shared +) + +set_target_properties( + ${LIB_NAME} + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/monodroid/jni/application_dso_stub.cc b/src/native/xamarin-app-stub/application_dso_stub.cc similarity index 100% rename from src/native/monodroid/jni/application_dso_stub.cc rename to src/native/xamarin-app-stub/application_dso_stub.cc diff --git a/src/native/monodroid/jni/xamarin-app.hh b/src/native/xamarin-app-stub/xamarin-app.hh similarity index 99% rename from src/native/monodroid/jni/xamarin-app.hh rename to src/native/xamarin-app-stub/xamarin-app.hh index 7d454880faf..09301170515 100644 --- a/src/native/monodroid/jni/xamarin-app.hh +++ b/src/native/xamarin-app-stub/xamarin-app.hh @@ -7,8 +7,8 @@ #include #include +#include -#include "monodroid.h" #include "xxhash.hh" static constexpr uint64_t FORMAT_TAG = 0x00025E6972616D58; // 'Xmari^XY' where XY is the format version From d6ba6244461c3dfa2628058c2155303559a20de3 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 16 Apr 2024 13:19:47 +0200 Subject: [PATCH 10/23] Most libs are built from separate directories now --- src/native/CMakeLists.txt | 5 + src/native/java-interop/CMakeLists.txt | 45 +++++++++ src/native/monodroid/CMakeLists.txt | 11 +-- src/native/monodroid/jni/debug.cc | 23 ----- src/native/monodroid/jni/debug.hh | 13 --- src/native/runtime-base/logger.cc | 98 ++++++++++++------- src/native/runtime-base/logger.hh | 84 ++++++++++------ src/native/runtime-base/util.hh | 2 +- .../xamarin-debug-app-helper/CMakeLists.txt | 52 ++++++++++ .../debug-app-helper.cc | 76 +++++++------- .../debug-app-helper.hh | 0 11 files changed, 264 insertions(+), 145 deletions(-) create mode 100644 src/native/java-interop/CMakeLists.txt create mode 100644 src/native/xamarin-debug-app-helper/CMakeLists.txt rename src/native/{monodroid/jni => xamarin-debug-app-helper}/debug-app-helper.cc (73%) rename src/native/{monodroid/jni => xamarin-debug-app-helper}/debug-app-helper.hh (100%) diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 7a35a5133f8..a001e1e65ef 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -415,5 +415,10 @@ add_link_options("$<$:${COMMON_C_LINKER_ARGS}>") add_subdirectory(libstub) add_subdirectory(libunwind) add_subdirectory(shared) +add_subdirectory(java-interop) add_subdirectory(xamarin-app-stub) add_subdirectory(runtime-base) + +if(DEBUG_BUILD) + add_subdirectory(xamarin-debug-app-helper) +endif() diff --git a/src/native/java-interop/CMakeLists.txt b/src/native/java-interop/CMakeLists.txt new file mode 100644 index 00000000000..e9d59b5bba1 --- /dev/null +++ b/src/native/java-interop/CMakeLists.txt @@ -0,0 +1,45 @@ +set(LIB_NAME xa-java-interop) +set(LIB_ALIAS xa::java-interop) + +set(JAVA_INTEROP_SOURCES + ${JAVA_INTEROP_SRC_PATH}/java-interop-dlfcn.cc + ${JAVA_INTEROP_SRC_PATH}/java-interop-mono.cc + ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc + ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc + ${JAVA_INTEROP_SRC_PATH}/java-interop.cc +) + +add_library( + ${LIB_NAME} + STATIC + ${JAVA_INTEROP_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" +) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} +) + +set_target_properties( + ${LIB_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index 1f312c8bf7e..9ee14eed26a 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -256,11 +256,6 @@ string(TOLOWER ${CMAKE_BUILD_TYPE} XAMARIN_MONO_ANDROID_SUFFIX) set(XAMARIN_MONO_ANDROID_LIB "mono-android${CHECKED_BUILD_INFIX}.${XAMARIN_MONO_ANDROID_SUFFIX}") set(XAMARIN_MONODROID_SOURCES - ${JAVA_INTEROP_SRC_PATH}/java-interop-dlfcn.cc - ${JAVA_INTEROP_SRC_PATH}/java-interop-mono.cc - ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc - ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc - ${JAVA_INTEROP_SRC_PATH}/java-interop.cc ${LZ4_SOURCES} ${XA_SHARED_SOURCES} ${SOURCES_DIR}/cpu-arch-detect.cc @@ -451,5 +446,9 @@ target_link_options( target_link_libraries( ${XAMARIN_MONO_ANDROID_LIB} - ${LINK_LIBS} xa::xamarin-app + ${LINK_LIBS} + xa::xamarin-app + xa::shared + xa::runtime-base + xa::java-interop ) diff --git a/src/native/monodroid/jni/debug.cc b/src/native/monodroid/jni/debug.cc index 33f9c0aaa67..54e4e12a3f8 100644 --- a/src/native/monodroid/jni/debug.cc +++ b/src/native/monodroid/jni/debug.cc @@ -133,29 +133,6 @@ Debug::load_profiler_from_handle (void *dso_handle, const char *desc, const char } #if defined (DEBUG) -void -Debug::set_debugger_log_level (const char *level) -{ - if (level == nullptr || *level == '\0') { - got_debugger_log_level = false; - return; - } - - unsigned long v = strtoul (level, nullptr, 0); - if (v == std::numeric_limits::max () && errno == ERANGE) { - log_error (LOG_DEFAULT, "Invalid debugger log level value '%s', expecting a positive integer or zero", level); - return; - } - - if (v > std::numeric_limits::max ()) { - log_warn (LOG_DEFAULT, "Debugger log level value is higher than the maximum of %u, resetting to the maximum value.", std::numeric_limits::max ()); - v = std::numeric_limits::max (); - } - - got_debugger_log_level = true; - debugger_log_level = static_cast(v); -} - inline void Debug::parse_options (char *options, ConnOptions *opts) { diff --git a/src/native/monodroid/jni/debug.hh b/src/native/monodroid/jni/debug.hh index 4eef337b3f0..e7f992d6aa2 100644 --- a/src/native/monodroid/jni/debug.hh +++ b/src/native/monodroid/jni/debug.hh @@ -43,17 +43,6 @@ namespace xamarin::android public: bool enable_soft_breakpoints (); void start_debugging_and_profiling (); - void set_debugger_log_level (const char *level); - - bool have_debugger_log_level () const - { - return got_debugger_log_level; - } - - int get_debugger_log_level () const - { - return debugger_log_level; - } private: DebuggerConnectionStatus start_connection (char *options); @@ -79,8 +68,6 @@ namespace xamarin::android bool config_timedout; timeval wait_tv; timespec wait_ts; - bool got_debugger_log_level = false; - int debugger_log_level = 0; #endif // def DEBUG }; } diff --git a/src/native/runtime-base/logger.cc b/src/native/runtime-base/logger.cc index db3c4fc47ca..75b7b38711c 100644 --- a/src/native/runtime-base/logger.cc +++ b/src/native/runtime-base/logger.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -10,6 +11,7 @@ #include #include "android-system.hh" +#include "cpp-util.hh" #include "logger.hh" #include "shared-constants.hh" #include "util.hh" @@ -52,46 +54,72 @@ unsigned int log_categories = LOG_NONE; unsigned int log_timing_categories; int gc_spew_enabled; -static FILE* -open_file (LogCategories category, const char *path, const char *override_dir, const char *filename) -{ - char *p = NULL; - FILE *f; +namespace { + FILE* + open_file (LogCategories category, const char *path, const char *override_dir, const char *filename) + { + char *p = NULL; + FILE *f; + + if (path && access (path, W_OK) < 0) { + log_warn (category, "Could not open path '%s' for logging (\"%s\"). Using '%s/%s' instead.", + path, strerror (errno), override_dir, filename); + path = NULL; + } - if (path && access (path, W_OK) < 0) { - log_warn (category, "Could not open path '%s' for logging (\"%s\"). Using '%s/%s' instead.", - path, strerror (errno), override_dir, filename); - path = NULL; - } + if (!path) { + Util::create_public_directory (override_dir); + p = Util::path_combine (override_dir, filename); + path = p; + } - if (!path) { - Util::create_public_directory (override_dir); - p = Util::path_combine (override_dir, filename); - path = p; - } + unlink (path); - unlink (path); + f = Util::monodroid_fopen (path, "a"); - f = Util::monodroid_fopen (path, "a"); + if (f) { + Util::set_world_accessable (path); + } else { + log_warn (category, "Could not open path '%s' for logging: %s", path, strerror (errno)); + } - if (f) { - Util::set_world_accessable (path); - } else { - log_warn (category, "Could not open path '%s' for logging: %s", path, strerror (errno)); + free (p); + + return f; } - free (p); - return f; + const char *gref_file = nullptr; + const char *lref_file = nullptr; + bool light_gref = false; + bool light_lref = false; } -static const char *gref_file = nullptr; -static const char *lref_file = nullptr; -static bool light_gref = false; -static bool light_lref = false; +void +Logger::set_debugger_log_level (const char *level) noexcept +{ + if (level == nullptr || *level == '\0') { + _got_debugger_log_level = false; + return; + } + + unsigned long v = strtoul (level, nullptr, 0); + if (v == std::numeric_limits::max () && errno == ERANGE) { + log_error (LOG_DEFAULT, "Invalid debugger log level value '%s', expecting a positive integer or zero", level); + return; + } + + if (v > std::numeric_limits::max ()) { + log_warn (LOG_DEFAULT, "Debugger log level value is higher than the maximum of %u, resetting to the maximum value.", std::numeric_limits::max ()); + v = std::numeric_limits::max (); + } + + _got_debugger_log_level = true; + _debugger_log_level = static_cast(v); +} void -init_reference_logging (const char *override_dir) +Logger::init_reference_logging (const char *override_dir) noexcept { if ((log_categories & LOG_GREF) != 0 && !light_gref) { gref_log = open_file (LOG_GREF, gref_file, override_dir, "grefs.txt"); @@ -107,8 +135,8 @@ init_reference_logging (const char *override_dir) } } -force_inline static bool -set_category (std::string_view const& name, string_segment& arg, unsigned int entry, bool arg_starts_with_name = false) +force_inline bool +Logger::set_category (std::string_view const& name, string_segment& arg, unsigned int entry, bool arg_starts_with_name) noexcept { if ((log_categories & entry) == entry) { return false; @@ -123,11 +151,11 @@ set_category (std::string_view const& name, string_segment& arg, unsigned int en } void -init_logging_categories (char*& mono_log_mask, char*& mono_log_level) +Logger::init_logging_categories (char*& mono_log_mask, char*& mono_log_level) noexcept { mono_log_mask = nullptr; mono_log_level = nullptr; - log_timing_categories = LOG_TIMING_DEFAULT; + _log_timing_categories = LogTimingCategories::Default; dynamic_local_string value; if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_LOG_PROPERTY, value) == 0) @@ -212,13 +240,13 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) if (param.starts_with ("timing=fast-bare")) { log_categories |= LOG_TIMING; - log_timing_categories |= LOG_TIMING_FAST_BARE; + _log_timing_categories |= LogTimingCategories::FastBare; continue; } if (param.starts_with ("timing=bare")) { log_categories |= LOG_TIMING; - log_timing_categories |= LOG_TIMING_BARE; + _log_timing_categories |= LogTimingCategories::Bare; continue; } @@ -239,7 +267,7 @@ init_logging_categories (char*& mono_log_mask, char*& mono_log_level) if (param.starts_with (DEBUGGER_LOG_LEVEL)) { dynamic_local_string level; level.assign (param.start () + DEBUGGER_LOG_LEVEL.length (), param.length () - DEBUGGER_LOG_LEVEL.length ()); - debug.set_debugger_log_level (level.get ()); + set_debugger_log_level (level.get ()); } #endif } diff --git a/src/native/runtime-base/logger.hh b/src/native/runtime-base/logger.hh index 81951615025..ec01000d040 100644 --- a/src/native/runtime-base/logger.hh +++ b/src/native/runtime-base/logger.hh @@ -1,39 +1,67 @@ #ifndef __MONODROID_LOGGER_H__ #define __MONODROID_LOGGER_H__ +#include + #include "java-interop-logger.h" +#include "strings.hh" -void init_logging_categories (char*& mono_log_mask, char*& mono_log_level); +namespace xamarin::android { + enum class LogTimingCategories : uint32_t + { + Default = 0, + Bare = 1 << 0, + FastBare = 1 << 1, + }; -void init_reference_logging (const char *override_dir); + class Logger + { + public: + static void init_logging_categories (char*& mono_log_mask, char*& mono_log_level) noexcept; + static void init_reference_logging (const char *override_dir) noexcept; -typedef enum _LogTimingCategories { - LOG_TIMING_DEFAULT = 0, - LOG_TIMING_BARE = 1 << 0, - LOG_TIMING_FAST_BARE = 1 << 1, -} LogTimingCategories; +#if defined(DEBUG) + static void set_debugger_log_level (const char *level) noexcept; -extern unsigned int log_timing_categories; + static bool have_debugger_log_level () noexcept + { + return _got_debugger_log_level; + } -#if DEBUG -extern int gc_spew_enabled; -#endif + static int get_debugger_log_level () noexcept + { + return _debugger_log_level; + } +#endif // def DEBUG + + private: + static bool set_category (std::string_view const& name, internal::string_segment& arg, unsigned int entry, bool arg_starts_with_name = false) noexcept; + + private: + static inline LogTimingCategories _log_timing_categories; +#if defined(DEBUG) + static inline bool _got_debugger_log_level = false; + static inline int _debugger_log_level = 0; + static inline int _gc_spew_enabled; +#endif // def DEBUG + }; + + // Keep in sync with LogLevel defined in JNIEnv.cs + enum class LogLevel : unsigned int + { + Unknown = 0x00, + Default = 0x01, + Verbose = 0x02, + Debug = 0x03, + Info = 0x04, + Warn = 0x05, + Error = 0x06, + Fatal = 0x07, + Silent = 0x08 + }; -// Keep in sync with LogLevel defined in JNIEnv.cs -enum class LogLevel : unsigned int -{ - Unknown = 0x00, - Default = 0x01, - Verbose = 0x02, - Debug = 0x03, - Info = 0x04, - Warn = 0x05, - Error = 0x06, - Fatal = 0x07, - Silent = 0x08 -}; - -// A slightly faster alternative to other log functions as it doesn't parse the message -// for format placeholders nor it uses variable arguments -void log_write (LogCategories category, LogLevel level, const char *message) noexcept; + // A slightly faster alternative to other log functions as it doesn't parse the message + // for format placeholders nor it uses variable arguments + void log_write (LogCategories category, LogLevel level, const char *message) noexcept; +} #endif diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 49c230e5bf0..3901e1f2f72 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -397,7 +397,7 @@ namespace xamarin::android } private: - static char package_property_suffix[9]; + static inline std::array package_property_suffix; static inline int page_size; }; } diff --git a/src/native/xamarin-debug-app-helper/CMakeLists.txt b/src/native/xamarin-debug-app-helper/CMakeLists.txt new file mode 100644 index 00000000000..1a831a1d7a8 --- /dev/null +++ b/src/native/xamarin-debug-app-helper/CMakeLists.txt @@ -0,0 +1,52 @@ +set(LIB_NAME xamarin-debug-app-helper) +set(LIB_ALIAS xa::debug-app-helper) + +set(XAMARIN_APP_SOURCES + debug-app-helper.cc +) + +add_library( + ${LIB_NAME} + SHARED + ${XAMARIN_APP_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_compile_definitions( + ${LIB_NAME} + PRIVATE -DDEBUG_APP_HELPER +) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} +) + +target_link_directories( + ${LIB_NAME} + PRIVATE + ${NET_RUNTIME_DIR}/native +) + +target_link_libraries( + ${LIB_NAME} + PRIVATE + xa::shared + xa::xamarin-app + xa::runtime-base + xa::java-interop + -ldl + -llog + -lmonosgen-2.0 +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/monodroid/jni/debug-app-helper.cc b/src/native/xamarin-debug-app-helper/debug-app-helper.cc similarity index 73% rename from src/native/monodroid/jni/debug-app-helper.cc rename to src/native/xamarin-debug-app-helper/debug-app-helper.cc index eb7066b6e62..9bdffa46b76 100644 --- a/src/native/monodroid/jni/debug-app-helper.cc +++ b/src/native/xamarin-debug-app-helper/debug-app-helper.cc @@ -9,8 +9,8 @@ #include -#include "basic-android-system.hh" -#include "basic-utilities.hh" +#include "android-system.hh" +#include "util.hh" #include "debug-app-helper.hh" #include "shared-constants.hh" #include "jni-wrappers.hh" @@ -40,8 +40,6 @@ bool maybe_load_library (const char *path); static constexpr char TAG[] = "debug-app-helper"; unsigned int log_categories = LOG_DEFAULT | LOG_ASSEMBLY; -BasicUtilities utils; -BasicAndroidSystem androidSystem; JNIEXPORT jint JNICALL JNI_OnLoad ([[maybe_unused]] JavaVM *vm, [[maybe_unused]] void *reserved) @@ -56,17 +54,17 @@ Java_mono_android_DebugRuntime_init (JNIEnv *env, [[maybe_unused]] jclass klass, jstring_array_wrapper applicationDirs (env, appDirs); jstring_array_wrapper runtimeApks (env, runtimeApksJava); - androidSystem.detect_embedded_dso_mode (applicationDirs); - androidSystem.set_primary_override_dir (applicationDirs [0]); - androidSystem.set_override_dir (0, androidSystem.get_primary_override_dir ()); - androidSystem.setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks); + AndroidSystem::detect_embedded_dso_mode (applicationDirs); + AndroidSystem::set_primary_override_dir (applicationDirs [0]); + AndroidSystem::set_override_dir (0, AndroidSystem::get_primary_override_dir ()); + AndroidSystem::setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks); jstring_wrapper jstr (env); if (runtimeNativeLibDir != nullptr) { jstr = runtimeNativeLibDir; - androidSystem.set_runtime_libdir (utils.strdup_new (jstr.get_cstr ())); - log_warn (LOG_DEFAULT, "Using runtime path: %s", androidSystem.get_runtime_libdir ()); + AndroidSystem::set_runtime_libdir (Util::strdup_new (jstr.get_cstr ())); + log_warn (LOG_DEFAULT, "Using runtime path: %s", AndroidSystem::get_runtime_libdir ()); } const char *monosgen_path = get_libmonosgen_path (); @@ -80,17 +78,17 @@ Java_mono_android_DebugRuntime_init (JNIEnv *env, [[maybe_unused]] jclass klass, static void copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) { - char *from_file = utils.path_combine (from_dir, file); + char *from_file = Util::path_combine (from_dir, file); char *to_file = nullptr; do { - if (!from_file || !utils.file_exists (from_file)) + if (!from_file || !Util::file_exists (from_file)) break; log_warn (LOG_DEFAULT, "Copying file `%s` from external location `%s` to internal location `%s`", file, from_dir, to_dir); - to_file = utils.path_combine (to_dir, file); + to_file = Util::path_combine (to_dir, file); if (!to_file) break; @@ -100,12 +98,12 @@ copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) break; } - if (!utils.file_copy (to_file, from_file)) { + if (!Util::file_copy (to_file, from_file)) { log_warn (LOG_DEFAULT, "Copy failed from `%s` to `%s`: %s", from_file, to_file, strerror (errno)); break; } - utils.set_user_executable (to_file); + Util::set_user_executable (to_file); } while (0); delete[] from_file; @@ -115,14 +113,14 @@ copy_file_to_internal_location (char *to_dir, char *from_dir, char *file) static void copy_native_libraries_to_internal_location () { - for (const char *od : BasicAndroidSystem::override_dirs) { + for (const char *od : AndroidSystem::override_dirs) { DIR *dir; dirent *e; - char *dir_path = utils.path_combine (od, "lib"); + char *dir_path = Util::path_combine (od, "lib"); log_warn (LOG_DEFAULT, "checking directory: `%s`", dir_path); - if (dir_path == nullptr || !utils.directory_exists (dir_path)) { + if (dir_path == nullptr || !Util::directory_exists (dir_path)) { log_warn (LOG_DEFAULT, "directory does not exist: `%s`", dir_path); delete[] dir_path; continue; @@ -136,8 +134,8 @@ copy_native_libraries_to_internal_location () while ((e = readdir (dir)) != nullptr) { log_warn (LOG_DEFAULT, "checking file: `%s`", e->d_name); - if (utils.monodroid_dirent_hasextension (e, ".so")) { - copy_file_to_internal_location (androidSystem.get_primary_override_dir (), dir_path, e->d_name); + if (Util::monodroid_dirent_hasextension (e, ".so")) { + copy_file_to_internal_location (AndroidSystem::get_primary_override_dir (), dir_path, e->d_name); } } ::closedir (dir); @@ -151,9 +149,9 @@ runtime_exists (const char *dir, char*& libmonoso) if (dir == nullptr || *dir == '\0') return false; - libmonoso = utils.path_combine (dir, SharedConstants::MONO_SGEN_SO); + libmonoso = Util::path_combine (dir, SharedConstants::MONO_SGEN_SO); log_warn (LOG_DEFAULT, "Checking whether Mono runtime exists at: %s", libmonoso); - if (utils.file_exists (libmonoso)) { + if (Util::file_exists (libmonoso)) { log_info (LOG_DEFAULT, "Mono runtime found at: %s", libmonoso); return true; } @@ -173,37 +171,37 @@ get_libmonosgen_path () // storage location before loading it. copy_native_libraries_to_internal_location (); - if (androidSystem.is_embedded_dso_mode_enabled ()) { + if (AndroidSystem::is_embedded_dso_mode_enabled ()) { return SharedConstants::MONO_SGEN_SO.data (); } - for (const char *od : BasicAndroidSystem::override_dirs) { + for (const char *od : AndroidSystem::override_dirs) { if (runtime_exists (od, libmonoso)) { return libmonoso; } } - for (const char *app_lib_dir : BasicAndroidSystem::app_lib_directories) { + for (const char *app_lib_dir : AndroidSystem::app_lib_directories) { if (runtime_exists (app_lib_dir, libmonoso)) { return libmonoso; } } - if (androidSystem.get_runtime_libdir () != nullptr) { - libmonoso = utils.path_combine (androidSystem.get_runtime_libdir (), SharedConstants::MONO_SGEN_ARCH_SO); + if (AndroidSystem::get_runtime_libdir () != nullptr) { + libmonoso = Util::path_combine (AndroidSystem::get_runtime_libdir (), SharedConstants::MONO_SGEN_ARCH_SO); } else libmonoso = nullptr; - if (libmonoso != nullptr && utils.file_exists (libmonoso)) { - char* links_dir = utils.path_combine (androidSystem.get_primary_override_dir (), "links"); - char* link = utils.path_combine (links_dir, SharedConstants::MONO_SGEN_SO); - if (!utils.directory_exists (links_dir)) { - if (!utils.directory_exists (androidSystem.get_primary_override_dir ())) - utils.create_public_directory (androidSystem.get_primary_override_dir ()); - utils.create_public_directory (links_dir); + if (libmonoso != nullptr && Util::file_exists (libmonoso)) { + char* links_dir = Util::path_combine (AndroidSystem::get_primary_override_dir (), "links"); + char* link = Util::path_combine (links_dir, SharedConstants::MONO_SGEN_SO); + if (!Util::directory_exists (links_dir)) { + if (!Util::directory_exists (AndroidSystem::get_primary_override_dir ())) + Util::create_public_directory (AndroidSystem::get_primary_override_dir ()); + Util::create_public_directory (links_dir); } delete[] links_dir; - if (!utils.file_exists (link)) { + if (!Util::file_exists (link)) { int result = symlink (libmonoso, link); if (result != 0 && errno == EEXIST) { log_warn (LOG_DEFAULT, "symlink exists, recreating: %s -> %s", link, libmonoso); @@ -218,21 +216,21 @@ get_libmonosgen_path () } log_warn (LOG_DEFAULT, "Trying to load sgen from: %s", libmonoso != nullptr ? libmonoso : ""); - if (libmonoso != nullptr && utils.file_exists (libmonoso)) + if (libmonoso != nullptr && Util::file_exists (libmonoso)) return libmonoso; delete[] libmonoso; - if (runtime_exists (BasicAndroidSystem::SYSTEM_LIB_PATH.data (), libmonoso)) + if (runtime_exists (AndroidSystem::SYSTEM_LIB_PATH.data (), libmonoso)) return libmonoso; log_fatal (LOG_DEFAULT, "Cannot find '%s'. Looked in the following locations:", SharedConstants::MONO_SGEN_SO); - for (const char *od : BasicAndroidSystem::override_dirs) { + for (const char *od : AndroidSystem::override_dirs) { if (od == nullptr) continue; log_fatal (LOG_DEFAULT, " %s", od); } - for (const char *app_lib_dir : BasicAndroidSystem::app_lib_directories) { + for (const char *app_lib_dir : AndroidSystem::app_lib_directories) { log_fatal (LOG_DEFAULT, " %s", app_lib_dir); } diff --git a/src/native/monodroid/jni/debug-app-helper.hh b/src/native/xamarin-debug-app-helper/debug-app-helper.hh similarity index 100% rename from src/native/monodroid/jni/debug-app-helper.hh rename to src/native/xamarin-debug-app-helper/debug-app-helper.hh From ccfe36ebe6a51e82866b9dd4b1ffa139bd7207bf Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 16 Apr 2024 17:24:03 +0200 Subject: [PATCH 11/23] All libraries are built in their own directories --- src/native/CMakeLists.txt | 14 +- src/native/libunwind/CMakeLists.txt | 17 +- src/native/lz4/CMakeLists.txt | 39 ++ src/native/monodroid/CMakeLists.txt | 391 +++--------------- src/native/monodroid/jni/debug-constants.cc | 4 +- src/native/monodroid/jni/debug.cc | 40 +- .../monodroid/jni/embedded-assemblies-zip.cc | 25 +- .../monodroid/jni/embedded-assemblies.cc | 22 +- src/native/monodroid/jni/globals.hh | 2 - src/native/monodroid/jni/monodroid-glue.cc | 138 +++---- .../monodroid/jni/monodroid-networkinfo.cc | 4 +- src/native/monodroid/jni/osbridge.cc | 23 +- .../monodroid/jni/pinvoke-override-api.cc | 26 +- src/native/monodroid/jni/timezones.cc | 2 +- src/native/monodroid/jni/timing-internal.hh | 11 +- src/native/monodroid/jni/timing.cc | 3 + .../monodroid/jni/xamarin_getifaddrs.cc | 13 +- src/native/runtime-base/logger.cc | 30 +- src/native/runtime-base/logger.hh | 19 +- src/native/runtime-base/util.hh | 4 +- src/native/shared/CMakeLists.txt | 70 ++-- .../{monodroid/jni => shared}/cppcompat.hh | 0 src/native/tracing/CMakeLists.txt | 71 ++++ src/native/tracing/native-tracing.hh | 2 + src/native/xamarin-app-stub/CMakeLists.txt | 6 + .../xamarin-debug-app-helper/CMakeLists.txt | 6 + 26 files changed, 447 insertions(+), 535 deletions(-) create mode 100644 src/native/lz4/CMakeLists.txt rename src/native/{monodroid/jni => shared}/cppcompat.hh (100%) create mode 100644 src/native/tracing/CMakeLists.txt diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index a001e1e65ef..aa890661804 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -25,6 +25,7 @@ endmacro() ensure_variable_set(ANDROID_ABI) ensure_variable_set(CMAKE_ANDROID_NDK) +ensure_variable_set(CMAKE_BUILD_TYPE) ensure_variable_set(OUTPUT_PATH) ensure_variable_set(XA_BUILD_CONFIGURATION) ensure_variable_set(XA_LIB_TOP_DIR) @@ -371,6 +372,11 @@ if (ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) ) endif() +set(POTENTIAL_XA_DSO_LINKER_ARGS + -fpic + -fstack-clash-protection +) + unset(SANITIZER_FLAGS) if (ENABLE_CLANG_ASAN) set(SANITIZER_FLAGS -fsanitize=address) @@ -405,6 +411,8 @@ xa_check_cxx_args(XA_COMMON_CXX_ARGS "${POTENTIAL_XA_COMMON_COMPILER_ARGS}") xa_check_c_args(XA_COMMON_C_ARGS "${POTENTIAL_XA_COMMON_COMPILER_ARGS}") xa_check_cxx_linker_args(XA_COMMON_CXX_LINKER_ARGS "${POTENTIAL_XA_COMMON_LINKER_ARGS}") xa_check_c_linker_args(XA_COMMON_C_LINKER_ARGS "${POTENTIAL_XA_COMMON_LINKER_ARGS}") +xa_check_c_linker_args(XA_C_DSO_LINKER_ARGS "${POTENTIAL_XA_DSO_LINKER_ARGS}") +xa_check_cxx_linker_args(XA_CXX_DSO_LINKER_ARGS "${POTENTIAL_XA_DSO_LINKER_ARGS}") add_compile_options("$<$:${COMMON_CXX_ARGS}>") add_compile_options("$<$:${COMMON_C_ARGS}>") @@ -412,13 +420,17 @@ add_compile_options("$<$:${COMMON_C_ARGS}>") add_link_options("$<$:${COMMON_CXX_LINKER_ARGS}>") add_link_options("$<$:${COMMON_C_LINKER_ARGS}>") -add_subdirectory(libstub) add_subdirectory(libunwind) +add_subdirectory(lz4) +add_subdirectory(libstub) add_subdirectory(shared) add_subdirectory(java-interop) add_subdirectory(xamarin-app-stub) add_subdirectory(runtime-base) +add_subdirectory(tracing) if(DEBUG_BUILD) add_subdirectory(xamarin-debug-app-helper) endif() + +add_subdirectory(monodroid) diff --git a/src/native/libunwind/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt index cfdb3408d9c..68005783341 100644 --- a/src/native/libunwind/CMakeLists.txt +++ b/src/native/libunwind/CMakeLists.txt @@ -323,13 +323,22 @@ add_library( add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) +list(APPEND LIBUNWIND_INCLUDE_DIRS + ${LIBUNWIND_SOURCE_DIR}/include/tdep + ${LIBUNWIND_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include/tdep + ${CMAKE_CURRENT_BINARY_DIR}/include +) +set(LIBUNWIND_INCLUDE_DIRS "${LIBUNWIND_INCLUDE_DIRS}" PARENT_SCOPE) + target_include_directories( ${LIB_NAME} PUBLIC - "$" - "$" - "$" - "$" + "$" + # "$" + # "$" + # "$" + # "$" ) if(TARGET_ARM) diff --git a/src/native/lz4/CMakeLists.txt b/src/native/lz4/CMakeLists.txt new file mode 100644 index 00000000000..fccd31776c8 --- /dev/null +++ b/src/native/lz4/CMakeLists.txt @@ -0,0 +1,39 @@ +set(LIB_NAME xa-lz4) +set(LIB_ALIAS xa::lz4) + +set(LZ4_SRC_DIR "${EXTERNAL_DIR}/lz4/lib") +set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR}) + +set(LZ4_SOURCES + ${LZ4_SRC_DIR}/lz4.c +) + +add_library( + ${LIB_NAME} + STATIC + ${LZ4_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_compile_definitions( + ${LIB_NAME} + PRIVATE + # Ugly, but this is the only way to change LZ4 symbols visibility without modifying lz4.h + "LZ4LIB_VISIBILITY=__attribute__ ((visibility (\"hidden\")))" + XXH_NAMESPACE=LZ4_ +) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" +) + +set_target_properties( + ${LIB_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index 9ee14eed26a..852c8488bd0 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -1,51 +1,5 @@ -cmake_minimum_required(VERSION 3.19) - -# -# MUST be included before project()! -# -include("../../build-tools/cmake/xa_preamble.cmake") - -project( - monodroid - VERSION ${XA_VERSION} - DESCRIPTION "Xamarin.Android native runtime" - HOMEPAGE_URL "https://github.com/xamarin/xamarin-android" - LANGUAGES CXX C -) - -# -# MUST be included after project()! -# -include("../../build-tools/cmake/xa_common.cmake") - option(ENABLE_TIMING "Build with timing support" OFF) -# Environment checks - -if(NOT DEFINED CONFIGURATION) - message(FATAL_ERROR "Please set the CONFIGURATION variable on command line (-DCONFIGURATION=name)") -endif() - -if(NOT DEFINED CMAKE_BUILD_TYPE) - message(FATAL_ERROR "Please set the CMAKE_BUILD_TYPE variable on command line (-DCMAKE_BUILD_TYPE=name)") -endif() - -if(NOT DEFINED XA_BUILD_CONFIGURATION) - message(FATAL_ERROR "Please set the XA_BUILD_CONFIGURATION variable on command line (-DXA_BUILD_CONFIGURATION=name)") -endif() - -if(NOT DEFINED XA_LIB_TOP_DIR) - message(FATAL_ERROR "Please set the XA_LIB_TOP_DIR variable on command line (-DXA_LIB_TOP_DIR=path)") -endif() - -if(NOT DEFINED LIBUNWIND_SOURCE_DIR) - message(FATAL_ERROR "Please set the LIBUNWIND_SOURCE_DIR on command line (-DLIBUNWIND_SOURCE_DIR=path)") -endif() - -if(NOT DEFINED LIBUNWIND_HEADERS_DIR) - message(FATAL_ERROR "Please set the LIBUNWIND_HEADERS_DIR on command line (-DLIBUNWIND_HEADERS_DIR=path)") -endif() - # Needed modules include(CheckIncludeFile) @@ -53,168 +7,10 @@ include(CheckCXXSymbolExists) # Paths -set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/jni) +set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/monodroid/jni) set(BIONIC_SOURCES_DIR "${REPO_ROOT_DIR}/src-ThirdParty/bionic") -set(LZ4_SRC_DIR "${EXTERNAL_DIR}/lz4/lib") -set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR}) set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map") -set(LZ4_SOURCES - "${LZ4_SRC_DIR}/lz4.c" - ) - -# Include directories -include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include) -include_directories(${EXTERNAL_DIR}) - -# The SYSTEM which will make clang skip warnings for the headers there. Since we can't do -# much about them, we can just as well avoid cluttered build output. -include_directories(SYSTEM ${CONSTEXPR_XXH3_DIR}) -include_directories(SYSTEM ${ROBIN_MAP_DIR}/include) -include_directories(SYSTEM ${LZ4_INCLUDE_DIR}) -include_directories("jni") - - -# Compiler defines - -add_compile_definitions(TSL_NO_EXCEPTIONS) -add_compile_definitions(HAVE_CONFIG_H) -add_compile_definitions(JI_DLL_EXPORT) -add_compile_definitions(MONO_DLL_EXPORT) -add_compile_definitions(NET) -add_compile_definitions(JI_NO_VISIBILITY) - -if(DONT_INLINE) - add_compile_definitions(NO_INLINE) -endif() - -if(DEBUG_BUILD AND NOT DISABLE_DEBUG) - add_compile_definitions(DEBUG) -endif() - -if (ENABLE_TIMING) - add_compile_definitions(MONODROID_TIMING) -endif() - -add_compile_definitions(HAVE_LZ4) - -# Compiler and linker flags -set(LINK_LIBS - -lmonosgen-2.0 - -llog -) - -# -# -Wformat-nonliteral is disabled as it's not very practical, because we use proxy functions to -# pass formats to the final Android logger functions. The Android functions have attributes that -# cause warnings similar to: -# -# warning G4FD2E6FD: format string is not a string literal [-Wformat-nonliteral] -# -# The warning is, in general, a good practice because the compiler can verify the printf format -# at compile time, but in our case it's not very useful. -# -set(LOCAL_COMMON_COMPILER_ARGS - -Wall - -Wconversion - -Wdeprecated - -Wduplicated-branches - -Wduplicated-cond - -Werror=format-security - -Werror=return-type - -Wextra - -Wformat-security - -Wformat=2 - -Wno-format-nonliteral - -Wimplicit-fallthrough - -Wmisleading-indentation - -Wnull-dereference - -Wpointer-arith - -Wshadow - -Wsign-compare - -Wtrampolines - -Wuninitialized - -fstrict-flex-arrays=3 - ) - -# Add some options to increase security. They may mildly affect performance but they won't be big, because the features are -# assisted by the hardware. -if((CMAKE_ANDROID_ARCH_ABI STREQUAL "x86") OR (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")) - # -fcf-protection=full: Enable control flow protection to counter Return Oriented Programming (ROP) and Jump Oriented Programming (JOP) attacks on many x86 architectures - list(APPEND LOCAL_COMMON_COMPILER_ARGS - -fcf-protection=full - ) -endif() - -if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") - # -mbranch-protection=standard: Enable branch protection to counter Return Oriented Programming (ROP) and Jump Oriented Programming (JOP) attacks on AArch64 - # In clang -mbranch-protection=standard is equivalent to -mbranch-protection=bti+pac-ret and invokes the AArch64 Branch Target Identification (BTI) and Pointer Authentication using key A (pac-ret) - list(APPEND LOCAL_COMMON_COMPILER_ARGS - -mbranch-protection=standard - ) -endif() - -if(COMPILER_DIAG_COLOR) - list(APPEND LOCAL_COMMON_COMPILER_ARGS - -fdiagnostics-color=always - -fcolor-diagnostics - ) -endif() - -set(LOCAL_COMMON_LINKER_ARGS - -shared - -fpic - -fstack-clash-protection -) - -if (ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) - list(APPEND LOCAL_COMMON_COMPILER_ARGS - -fno-omit-frame-pointer - -fno-optimize-sibling-calls - ) -endif() - -unset(SANITIZER_FLAGS) -if (ENABLE_CLANG_ASAN) - set(SANITIZER_FLAGS -fsanitize=address) - set(CHECKED_BUILD_INFIX "-checked+asan") -elseif(ENABLE_CLANG_UBSAN) - set(SANITIZER_FLAGS -fsanitize=undefined) - set(CHECKED_BUILD_INFIX "-checked+ubsan") -endif() - -if(SANITIZER_FLAGS) - message(STATUS "Got sanitizer: ${SANITIZER_FLAGS}") - - list(APPEND LOCAL_COMMON_COMPILER_ARGS ${SANITIZER_FLAGS}) - list(APPEND LOCAL_COMMON_LINKER_ARGS ${SANITIZER_FLAGS}) - list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${SANITIZER_FLAGS}) -endif() - -if(STRIP_DEBUG) - list(APPEND LOCAL_COMMON_LINKER_ARGS LINKER:-S) -else() - # When not stripping symbols, we likely want to have precise stack traces, so - # we won't omit frame pointers - list(APPEND LOCAL_COMMON_COMPILER_ARGS - -fno-omit-frame-pointer - -fno-limit-debug-info - ) -endif() - -# Parameters to both functions are (all required): -# -# -# -xa_check_compiler_flags(XA_CXX_FLAGS XA_C_FLAGS "${LOCAL_COMMON_COMPILER_ARGS}" "${LOCAL_COMMON_COMPILER_ARGS}") -xa_check_linker_flags(XA_CXX_LINKER_FLAGS XA_C_LINKER_FLAGS "${LOCAL_COMMON_LINKER_ARGS}" "${LOCAL_COMMON_LINKER_ARGS}") - -add_compile_options("$<$:${XA_CXX_FLAGS}>") -add_compile_options("$<$:${XA_C_FLAGS}>") - -add_link_options("$<$:${XA_CXX_LINKER_FLAGS}>") -add_link_options("$<$:${XA_C_LINKER_FLAGS}>") - if(DEBUG_BUILD) # Convince NDK to really optimize our Debug builds. Without this, NDK's cmake toolchain definition # will force a -O0 on us and our "debug" build is not really for debugging of our native code but @@ -227,7 +23,6 @@ endif() # Library directories set(XA_LIBRARY_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/lib/${ANDROID_RID}") set(XA_LIBRARY_STUBS_OUTPUT_DIRECTORY "${XA_LIB_TOP_DIR}/libstubs/${ANDROID_RID}") -link_directories("${NET_RUNTIME_DIR}/native") # Header checks @@ -246,26 +41,16 @@ if(ENABLE_CLANG_UBSAN OR ENABLE_CLANG_ASAN) endif() # Sources - -set(XAMARIN_INTERNAL_API_LIB xa-internal-api${CHECKED_BUILD_INFIX}) -set(XAMARIN_DEBUG_APP_HELPER_LIB xamarin-debug-app-helper${CHECKED_BUILD_INFIX}) -set(XAMARIN_APP_STUB_LIB xamarin-app) -set(XAMARIN_NATIVE_TRACING_LIB xamarin-native-tracing) - string(TOLOWER ${CMAKE_BUILD_TYPE} XAMARIN_MONO_ANDROID_SUFFIX) set(XAMARIN_MONO_ANDROID_LIB "mono-android${CHECKED_BUILD_INFIX}.${XAMARIN_MONO_ANDROID_SUFFIX}") set(XAMARIN_MONODROID_SOURCES - ${LZ4_SOURCES} - ${XA_SHARED_SOURCES} - ${SOURCES_DIR}/cpu-arch-detect.cc ${SOURCES_DIR}/debug-constants.cc ${SOURCES_DIR}/debug.cc ${SOURCES_DIR}/embedded-assemblies-zip.cc ${SOURCES_DIR}/embedded-assemblies.cc ${SOURCES_DIR}/globals.cc ${SOURCES_DIR}/jni-remapping.cc - ${SOURCES_DIR}/logger.cc ${SOURCES_DIR}/mono-log-adapter.cc ${SOURCES_DIR}/monodroid-glue.cc ${SOURCES_DIR}/monodroid-networkinfo.cc @@ -274,7 +59,7 @@ set(XAMARIN_MONODROID_SOURCES ${SOURCES_DIR}/osbridge.cc ${SOURCES_DIR}/pinvoke-override-api.cc ${SOURCES_DIR}/runtime-util.cc - ${SOURCES_DIR}/shared-constants.cc + ${SOURCES_DIR}/timing.cc ${SOURCES_DIR}/timezones.cc ${SOURCES_DIR}/timing-internal.cc ${SOURCES_DIR}/xamarin_getifaddrs.cc @@ -289,159 +74,88 @@ endif() if(NOT USES_LIBSTDCPP) list(APPEND XAMARIN_MONODROID_SOURCES ${BIONIC_SOURCES_DIR}/cxa_guard.cc - ${SHARED_SOURCES_DIR}/cxx-abi/string.cc - ${SHARED_SOURCES_DIR}/cxx-abi/terminate.cc ) endif() -set(NATIVE_TRACING_SOURCES - ${SHARED_SOURCES_DIR}/cxx-abi/string.cc -# ${SHARED_SOURCES_DIR}/cxx-abi/terminate.cc - ${TRACING_SOURCES_DIR}/native-tracing.cc - ${XA_SHARED_SOURCES} -) - -set(XAMARIN_APP_STUB_SOURCES - ${SOURCES_DIR}/application_dso_stub.cc - ) - -set(XAMARIN_DEBUG_APP_HELPER_SOURCES - ${SOURCES_DIR}/basic-android-system.cc - ${SOURCES_DIR}/basic-utilities.cc - ${SOURCES_DIR}/cpu-arch-detect.cc - ${SOURCES_DIR}/debug-app-helper.cc - ${SOURCES_DIR}/shared-constants.cc - ${XA_SHARED_SOURCES} - ) - -set(XAMARIN_STUB_LIB_SOURCES - libstub/stub.cc -) - # Build configure_file(jni/host-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/host-config.h) -add_library( - ${XAMARIN_APP_STUB_LIB} - SHARED - ${XAMARIN_APP_STUB_SOURCES} -) - -target_link_options( - ${XAMARIN_APP_STUB_LIB} - PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} -) - -set_target_properties( - ${XAMARIN_APP_STUB_LIB} - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${XA_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}" -) - -if(DEBUG_BUILD) - add_library( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - SHARED - ${XAMARIN_DEBUG_APP_HELPER_SOURCES} - ) - - target_link_options( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - PRIVATE ${XA_SYMBOL_VISIBILITY} - ) - - target_link_libraries( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - -ldl - ) - - target_link_libraries( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - -llog - ) - - target_compile_options( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - PRIVATE ${XA_SYMBOL_VISIBILITY} - ) - - target_compile_definitions( - ${XAMARIN_DEBUG_APP_HELPER_LIB} - PUBLIC -DDEBUG_APP_HELPER - ) -endif() - add_library( ${XAMARIN_MONO_ANDROID_LIB} SHARED ${XAMARIN_MONODROID_SOURCES} ) -if(NOT DEBUG_BUILD) - set(CPP_ABI_PATH ${CMAKE_SYSROOT}/usr/lib/${SYSROOT_ABI_LIB_DIR}/${TOOLCHAIN_TRIPLE}/libc++abi.a) - - add_library( - ${XAMARIN_NATIVE_TRACING_LIB} - SHARED ${NATIVE_TRACING_SOURCES} - ) - - target_include_directories( - ${XAMARIN_NATIVE_TRACING_LIB} BEFORE - PRIVATE - ${LIBUNWIND_SOURCE_DIR}/include - ${LIBUNWIND_HEADERS_DIR}/${CMAKE_ANDROID_ARCH_ABI} - ${NDK_CXX_LIBCPPABI_SOURCE_PATH}/include - ) +target_compile_definitions( + ${XAMARIN_MONO_ANDROID_LIB} + PRIVATE + HAVE_CONFIG_H + HAVE_LZ4 + JI_DLL_EXPORT + JI_NO_VISIBILITY + MONO_DLL_EXPORT + NET + TSL_NO_EXCEPTIONS +) - target_compile_options( - ${XAMARIN_NATIVE_TRACING_LIB} +if(DONT_INLINE) + target_compile_definitions( + ${XAMARIN_MONO_ANDROID_LIB} PRIVATE - # Avoid the 'warning: dynamic exception specifications are deprecated' warning from libc++ headers - -Wno-deprecated-dynamic-exception-spec - ${XA_DEFAULT_SYMBOL_VISIBILITY} - # Prevent genration of the .eh_frame section (we don't use exceptions and don't need it) - -fno-asynchronous-unwind-tables - ) - - target_link_options( - ${XAMARIN_NATIVE_TRACING_LIB} - PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} + NO_INLINE ) +endif() - target_link_libraries( - ${XAMARIN_NATIVE_TRACING_LIB} +if(DEBUG_BUILD AND NOT DISABLE_DEBUG) + target_compile_definitions( + ${XAMARIN_MONO_ANDROID_LIB} PRIVATE - -llog - ${CPP_ABI_PATH} - ${XA_LIBRARY_OUTPUT_DIRECTORY}/libunwind_xamarin.a + DEBUG ) +endif() +if (ENABLE_TIMING) target_compile_definitions( - ${XAMARIN_NATIVE_TRACING_LIB} + ${XAMARIN_MONO_ANDROID_LIB} PRIVATE - XAMARIN_TRACING + MONODROID_TIMING ) endif() -# Ugly, but this is the only way to change LZ4 symbols visibility without modifying lz4.h -set(LZ4_VISIBILITY_OPTS "-DLZ4LIB_VISIBILITY=__attribute__ ((visibility (\"hidden\")))") - target_compile_options( ${XAMARIN_MONO_ANDROID_LIB} - PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} "${LZ4_VISIBILITY_OPTS}" - ) + PRIVATE + ${XA_DEFAULT_SYMBOL_VISIBILITY} +) target_include_directories( ${XAMARIN_MONO_ANDROID_LIB} BEFORE PRIVATE - ${LIBUNWIND_SOURCE_DIR}/include - ${LIBUNWIND_HEADERS_DIR}/${CMAKE_ANDROID_ARCH_ABI} + ${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include + ${EXTERNAL_DIR} + ${ROBIN_MAP_DIR}/include + jni +) + +target_include_directories( + ${XAMARIN_MONO_ANDROID_LIB} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} + ${NATIVE_TRACING_INCLUDE_DIR} + ${LIBUNWIND_INCLUDE_DIRS} ) -set(DEBUG_HELPER_LINK_LIBS "-ldl") +target_link_directories( + ${XAMARIN_MONO_ANDROID_LIB} + PRIVATE + ${NET_RUNTIME_DIR}/native +) target_link_options( ${XAMARIN_MONO_ANDROID_LIB} - PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} + PRIVATE + ${XA_DEFAULT_SYMBOL_VISIBILITY} + ${XA_CXX_DSO_LINKER_ARGS} ) target_link_libraries( @@ -451,4 +165,9 @@ target_link_libraries( xa::shared xa::runtime-base xa::java-interop + xa::lz4 + -lmonosgen-2.0 + -llog ) + +xa_add_compile_definitions(${XAMARIN_MONO_ANDROID_LIB}) diff --git a/src/native/monodroid/jni/debug-constants.cc b/src/native/monodroid/jni/debug-constants.cc index 82fa9f30008..cf30e8a3621 100644 --- a/src/native/monodroid/jni/debug-constants.cc +++ b/src/native/monodroid/jni/debug-constants.cc @@ -1,8 +1,10 @@ #include "debug.hh" +#include "shared-constants.hh" using namespace xamarin::android; +using namespace xamarin::android::internal; extern "C" const char *__get_debug_mono_log_property (void) { - return static_cast (Debug::DEBUG_MONO_LOG_PROPERTY.data ()); + return static_cast (SharedConstants::DEBUG_MONO_LOG_PROPERTY.data ()); } diff --git a/src/native/monodroid/jni/debug.cc b/src/native/monodroid/jni/debug.cc index 54e4e12a3f8..b422feacd82 100644 --- a/src/native/monodroid/jni/debug.cc +++ b/src/native/monodroid/jni/debug.cc @@ -74,24 +74,24 @@ Debug::monodroid_profiler_load (const char *libmono_path, const char *desc, cons strncpy (mname_ptr, desc, name_len); mname_ptr [name_len] = 0; } else { - mname_ptr = utils.strdup_new (desc); + mname_ptr = Util::strdup_new (desc); } std::unique_ptr mname {mname_ptr}; unsigned int dlopen_flags = JAVA_INTEROP_LIB_LOAD_LOCALLY; - std::unique_ptr libname {utils.string_concat ("libmono-profiler-", mname.get (), ".so")}; + std::unique_ptr libname {Util::string_concat ("libmono-profiler-", mname.get (), ".so")}; bool found = false; - void *handle = androidSystem.load_dso_from_any_directories (libname.get (), dlopen_flags); + void *handle = AndroidSystem::load_dso_from_any_directories (libname.get (), dlopen_flags); found = load_profiler_from_handle (handle, desc, mname.get ()); if (!found && libmono_path != nullptr) { - std::unique_ptr full_path {utils.path_combine (libmono_path, libname.get ())}; - handle = androidSystem.load_dso (full_path.get (), dlopen_flags, FALSE); + std::unique_ptr full_path {Util::path_combine (libmono_path, libname.get ())}; + handle = AndroidSystem::load_dso (full_path.get (), dlopen_flags, FALSE); found = load_profiler_from_handle (handle, desc, mname.get ()); } if (found && logfile != nullptr) - utils.set_world_accessable (logfile); + Util::set_world_accessable (logfile); if (!found) log_warn (LOG_DEFAULT, @@ -123,7 +123,7 @@ Debug::load_profiler_from_handle (void *dso_handle, const char *desc, const char if (!dso_handle) return false; - std::unique_ptr symbol {utils.string_concat (INITIALIZER_NAME.data (), "_", name)}; + std::unique_ptr symbol {Util::string_concat (INITIALIZER_NAME.data (), "_", name)}; bool result = load_profiler (dso_handle, desc, symbol.get ()); if (result) @@ -140,7 +140,7 @@ Debug::parse_options (char *options, ConnOptions *opts) log_info (LOG_DEFAULT, "Connection options: '%s'", options); - args = utils.monodroid_strsplit (options, ",", 0); + args = Util::monodroid_strsplit (options, ",", 0); for (ptr = args; ptr && *ptr; ptr++) { const char *arg = *ptr; @@ -213,7 +213,7 @@ Debug::start_debugging_and_profiling () } char *connect_args = nullptr; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_CONNECT_PROPERTY, &connect_args) > 0) { + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_CONNECT_PROPERTY, &connect_args) > 0) { DebuggerConnectionStatus res = start_connection (connect_args); if (res == DebuggerConnectionStatus::Error) { log_fatal (LOG_DEBUGGER, "Could not start a connection to the debugger with connection args '%s'.", connect_args); @@ -250,7 +250,7 @@ Debug::process_connection (int fd) char command [257]; uint8_t cmd_len; - ssize_t rv = utils.recv_uninterrupted (fd, &cmd_len, sizeof(cmd_len)); + ssize_t rv = Util::recv_uninterrupted (fd, &cmd_len, sizeof(cmd_len)); if (rv == 0) { log_info (LOG_DEFAULT, "EOF on socket.\n"); return false; @@ -260,7 +260,7 @@ Debug::process_connection (int fd) return false; } - rv = utils.recv_uninterrupted (fd, command, cmd_len); + rv = Util::recv_uninterrupted (fd, command, cmd_len); if (rv <= 0) { log_info (LOG_DEFAULT, "Error while receiving command from XS (%s)\n", strerror (errno)); return false; @@ -287,7 +287,7 @@ Debug::handle_server_connection (void) int flags = 1; int rv = setsockopt (listen_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof (flags)); - if (rv == -1 && utils.should_log (LOG_DEFAULT)) { + if (rv == -1 && Util::should_log (LOG_DEFAULT)) { log_info_nocheck (LOG_DEFAULT, "Could not set SO_REUSEADDR on the listening socket (%s)", strerror (errno)); // not a fatal failure } @@ -434,7 +434,7 @@ Debug::process_cmd (int fd, char *cmd) constexpr std::string_view PING_CMD { "ping" }; constexpr std::string_view PONG_REPLY { "pong" }; if (strcmp (cmd, PING_CMD.data ()) == 0) { - if (!utils.send_uninterrupted (fd, const_cast (reinterpret_cast (PONG_REPLY.data ())), 5)) + if (!Util::send_uninterrupted (fd, const_cast (reinterpret_cast (PONG_REPLY.data ())), 5)) log_error (LOG_DEFAULT, "Got keepalive request from XS, but could not send response back (%s)\n", strerror (errno)); return false; } @@ -479,7 +479,7 @@ Debug::process_cmd (int fd, char *cmd) } else if (strncmp (prof, PROFILER_LOG.data (), PROFILER_LOG.length ()) == 0) { use_fd = true; profiler_fd = fd; - profiler_description = utils.monodroid_strdup_printf ("%s,output=#%i", prof, profiler_fd); + profiler_description = Util::monodroid_strdup_printf ("%s,output=#%i", prof, profiler_fd); } else { log_error (LOG_DEFAULT, "Unknown profiler: '%s'", prof); } @@ -512,7 +512,7 @@ Debug::start_debugging (void) embeddedAssemblies.set_register_debug_symbols (true); - char *debug_arg = utils.monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); + char *debug_arg = Util::monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); std::array debug_options = { debug_arg, nullptr @@ -548,7 +548,7 @@ Debug::start_profiling () return; log_info (LOG_DEFAULT, "Loading profiler: '%s'", profiler_description); - monodroid_profiler_load (androidSystem.get_runtime_libdir (), profiler_description, nullptr); + monodroid_profiler_load (AndroidSystem::get_runtime_libdir (), profiler_description, nullptr); } static const char *soft_breakpoint_kernel_list[] = { @@ -574,18 +574,18 @@ Debug::enable_soft_breakpoints (void) char *value; /* Soft breakpoints are enabled by default */ - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_SOFT_BREAKPOINTS, &value) <= 0) { - log_info (LOG_DEBUGGER, "soft breakpoints enabled by default (%s property not defined)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data ()); + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_SOFT_BREAKPOINTS, &value) <= 0) { + log_info (LOG_DEBUGGER, "soft breakpoints enabled by default (%s property not defined)", SharedConstants::DEBUG_MONO_SOFT_BREAKPOINTS.data ()); return 1; } bool ret; if (strcmp ("0", value) == 0) { ret = false; - log_info (LOG_DEBUGGER, "soft breakpoints disabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); + log_info (LOG_DEBUGGER, "soft breakpoints disabled (%s property set to %s)", SharedConstants::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); } else { ret = true; - log_info (LOG_DEBUGGER, "soft breakpoints enabled (%s property set to %s)", Debug::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); + log_info (LOG_DEBUGGER, "soft breakpoints enabled (%s property set to %s)", SharedConstants::DEBUG_MONO_SOFT_BREAKPOINTS.data (), value); } delete[] value; return ret; diff --git a/src/native/monodroid/jni/embedded-assemblies-zip.cc b/src/native/monodroid/jni/embedded-assemblies-zip.cc index b2631fe8b19..d8cf63b31fa 100644 --- a/src/native/monodroid/jni/embedded-assemblies-zip.cc +++ b/src/native/monodroid/jni/embedded-assemblies-zip.cc @@ -8,6 +8,7 @@ #include "embedded-assemblies.hh" #include "globals.hh" +#include "strings.hh" #include "xamarin-app.hh" #include "xxhash.hh" @@ -51,7 +52,7 @@ EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vector const& entry_name, ZipEntryLoadState const& state, [[maybe_unused]] monodroid_should_register should_register) noexcept { #if defined (DEBUG) - const char *last_slash = utils.find_last (entry_name, '/'); + const char *last_slash = Util::find_last (entry_name, '/'); bool entry_is_overridden = last_slash == nullptr ? false : !should_register (last_slash + 1); #else constexpr bool entry_is_overridden = false; #endif - if (register_debug_symbols && !entry_is_overridden && utils.ends_with (entry_name, SharedConstants::PDB_EXTENSION)) { + if (register_debug_symbols && !entry_is_overridden && Util::ends_with (entry_name, SharedConstants::PDB_EXTENSION)) { if (bundled_debug_data == nullptr) { bundled_debug_data = new std::vector (); bundled_debug_data->reserve (application_config.number_of_assemblies_in_apk); @@ -89,7 +90,7 @@ EmbeddedAssemblies::store_individual_assembly_data (dynamic_local_string int fd; bool close_fd; - if (!androidSystem.is_embedded_dso_mode_enabled ()) { + if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { log_debug (LOG_ASSEMBLY, "Mapping assembly blob file from filesystem"); close_fd = true; @@ -232,7 +233,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& continue; } - if (!assembly_store_found && utils.ends_with (entry_name, assembly_store_file_path)) { + if (!assembly_store_found && Util::ends_with (entry_name, assembly_store_file_path)) { assembly_store_found = true; map_assembly_store (entry_name, state); continue; @@ -244,7 +245,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& // Since it's not an assembly store, it's a shared library most likely and it is long enough for us not to have // to check the length - if (utils.ends_with (entry_name, dso_suffix)) { + if (Util::ends_with (entry_name, dso_suffix)) { constexpr size_t apk_lib_prefix_len = apk_lib_prefix.size () - 1; const char *const name = entry_name.get () + apk_lib_prefix_len; @@ -315,15 +316,15 @@ EmbeddedAssemblies::set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEnt { entry.file_fd = state.file_fd; if constexpr (NeedsNameAlloc) { - entry.name = utils.strdup_new (entry_name.get () + state.prefix_len); - if (!androidSystem.is_embedded_dso_mode_enabled () && state.file_name != nullptr) { - entry.file_name = utils.strdup_new (state.file_name); + entry.name = Util::strdup_new (entry_name.get () + state.prefix_len); + if (!AndroidSystem::is_embedded_dso_mode_enabled () && state.file_name != nullptr) { + entry.file_name = Util::strdup_new (state.file_name); } } else { // entry.name is preallocated at build time here and is max_name_size + 1 bytes long, filled with 0s, thus we // don't need to append the terminating NUL even for strings of `max_name_size` characters strncpy (entry.name, entry_name.get () + state.prefix_len, state.max_assembly_name_size); - if (!androidSystem.is_embedded_dso_mode_enabled () && state.file_name != nullptr) { + if (!AndroidSystem::is_embedded_dso_mode_enabled () && state.file_name != nullptr) { strncpy (entry.file_name, state.file_name, state.max_assembly_file_name_size); } } diff --git a/src/native/monodroid/jni/embedded-assemblies.cc b/src/native/monodroid/jni/embedded-assemblies.cc index f9119817818..a93f4f9ef5b 100644 --- a/src/native/monodroid/jni/embedded-assemblies.cc +++ b/src/native/monodroid/jni/embedded-assemblies.cc @@ -68,7 +68,7 @@ void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) { if (assemblies_prefix_override != nullptr) delete[] assemblies_prefix_override; - assemblies_prefix_override = prefix != nullptr ? utils.strdup_new (prefix) : nullptr; + assemblies_prefix_override = prefix != nullptr ? Util::strdup_new (prefix) : nullptr; } force_inline void @@ -159,7 +159,7 @@ EmbeddedAssemblies::map_runtime_file (XamarinAndroidBundledAssembly& file) noexc { int fd; bool close_fd; - if (!androidSystem.is_embedded_dso_mode_enabled ()) { + if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { log_debug (LOG_ASSEMBLY, "Mapping a runtime file from a filesystem"); close_fd = true; @@ -200,7 +200,7 @@ EmbeddedAssemblies::map_runtime_file (XamarinAndroidBundledAssembly& file) noexc } if constexpr (LogMapping) { - if (utils.should_log (LOG_ASSEMBLY) && map_info.area != nullptr) [[unlikely]] { + if (Util::should_log (LOG_ASSEMBLY) && map_info.area != nullptr) [[unlikely]] { const char *p = (const char*) file.data; std::array header; @@ -300,7 +300,7 @@ template force_inline MonoAssembly* EmbeddedAssemblies::individual_assemblies_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept { - if (!utils.ends_with (name, SharedConstants::DLL_EXTENSION)) { + if (!Util::ends_with (name, SharedConstants::DLL_EXTENSION)) { name.append (SharedConstants::DLL_EXTENSION); } @@ -598,7 +598,7 @@ EmbeddedAssemblies::typemap_java_to_managed ([[maybe_unused]] hash_t hash, const return nullptr; } - MonoReflectionType *ret = mono_type_get_object (utils.get_current_domain (), type); + MonoReflectionType *ret = mono_type_get_object (Util::get_current_domain (), type); if (ret == nullptr) [[unlikely]] { log_warn (LOG_ASSEMBLY, "typemap: unable to instantiate managed type '%s'", managed_type_name); return nullptr; @@ -865,7 +865,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uint32_t offset, size_t size, cons md_mmap_info file_info; md_mmap_info mmap_info; - size_t pageSize = static_cast(utils.monodroid_getpagesize ()); + size_t pageSize = static_cast(Util::monodroid_getpagesize ()); size_t offsetFromPage = offset % pageSize; size_t offsetPage = offset - offsetFromPage; size_t offsetSize = size + offsetFromPage; @@ -1128,7 +1128,7 @@ EmbeddedAssemblies::try_load_typemaps_from_directory (const char *path) return; } - std::unique_ptr dir_path {utils.path_combine (path, "typemaps")}; + std::unique_ptr dir_path {Util::path_combine (path, "typemaps")}; DIR *dir; if ((dir = ::opendir (dir_path.get ())) == nullptr) { log_warn (LOG_ASSEMBLY, "typemap: could not open directory: `%s`", dir_path.get ()); @@ -1211,8 +1211,8 @@ EmbeddedAssemblies::maybe_register_assembly_from_filesystem ( return false; } } else { - if (utils.ends_with (dir_entry->d_name, SharedConstants::DLL_EXTENSION) || - utils.ends_with (dir_entry->d_name, SharedConstants::PDB_EXTENSION)) { + if (Util::ends_with (dir_entry->d_name, SharedConstants::DLL_EXTENSION) || + Util::ends_with (dir_entry->d_name, SharedConstants::PDB_EXTENSION)) { assembly_count++; copy_dentry_and_update_state (entry_name, state, dir_entry); } else { @@ -1359,7 +1359,7 @@ EmbeddedAssemblies::register_from_filesystem (monodroid_should_register should_r log_debug (LOG_ASSEMBLY, "Registering assemblies from the filesystem"); constexpr bool LookForMangledNames = true; size_t assembly_count = register_from_filesystem ( - androidSystem.app_lib_directories[0], + AndroidSystem::app_lib_directories[0], LookForMangledNames, should_register ); @@ -1368,7 +1368,7 @@ EmbeddedAssemblies::register_from_filesystem (monodroid_should_register should_r constexpr bool DoNotLookForMangledNames = false; assembly_count += register_from_filesystem ( - androidSystem.get_primary_override_dir (), + AndroidSystem::get_primary_override_dir (), DoNotLookForMangledNames, should_register ); diff --git a/src/native/monodroid/jni/globals.hh b/src/native/monodroid/jni/globals.hh index 67d482acea1..7717ec2ec79 100644 --- a/src/native/monodroid/jni/globals.hh +++ b/src/native/monodroid/jni/globals.hh @@ -10,8 +10,6 @@ #include "monodroid-glue-internal.hh" extern xamarin::android::Debug debug; -extern xamarin::android::Util utils; -extern xamarin::android::internal::AndroidSystem androidSystem; extern xamarin::android::internal::OSBridge osBridge; extern xamarin::android::internal::EmbeddedAssemblies embeddedAssemblies; extern xamarin::android::internal::MonodroidRuntime monodroidRuntime; diff --git a/src/native/monodroid/jni/monodroid-glue.cc b/src/native/monodroid/jni/monodroid-glue.cc index 53fbdc7b721..79fbbed84f1 100644 --- a/src/native/monodroid/jni/monodroid-glue.cc +++ b/src/native/monodroid/jni/monodroid-glue.cc @@ -171,26 +171,26 @@ MonodroidRuntime::open_from_update_dir (MonoAssemblyName *aname, [[maybe_unused] } pname.append (name, name_len); - bool is_dll = utils.ends_with (name, SharedConstants::DLL_EXTENSION); + bool is_dll = Util::ends_with (name, SharedConstants::DLL_EXTENSION); size_t file_name_len = pname.length () + 1; if (!is_dll) file_name_len += SharedConstants::DLL_EXTENSION.length (); MonoAssembly *result = nullptr; for (const char *override_dir : AndroidSystem::override_dirs) { - if (override_dir == nullptr || !utils.directory_exists (override_dir)) { + if (override_dir == nullptr || !Util::directory_exists (override_dir)) { continue; } size_t override_dir_len = strlen (override_dir); static_local_string fullpath (override_dir_len + file_name_len); - utils.path_combine (fullpath, override_dir, override_dir_len, pname.get (), pname.length ()); + Util::path_combine (fullpath, override_dir, override_dir_len, pname.get (), pname.length ()); if (!is_dll) { fullpath.append (SharedConstants::DLL_EXTENSION); } log_debug (LOG_ASSEMBLY, "open_from_update_dir: trying to open assembly: %s\n", fullpath.get ()); - if (utils.file_exists (fullpath.get ())) { + if (Util::file_exists (fullpath.get ())) { MonoImageOpenStatus status{}; result = mono_assembly_open_full (fullpath.get (), &status, 0); if (result == nullptr || status != MonoImageOpenStatus::MONO_IMAGE_OK) { @@ -205,7 +205,7 @@ MonodroidRuntime::open_from_update_dir (MonoAssemblyName *aname, [[maybe_unused] } } - if (result != nullptr && utils.should_log (LOG_ASSEMBLY)) { + if (result != nullptr && Util::should_log (LOG_ASSEMBLY)) { log_info_nocheck (LOG_ASSEMBLY, "open_from_update_dir: loaded assembly: %p\n", result); } return result; @@ -228,8 +228,8 @@ MonodroidRuntime::should_register_file ([[maybe_unused]] const char *filename) size_t odir_len = strlen (odir); static_local_string p (odir_len + filename_len); - utils.path_combine (p, odir, odir_len, filename, filename_len); - bool exists = utils.file_exists (p.get ()); + Util::path_combine (p, odir, odir_len, filename, filename_len); + bool exists = Util::file_exists (p.get ()); if (exists) { return false; @@ -245,7 +245,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, #if defined(DEBUG) if (application_config.instant_run_enabled) { for (const char *od : AndroidSystem::override_dirs) { - if (od == nullptr || !utils.directory_exists (od)) { + if (od == nullptr || !Util::directory_exists (od)) { continue; } @@ -258,7 +258,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, } #endif - if (!androidSystem.is_embedded_dso_mode_enabled ()) { + if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { *out_user_assemblies_count = embeddedAssemblies.register_from_filesystem (); return; } @@ -276,9 +276,9 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, // With split configs we need to scan only the abi apk, because both the assembly stores and the runtime // configuration blob are in `lib/{ARCH}`, which in turn lives in the split config APK - if (!got_split_config_abi_apk && utils.ends_with (apk_file.get_cstr (), SharedConstants::split_config_abi_apk_name)) { + if (!got_split_config_abi_apk && Util::ends_with (apk_file.get_cstr (), SharedConstants::split_config_abi_apk_name)) { got_split_config_abi_apk = scan_apk = true; - } else if (!application_config.have_assembly_store && !got_base_apk && utils.ends_with (apk_file.get_cstr (), base_apk_name)) { + } else if (!application_config.have_assembly_store && !got_base_apk && Util::ends_with (apk_file.get_cstr (), base_apk_name)) { got_base_apk = scan_apk = true; } @@ -379,7 +379,7 @@ MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) { JNIEnv *env; - androidSystem.init_max_gref_count (); + AndroidSystem::init_max_gref_count (); vm->GetEnv ((void**)&env, JNI_VERSION_1_6); osBridge.initialize_on_onload (vm, env); @@ -392,7 +392,7 @@ MonodroidRuntime::parse_gdb_options () { dynamic_local_string val; - if (!(androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_GDB_PROPERTY, val) > 0)) + if (!(AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_GDB_PROPERTY, val) > 0)) return; constexpr std::string_view wait_param { "wait:" }; @@ -411,7 +411,7 @@ MonodroidRuntime::parse_gdb_options () time_t secs = time (nullptr); if (v + 10 < secs) { - log_warn (LOG_DEFAULT, "Found stale %s property with value '%s', not waiting.", Debug::DEBUG_MONO_GDB_PROPERTY.data (), val.get ()); + log_warn (LOG_DEFAULT, "Found stale %s property with value '%s', not waiting.", SharedConstants::DEBUG_MONO_GDB_PROPERTY.data (), val.get ()); do_wait = false; } } @@ -457,7 +457,7 @@ MonodroidRuntime::parse_runtime_args (dynamic_local_stringhost = host; options->sdb_port = static_cast(sdb_port); @@ -525,7 +525,7 @@ MonodroidRuntime::parse_runtime_args (dynamic_local_string jit_log_path {utils.path_combine (AndroidSystem::override_dirs [0], "methods.txt")}; - utils.create_directory (AndroidSystem::override_dirs [0], 0755); - jit_log = utils.monodroid_fopen (jit_log_path.get (), "a"); - utils.set_world_accessable (jit_log_path.get ()); + std::unique_ptr jit_log_path {Util::path_combine (AndroidSystem::override_dirs [0], "methods.txt")}; + Util::create_directory (AndroidSystem::override_dirs [0], 0755); + jit_log = Util::monodroid_fopen (jit_log_path.get (), "a"); + Util::set_world_accessable (jit_log_path.get ()); } profiler_handle = mono_profiler_create (nullptr); @@ -671,12 +671,12 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse dynamic_local_string prop_val; /* Additional runtime arguments passed to mono_jit_parse_options () */ - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_RUNTIME_ARGS_PROPERTY, prop_val) > 0) { + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_RUNTIME_ARGS_PROPERTY, prop_val) > 0) { char **ptr; log_warn (LOG_DEBUGGER, "passing '%s' as extra arguments to the runtime.\n", prop_val.get ()); - char **args = utils.monodroid_strsplit (prop_val.get (), " ", 0); + char **args = Util::monodroid_strsplit (prop_val.get (), " ", 0); int argc = 0; for (ptr = args; *ptr; ptr++) @@ -743,7 +743,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks } } - if (user_assemblies_count == 0 && androidSystem.count_override_assemblies () == 0 && !is_running_on_desktop) { + if (user_assemblies_count == 0 && AndroidSystem::count_override_assemblies () == 0 && !is_running_on_desktop) { #if defined (DEBUG) log_fatal (LOG_DEFAULT, "No assemblies found in '%s' or '%s'. Assuming this is part of Fast Deployment. Exiting...", AndroidSystem::override_dirs [0], @@ -765,7 +765,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks char *corlib_error_message = corlib_error_message_guard.get (); if (corlib_error_message == nullptr) { - if (!androidSystem.monodroid_get_system_property ("xamarin.studio.fakefaultycorliberrormessage", &corlib_error_message)) { + if (!AndroidSystem::monodroid_get_system_property ("xamarin.studio.fakefaultycorliberrormessage", &corlib_error_message)) { corlib_error_message = nullptr; } } @@ -875,7 +875,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec init.marshalMethodsEnabled = application_config.marshal_methods_enabled; // GC threshold is 90% of the max GREF count - init.grefGcThreshold = static_cast(androidSystem.get_gref_gc_threshold ()); + init.grefGcThreshold = static_cast(AndroidSystem::get_gref_gc_threshold ()); log_info (LOG_GC, "GREF GC Threshold: %i", init.grefGcThreshold); @@ -885,7 +885,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec MonoAssembly *mono_android_assembly; - mono_android_assembly = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); + mono_android_assembly = Util::monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *mono_android_assembly_image = mono_assembly_get_image (mono_android_assembly); uint32_t i = 0; @@ -912,7 +912,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec abort_unless (method != nullptr, "INTERNAL ERROR: Unable to find the Android.Runtime.JNIEnvInit.Initialize method!"); MonoAssembly *ji_assm; - ji_assm = utils.monodroid_load_assembly (default_alc, SharedConstants::JAVA_INTEROP_ASSEMBLY_NAME.data ()); + ji_assm = Util::monodroid_load_assembly (default_alc, SharedConstants::JAVA_INTEROP_ASSEMBLY_NAME.data ()); MonoImage *ji_image = mono_assembly_get_image (ji_assm); for ( ; i < OSBridge::NUM_XA_GC_BRIDGE_TYPES + OSBridge::NUM_JI_GC_BRIDGE_TYPES; ++i) { @@ -973,7 +973,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec MonoClass* MonodroidRuntime::get_android_runtime_class () { - MonoAssembly *assm = utils.monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); + MonoAssembly *assm = Util::monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *image = mono_assembly_get_image (assm); return mono_class_from_name (image, SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), SharedConstants::JNIENV_CLASS_NAME.data ()); } @@ -996,8 +996,8 @@ MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, static void setup_gc_logging (void) { - gc_spew_enabled = androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_GC_PROPERTY, nullptr) > 0; - if (gc_spew_enabled) { + Logger::set_gc_spew_enabled (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_GC_PROPERTY, nullptr) > 0); + if (Logger::gc_spew_enabled ()) { log_categories |= LOG_GC; } } @@ -1033,7 +1033,7 @@ MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, con if (load_error == nullptr) { load_error = "Unknown error"; } - *err = utils.monodroid_strdup_printf ("Could not load library '%s'. %s", full_name, load_error); + *err = Util::monodroid_strdup_printf ("Could not load library '%s'. %s", full_name, load_error); } if (free_memory) { @@ -1078,12 +1078,12 @@ MonodroidRuntime::monodroid_dlopen_ignore_component_or_load ([[maybe_unused]] ha } unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags); - void * handle = androidSystem.load_dso_from_any_directories (name, dl_flags); + void * handle = AndroidSystem::load_dso_from_any_directories (name, dl_flags); if (handle != nullptr) { return monodroid_dlopen_log_and_return (handle, err, name, false /* name_needs_free */); } - handle = androidSystem.load_dso (name, dl_flags, false /* skip_existing_check */); + handle = AndroidSystem::load_dso (name, dl_flags, false /* skip_existing_check */); return monodroid_dlopen_log_and_return (handle, err, name, false /* name_needs_free */); } @@ -1109,7 +1109,7 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err) noe StartupAwareLock lock (dso_handle_write_lock); #if defined (RELEASE) - if (androidSystem.is_embedded_dso_mode_enabled ()) { + if (AndroidSystem::is_embedded_dso_mode_enabled ()) { DSOApkEntry *apk_entry = dso_apk_entries; for (size_t i = 0; i < application_config.number_of_shared_libraries; i++) { if (apk_entry->name_hash != dso->real_name_hash) { @@ -1131,13 +1131,13 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err) noe } #endif unsigned int dl_flags = monodroidRuntime.convert_dl_flags (flags); - dso->handle = androidSystem.load_dso_from_any_directories (dso->name, dl_flags); + dso->handle = AndroidSystem::load_dso_from_any_directories (dso->name, dl_flags); if (dso->handle != nullptr) { return monodroid_dlopen_log_and_return (dso->handle, err, dso->name, false /* name_needs_free */); } - dso->handle = androidSystem.load_dso_from_any_directories (name, dl_flags); + dso->handle = AndroidSystem::load_dso_from_any_directories (name, dl_flags); return monodroid_dlopen_log_and_return (dso->handle, err, name, false /* name_needs_free */); } @@ -1161,7 +1161,7 @@ MonodroidRuntime::monodroid_dlsym (void *handle, const char *name, char **err, [ s = java_interop_lib_symbol (handle, name, &e); if (!s && err) { - *err = utils.monodroid_strdup_printf ("Could not find symbol '%s': %s", name, e); + *err = Util::monodroid_strdup_printf ("Could not find symbol '%s': %s", name, e); } if (e) { java_interop_free (e); @@ -1174,7 +1174,7 @@ inline void MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) { if (createDirectory) { - int rv = utils.create_directory (value.get_cstr (), mode); + int rv = Util::create_directory (value.get_cstr (), mode); if (rv < 0 && errno != EEXIST) log_warn (LOG_DEFAULT, "Failed to create directory for environment variable %s. %s", name, strerror (errno)); } @@ -1185,9 +1185,9 @@ inline void MonodroidRuntime::create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept { static_local_string dir (home_len + relative_path.length ()); - utils.path_combine (dir, home.get_cstr (), home_len, relative_path.data (), relative_path.length ()); + Util::path_combine (dir, home.get_cstr (), home_len, relative_path.data (), relative_path.length ()); log_debug (LOG_DEFAULT, "Creating XDG directory: %s", dir.get ()); - int rv = utils.create_directory (dir.get (), DEFAULT_DIRECTORY_MODE); + int rv = Util::create_directory (dir.get (), DEFAULT_DIRECTORY_MODE); if (rv < 0 && errno != EEXIST) log_warn (LOG_DEFAULT, "Failed to create XDG directory %s. %s", dir.get (), strerror (errno)); if (!environment_variable_name.empty ()) { @@ -1214,7 +1214,7 @@ void MonodroidRuntime::set_debug_env_vars (void) { dynamic_local_string value; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_ENV_PROPERTY, value) == 0) + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_ENV_PROPERTY, value) == 0) return; auto log_envvar = [](const char *name, const char *v) { @@ -1254,7 +1254,7 @@ inline void MonodroidRuntime::set_trace_options (void) { dynamic_local_string value; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_TRACE_PROPERTY, value) == 0) + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_TRACE_PROPERTY, value) == 0) return; mono_jit_set_trace_options (value.get ()); @@ -1268,7 +1268,7 @@ MonodroidRuntime::set_profile_options () dynamic_local_string value; { dynamic_local_string prop_value; - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_PROFILE_PROPERTY, prop_value) == 0) + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_PROFILE_PROPERTY, prop_value) == 0) return; value.assign (prop_value); @@ -1317,12 +1317,12 @@ MonodroidRuntime::set_profile_options () .append (OUTPUT_ARG) .append (output_path.get (), output_path.length ()); } - if (utils.create_directory (AndroidSystem::override_dirs[0], 0) < 0) { + if (Util::create_directory (AndroidSystem::override_dirs[0], 0) < 0) { log_warn (LOG_DEFAULT, "Failed to create directory '%s'. %s", AndroidSystem::override_dirs[0], std::strerror (errno)); } log_warn (LOG_DEFAULT, "Initializing profiler with options: %s", value.get ()); - debug.monodroid_profiler_load (androidSystem.get_runtime_libdir (), value.get (), output_path.get ()); + debug.monodroid_profiler_load (AndroidSystem::get_runtime_libdir (), value.get (), output_path.get ()); } inline void @@ -1372,7 +1372,7 @@ MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) } MonoAssemblyName *aname = mono_assembly_name_new (assm_name); - MonoDomain *current = utils.get_current_domain (); + MonoDomain *current = Util::get_current_domain (); if (domain != current) { mono_domain_set (domain, FALSE); mono_assembly_load_full (aname, NULL, NULL, 0); @@ -1450,7 +1450,7 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass embeddedAssemblies.install_preload_hooks_for_alc (); log_debug (LOG_ASSEMBLY, "ALC hooks installed"); - bool preload = (androidSystem.is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies)); + bool preload = (AndroidSystem::is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies)); load_assemblies (default_alc, preload, assemblies); init_android_runtime (env, runtimeClass, loader); @@ -1569,13 +1569,13 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl char *mono_log_mask_raw = nullptr; char *mono_log_level_raw = nullptr; - init_logging_categories (mono_log_mask_raw, mono_log_level_raw); + Logger::init_logging_categories (mono_log_mask_raw, mono_log_level_raw); std::unique_ptr mono_log_mask (mono_log_mask_raw); std::unique_ptr mono_log_level (mono_log_level_raw); // If fast logging is disabled, log messages immediately - FastTiming::initialize ((log_timing_categories & LOG_TIMING_FAST_BARE) == 0); + FastTiming::initialize ((Logger::log_timing_categories() & LogTimingCategories::FastBare) != LogTimingCategories::FastBare); size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1605,28 +1605,28 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl } android_api_level = apiLevel; - androidSystem.detect_embedded_dso_mode (applicationDirs); - androidSystem.set_running_in_emulator (isEmulator); + AndroidSystem::detect_embedded_dso_mode (applicationDirs); + AndroidSystem::set_running_in_emulator (isEmulator); java_TimeZone = RuntimeUtil::get_class_from_runtime_field (env, klass, "java_util_TimeZone", true); - utils.monodroid_store_package_name (application_config.android_package_name); + Util::monodroid_store_package_name (application_config.android_package_name); jstring_wrapper jstr (env, lang); set_environment_variable ("LANG", jstr); - androidSystem.setup_environment (); + AndroidSystem::setup_environment (); set_environment_variable_for_directory ("TMPDIR", applicationDirs[SharedConstants::APP_DIRS_CACHE_DIR_INDEX]); set_environment_variable_for_directory ("HOME", home); create_xdg_directories_and_environment (home); - androidSystem.set_primary_override_dir (home); + AndroidSystem::set_primary_override_dir (home); jstring_array_wrapper runtimeApks (env, runtimeApksJava); - androidSystem.setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks); + AndroidSystem::setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks); - init_reference_logging (androidSystem.get_primary_override_dir ()); - androidSystem.create_update_dir (androidSystem.get_primary_override_dir ()); + Logger::init_reference_logging (AndroidSystem::get_primary_override_dir ()); + AndroidSystem::create_update_dir (AndroidSystem::get_primary_override_dir ()); #if DEBUG setup_gc_logging (); @@ -1647,11 +1647,11 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl if (runtimeNativeLibDir != nullptr) { jstr = runtimeNativeLibDir; - androidSystem.set_runtime_libdir (strdup (jstr.get_cstr ())); - log_debug (LOG_DEFAULT, "Using runtime path: %s", androidSystem.get_runtime_libdir ()); + AndroidSystem::set_runtime_libdir (strdup (jstr.get_cstr ())); + log_debug (LOG_DEFAULT, "Using runtime path: %s", AndroidSystem::get_runtime_libdir ()); } - androidSystem.setup_process_args (runtimeApks); + AndroidSystem::setup_process_args (runtimeApks); mono_dl_fallback_register (monodroid_dlopen, monodroid_dlsym, nullptr, nullptr); set_profile_options (); @@ -1665,8 +1665,8 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl log_debug (LOG_DEFAULT, "Probing for Mono AOT mode\n"); MonoAotMode mode = MonoAotMode::MONO_AOT_MODE_NONE; - if (androidSystem.is_mono_aot_enabled ()) { - mode = androidSystem.get_mono_aot_mode (); + if (AndroidSystem::is_mono_aot_enabled ()) { + mode = AndroidSystem::get_mono_aot_mode (); if (mode != MonoAotMode::MONO_AOT_MODE_INTERP_ONLY) { log_debug (LOG_DEFAULT, "Enabling AOT mode in Mono"); } else { @@ -1677,7 +1677,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl log_debug (LOG_DEFAULT, "Probing if we should use LLVM\n"); - if (androidSystem.is_mono_llvm_enabled ()) { + if (AndroidSystem::is_mono_llvm_enabled ()) { char *args [1]; args[0] = const_cast ("--llvm"); log_debug (LOG_DEFAULT, "Enabling LLVM mode in Mono\n"); @@ -1686,7 +1686,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl } dynamic_local_string runtime_args; - androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_EXTRA_PROPERTY, runtime_args); + AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_EXTRA_PROPERTY, runtime_args); size_t mono_runtime_init_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1710,7 +1710,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl reinterpret_cast (monodroid_Mono_UnhandledException_internal)); } - if (utils.should_log (LOG_DEFAULT)) [[unlikely]] { + if (Util::should_log (LOG_DEFAULT)) [[unlikely]] { log_info_nocheck ( LOG_DEFAULT, ".NET Android version: %s (%s; %s); built on %s; NDK version: %s; API level: %s; MonoVM version: %s", diff --git a/src/native/monodroid/jni/monodroid-networkinfo.cc b/src/native/monodroid/jni/monodroid-networkinfo.cc index a2aec751339..e14aa71309e 100644 --- a/src/native/monodroid/jni/monodroid-networkinfo.cc +++ b/src/native/monodroid/jni/monodroid-networkinfo.cc @@ -28,6 +28,7 @@ #include #include +#include "android-system.hh" #include "monodroid.h" #include "monodroid-glue.hh" @@ -35,6 +36,7 @@ #include "globals.hh" using namespace xamarin::android; +using namespace xamarin::android::internal; static pthread_once_t java_classes_once_control = PTHREAD_ONCE_INIT; static jclass NetworkInterface_class; @@ -153,7 +155,7 @@ _monodroid_get_dns_servers (void **dns_servers_array) char prop_name[] = "net.dnsX"; for (int i = 0; i < 8; i++) { prop_name [7] = (char)(i + 0x31); - len = static_cast(androidSystem.monodroid_get_system_property (prop_name, &dns)); + len = static_cast(AndroidSystem::monodroid_get_system_property (prop_name, &dns)); if (len == 0) { dns_servers [i] = nullptr; continue; diff --git a/src/native/monodroid/jni/osbridge.cc b/src/native/monodroid/jni/osbridge.cc index 50e3d560b92..e4c268ba63b 100644 --- a/src/native/monodroid/jni/osbridge.cc +++ b/src/native/monodroid/jni/osbridge.cc @@ -17,6 +17,7 @@ #include "globals.hh" #include "osbridge.hh" +#include "runtime-util.hh" using namespace xamarin::android; using namespace xamarin::android::internal; @@ -653,12 +654,12 @@ OSBridge::describe_target (OSBridge::AddReferenceTarget target) { if (target.is_mono_object) { MonoClass *klass = mono_object_get_class (target.obj); - return utils.monodroid_strdup_printf ("object of class %s.%s", + return Util::monodroid_strdup_printf ("object of class %s.%s", mono_class_get_namespace (klass), mono_class_get_name (klass)); } else - return utils.monodroid_strdup_printf ("", target.jobj); + return Util::monodroid_strdup_printf ("", target.jobj); } #endif @@ -685,7 +686,7 @@ OSBridge::add_reference (JNIEnv *env, OSBridge::AddReferenceTarget target, OSBri } #if DEBUG - if (gc_spew_enabled) { + if (Logger::gc_spew_enabled ()) { char *description = describe_target (target), *reffed_description = describe_target (reffed_target); @@ -922,7 +923,7 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri } else { env->ExceptionClear (); #if DEBUG - if (gc_spew_enabled) { + if (Logger::gc_spew_enabled ()) { klass = mono_object_get_class (obj); log_error (LOG_GC, "Missing monodroidClearReferences method for object of class %s.%s", mono_class_get_namespace (klass), @@ -966,7 +967,7 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre return; #if DEBUG - if (gc_spew_enabled) { + if (Logger::gc_spew_enabled ()) { int i, j; log_info (LOG_GC, "cross references callback invoked with %d sccs and %d xrefs.", num_sccs, num_xrefs); @@ -982,7 +983,7 @@ OSBridge::gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xre } } - if (utils.should_log (LOG_GC)) { + if (Util::should_log (LOG_GC)) { for (i = 0; i < num_xrefs; ++i) log_info_nocheck (LOG_GC, "xref [%d] %d -> %d", i, xrefs [i].src_scc_index, xrefs [i].dst_scc_index); } @@ -1006,12 +1007,12 @@ OSBridge::platform_supports_weak_refs (void) char *value; int api_level = 0; - if (androidSystem.monodroid_get_system_property ("ro.build.version.sdk", &value) > 0) { + if (AndroidSystem::monodroid_get_system_property ("ro.build.version.sdk", &value) > 0) { api_level = atoi (value); free (value); } - if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_WREF_PROPERTY, &value) > 0) { + if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_WREF_PROPERTY, &value) > 0) { int use_weak_refs = 0; if (!strcmp ("jni", value)) use_weak_refs = 1; @@ -1066,7 +1067,7 @@ OSBridge::ensure_jnienv (void) JNIEnv *env; jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); if (env == nullptr) { - mono_thread_attach (utils.get_current_domain (/* attach_thread_if_needed */ false)); + mono_thread_attach (Util::get_current_domain (/* attach_thread_if_needed */ false)); jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); } return env; @@ -1101,7 +1102,7 @@ void OSBridge::initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass) { abort_if_invalid_pointer_argument (env); - GCUserPeer_class = utils.get_class_from_runtime_field(env, runtimeClass, "mono_android_GCUserPeer", true); + GCUserPeer_class = RuntimeUtil::get_class_from_runtime_field(env, runtimeClass, "mono_android_GCUserPeer", true); GCUserPeer_ctor = env->GetMethodID (GCUserPeer_class, "", "()V"); abort_unless (GCUserPeer_class != nullptr && GCUserPeer_ctor != nullptr, "Failed to load mono.android.GCUserPeer!"); } @@ -1115,7 +1116,7 @@ OSBridge::add_monodroid_domain (MonoDomain *domain) * use GC API to allocate memory and thus can't be called from within the GC callback as it causes a deadlock * (the routine allocating the memory waits for the GC round to complete first) */ - MonoClass *runtime = utils.monodroid_get_class_from_name ( + MonoClass *runtime = Util::monodroid_get_class_from_name ( domain, SharedConstants::MONO_ANDROID_RUNTIME_ASSEMBLY_NAME.data (), SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), diff --git a/src/native/monodroid/jni/pinvoke-override-api.cc b/src/native/monodroid/jni/pinvoke-override-api.cc index 09710484807..a83c544a074 100644 --- a/src/native/monodroid/jni/pinvoke-override-api.cc +++ b/src/native/monodroid/jni/pinvoke-override-api.cc @@ -39,7 +39,7 @@ monodroid_get_log_categories () static int monodroid_get_system_property (const char *name, char **value) { - return androidSystem.monodroid_get_system_property (name, value); + return AndroidSystem::monodroid_get_system_property (name, value); } static int @@ -92,7 +92,7 @@ monodroid_free (void *ptr) static int _monodroid_max_gref_get () { - return static_cast(androidSystem.get_max_gref_count ()); + return static_cast(AndroidSystem::get_max_gref_count ()); } static int @@ -240,13 +240,13 @@ monodroid_timing_stop (managed_timing_sequence *sequence, const char *message) static char** monodroid_strsplit (const char *str, const char *delimiter, size_t max_tokens) { - return utils.monodroid_strsplit (str, delimiter, max_tokens); + return Util::monodroid_strsplit (str, delimiter, max_tokens); } static void monodroid_strfreev (char **str_array) { - utils.monodroid_strfreev (str_array); + Util::monodroid_strfreev (str_array); } static char* @@ -255,7 +255,7 @@ monodroid_strdup_printf (const char *format, ...) va_list args; va_start (args, format); - char *ret = utils.monodroid_strdup_vprintf (format, args); + char *ret = Util::monodroid_strdup_vprintf (format, args); va_end (args); return ret; @@ -270,19 +270,19 @@ monodroid_TypeManager_get_java_class_name (jclass klass) static void monodroid_store_package_name (const char *name) { - utils.monodroid_store_package_name (name); + Util::monodroid_store_package_name (name); } static int monodroid_get_namespaced_system_property (const char *name, char **value) { - return static_cast(androidSystem.monodroid_get_system_property (name, value)); + return static_cast(AndroidSystem::monodroid_get_system_property (name, value)); } static FILE* monodroid_fopen (const char* filename, const char* mode) { - return utils.monodroid_fopen (filename, mode); + return Util::monodroid_fopen (filename, mode); } static int @@ -290,7 +290,7 @@ send_uninterrupted (int fd, void *buf, int len) { if (len < 0) len = 0; - return utils.send_uninterrupted (fd, buf, static_cast(len)); + return Util::send_uninterrupted (fd, buf, static_cast(len)); } static int @@ -298,25 +298,25 @@ recv_uninterrupted (int fd, void *buf, int len) { if (len < 0) len = 0; - return static_cast(utils.recv_uninterrupted (fd, buf, static_cast(len))); + return static_cast(Util::recv_uninterrupted (fd, buf, static_cast(len))); } static void set_world_accessable (const char *path) { - utils.set_world_accessable (path); + Util::set_world_accessable (path); } static void create_public_directory (const char *dir) { - utils.create_public_directory (dir); + Util::create_public_directory (dir); } static char* path_combine (const char *path1, const char *path2) { - return utils.path_combine (path1, path2); + return Util::path_combine (path1, path2); } static void* diff --git a/src/native/monodroid/jni/timezones.cc b/src/native/monodroid/jni/timezones.cc index f5179350ed9..2680af72a2f 100644 --- a/src/native/monodroid/jni/timezones.cc +++ b/src/native/monodroid/jni/timezones.cc @@ -33,7 +33,7 @@ init () if (AndroidEnvironment_NotifyTimeZoneChanged) return; - Mono_Android_dll = utils.monodroid_load_assembly (utils.get_current_domain (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); + Mono_Android_dll = Util::monodroid_load_assembly (Util::get_current_domain (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); Mono_Android_image = mono_assembly_get_image (Mono_Android_dll); AndroidEnvironment = mono_class_from_name (Mono_Android_image, SharedConstants::ANDROID_RUNTIME_NS_NAME.data (), SharedConstants::ANDROID_ENVIRONMENT_CLASS_NAME.data ()); AndroidEnvironment_NotifyTimeZoneChanged = mono_class_get_method_from_name (AndroidEnvironment, "NotifyTimeZoneChanged", 0); diff --git a/src/native/monodroid/jni/timing-internal.hh b/src/native/monodroid/jni/timing-internal.hh index 47417123f27..519b98cb28e 100644 --- a/src/native/monodroid/jni/timing-internal.hh +++ b/src/native/monodroid/jni/timing-internal.hh @@ -6,6 +6,7 @@ #include #include +#include "cpp-util.hh" #include "logger.hh" #include "startup-aware-lock.hh" #include "strings.hh" @@ -100,13 +101,13 @@ namespace xamarin::android::internal force_inline static bool is_bare_mode () noexcept { return - (log_timing_categories & LOG_TIMING_BARE) == LOG_TIMING_BARE || - (log_timing_categories & LOG_TIMING_FAST_BARE) == LOG_TIMING_FAST_BARE; + (Logger::log_timing_categories() & LogTimingCategories::Bare) == LogTimingCategories::Bare || + (Logger::log_timing_categories() & LogTimingCategories::FastBare) == LogTimingCategories::FastBare; } force_inline static void initialize (bool log_immediately) noexcept { - if (!utils.should_log (LOG_TIMING)) [[likely]] { + if (!Util::should_log (LOG_TIMING)) [[likely]] { return; } @@ -172,7 +173,7 @@ namespace xamarin::android::internal return; } - events[event_index].more_info = utils.strdup_new (str.get (), str.length ()); + events[event_index].more_info = Util::strdup_new (str.get (), str.length ()); log (events[event_index], false /* skip_log_if_more_info_missing */); } @@ -182,7 +183,7 @@ namespace xamarin::android::internal return; } - events[event_index].more_info = utils.strdup_new (str, strlen (str)); + events[event_index].more_info = Util::strdup_new (str, strlen (str)); log (events[event_index], false /* skip_log_if_more_info_missing */); } diff --git a/src/native/monodroid/jni/timing.cc b/src/native/monodroid/jni/timing.cc index ec48972850b..023b16271ec 100644 --- a/src/native/monodroid/jni/timing.cc +++ b/src/native/monodroid/jni/timing.cc @@ -1,5 +1,8 @@ #include "timing-internal.hh" +using namespace xamarin::android; +using namespace xamarin::android::internal; + void timing_point::mark () { FastTiming::get_time (sec, ns); diff --git a/src/native/monodroid/jni/xamarin_getifaddrs.cc b/src/native/monodroid/jni/xamarin_getifaddrs.cc index 9918bde5fa7..211e250763f 100644 --- a/src/native/monodroid/jni/xamarin_getifaddrs.cc +++ b/src/native/monodroid/jni/xamarin_getifaddrs.cc @@ -30,10 +30,13 @@ #endif #include "logger.hh" +#include "util.hh" #include "globals.hh" #include "xamarin_getifaddrs.h" +using namespace xamarin::android; + /* Some of these aren't defined in android's rtnetlink.h (as of ndk 16). We define values for all of * them if they aren't found so that the debug code works properly. We could skip them but future * versions of the NDK might include definitions for them. @@ -556,7 +559,7 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd } #if DEBUG - if (utils.should_log (LOG_NETLINK)) { + if (Util::should_log (LOG_NETLINK)) { log_debug_nocheck (LOG_NETLINK, "response flags:"); if (netlink_reply.msg_flags == 0) log_debug_nocheck (LOG_NETLINK, " [NONE]"); @@ -818,7 +821,7 @@ calculate_address_netmask (struct _monodroid_ifaddrs *ifa, struct ifaddrmsg *net if (prefix_bytes + 2 < data_length) /* Set the rest of the mask bits in the byte following the last 0xFF value */ netmask_data [prefix_bytes + 1] = static_cast(0xff << (8 - (prefix_length % 8))); - if (utils.should_log (LOG_NETLINK)) { + if (Util::should_log (LOG_NETLINK)) { log_debug_nocheck (LOG_NETLINK, " netmask is: "); for (uint32_t i = 0; i < data_length; i++) { log_debug_nocheck (LOG_NETLINK, "%s%u", i == 0 ? " " : ".", (unsigned char)ifa->ifa_netmask->sa_data [i]); @@ -1013,7 +1016,7 @@ get_link_info (const struct nlmsghdr *message) if (!ifa->ifa_name) { goto error; } - if (utils.should_log (LOG_NETLINK)) { + if (Util::should_log (LOG_NETLINK)) { log_debug_nocheck (LOG_NETLINK, " interface name (payload length: %d; string length: %d)\n", RTA_PAYLOAD (attribute), strlen (ifa->ifa_name)); log_debug_nocheck (LOG_NETLINK, " %s\n", ifa->ifa_name); } @@ -1134,7 +1137,7 @@ struct enumvalue iflas[] = { static void print_ifla_name (int id) { - if (!utils.should_log (LOG_NETLINK)) + if (!Util::should_log (LOG_NETLINK)) return; int i = 0; @@ -1156,7 +1159,7 @@ print_ifla_name (int id) static void print_address_list (const char title[], struct _monodroid_ifaddrs *list) { - if (!utils.should_log (LOG_NETLINK)) + if (!Util::should_log (LOG_NETLINK)) return; struct _monodroid_ifaddrs *cur; diff --git a/src/native/runtime-base/logger.cc b/src/native/runtime-base/logger.cc index 75b7b38711c..0b62f3c87b8 100644 --- a/src/native/runtime-base/logger.cc +++ b/src/native/runtime-base/logger.cc @@ -51,8 +51,6 @@ static constexpr std::array log_names = { #define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [static_cast(ffs (value))]) unsigned int log_categories = LOG_NONE; -unsigned int log_timing_categories; -int gc_spew_enabled; namespace { FILE* @@ -95,6 +93,7 @@ namespace { bool light_lref = false; } +#if defined(DEBUG) void Logger::set_debugger_log_level (const char *level) noexcept { @@ -117,6 +116,7 @@ Logger::set_debugger_log_level (const char *level) noexcept _got_debugger_log_level = true; _debugger_log_level = static_cast(v); } +#endif // def DEBUG void Logger::init_reference_logging (const char *override_dir) noexcept @@ -274,7 +274,7 @@ Logger::init_logging_categories (char*& mono_log_mask, char*& mono_log_level) no #if DEBUG if ((log_categories & LOG_GC) != 0) - gc_spew_enabled = 1; + _gc_spew_enabled = 1; #endif /* DEBUG */ } @@ -341,17 +341,19 @@ static constexpr android_LogPriority loglevel_map[] = { static constexpr size_t loglevel_map_max_index = (sizeof(loglevel_map) / sizeof(android_LogPriority)) - 1; -void -log_write (LogCategories category, LogLevel level, const char *message) noexcept -{ - size_t map_index = static_cast(level); - android_LogPriority priority; +namespace xamarin::android { + void + log_write (LogCategories category, LogLevel level, const char *message) noexcept + { + size_t map_index = static_cast(level); + android_LogPriority priority; - if (map_index > loglevel_map_max_index) { - priority = DEFAULT_PRIORITY; - } else { - priority = loglevel_map[map_index]; - } + if (map_index > loglevel_map_max_index) { + priority = DEFAULT_PRIORITY; + } else { + priority = loglevel_map[map_index]; + } - __android_log_write (priority, CATEGORY_NAME (category), message); + __android_log_write (priority, CATEGORY_NAME (category), message); + } } diff --git a/src/native/runtime-base/logger.hh b/src/native/runtime-base/logger.hh index ec01000d040..6a477f1a4c7 100644 --- a/src/native/runtime-base/logger.hh +++ b/src/native/runtime-base/logger.hh @@ -20,6 +20,11 @@ namespace xamarin::android { static void init_logging_categories (char*& mono_log_mask, char*& mono_log_level) noexcept; static void init_reference_logging (const char *override_dir) noexcept; + static LogTimingCategories log_timing_categories () noexcept + { + return _log_timing_categories; + } + #if defined(DEBUG) static void set_debugger_log_level (const char *level) noexcept; @@ -32,6 +37,16 @@ namespace xamarin::android { { return _debugger_log_level; } + + static void set_gc_spew_enabled (int yesno) noexcept + { + _gc_spew_enabled = yesno; + } + + static int gc_spew_enabled () noexcept + { + return _gc_spew_enabled; + } #endif // def DEBUG private: @@ -42,7 +57,7 @@ namespace xamarin::android { #if defined(DEBUG) static inline bool _got_debugger_log_level = false; static inline int _debugger_log_level = 0; - static inline int _gc_spew_enabled; + static inline int _gc_spew_enabled = 0; #endif // def DEBUG }; @@ -64,4 +79,6 @@ namespace xamarin::android { // for format placeholders nor it uses variable arguments void log_write (LogCategories category, LogLevel level, const char *message) noexcept; } + +extern unsigned int log_categories; #endif diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 3901e1f2f72..87b03319d4b 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -165,12 +165,12 @@ namespace xamarin::android } template - static bool ends_with (internal::dynamic_local_string& str, std::string_view const& sv) noexcept + static bool ends_with (internal::dynamic_local_string const& str, std::string_view const& sv) noexcept { return ends_with(static_cast const&>(str), sv); } - bool ends_with (const char *str, std::string_view const& sv) const noexcept + static bool ends_with (const char *str, std::string_view const& sv) noexcept { size_t len = strlen (str); if (len < sv.length ()) { diff --git a/src/native/shared/CMakeLists.txt b/src/native/shared/CMakeLists.txt index 0dcfce8bbe3..23f3fe105b3 100644 --- a/src/native/shared/CMakeLists.txt +++ b/src/native/shared/CMakeLists.txt @@ -1,9 +1,15 @@ set(LIB_NAME xa-shared-bits) set(LIB_ALIAS xa::shared) -set(XA_SHARED_SOURCES +set(LIB_NAME_NO_ABI ${LIB_NAME}-no-abi) +set(LIB_ALIAS_NO_ABI ${LIB_ALIAS}-no-abi) + +set(XA_SHARED_CXX_ABI_SOURCES cxx-abi/string.cc cxx-abi/terminate.cc +) + +set(XA_SHARED_SOURCES helpers.cc new_delete.cc ) @@ -15,36 +21,48 @@ add_library( ${LIB_NAME} STATIC ${XA_SHARED_SOURCES} + ${XA_SHARED_CXX_ABI_SOURCES} ) - add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) -target_include_directories( - ${LIB_NAME} - PUBLIC - "$" - "$" - "$" - "$" +add_library( + ${LIB_NAME_NO_ABI} + STATIC + ${XA_SHARED_SOURCES} ) +add_library(${LIB_ALIAS_NO_ABI} ALIAS ${LIB_NAME_NO_ABI}) -target_include_directories( - ${LIB_NAME} - SYSTEM PRIVATE - ${SYSROOT_CXX_INCLUDE_DIR} - ${MONO_RUNTIME_INCLUDE_DIR} -) +macro(lib_target_options TARGET_NAME) + target_include_directories( + ${TARGET_NAME} + PUBLIC + "$" + "$" + "$" + "$" + ) -target_compile_options( - ${LIB_NAME} - PRIVATE - ${XA_COMMON_CXX_ARGS} -) + target_include_directories( + ${TARGET_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} + ) -set_target_properties( - ${LIB_NAME} - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" -) + target_compile_options( + ${TARGET_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} + ) + + set_target_properties( + ${TARGET_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + + xa_add_compile_definitions(${TARGET_NAME}) +endmacro() -xa_add_compile_definitions(${LIB_NAME}) +lib_target_options(${LIB_NAME}) +lib_target_options(${LIB_NAME_NO_ABI}) diff --git a/src/native/monodroid/jni/cppcompat.hh b/src/native/shared/cppcompat.hh similarity index 100% rename from src/native/monodroid/jni/cppcompat.hh rename to src/native/shared/cppcompat.hh diff --git a/src/native/tracing/CMakeLists.txt b/src/native/tracing/CMakeLists.txt new file mode 100644 index 00000000000..1b5ac0f4c03 --- /dev/null +++ b/src/native/tracing/CMakeLists.txt @@ -0,0 +1,71 @@ +set(LIB_NAME xamarin-native-tracing) +set(LIB_ALIAS xa::native-tracing) + +set(NATIVE_TRACING_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) + +set(XAMARIN_TRACING_SOURCES + native-tracing.cc +) + +add_library( + ${LIB_NAME} + SHARED + ${XAMARIN_TRACING_SOURCES} +) + +add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) + +target_include_directories( + ${LIB_NAME} + PUBLIC + "$" +) + +target_include_directories( + ${LIB_NAME} + SYSTEM PRIVATE + ${SYSROOT_CXX_INCLUDE_DIR} + ${MONO_RUNTIME_INCLUDE_DIR} +) + +target_compile_definitions( + ${LIB_NAME} + PRIVATE + XAMARIN_TRACING +) + +target_compile_options( + ${LIB_NAME} + PRIVATE + ${XA_COMMON_CXX_ARGS} + # Avoid the 'warning: dynamic exception specifications are deprecated' warning from libc++ headers + -Wno-deprecated-dynamic-exception-spec + # Prevent genration of the .eh_frame section (we don't use exceptions and don't need it) + -fno-asynchronous-unwind-tables +) + +target_link_directories( + ${LIB_NAME} + PRIVATE + ${NET_RUNTIME_DIR}/native +) + +target_link_options( + ${LIB_NAME} + PRIVATE + ${XA_CXX_DSO_LINKER_ARGS} +) + +target_link_libraries( + ${LIB_NAME} + PRIVATE + xa::shared-no-abi + xa::unwind + xa::runtime-base + xa::java-interop + -lmonosgen-2.0 + -llog + ${CMAKE_SYSROOT}/usr/lib/${SYSROOT_ABI_LIB_DIR}/${TOOLCHAIN_TRIPLE}/libc++abi.a +) + +xa_add_compile_definitions(${LIB_NAME}) diff --git a/src/native/tracing/native-tracing.hh b/src/native/tracing/native-tracing.hh index 6f08e7273b3..f10697ae666 100644 --- a/src/native/tracing/native-tracing.hh +++ b/src/native/tracing/native-tracing.hh @@ -5,7 +5,9 @@ #include #include +#if !defined(UNW_LOCAL_ONLY) #define UNW_LOCAL_ONLY +#endif #include // Public API must not expose any types that are part of libc++ - we don't know what version of the diff --git a/src/native/xamarin-app-stub/CMakeLists.txt b/src/native/xamarin-app-stub/CMakeLists.txt index ff40ebcc227..d04dd98348b 100644 --- a/src/native/xamarin-app-stub/CMakeLists.txt +++ b/src/native/xamarin-app-stub/CMakeLists.txt @@ -32,6 +32,12 @@ target_compile_options( ${XA_COMMON_CXX_ARGS} ) +target_link_options( + ${LIB_NAME} + PRIVATE + ${XA_CXX_DSO_LINKER_ARGS} +) + target_link_libraries( ${LIB_NAME} PRIVATE diff --git a/src/native/xamarin-debug-app-helper/CMakeLists.txt b/src/native/xamarin-debug-app-helper/CMakeLists.txt index 1a831a1d7a8..a6bc43a05ba 100644 --- a/src/native/xamarin-debug-app-helper/CMakeLists.txt +++ b/src/native/xamarin-debug-app-helper/CMakeLists.txt @@ -37,6 +37,12 @@ target_link_directories( ${NET_RUNTIME_DIR}/native ) +target_link_options( + ${LIB_NAME} + PRIVATE + ${XA_CXX_DSO_LINKER_ARGS} +) + target_link_libraries( ${LIB_NAME} PRIVATE From c45283bd6d9adfdc70fd461288940bef0d02c0a0 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 17 Apr 2024 11:20:54 +0200 Subject: [PATCH 12/23] Should fully build now --- src/native/libunwind/CMakeLists.txt | 6 +----- src/native/monodroid/CMakeLists.txt | 2 +- src/native/tracing/CMakeLists.txt | 5 +++-- src/native/xamarin-app-stub/CMakeLists.txt | 12 ++++++++++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/native/libunwind/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt index 68005783341..286bf7dabc5 100644 --- a/src/native/libunwind/CMakeLists.txt +++ b/src/native/libunwind/CMakeLists.txt @@ -1,5 +1,5 @@ ensure_variable_set(LIBUNWIND_SOURCE_DIR) -set(LIB_NAME unwind-xamarin) +set(LIB_NAME unwind_xamarin) set(LIB_ALIAS xa::unwind) # @@ -335,10 +335,6 @@ target_include_directories( ${LIB_NAME} PUBLIC "$" - # "$" - # "$" - # "$" - # "$" ) if(TARGET_ARM) diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index 852c8488bd0..7f0706ef161 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -141,7 +141,7 @@ target_include_directories( SYSTEM PRIVATE ${SYSROOT_CXX_INCLUDE_DIR} ${MONO_RUNTIME_INCLUDE_DIR} - ${NATIVE_TRACING_INCLUDE_DIR} + ${NATIVE_TRACING_INCLUDE_DIRS} ${LIBUNWIND_INCLUDE_DIRS} ) diff --git a/src/native/tracing/CMakeLists.txt b/src/native/tracing/CMakeLists.txt index 1b5ac0f4c03..1ff574f5cf7 100644 --- a/src/native/tracing/CMakeLists.txt +++ b/src/native/tracing/CMakeLists.txt @@ -1,7 +1,8 @@ set(LIB_NAME xamarin-native-tracing) set(LIB_ALIAS xa::native-tracing) -set(NATIVE_TRACING_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) +set(NATIVE_TRACING_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") +set(NATIVE_TRACING_INCLUDE_DIRS "${NATIVE_TRACING_INCLUDE_DIRS}" PARENT_SCOPE) set(XAMARIN_TRACING_SOURCES native-tracing.cc @@ -18,7 +19,7 @@ add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) target_include_directories( ${LIB_NAME} PUBLIC - "$" + "$" ) target_include_directories( diff --git a/src/native/xamarin-app-stub/CMakeLists.txt b/src/native/xamarin-app-stub/CMakeLists.txt index d04dd98348b..40715846857 100644 --- a/src/native/xamarin-app-stub/CMakeLists.txt +++ b/src/native/xamarin-app-stub/CMakeLists.txt @@ -13,10 +13,12 @@ add_library( add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) +set(XAMARIN_APP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") +set(XAMARIN_APP_INCLUDE_DIRS "${XAMARIN_APP_INCLUDE_DIRS}" PARENT_SCOPE) target_include_directories( ${LIB_NAME} PUBLIC - "$" + "$" ) target_include_directories( @@ -44,10 +46,16 @@ target_link_libraries( xa::shared ) +if(DEBUG_BUILD) + set(LIB_SUBDIR "Debug") +else() + set(LIB_SUBDIR "Release") +endif() + set_target_properties( ${LIB_NAME} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIB_SUBDIR}" ) xa_add_compile_definitions(${LIB_NAME}) From 4a317bb83937782843416013b3f71ba590bb5dcc Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 17 Apr 2024 18:09:30 +0200 Subject: [PATCH 13/23] A few more build tweaks, mostly for analyzer builds --- src/native/CMakeLists.txt | 7 + src/native/libunwind/CMakeLists.txt | 2 + src/native/monodroid/CMakeLists.txt | 5 +- src/native/native.targets | 10 ++ src/native/runtime-base/CMakeLists.txt | 2 +- src/native/runtime-base/logger.cc | 113 ----------------- src/native/runtime-base/logger.hh | 29 +---- src/native/shared/CMakeLists.txt | 8 ++ src/native/shared/log_functions.cc | 120 ++++++++++++++++++ src/native/shared/log_types.hh | 35 +++++ src/native/tracing/CMakeLists.txt | 1 + src/native/tracing/native-tracing.cc | 2 +- src/native/xamarin-app-stub/CMakeLists.txt | 3 +- .../xamarin-debug-app-helper/CMakeLists.txt | 3 +- 14 files changed, 193 insertions(+), 147 deletions(-) create mode 100644 src/native/shared/log_functions.cc create mode 100644 src/native/shared/log_types.hh diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index aa890661804..e940659baa1 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -99,6 +99,13 @@ else() set(USES_LIBSTDCPP True) endif() +if(ANALYZERS_ENABLED) + message(STATUS "Analyzers enabled") + set(SHARED_LIB_NAME xa::shared-no-abi) +else() + message(STATUS "NO analyzers enabled") + set(SHARED_LIB_NAME xa::shared) +endif() # # Needed modules # diff --git a/src/native/libunwind/CMakeLists.txt b/src/native/libunwind/CMakeLists.txt index 286bf7dabc5..3de53d23d34 100644 --- a/src/native/libunwind/CMakeLists.txt +++ b/src/native/libunwind/CMakeLists.txt @@ -55,7 +55,9 @@ list(APPEND POTENTIAL_LOCAL_COMPILER_ARGS -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-macro-redefined + -Wno-sign-conversion -Wno-single-bit-bitfield-constant-conversion + -Wno-tautological-constant-out-of-range-compare ) xa_check_c_args(LIBUNWIND_C_ARGS "${POTENTIAL_LOCAL_COMPILER_ARGS}") diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index 7f0706ef161..5d4bf1f723a 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -155,14 +155,15 @@ target_link_options( ${XAMARIN_MONO_ANDROID_LIB} PRIVATE ${XA_DEFAULT_SYMBOL_VISIBILITY} + ${XA_COMMON_CXX_LINKER_ARGS} ${XA_CXX_DSO_LINKER_ARGS} - ) +) target_link_libraries( ${XAMARIN_MONO_ANDROID_LIB} ${LINK_LIBS} xa::xamarin-app - xa::shared + ${SHARED_LIB_NAME} xa::runtime-base xa::java-interop xa::lz4 diff --git a/src/native/native.targets b/src/native/native.targets index 97394fd5c65..67bb4bb46d9 100644 --- a/src/native/native.targets +++ b/src/native/native.targets @@ -8,14 +8,24 @@ <_ConfigureRuntimesInputs Include="CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="java-interop\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="libstub\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="libunwind\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="lz4\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="monodroid\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="runtime-base\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="shared\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="shared\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="tracing\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="xamarin-app-debug-helper\CMakeLists.txt" /> + <_ConfigureRuntimesInputs Include="xamarin-app-stub\CMakeLists.txt" /> <_ConfigureRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" /> <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Debug\CMakeCache.txt')" /> <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Release\CMakeCache.txt')" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-asan-Debug\CMakeCache.txt')" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-asan-Release\CMakeCache.txt')" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-ubsan-Debug\CMakeCache.txt')" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> + <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-ubsan-Release\CMakeCache.txt')" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug" /> <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release" /> <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> diff --git a/src/native/runtime-base/CMakeLists.txt b/src/native/runtime-base/CMakeLists.txt index a10a50da582..954b15277c3 100644 --- a/src/native/runtime-base/CMakeLists.txt +++ b/src/native/runtime-base/CMakeLists.txt @@ -47,7 +47,7 @@ target_include_directories( target_link_libraries( ${LIB_NAME} PRIVATE - xa::shared + ${SHARED_LIB_NAME} xa::xamarin-app ) diff --git a/src/native/runtime-base/logger.cc b/src/native/runtime-base/logger.cc index 0b62f3c87b8..4f39b25ff6b 100644 --- a/src/native/runtime-base/logger.cc +++ b/src/native/runtime-base/logger.cc @@ -16,42 +16,9 @@ #include "shared-constants.hh" #include "util.hh" -#undef DO_LOG -#define DO_LOG(_level_,_category_,_format_,_args_) \ - va_start ((_args_), (_format_)); \ - __android_log_vprint ((_level_), CATEGORY_NAME((_category_)), (_format_), (_args_)); \ - va_end ((_args_)); - using namespace xamarin::android; using namespace xamarin::android::internal; -// Must match the same ordering as LogCategories -static constexpr std::array log_names = { - "*none*", - "monodroid", - "monodroid-assembly", - "monodroid-debug", - "monodroid-gc", - "monodroid-gref", - "monodroid-lref", - "monodroid-timing", - "monodroid-bundle", - "monodroid-network", - "monodroid-netlink", - "*error*", -}; - -#if defined(__i386__) && defined(__GNUC__) -#define ffs(__value__) __builtin_ffs ((__value__)) -#elif defined(__x86_64__) && defined(__GNUC__) -#define ffs(__value__) __builtin_ffsll ((__value__)) -#endif - -// ffs(value) returns index of lowest bit set in `value` -#define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [static_cast(ffs (value))]) - -unsigned int log_categories = LOG_NONE; - namespace { FILE* open_file (LogCategories category, const char *path, const char *override_dir, const char *filename) @@ -277,83 +244,3 @@ Logger::init_logging_categories (char*& mono_log_mask, char*& mono_log_level) no _gc_spew_enabled = 1; #endif /* DEBUG */ } - -void -log_error (LogCategories category, const char *format, ...) -{ - va_list args; - - DO_LOG (ANDROID_LOG_ERROR, category, format, args); -} - -void -log_fatal (LogCategories category, const char *format, ...) -{ - va_list args; - - DO_LOG (ANDROID_LOG_FATAL, category, format, args); -} - -void -log_info_nocheck (LogCategories category, const char *format, ...) -{ - va_list args; - - if ((log_categories & category) == 0) - return; - - DO_LOG (ANDROID_LOG_INFO, category, format, args); -} - -void -log_warn (LogCategories category, const char *format, ...) -{ - va_list args; - - DO_LOG (ANDROID_LOG_WARN, category, format, args); -} - -void -log_debug_nocheck (LogCategories category, const char *format, ...) -{ - va_list args; - - if ((log_categories & category) == 0) - return; - - DO_LOG (ANDROID_LOG_DEBUG, category, format, args); -} - -constexpr android_LogPriority DEFAULT_PRIORITY = ANDROID_LOG_INFO; - -// relies on the fact that the LogLevel enum has sequential values -static constexpr android_LogPriority loglevel_map[] = { - DEFAULT_PRIORITY, // Unknown - DEFAULT_PRIORITY, // Default - ANDROID_LOG_VERBOSE, // Verbose - ANDROID_LOG_DEBUG, // Debug - ANDROID_LOG_INFO, // Info - ANDROID_LOG_WARN, // Warn - ANDROID_LOG_ERROR, // Error - ANDROID_LOG_FATAL, // Fatal - ANDROID_LOG_SILENT, // Silent -}; - -static constexpr size_t loglevel_map_max_index = (sizeof(loglevel_map) / sizeof(android_LogPriority)) - 1; - -namespace xamarin::android { - void - log_write (LogCategories category, LogLevel level, const char *message) noexcept - { - size_t map_index = static_cast(level); - android_LogPriority priority; - - if (map_index > loglevel_map_max_index) { - priority = DEFAULT_PRIORITY; - } else { - priority = loglevel_map[map_index]; - } - - __android_log_write (priority, CATEGORY_NAME (category), message); - } -} diff --git a/src/native/runtime-base/logger.hh b/src/native/runtime-base/logger.hh index 6a477f1a4c7..2111c628bdd 100644 --- a/src/native/runtime-base/logger.hh +++ b/src/native/runtime-base/logger.hh @@ -3,17 +3,10 @@ #include -#include "java-interop-logger.h" +#include "log_types.hh" #include "strings.hh" namespace xamarin::android { - enum class LogTimingCategories : uint32_t - { - Default = 0, - Bare = 1 << 0, - FastBare = 1 << 1, - }; - class Logger { public: @@ -60,25 +53,5 @@ namespace xamarin::android { static inline int _gc_spew_enabled = 0; #endif // def DEBUG }; - - // Keep in sync with LogLevel defined in JNIEnv.cs - enum class LogLevel : unsigned int - { - Unknown = 0x00, - Default = 0x01, - Verbose = 0x02, - Debug = 0x03, - Info = 0x04, - Warn = 0x05, - Error = 0x06, - Fatal = 0x07, - Silent = 0x08 - }; - - // A slightly faster alternative to other log functions as it doesn't parse the message - // for format placeholders nor it uses variable arguments - void log_write (LogCategories category, LogLevel level, const char *message) noexcept; } - -extern unsigned int log_categories; #endif diff --git a/src/native/shared/CMakeLists.txt b/src/native/shared/CMakeLists.txt index 23f3fe105b3..4f60ac53c25 100644 --- a/src/native/shared/CMakeLists.txt +++ b/src/native/shared/CMakeLists.txt @@ -11,6 +11,7 @@ set(XA_SHARED_CXX_ABI_SOURCES set(XA_SHARED_SOURCES helpers.cc + log_functions.cc new_delete.cc ) @@ -42,6 +43,13 @@ macro(lib_target_options TARGET_NAME) "$" ) + target_link_libraries( + ${TARGET_NAME} + PUBLIC + xa::java-interop + -llog + ) + target_include_directories( ${TARGET_NAME} SYSTEM PRIVATE diff --git a/src/native/shared/log_functions.cc b/src/native/shared/log_functions.cc new file mode 100644 index 00000000000..114bc0186e7 --- /dev/null +++ b/src/native/shared/log_functions.cc @@ -0,0 +1,120 @@ +#include +#include + +#include + +#include "java-interop-logger.h" +#include "log_types.hh" + +// Must match the same ordering as LogCategories +static constexpr std::array log_names = { + "*none*", + "monodroid", + "monodroid-assembly", + "monodroid-debug", + "monodroid-gc", + "monodroid-gref", + "monodroid-lref", + "monodroid-timing", + "monodroid-bundle", + "monodroid-network", + "monodroid-netlink", + "*error*", +}; + +#if defined(__i386__) && defined(__GNUC__) +#define ffs(__value__) __builtin_ffs ((__value__)) +#elif defined(__x86_64__) && defined(__GNUC__) +#define ffs(__value__) __builtin_ffsll ((__value__)) +#endif + +// ffs(value) returns index of lowest bit set in `value` +#define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [static_cast(ffs (value))]) + +unsigned int log_categories = LOG_NONE; + +#undef DO_LOG +#define DO_LOG(_level_,_category_,_format_,_args_) \ + va_start ((_args_), (_format_)); \ + __android_log_vprint ((_level_), CATEGORY_NAME((_category_)), (_format_), (_args_)); \ + va_end ((_args_)); + +void +log_error (LogCategories category, const char *format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_ERROR, category, format, args); +} + +void +log_fatal (LogCategories category, const char *format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_FATAL, category, format, args); +} + +void +log_info_nocheck (LogCategories category, const char *format, ...) +{ + va_list args; + + if ((log_categories & category) == 0) + return; + + DO_LOG (ANDROID_LOG_INFO, category, format, args); +} + +void +log_warn (LogCategories category, const char *format, ...) +{ + va_list args; + + DO_LOG (ANDROID_LOG_WARN, category, format, args); +} + +void +log_debug_nocheck (LogCategories category, const char *format, ...) +{ + va_list args; + + if ((log_categories & category) == 0) + return; + + DO_LOG (ANDROID_LOG_DEBUG, category, format, args); +} + +constexpr android_LogPriority DEFAULT_PRIORITY = ANDROID_LOG_INFO; + +// relies on the fact that the LogLevel enum has sequential values +static constexpr android_LogPriority loglevel_map[] = { + DEFAULT_PRIORITY, // Unknown + DEFAULT_PRIORITY, // Default + ANDROID_LOG_VERBOSE, // Verbose + ANDROID_LOG_DEBUG, // Debug + ANDROID_LOG_INFO, // Info + ANDROID_LOG_WARN, // Warn + ANDROID_LOG_ERROR, // Error + ANDROID_LOG_FATAL, // Fatal + ANDROID_LOG_SILENT, // Silent +}; + +static constexpr size_t loglevel_map_max_index = (sizeof(loglevel_map) / sizeof(android_LogPriority)) - 1; + +namespace xamarin::android { + void + log_write (LogCategories category, LogLevel level, const char *message) noexcept + { + size_t map_index = static_cast(level); + android_LogPriority priority; + + if (map_index > loglevel_map_max_index) { + priority = DEFAULT_PRIORITY; + } else { + priority = loglevel_map[map_index]; + } + + __android_log_write (priority, CATEGORY_NAME (category), message); + } +} diff --git a/src/native/shared/log_types.hh b/src/native/shared/log_types.hh new file mode 100644 index 00000000000..b0ed20018d9 --- /dev/null +++ b/src/native/shared/log_types.hh @@ -0,0 +1,35 @@ +#if !defined(LOG_LEVEL_HH) +#define LOG_LEVEL_HH + +#include + +#include "java-interop-logger.h" + +namespace xamarin::android { + enum class LogTimingCategories : uint32_t + { + Default = 0, + Bare = 1 << 0, + FastBare = 1 << 1, + }; + + // Keep in sync with LogLevel defined in JNIEnv.cs + enum class LogLevel : unsigned int + { + Unknown = 0x00, + Default = 0x01, + Verbose = 0x02, + Debug = 0x03, + Info = 0x04, + Warn = 0x05, + Error = 0x06, + Fatal = 0x07, + Silent = 0x08 + }; + + // A slightly faster alternative to other log functions as it doesn't parse the message + // for format placeholders nor it uses variable arguments + void log_write (LogCategories category, LogLevel level, const char *message) noexcept; +} +extern unsigned int log_categories; +#endif // ndef LOG_LEVEL_HH diff --git a/src/native/tracing/CMakeLists.txt b/src/native/tracing/CMakeLists.txt index 1ff574f5cf7..d028f1fd581 100644 --- a/src/native/tracing/CMakeLists.txt +++ b/src/native/tracing/CMakeLists.txt @@ -54,6 +54,7 @@ target_link_directories( target_link_options( ${LIB_NAME} PRIVATE + ${XA_COMMON_CXX_LINKER_ARGS} ${XA_CXX_DSO_LINKER_ARGS} ) diff --git a/src/native/tracing/native-tracing.cc b/src/native/tracing/native-tracing.cc index 5b69cda234a..f76983a3ef1 100644 --- a/src/native/tracing/native-tracing.cc +++ b/src/native/tracing/native-tracing.cc @@ -158,7 +158,7 @@ const char* xa_get_java_backtrace (JNIEnv *env) noexcept trace.append ("\n"); } - append_frame_number (trace, i); + append_frame_number (trace, static_cast(i)); trace.append (frame_desc); env->ReleaseStringUTFChars (frame_desc_java, frame_desc); } diff --git a/src/native/xamarin-app-stub/CMakeLists.txt b/src/native/xamarin-app-stub/CMakeLists.txt index 40715846857..fa912688d0e 100644 --- a/src/native/xamarin-app-stub/CMakeLists.txt +++ b/src/native/xamarin-app-stub/CMakeLists.txt @@ -37,13 +37,14 @@ target_compile_options( target_link_options( ${LIB_NAME} PRIVATE + ${XA_COMMON_CXX_LINKER_ARGS} ${XA_CXX_DSO_LINKER_ARGS} ) target_link_libraries( ${LIB_NAME} PRIVATE - xa::shared + ${SHARED_LIB_NAME} ) if(DEBUG_BUILD) diff --git a/src/native/xamarin-debug-app-helper/CMakeLists.txt b/src/native/xamarin-debug-app-helper/CMakeLists.txt index a6bc43a05ba..18675eb7a1e 100644 --- a/src/native/xamarin-debug-app-helper/CMakeLists.txt +++ b/src/native/xamarin-debug-app-helper/CMakeLists.txt @@ -40,13 +40,14 @@ target_link_directories( target_link_options( ${LIB_NAME} PRIVATE + ${XA_COMMON_CXX_LINKER_ARGS} ${XA_CXX_DSO_LINKER_ARGS} ) target_link_libraries( ${LIB_NAME} PRIVATE - xa::shared + ${SHARED_LIB_NAME} xa::xamarin-app xa::runtime-base xa::java-interop From f09a8392a800445d7cf58d46b21e634b7448248a Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 18 Apr 2024 15:50:35 +0200 Subject: [PATCH 14/23] Update apkdesc files --- .../BuildReleaseArm64SimpleDotNet.apkdesc | 33 ++++---- .../BuildReleaseArm64XFormsDotNet.apkdesc | 83 ++++++++++--------- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index aa48fb18d6c..b526f27e731 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -11,43 +11,43 @@ "Size": 1027 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 64238 + "Size": 64240 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { "Size": 91590 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5318 + "Size": 5317 }, "lib/arm64-v8a/lib_System.Console.dll.so": { - "Size": 6543 + "Size": 6539 }, "lib/arm64-v8a/lib_System.Linq.dll.so": { - "Size": 8520 + "Size": 8525 }, "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { - "Size": 566145 + "Size": 570166 }, "lib/arm64-v8a/lib_System.Runtime.dll.so": { - "Size": 2545 + "Size": 2544 }, "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { - "Size": 4017 + "Size": 4020 }, "lib/arm64-v8a/lib_UnnamedProject.dll.so": { - "Size": 2932 + "Size": 2933 }, "lib/arm64-v8a/libarc.bin.so": { - "Size": 1512 + "Size": 1586 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 481952 + "Size": 444392 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3135328 + "Size": 3138768 }, "lib/arm64-v8a/libSystem.Globalization.Native.so": { "Size": 67248 @@ -62,16 +62,19 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 12696 + "Size": 12984 + }, + "lib/arm64-v8a/libxamarin-native-tracing.so": { + "Size": 424360 }, "META-INF/BNDLTOOL.RSA": { "Size": 1223 }, "META-INF/BNDLTOOL.SF": { - "Size": 3266 + "Size": 3380 }, "META-INF/MANIFEST.MF": { - "Size": 3139 + "Size": 3253 }, "res/drawable-hdpi-v4/icon.png": { "Size": 2178 @@ -98,5 +101,5 @@ "Size": 1904 } }, - "PackageSize": 2738709 + "PackageSize": 2853485 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc index 979456f1439..88849656f9a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc @@ -38,13 +38,13 @@ "Size": 8090 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 72398 + "Size": 72410 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { "Size": 458239 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5318 + "Size": 5317 }, "lib/arm64-v8a/lib_mscorlib.dll.so": { "Size": 3991 @@ -53,61 +53,61 @@ "Size": 5625 }, "lib/arm64-v8a/lib_System.Collections.Concurrent.dll.so": { - "Size": 11517 + "Size": 11516 }, "lib/arm64-v8a/lib_System.Collections.dll.so": { - "Size": 15409 + "Size": 15411 }, "lib/arm64-v8a/lib_System.Collections.NonGeneric.dll.so": { - "Size": 7436 + "Size": 7441 }, "lib/arm64-v8a/lib_System.ComponentModel.dll.so": { - "Size": 1934 + "Size": 1933 }, "lib/arm64-v8a/lib_System.ComponentModel.Primitives.dll.so": { - "Size": 2548 + "Size": 2547 }, "lib/arm64-v8a/lib_System.ComponentModel.TypeConverter.dll.so": { - "Size": 6082 + "Size": 6081 }, "lib/arm64-v8a/lib_System.Console.dll.so": { - "Size": 6575 + "Size": 6571 }, "lib/arm64-v8a/lib_System.Core.dll.so": { - "Size": 1968 + "Size": 1969 }, "lib/arm64-v8a/lib_System.Diagnostics.DiagnosticSource.dll.so": { - "Size": 9057 + "Size": 9060 }, "lib/arm64-v8a/lib_System.Diagnostics.TraceSource.dll.so": { - "Size": 6543 + "Size": 6545 }, "lib/arm64-v8a/lib_System.dll.so": { - "Size": 2323 + "Size": 2325 }, "lib/arm64-v8a/lib_System.Drawing.dll.so": { - "Size": 1931 + "Size": 1930 }, "lib/arm64-v8a/lib_System.Drawing.Primitives.dll.so": { "Size": 11963 }, "lib/arm64-v8a/lib_System.IO.Compression.Brotli.dll.so": { - "Size": 11184 + "Size": 11183 }, "lib/arm64-v8a/lib_System.IO.Compression.dll.so": { - "Size": 15861 + "Size": 15859 }, "lib/arm64-v8a/lib_System.IO.IsolatedStorage.dll.so": { - "Size": 9893 + "Size": 9902 }, "lib/arm64-v8a/lib_System.Linq.dll.so": { - "Size": 20208 + "Size": 20211 }, "lib/arm64-v8a/lib_System.Linq.Expressions.dll.so": { - "Size": 164627 + "Size": 164628 }, "lib/arm64-v8a/lib_System.Net.Http.dll.so": { - "Size": 68134 + "Size": 68041 }, "lib/arm64-v8a/lib_System.Net.Primitives.dll.so": { "Size": 22237 @@ -116,49 +116,49 @@ "Size": 3587 }, "lib/arm64-v8a/lib_System.ObjectModel.dll.so": { - "Size": 8561 + "Size": 8563 }, "lib/arm64-v8a/lib_System.Private.CoreLib.dll.so": { - "Size": 872591 + "Size": 874803 }, "lib/arm64-v8a/lib_System.Private.DataContractSerialization.dll.so": { "Size": 193451 }, "lib/arm64-v8a/lib_System.Private.Uri.dll.so": { - "Size": 42906 + "Size": 42901 }, "lib/arm64-v8a/lib_System.Private.Xml.dll.so": { "Size": 215939 }, "lib/arm64-v8a/lib_System.Private.Xml.Linq.dll.so": { - "Size": 16624 + "Size": 16623 }, "lib/arm64-v8a/lib_System.Runtime.dll.so": { "Size": 2701 }, "lib/arm64-v8a/lib_System.Runtime.InteropServices.dll.so": { - "Size": 4017 + "Size": 4020 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.dll.so": { - "Size": 1858 + "Size": 1857 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.Formatters.dll.so": { - "Size": 2478 + "Size": 2477 }, "lib/arm64-v8a/lib_System.Runtime.Serialization.Primitives.dll.so": { - "Size": 3751 + "Size": 3750 }, "lib/arm64-v8a/lib_System.Security.Cryptography.dll.so": { - "Size": 8095 + "Size": 8101 }, "lib/arm64-v8a/lib_System.Text.RegularExpressions.dll.so": { - "Size": 161223 + "Size": 161254 }, "lib/arm64-v8a/lib_System.Xml.dll.so": { - "Size": 1753 + "Size": 1752 }, "lib/arm64-v8a/lib_System.Xml.Linq.dll.so": { - "Size": 1769 + "Size": 1768 }, "lib/arm64-v8a/lib_UnnamedProject.dll.so": { "Size": 5007 @@ -233,16 +233,16 @@ "Size": 66169 }, "lib/arm64-v8a/libarc.bin.so": { - "Size": 1512 + "Size": 1586 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 481952 + "Size": 444392 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3135328 + "Size": 3138768 }, "lib/arm64-v8a/libSystem.Globalization.Native.so": { "Size": 67248 @@ -257,7 +257,10 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 118920 + "Size": 119192 + }, + "lib/arm64-v8a/libxamarin-native-tracing.so": { + "Size": 424360 }, "META-INF/androidx.activity_activity.version": { "Size": 6 @@ -410,10 +413,10 @@ "Size": 6 }, "META-INF/BNDLTOOL.RSA": { - "Size": 1223 + "Size": 1221 }, "META-INF/BNDLTOOL.SF": { - "Size": 98298 + "Size": 98412 }, "META-INF/com.android.tools/proguard/coroutines.pro": { "Size": 1345 @@ -440,7 +443,7 @@ "Size": 5 }, "META-INF/MANIFEST.MF": { - "Size": 98171 + "Size": 98285 }, "META-INF/maven/com.google.guava/listenablefuture/pom.properties": { "Size": 96 @@ -2480,5 +2483,5 @@ "Size": 812848 } }, - "PackageSize": 10267688 + "PackageSize": 10386560 } \ No newline at end of file From fe3200848667a03b93951c4dcd98258dc468c99c Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Fri, 19 Apr 2024 16:39:54 +0200 Subject: [PATCH 15/23] Fix a handful of tests, plus... ...remove unused p/invoke + associated code (`monodroid_store_package_name`) ...fix endless recursion caused by a typo in `Util::ends_with` overload ...fix p/invoke include generation script ...update p/invoke dispatcher accordingly --- .../scripts/generate-pinvoke-tables.sh | 4 +- .../monodroid/jni/generate-pinvoke-tables.cc | 3 +- src/native/monodroid/jni/monodroid-glue.cc | 2 - .../monodroid/jni/pinvoke-override-api.cc | 6 --- .../monodroid/jni/pinvoke-tables.include | 4 +- src/native/runtime-base/util.cc | 41 ------------------- src/native/runtime-base/util.hh | 14 +++---- src/native/xamarin-app-stub/CMakeLists.txt | 1 - 8 files changed, 9 insertions(+), 66 deletions(-) diff --git a/build-tools/scripts/generate-pinvoke-tables.sh b/build-tools/scripts/generate-pinvoke-tables.sh index a63853f8562..160ce12520b 100755 --- a/build-tools/scripts/generate-pinvoke-tables.sh +++ b/build-tools/scripts/generate-pinvoke-tables.sh @@ -2,14 +2,14 @@ MY_DIR="$(dirname $0)" HOST="$(uname | tr A-Z a-z)" -MONODROID_SOURCE_DIR="${MY_DIR}/../../src/monodroid/jni" +NATIVE_DIR="${MY_DIR}/../../src/native" +MONODROID_SOURCE_DIR="${NATIVE_DIR}/monodroid/jni" GENERATOR_SOURCE="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables.cc" GENERATOR_BINARY="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables" TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include" GENERATED_FILE="${TARGET_FILE}.generated" DIFF_FILE="${TARGET_FILE}.diff" EXTERNAL_DIR="${MY_DIR}/../../external/" -NATIVE_DIR="${MY_DIR}/../../src/native" function die() { diff --git a/src/native/monodroid/jni/generate-pinvoke-tables.cc b/src/native/monodroid/jni/generate-pinvoke-tables.cc index c29358d1e5b..54886c5a48d 100644 --- a/src/native/monodroid/jni/generate-pinvoke-tables.cc +++ b/src/native/monodroid/jni/generate-pinvoke-tables.cc @@ -1,7 +1,7 @@ // // To build and run this utility run (on Linux or macOS): // -// ../../../build-tools/scripts/generate-pinvoke-tables.sh +// ../../../../build-tools/scripts/generate-pinvoke-tables.sh // // A reasonable C++20 compiler is required (g++ 10+, clang 11+, on mac it may require XCode 12.5 or newer) // @@ -67,7 +67,6 @@ const std::vector internal_pinvoke_names = { "_monodroid_lref_log_delete", "_monodroid_lref_log_new", "_monodroid_max_gref_get", - "monodroid_store_package_name", "monodroid_strdup_printf", "monodroid_strfreev", "monodroid_strsplit", diff --git a/src/native/monodroid/jni/monodroid-glue.cc b/src/native/monodroid/jni/monodroid-glue.cc index 79fbbed84f1..bde0d634242 100644 --- a/src/native/monodroid/jni/monodroid-glue.cc +++ b/src/native/monodroid/jni/monodroid-glue.cc @@ -1610,8 +1610,6 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl java_TimeZone = RuntimeUtil::get_class_from_runtime_field (env, klass, "java_util_TimeZone", true); - Util::monodroid_store_package_name (application_config.android_package_name); - jstring_wrapper jstr (env, lang); set_environment_variable ("LANG", jstr); diff --git a/src/native/monodroid/jni/pinvoke-override-api.cc b/src/native/monodroid/jni/pinvoke-override-api.cc index a83c544a074..c020027eb8a 100644 --- a/src/native/monodroid/jni/pinvoke-override-api.cc +++ b/src/native/monodroid/jni/pinvoke-override-api.cc @@ -267,12 +267,6 @@ monodroid_TypeManager_get_java_class_name (jclass klass) return monodroidRuntime.get_java_class_name_for_TypeManager (klass); } -static void -monodroid_store_package_name (const char *name) -{ - Util::monodroid_store_package_name (name); -} - static int monodroid_get_namespaced_system_property (const char *name, char **value) { diff --git a/src/native/monodroid/jni/pinvoke-tables.include b/src/native/monodroid/jni/pinvoke-tables.include index e358a4d848f..b422e0917a6 100644 --- a/src/native/monodroid/jni/pinvoke-tables.include +++ b/src/native/monodroid/jni/pinvoke-tables.include @@ -13,7 +13,6 @@ static PinvokeEntry internal_pinvokes[] = { {0x452e23128e42f0a, "monodroid_get_log_categories", reinterpret_cast(&monodroid_get_log_categories)}, {0xa50ce5de13bf8b5, "_monodroid_timezone_get_default_id", reinterpret_cast(&_monodroid_timezone_get_default_id)}, {0x19055d65edfd668e, "_monodroid_get_network_interface_up_state", reinterpret_cast(&_monodroid_get_network_interface_up_state)}, - {0x2637a308c07d56b2, "monodroid_store_package_name", reinterpret_cast(&monodroid_store_package_name)}, {0x2b3b0ca1d14076da, "monodroid_get_dylib", reinterpret_cast(&monodroid_get_dylib)}, {0x2fbe68718cf2510d, "_monodroid_get_identity_hash_code", reinterpret_cast(&_monodroid_get_identity_hash_code)}, {0x3ade4348ac8ce0fa, "_monodroid_freeifaddrs", reinterpret_cast(&_monodroid_freeifaddrs)}, @@ -536,7 +535,6 @@ static PinvokeEntry internal_pinvokes[] = { {0xc439b5d7, "_monodroid_lookup_replacement_type", reinterpret_cast(&_monodroid_lookup_replacement_type)}, {0xc5146c54, "_monodroid_gref_log_delete", reinterpret_cast(&_monodroid_gref_log_delete)}, {0xc58eafa5, "java_interop_free", reinterpret_cast(&java_interop_free)}, - {0xc6c99d41, "monodroid_store_package_name", reinterpret_cast(&monodroid_store_package_name)}, {0xd3b5d2c1, "_monodroid_freeifaddrs", reinterpret_cast(&_monodroid_freeifaddrs)}, {0xd78c749d, "monodroid_get_log_categories", reinterpret_cast(&monodroid_get_log_categories)}, {0xd91f3619, "create_public_directory", reinterpret_cast(&create_public_directory)}, @@ -991,5 +989,5 @@ constexpr hash_t system_io_compression_native_library_hash = 0xafe3142c; constexpr hash_t system_security_cryptography_native_android_library_hash = 0x93625cd; #endif -constexpr size_t internal_pinvokes_count = 50; +constexpr size_t internal_pinvokes_count = 49; constexpr size_t dotnet_pinvokes_count = 428; diff --git a/src/native/runtime-base/util.cc b/src/native/runtime-base/util.cc index a5ff68f04a8..b1de31a6e6d 100644 --- a/src/native/runtime-base/util.cc +++ b/src/native/runtime-base/util.cc @@ -54,47 +54,6 @@ Util::recv_uninterrupted (int fd, void *buf, size_t len) return static_cast(total); } -template -inline void -Util::package_hash_to_hex (IdxType /* idx */) -{ - package_property_suffix[sizeof (package_property_suffix) / sizeof (char) - 1] = 0x00; -} - -template -inline void -Util::package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices) -{ - package_property_suffix [idx] = hex_chars [(hash & (0xF0000000 >> idx * 4)) >> ((7 - idx) * 4)]; - package_hash_to_hex (hash, indices...); -} - -void -Util::monodroid_store_package_name (const char *name) -{ - if (!name || *name == '\0') - return; - - /* Android properties can be at most 32 bytes long (!) and so we mustn't append the package name - * as-is since it will most likely generate conflicts (packages tend to be named - * com.mycompany.app), so we simply generate a hash code and use that instead. We treat the name - * as a stream of bytes assumming it's an ASCII string using a simplified version of the hash - * algorithm used by BCL's String.GetHashCode () - */ - const char *ch = name; - uint32_t hash = 0; - while (*ch) - hash = (hash << 5) - (hash + static_cast(*ch++)); - - // In C++14 or newer we could use std::index_sequence, but in C++11 it's a bit too much ado - // for this simple case, so a manual sequence it is. - // - // And yes, I know it could be done in a simple loop or in even simpler 8 lines of code, but - // that would be boring, wouldn't it? :) - package_hash_to_hex (hash, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u); - log_debug (LOG_DEFAULT, "Generated hash 0x%s for package name %s", package_property_suffix, name); -} - MonoAssembly* Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename) { diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 87b03319d4b..0f67ae6d84e 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -58,7 +58,6 @@ namespace xamarin::android return page_size; } - static void monodroid_store_package_name (const char *name); static MonoAssembly *monodroid_load_assembly (MonoDomain *domain, const char *basename); static MonoAssembly *monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename); static MonoClass *monodroid_get_class_from_name (MonoDomain *domain, const char* assembly, const char *_namespace, const char *type); @@ -167,7 +166,11 @@ namespace xamarin::android template static bool ends_with (internal::dynamic_local_string const& str, std::string_view const& sv) noexcept { - return ends_with(static_cast const&>(str), sv); + if (str.length () < sv.length ()) { + return false; + } + + return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; } static bool ends_with (const char *str, std::string_view const& sv) noexcept @@ -384,12 +387,6 @@ namespace xamarin::android } private: - template - static void package_hash_to_hex (IdxType idx); - - template - static void package_hash_to_hex (uint32_t hash, IdxType idx, Indices... indices); - template static constexpr void assert_char_type () { @@ -397,7 +394,6 @@ namespace xamarin::android } private: - static inline std::array package_property_suffix; static inline int page_size; }; } diff --git a/src/native/xamarin-app-stub/CMakeLists.txt b/src/native/xamarin-app-stub/CMakeLists.txt index fa912688d0e..13044940b7a 100644 --- a/src/native/xamarin-app-stub/CMakeLists.txt +++ b/src/native/xamarin-app-stub/CMakeLists.txt @@ -14,7 +14,6 @@ add_library( add_library(${LIB_ALIAS} ALIAS ${LIB_NAME}) set(XAMARIN_APP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") -set(XAMARIN_APP_INCLUDE_DIRS "${XAMARIN_APP_INCLUDE_DIRS}" PARENT_SCOPE) target_include_directories( ${LIB_NAME} PUBLIC From ce05433a6873710baafa3c97bfcbd4de0ec129f3 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 22 Apr 2024 11:48:59 +0200 Subject: [PATCH 16/23] Don't put the native tracing library in apk by default To include `libxamarin-native-tracing.so`, one has to request it by setting the `$(_AndroidEnableNativeStackTracing)` MSBuild property to `true` --- .../Microsoft.Android.Sdk.AssemblyResolution.targets | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets index 05c6c56639f..4ad281d2f17 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.AssemblyResolution.targets @@ -214,6 +214,7 @@ _ResolveAssemblies MSBuild target. <_AndroidIncludeSystemGlobalizationNative Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' == '' ">true + <_AndroidEnableNativeStackTracing Condition=" '$(_AndroidEnableNativeStackTracing)' == ''">false <_ResolvedNativeLibraries Include="@(ResolvedFileToPublish)" Condition=" '%(ResolvedFileToPublish.Extension)' == '.so' " /> @@ -224,11 +225,12 @@ _ResolveAssemblies MSBuild target. <_MonoComponent Condition=" '$(AndroidIncludeDebugSymbols)' == 'true' " Include="debugger" /> <_MonoComponent Condition=" '$(_AndroidExcludeMarshalIlgenComponent)' != 'true' " Include="marshal-ilgen" /> - <_MonoExcludedLibraries Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' != 'true' " Include="libSystem.Globalization.Native" /> + <_ExcludedNativeLibraries Condition=" '$(_AndroidIncludeSystemGlobalizationNative)' != 'true' " Include="libSystem.Globalization.Native" /> + <_ExcludedNativeLibraries Condition=" '$(_AndroidEnableNativeStackTracing)' != 'true' " Include="libxamarin-native-tracing" /> From ec09869674f1dc02bcc33979b8263898674dc05e Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 22 Apr 2024 15:31:51 +0200 Subject: [PATCH 17/23] Update apkdesc + use anonymous namespace --- .../BuildReleaseArm64SimpleDotNet.apkdesc | 19 +++++++---------- .../BuildReleaseArm64XFormsDotNet.apkdesc | 21 ++++++++----------- src/native/monodroid/jni/monodroid-tracing.cc | 16 +++++++------- 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index b526f27e731..0191375dc54 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -11,13 +11,13 @@ "Size": 1027 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 64240 + "Size": 64231 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { "Size": 91590 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5317 + "Size": 5315 }, "lib/arm64-v8a/lib_System.Console.dll.so": { "Size": 6539 @@ -44,7 +44,7 @@ "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 444392 + "Size": 476432 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 3138768 @@ -62,19 +62,16 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 12984 - }, - "lib/arm64-v8a/libxamarin-native-tracing.so": { - "Size": 424360 + "Size": 12696 }, "META-INF/BNDLTOOL.RSA": { - "Size": 1223 + "Size": 1221 }, "META-INF/BNDLTOOL.SF": { - "Size": 3380 + "Size": 3266 }, "META-INF/MANIFEST.MF": { - "Size": 3253 + "Size": 3139 }, "res/drawable-hdpi-v4/icon.png": { "Size": 2178 @@ -101,5 +98,5 @@ "Size": 1904 } }, - "PackageSize": 2853485 + "PackageSize": 2742805 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc index 88849656f9a..1fff2e3e9e1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc @@ -38,13 +38,13 @@ "Size": 8090 }, "lib/arm64-v8a/lib_Java.Interop.dll.so": { - "Size": 72410 + "Size": 72406 }, "lib/arm64-v8a/lib_Mono.Android.dll.so": { - "Size": 458239 + "Size": 458238 }, "lib/arm64-v8a/lib_Mono.Android.Runtime.dll.so": { - "Size": 5317 + "Size": 5315 }, "lib/arm64-v8a/lib_mscorlib.dll.so": { "Size": 3991 @@ -239,7 +239,7 @@ "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 444392 + "Size": 476432 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 3138768 @@ -257,10 +257,7 @@ "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 119192 - }, - "lib/arm64-v8a/libxamarin-native-tracing.so": { - "Size": 424360 + "Size": 118920 }, "META-INF/androidx.activity_activity.version": { "Size": 6 @@ -413,10 +410,10 @@ "Size": 6 }, "META-INF/BNDLTOOL.RSA": { - "Size": 1221 + "Size": 1223 }, "META-INF/BNDLTOOL.SF": { - "Size": 98412 + "Size": 98298 }, "META-INF/com.android.tools/proguard/coroutines.pro": { "Size": 1345 @@ -443,7 +440,7 @@ "Size": 5 }, "META-INF/MANIFEST.MF": { - "Size": 98285 + "Size": 98171 }, "META-INF/maven/com.google.guava/listenablefuture/pom.properties": { "Size": 96 @@ -2483,5 +2480,5 @@ "Size": 812848 } }, - "PackageSize": 10386560 + "PackageSize": 10271784 } \ No newline at end of file diff --git a/src/native/monodroid/jni/monodroid-tracing.cc b/src/native/monodroid/jni/monodroid-tracing.cc index 7f85117ae27..e5d0771d49b 100644 --- a/src/native/monodroid/jni/monodroid-tracing.cc +++ b/src/native/monodroid/jni/monodroid-tracing.cc @@ -5,18 +5,18 @@ #include "mono/utils/details/mono-dl-fallback-types.h" #include "monodroid-glue-internal.hh" #include "native-tracing.hh" -#include "cppcompat.hh" #include using namespace xamarin::android::internal; -static decltype(xa_get_native_backtrace)* _xa_get_native_backtrace; -static decltype(xa_get_managed_backtrace)* _xa_get_managed_backtrace; -static decltype(xa_get_java_backtrace)* _xa_get_java_backtrace; -static decltype(xa_get_interesting_signal_handlers)* _xa_get_interesting_signal_handlers; -static bool tracing_init_done; - -static std::mutex tracing_init_lock {}; +namespace { + decltype(xa_get_native_backtrace)* _xa_get_native_backtrace; + decltype(xa_get_managed_backtrace)* _xa_get_managed_backtrace; + decltype(xa_get_java_backtrace)* _xa_get_java_backtrace; + decltype(xa_get_interesting_signal_handlers)* _xa_get_interesting_signal_handlers; + bool tracing_init_done; + std::mutex tracing_init_lock {}; +} void MonodroidRuntime::log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept From e4a8eff978ec9c71c7460c86aec0d797613f5208 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Mon, 22 Apr 2024 08:41:23 -0700 Subject: [PATCH 18/23] Update policheck/source.gdnsuppress --- .gdn/policheck/source.gdnsuppress | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.gdn/policheck/source.gdnsuppress b/.gdn/policheck/source.gdnsuppress index f73824769dc..564ebc5b8db 100644 --- a/.gdn/policheck/source.gdnsuppress +++ b/.gdn/policheck/source.gdnsuppress @@ -9,7 +9,7 @@ "default": { "name": "default", "createdDate": "2023-02-22 23:55:29Z", - "lastUpdatedDate": "2024-02-22 21:40:38Z" + "lastUpdatedDate": "2024-04-22 13:40:30Z" } }, "results": { @@ -101,10 +101,10 @@ "justification": "Reference to an Android logging function.", "createdDate": "2023-02-22 23:55:29Z" }, - "a2b4d032c59a9d1211d218c3cd550cf8febb369941d70284d07d03ebee855bc0": { - "signature": "a2b4d032c59a9d1211d218c3cd550cf8febb369941d70284d07d03ebee855bc0", + "bca629d8e7888af4116b013c6585b78d0908d248a80138339e0eb1620832eb10": { + "signature": "bca629d8e7888af4116b013c6585b78d0908d248a80138339e0eb1620832eb10", "alternativeSignatures": [ - "9feaec8a73b72e0d212c0e18d863e4fe16ff010c5d33cf8d47d8b0f465cc4c5e" + "f35d63032e4f346c1afcc299d50eb17a0a05ecea81ba3025f14c7fbf78b10100" ], "memberOf": [ "default" @@ -112,10 +112,10 @@ "justification": "Reference to find first set bit function.", "createdDate": "2023-02-22 23:55:29Z" }, - "1c87b45a6044d205dc3f3562f349c238f7cabe22b4609da762df9dc44151e9fb": { - "signature": "1c87b45a6044d205dc3f3562f349c238f7cabe22b4609da762df9dc44151e9fb", + "dc43990fd9fa6a44f2fb2fffcb0497571af4379f23090482035d79a98970e7ae": { + "signature": "dc43990fd9fa6a44f2fb2fffcb0497571af4379f23090482035d79a98970e7ae", "alternativeSignatures": [ - "9feaec8a73b72e0d212c0e18d863e4fe16ff010c5d33cf8d47d8b0f465cc4c5e" + "f35d63032e4f346c1afcc299d50eb17a0a05ecea81ba3025f14c7fbf78b10100" ], "memberOf": [ "default" @@ -123,10 +123,10 @@ "justification": "Reference to find first set bit function.", "createdDate": "2023-02-22 23:55:29Z" }, - "a6639098c4785509a4215c9e2fc10f82c06fce461915dc11a00227ddec558845": { - "signature": "a6639098c4785509a4215c9e2fc10f82c06fce461915dc11a00227ddec558845", + "eb60d4f1e48ca85ad5fa4a413d8ff76c4975bccb12931f51179d67c24a82f354": { + "signature": "eb60d4f1e48ca85ad5fa4a413d8ff76c4975bccb12931f51179d67c24a82f354", "alternativeSignatures": [ - "9feaec8a73b72e0d212c0e18d863e4fe16ff010c5d33cf8d47d8b0f465cc4c5e" + "f35d63032e4f346c1afcc299d50eb17a0a05ecea81ba3025f14c7fbf78b10100" ], "memberOf": [ "default" @@ -134,10 +134,10 @@ "justification": "Reference to find first set bit function.", "createdDate": "2023-02-22 23:55:29Z" }, - "f94ede7b396cb54934db2084f0879cd31a17ce2584eb01e0bfcd35324a724c31": { - "signature": "f94ede7b396cb54934db2084f0879cd31a17ce2584eb01e0bfcd35324a724c31", + "bb80a900ad96e4833eb7f54f55723a3425e846a290dd62b709d4714952cd9d45": { + "signature": "bb80a900ad96e4833eb7f54f55723a3425e846a290dd62b709d4714952cd9d45", "alternativeSignatures": [ - "9feaec8a73b72e0d212c0e18d863e4fe16ff010c5d33cf8d47d8b0f465cc4c5e" + "f35d63032e4f346c1afcc299d50eb17a0a05ecea81ba3025f14c7fbf78b10100" ], "memberOf": [ "default" From e1c3c8fcd0dfa4cb6a692fe151c9e6ce9391a7fc Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 22 Apr 2024 17:07:46 +0200 Subject: [PATCH 19/23] Drop use of some macros Using `std::source_location` we can now report on, well, source location without having to resort to C macros. --- src/native/monodroid/jni/debug.cc | 2 +- .../monodroid/jni/embedded-assemblies.cc | 5 ++--- .../monodroid/jni/monodroid-networkinfo.cc | 2 +- .../monodroid/jni/xamarin_getifaddrs.cc | 4 ++-- src/native/runtime-base/android-system.cc | 10 ++++----- src/native/runtime-base/strings.hh | 8 +++---- src/native/runtime-base/util.cc | 6 +++--- src/native/runtime-base/util.hh | 2 +- src/native/shared/cpp-util.hh | 11 ++++++---- src/native/shared/helpers.cc | 12 ++++++++++- src/native/shared/helpers.hh | 21 +++++++++++-------- 11 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/native/monodroid/jni/debug.cc b/src/native/monodroid/jni/debug.cc index b422feacd82..7397fece427 100644 --- a/src/native/monodroid/jni/debug.cc +++ b/src/native/monodroid/jni/debug.cc @@ -69,7 +69,7 @@ Debug::monodroid_profiler_load (const char *libmono_path, const char *desc, cons if (col != nullptr) { size_t name_len = static_cast(col - desc); - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, name_len, 1); + size_t alloc_size = Helpers::add_with_overflow_check (name_len, 1); mname_ptr = new char [alloc_size]; strncpy (mname_ptr, desc, name_len); mname_ptr [name_len] = 0; diff --git a/src/native/monodroid/jni/embedded-assemblies.cc b/src/native/monodroid/jni/embedded-assemblies.cc index a93f4f9ef5b..07eddf61114 100644 --- a/src/native/monodroid/jni/embedded-assemblies.cc +++ b/src/native/monodroid/jni/embedded-assemblies.cc @@ -1015,7 +1015,7 @@ EmbeddedAssemblies::typemap_load_index (int dir_fd, const char *dir_path, const bool EmbeddedAssemblies::typemap_load_file (BinaryTypeMapHeader &header, const char *dir_path, const char *file_path, int file_fd, TypeMap &module) { - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, header.assembly_name_length, 1); + size_t alloc_size = Helpers::add_with_overflow_check (header.assembly_name_length, 1); module.assembly_name = new char[alloc_size]; ssize_t nread = do_read (file_fd, module.assembly_name, header.assembly_name_length); @@ -1036,8 +1036,7 @@ EmbeddedAssemblies::typemap_load_file (BinaryTypeMapHeader &header, const char * // [name][index] size_t java_entry_size = header.java_name_width + sizeof(uint32_t); size_t managed_entry_size = header.managed_name_width + sizeof(uint32_t); - size_t data_size = ADD_WITH_OVERFLOW_CHECK ( - size_t, + size_t data_size = Helpers::add_with_overflow_check ( header.entry_count * java_entry_size, header.entry_count * managed_entry_size ); diff --git a/src/native/monodroid/jni/monodroid-networkinfo.cc b/src/native/monodroid/jni/monodroid-networkinfo.cc index e14aa71309e..50267299def 100644 --- a/src/native/monodroid/jni/monodroid-networkinfo.cc +++ b/src/native/monodroid/jni/monodroid-networkinfo.cc @@ -167,7 +167,7 @@ _monodroid_get_dns_servers (void **dns_servers_array) if (count <= 0) return 0; - size_t alloc_size = MULTIPLY_WITH_OVERFLOW_CHECK (size_t, sizeof (char*), static_cast(count)); + size_t alloc_size = Helpers::multiply_with_overflow_check (sizeof (char*), static_cast(count)); char **ret = (char**)malloc (alloc_size); char **p = ret; for (int i = 0; i < 8; i++) { diff --git a/src/native/monodroid/jni/xamarin_getifaddrs.cc b/src/native/monodroid/jni/xamarin_getifaddrs.cc index 211e250763f..d2dab9643eb 100644 --- a/src/native/monodroid/jni/xamarin_getifaddrs.cc +++ b/src/native/monodroid/jni/xamarin_getifaddrs.cc @@ -531,7 +531,7 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd size_t buf_size = static_cast(getpagesize ()); log_debug (LOG_NETLINK, "receive buffer size == %d", buf_size); - size_t alloc_size = MULTIPLY_WITH_OVERFLOW_CHECK (size_t, sizeof(*response), buf_size); + size_t alloc_size = Helpers::multiply_with_overflow_check (sizeof(*response), buf_size); response = (unsigned char*)malloc (alloc_size); ssize_t length = 0; if (!response) { @@ -879,7 +879,7 @@ get_link_address (const struct nlmsghdr *message, struct _monodroid_ifaddrs **if } if (payload_size > 0) { - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, payload_size, room_for_trailing_null); + size_t alloc_size = Helpers::add_with_overflow_check (payload_size, room_for_trailing_null); ifa->ifa_name = (char*)malloc (alloc_size); if (!ifa->ifa_name) { goto error; diff --git a/src/native/runtime-base/android-system.cc b/src/native/runtime-base/android-system.cc index c6643b7e19f..cdc73976dd9 100644 --- a/src/native/runtime-base/android-system.cc +++ b/src/native/runtime-base/android-system.cc @@ -107,7 +107,7 @@ AndroidSystem::add_system_property (const char *name, const char *value) noexcep } size_t name_len = strlen (name); - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, sizeof (BundledProperty), name_len + 1); + size_t alloc_size = Helpers::add_with_overflow_check (sizeof (BundledProperty), name_len + 1); p = reinterpret_cast (malloc (alloc_size)); if (p == nullptr) return; @@ -137,7 +137,7 @@ AndroidSystem::_monodroid__system_property_get (const char *name, char *sp_value char *buf = nullptr; if (sp_value_len < PROPERTY_VALUE_BUFFER_LEN) { - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, PROPERTY_VALUE_BUFFER_LEN, 1); + size_t alloc_size = Helpers::add_with_overflow_check (PROPERTY_VALUE_BUFFER_LEN, 1); log_warn (LOG_DEFAULT, "Buffer to store system property may be too small, will copy only %u bytes", sp_value_len); buf = new char [alloc_size]; } @@ -168,7 +168,7 @@ AndroidSystem::monodroid_get_system_property (const char *name, dynamic_local_st return len; value.assign (v, plen); - return ADD_WITH_OVERFLOW_CHECK (int, plen, 0); + return Helpers::add_with_overflow_check (plen, 0); } int @@ -191,7 +191,7 @@ AndroidSystem::monodroid_get_system_property (const char *name, char **value) no } if (len >= 0 && value) { - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, static_cast(len), 1); + size_t alloc_size = Helpers::add_with_overflow_check (static_cast(len), 1); *value = new char [alloc_size]; if (*value == nullptr) return -len; @@ -225,7 +225,7 @@ AndroidSystem::_monodroid_get_system_property_from_file (const char *path, char return file_size + 1; } - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, file_size, 1); + size_t alloc_size = Helpers::add_with_overflow_check (file_size, 1); *value = new char[alloc_size]; size_t len = fread (*value, 1, file_size, fp); diff --git a/src/native/runtime-base/strings.hh b/src/native/runtime-base/strings.hh index 97f22e0b805..a552abd345c 100644 --- a/src/native/runtime-base/strings.hh +++ b/src/native/runtime-base/strings.hh @@ -776,7 +776,7 @@ namespace xamarin::android::internal force_inline void ensure_have_extra (size_t length) noexcept { - size_t needed_space = ADD_WITH_OVERFLOW_CHECK (size_t, length, idx + 1); + size_t needed_space = Helpers::add_with_overflow_check (length, idx + 1); if (needed_space > buffer.size ()) { log_fatal ( LOG_DEFAULT, @@ -790,11 +790,11 @@ namespace xamarin::android::internal force_inline void resize_for_extra (size_t needed_space) noexcept { if constexpr (TStorage::has_resize) { - size_t required_space = ADD_WITH_OVERFLOW_CHECK (size_t, needed_space, idx + 1); + size_t required_space = Helpers::add_with_overflow_check (needed_space, idx + 1); size_t current_size = buffer.size (); if (required_space > current_size) { - size_t new_size = ADD_WITH_OVERFLOW_CHECK (size_t, current_size, (current_size / 2)); - new_size = ADD_WITH_OVERFLOW_CHECK (size_t, new_size, required_space); + size_t new_size = Helpers::add_with_overflow_check (current_size, (current_size / 2)); + new_size = Helpers::add_with_overflow_check (new_size, required_space); buffer.resize (new_size); } } diff --git a/src/native/runtime-base/util.cc b/src/native/runtime-base/util.cc index b1de31a6e6d..892d7fe5343 100644 --- a/src/native/runtime-base/util.cc +++ b/src/native/runtime-base/util.cc @@ -124,7 +124,7 @@ Util::path_combine (const char *path1, const char *path2) if (path2 == nullptr) return strdup_new (path1); - size_t len = ADD_WITH_OVERFLOW_CHECK (size_t, strlen (path1), strlen (path2) + 2); + size_t len = Helpers::add_with_overflow_check (strlen (path1), strlen (path2) + 2); char *ret = new char [len]; *ret = '\0'; @@ -341,7 +341,7 @@ Util::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tok size_t vector_size = (max_tokens > 0 && tokens_in_str >= max_tokens) ? max_tokens + 1 : tokens_in_str + 2; // Includes the terminating 'nullptr` entry - char **vector = static_cast(xmalloc (MULTIPLY_WITH_OVERFLOW_CHECK (size_t, sizeof(char*), vector_size))); + char **vector = static_cast(xmalloc (Helpers::multiply_with_overflow_check (sizeof(char*), vector_size))); size_t vector_idx = 0; while (*str != '\0' && !(max_tokens > 0 && vector_idx + 1 >= max_tokens)) { @@ -363,7 +363,7 @@ Util::monodroid_strsplit (const char *str, const char *delimiter, size_t max_tok } size_t toklen = static_cast((str - c)); - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, toklen, 1); + size_t alloc_size = Helpers::add_with_overflow_check (toklen, 1); char *token = static_cast(xmalloc (alloc_size)); strncpy (token, c, toklen); token [toklen] = '\0'; diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 0f67ae6d84e..718e2e87551 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -281,7 +281,7 @@ namespace xamarin::android return nullptr; } - size_t alloc_size = ADD_WITH_OVERFLOW_CHECK (size_t, len, 1); + size_t alloc_size = Helpers::add_with_overflow_check (len, 1); auto ret = new char[alloc_size]; memcpy (ret, s, len); ret[len] = '\0'; diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index 66dddc1d325..3ac87f9de82 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -33,10 +34,12 @@ do_abort_unless (const char* fmt, ...) #define abort_if_invalid_pointer_argument(_ptr_) abort_unless ((_ptr_) != nullptr, "Parameter '%s' must be a valid pointer", #_ptr_) #define abort_if_negative_integer_argument(_arg_) abort_unless ((_arg_) > 0, "Parameter '%s' must be larger than 0", #_arg_) -// Helpers to use in "printf debugging". Normally not used in code anywhere. No code should be shipped with any -// of the macros present. -#define PD_LOG_LOCATION() log_info_nocheck (LOG_DEFAULT, "loc: %s:%d (%s)", __FILE__, __LINE__, __FUNCTION__) -#define PD_LOG_FUNCTION() log_info_nocheck (LOG_DEFAULT, "%s [%s:%d]", __PRETTY_FUNCTION__, __FILE__, __LINE__) +// Helper to use in "printf debugging". Normally not used in code anywhere. No code should be shipped with any +// of the calls present. +force_inline inline void pd_log_location (std::source_location sloc = std::source_location::current ()) noexcept +{ + log_info_nocheck (LOG_DEFAULT, "loc: %s:%u ('%s')", sloc.file_name (), sloc.line (), sloc.function_name ()); +} namespace xamarin::android { diff --git a/src/native/shared/helpers.cc b/src/native/shared/helpers.cc index e3103c04597..5ccd7bd4e3f 100644 --- a/src/native/shared/helpers.cc +++ b/src/native/shared/helpers.cc @@ -3,7 +3,17 @@ using namespace xamarin::android; [[noreturn]] void -Helpers::abort_application () noexcept +Helpers::abort_application (bool log_location, std::source_location sloc) noexcept { + if (log_location) { + log_fatal ( + LOG_DEFAULT, + "Abort at %s:%u:%u ('%s')", + sloc.file_name (), + sloc.line (), + sloc.column (), + sloc.function_name () + ); + } std::abort (); } diff --git a/src/native/shared/helpers.hh b/src/native/shared/helpers.hh index 40eff78eaca..ea758799dd3 100644 --- a/src/native/shared/helpers.hh +++ b/src/native/shared/helpers.hh @@ -3,26 +3,28 @@ #include #include +#include #include #include "platform-compat.hh" namespace xamarin::android { -#define ADD_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::add_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) -#define MULTIPLY_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::multiply_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) +// #define ADD_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::add_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) +// #define MULTIPLY_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::multiply_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) class [[gnu::visibility("hidden")]] Helpers { public: template - force_inline static Ret add_with_overflow_check (const char *file, uint32_t line, P1 a, P2 b) noexcept + force_inline static Ret add_with_overflow_check (P1 a, P2 b, std::source_location sloc = std::source_location::current ()) noexcept { + constexpr bool DoNotLogLocation = false; Ret ret; if (__builtin_add_overflow (a, b, &ret)) [[unlikely]] { - log_fatal (LOG_DEFAULT, "Integer overflow on addition at %s:%u", file, line); - abort_application (); + log_fatal (LOG_DEFAULT, "Integer overflow on addition at %s:%u", sloc.file_name (), sloc.line ()); + abort_application (DoNotLogLocation); } return ret; @@ -40,19 +42,20 @@ namespace xamarin::android // fail // template - force_inline static Ret multiply_with_overflow_check (const char *file, uint32_t line, size_t a, size_t b) noexcept + force_inline static Ret multiply_with_overflow_check (size_t a, size_t b, std::source_location sloc = std::source_location::current ()) noexcept { + constexpr bool DoNotLogLocation = false; Ret ret; if (__builtin_mul_overflow (a, b, &ret)) [[unlikely]] { - log_fatal (LOG_DEFAULT, "Integer overflow on multiplication at %s:%u", file, line); - abort_application (); + log_fatal (LOG_DEFAULT, "Integer overflow on multiplication at %s:%u", sloc.file_name (), sloc.line ()); + abort_application (DoNotLogLocation); } return ret; } - [[noreturn]] static void abort_application () noexcept; + [[noreturn]] static void abort_application (bool log_location = true, std::source_location sloc = std::source_location::current ()) noexcept; }; } #endif // __HELPERS_HH From 8986fc2b23cd3d27c31da8073915df63bf3929d0 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 22 Apr 2024 17:21:35 +0200 Subject: [PATCH 20/23] Cleanup --- src/native/shared/helpers.hh | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/native/shared/helpers.hh b/src/native/shared/helpers.hh index ea758799dd3..ba576d0fef2 100644 --- a/src/native/shared/helpers.hh +++ b/src/native/shared/helpers.hh @@ -1,7 +1,6 @@ #ifndef __HELPERS_HH #define __HELPERS_HH -#include #include #include @@ -10,9 +9,6 @@ namespace xamarin::android { -// #define ADD_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::add_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) -// #define MULTIPLY_WITH_OVERFLOW_CHECK(__ret_type__, __a__, __b__) xamarin::android::Helpers::multiply_with_overflow_check<__ret_type__>(__FILE__, __LINE__, (__a__), (__b__)) - class [[gnu::visibility("hidden")]] Helpers { public: @@ -24,32 +20,21 @@ namespace xamarin::android if (__builtin_add_overflow (a, b, &ret)) [[unlikely]] { log_fatal (LOG_DEFAULT, "Integer overflow on addition at %s:%u", sloc.file_name (), sloc.line ()); - abort_application (DoNotLogLocation); + abort_application (DoNotLogLocation, sloc); } return ret; } - // Can't use templates as above with add_with_oveflow because of a bug in the clang compiler - // shipped with the NDK: - // - // https://github.com/android-ndk/ndk/issues/294 - // https://github.com/android-ndk/ndk/issues/295 - // https://bugs.llvm.org/show_bug.cgi?id=16404 - // - // Using templated parameter types for `a` and `b` would make clang generate that tries to - // use 128-bit integers and thus output code that calls `__muloti4` and so linking would - // fail - // - template - force_inline static Ret multiply_with_overflow_check (size_t a, size_t b, std::source_location sloc = std::source_location::current ()) noexcept + template + force_inline static Ret multiply_with_overflow_check (P1 a, P2 b, std::source_location sloc = std::source_location::current ()) noexcept { constexpr bool DoNotLogLocation = false; Ret ret; if (__builtin_mul_overflow (a, b, &ret)) [[unlikely]] { log_fatal (LOG_DEFAULT, "Integer overflow on multiplication at %s:%u", sloc.file_name (), sloc.line ()); - abort_application (DoNotLogLocation); + abort_application (DoNotLogLocation, sloc); } return ret; From 48cb44df72d8e92d005c8dc7e5a9852205b4ea35 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 23 Apr 2024 16:46:28 +0200 Subject: [PATCH 21/23] Hopefully final cleanup steps --- Configuration.props | 2 + .../scripts/generate-pinvoke-tables.sh | 2 +- src/native/.gitignore | 1 + src/native/CMakeLists.txt | 20 ++ src/native/java-interop/CMakeLists.txt | 1 + src/native/monodroid/.gitignore | 4 + src/native/monodroid/CMakeLists.txt | 50 ++-- src/native/monodroid/{jni => }/build-info.hh | 0 src/native/monodroid/{jni => }/config.h | 0 src/native/monodroid/config.xml | 41 --- .../monodroid/{jni => }/debug-constants.cc | 0 src/native/monodroid/{jni => }/debug.cc | 0 src/native/monodroid/{jni => }/debug.hh | 0 .../{jni => }/designer-assemblies.cc | 0 .../{jni => }/designer-assemblies.hh | 0 .../{jni => }/embedded-assemblies-zip.cc | 0 .../{jni => }/embedded-assemblies.cc | 0 .../{jni => }/embedded-assemblies.hh | 0 .../{jni => }/generate-pinvoke-tables.cc | 2 +- src/native/monodroid/{jni => }/globals.cc | 0 src/native/monodroid/{jni => }/globals.hh | 0 .../monodroid/{jni => }/host-config.h.in | 0 .../{jni => }/internal-pinvoke-api.cc | 0 .../monodroid/{jni => }/jni-remapping.cc | 0 .../monodroid/{jni => }/jni-remapping.hh | 0 src/native/monodroid/jni/.gitignore | 7 - src/native/monodroid/jni/TODO.md | 11 - src/native/monodroid/machine.config.xml | 150 ---------- .../monodroid/{jni => }/mono-image-loader.hh | 0 .../monodroid/{jni => }/mono-log-adapter.cc | 0 .../{jni => }/mono_android_Runtime.h | 0 .../{jni => }/monodroid-glue-designer.cc | 0 .../{jni => }/monodroid-glue-internal.hh | 0 .../monodroid/{jni => }/monodroid-glue.cc | 0 .../monodroid/{jni => }/monodroid-glue.hh | 0 .../{jni => }/monodroid-networkinfo.cc | 0 .../monodroid/{jni => }/monodroid-tracing.cc | 0 src/native/monodroid/monodroid.csproj | 22 -- src/native/monodroid/{jni => }/monodroid.h | 0 src/native/monodroid/monodroid.targets | 278 ------------------ src/native/monodroid/{jni => }/monodroid.x | Bin .../monodroid/{jni => }/monovm-properties.cc | 0 .../monodroid/{jni => }/monovm-properties.hh | 0 src/native/monodroid/{jni => }/osbridge.cc | 0 src/native/monodroid/{jni => }/osbridge.hh | 0 .../{jni => }/pinvoke-override-api.cc | 0 .../{jni => }/pinvoke-tables.include | 0 .../monodroid/{jni => }/runtime-util.cc | 0 .../monodroid/{jni => }/runtime-util.hh | 0 src/native/monodroid/{jni => }/search.hh | 0 .../monodroid/{jni => }/startup-aware-lock.hh | 0 src/native/monodroid/{jni => }/timezones.cc | 0 .../monodroid/{jni => }/timing-internal.cc | 0 .../monodroid/{jni => }/timing-internal.hh | 0 src/native/monodroid/{jni => }/timing.cc | 0 src/native/monodroid/{jni => }/timing.hh | 0 src/native/monodroid/{jni => }/win32/jni_md.h | 0 .../{jni => }/xa-internal-api-impl.hh | 0 .../monodroid/{jni => }/xa-internal-api.cc | 0 .../monodroid/{jni => }/xa-internal-api.hh | 0 .../{jni => }/xamarin-android-app-context.cc | 0 .../monodroid/{jni => }/xamarin_getifaddrs.cc | 0 .../monodroid/{jni => }/xamarin_getifaddrs.h | 0 src/native/native.targets | 28 +- src/native/runtime-base/CMakeLists.txt | 1 + src/native/shared/CMakeLists.txt | 1 + src/native/tracing/CMakeLists.txt | 1 + .../xamarin-debug-app-helper/CMakeLists.txt | 5 +- 68 files changed, 91 insertions(+), 536 deletions(-) rename src/native/monodroid/{jni => }/build-info.hh (100%) rename src/native/monodroid/{jni => }/config.h (100%) delete mode 100644 src/native/monodroid/config.xml rename src/native/monodroid/{jni => }/debug-constants.cc (100%) rename src/native/monodroid/{jni => }/debug.cc (100%) rename src/native/monodroid/{jni => }/debug.hh (100%) rename src/native/monodroid/{jni => }/designer-assemblies.cc (100%) rename src/native/monodroid/{jni => }/designer-assemblies.hh (100%) rename src/native/monodroid/{jni => }/embedded-assemblies-zip.cc (100%) rename src/native/monodroid/{jni => }/embedded-assemblies.cc (100%) rename src/native/monodroid/{jni => }/embedded-assemblies.hh (100%) rename src/native/monodroid/{jni => }/generate-pinvoke-tables.cc (99%) rename src/native/monodroid/{jni => }/globals.cc (100%) rename src/native/monodroid/{jni => }/globals.hh (100%) rename src/native/monodroid/{jni => }/host-config.h.in (100%) rename src/native/monodroid/{jni => }/internal-pinvoke-api.cc (100%) rename src/native/monodroid/{jni => }/jni-remapping.cc (100%) rename src/native/monodroid/{jni => }/jni-remapping.hh (100%) delete mode 100644 src/native/monodroid/jni/.gitignore delete mode 100644 src/native/monodroid/jni/TODO.md delete mode 100644 src/native/monodroid/machine.config.xml rename src/native/monodroid/{jni => }/mono-image-loader.hh (100%) rename src/native/monodroid/{jni => }/mono-log-adapter.cc (100%) rename src/native/monodroid/{jni => }/mono_android_Runtime.h (100%) rename src/native/monodroid/{jni => }/monodroid-glue-designer.cc (100%) rename src/native/monodroid/{jni => }/monodroid-glue-internal.hh (100%) rename src/native/monodroid/{jni => }/monodroid-glue.cc (100%) rename src/native/monodroid/{jni => }/monodroid-glue.hh (100%) rename src/native/monodroid/{jni => }/monodroid-networkinfo.cc (100%) rename src/native/monodroid/{jni => }/monodroid-tracing.cc (100%) delete mode 100644 src/native/monodroid/monodroid.csproj rename src/native/monodroid/{jni => }/monodroid.h (100%) delete mode 100644 src/native/monodroid/monodroid.targets rename src/native/monodroid/{jni => }/monodroid.x (100%) rename src/native/monodroid/{jni => }/monovm-properties.cc (100%) rename src/native/monodroid/{jni => }/monovm-properties.hh (100%) rename src/native/monodroid/{jni => }/osbridge.cc (100%) rename src/native/monodroid/{jni => }/osbridge.hh (100%) rename src/native/monodroid/{jni => }/pinvoke-override-api.cc (100%) rename src/native/monodroid/{jni => }/pinvoke-tables.include (100%) rename src/native/monodroid/{jni => }/runtime-util.cc (100%) rename src/native/monodroid/{jni => }/runtime-util.hh (100%) rename src/native/monodroid/{jni => }/search.hh (100%) rename src/native/monodroid/{jni => }/startup-aware-lock.hh (100%) rename src/native/monodroid/{jni => }/timezones.cc (100%) rename src/native/monodroid/{jni => }/timing-internal.cc (100%) rename src/native/monodroid/{jni => }/timing-internal.hh (100%) rename src/native/monodroid/{jni => }/timing.cc (100%) rename src/native/monodroid/{jni => }/timing.hh (100%) rename src/native/monodroid/{jni => }/win32/jni_md.h (100%) rename src/native/monodroid/{jni => }/xa-internal-api-impl.hh (100%) rename src/native/monodroid/{jni => }/xa-internal-api.cc (100%) rename src/native/monodroid/{jni => }/xa-internal-api.hh (100%) rename src/native/monodroid/{jni => }/xamarin-android-app-context.cc (100%) rename src/native/monodroid/{jni => }/xamarin_getifaddrs.cc (100%) rename src/native/monodroid/{jni => }/xamarin_getifaddrs.h (100%) diff --git a/Configuration.props b/Configuration.props index 68373be4123..522ba39d3a4 100644 --- a/Configuration.props +++ b/Configuration.props @@ -106,6 +106,7 @@ $(MSBuildThisFileDirectory)external\sqlite $(MSBuildThisFileDirectory)external\libunwind $(BootstrapOutputDirectory)\libunwind + $(MSBuildThisFileDirectory)external\lz4 $(MSBuildThisFileDirectory) $(MSBuildThisFileDirectory)src-ThirdParty\ armeabi-v7a;x86 @@ -148,6 +149,7 @@ $([System.IO.Path]::GetFullPath ('$(SqliteSourceDirectory)')) $([System.IO.Path]::GetFullPath ('$(LibUnwindSourceDirectory)')) $([System.IO.Path]::GetFullPath ('$(LibUnwindGeneratedHeadersDirectory)')) + $([System.IO.Path]::GetFullPath ('$(LZ4SourceDirectory)')) $([System.IO.Path]::GetFullPath ('$(OpenTKSourceDirectory)')) net8.0 diff --git a/build-tools/scripts/generate-pinvoke-tables.sh b/build-tools/scripts/generate-pinvoke-tables.sh index 160ce12520b..0a7c187168a 100755 --- a/build-tools/scripts/generate-pinvoke-tables.sh +++ b/build-tools/scripts/generate-pinvoke-tables.sh @@ -3,7 +3,7 @@ MY_DIR="$(dirname $0)" HOST="$(uname | tr A-Z a-z)" NATIVE_DIR="${MY_DIR}/../../src/native" -MONODROID_SOURCE_DIR="${NATIVE_DIR}/monodroid/jni" +MONODROID_SOURCE_DIR="${NATIVE_DIR}/monodroid" GENERATOR_SOURCE="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables.cc" GENERATOR_BINARY="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables" TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include" diff --git a/src/native/.gitignore b/src/native/.gitignore index 34d21e62347..06af5ee0acd 100644 --- a/src/native/.gitignore +++ b/src/native/.gitignore @@ -1,2 +1,3 @@ CMakeUserPresets.json CMakePresets.json +static-analysis.*.txt diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index e940659baa1..3ed2976b575 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -278,6 +278,19 @@ macro(xa_check_cxx_linker_args VARNAME _CHECK_ARGS) set(${VARNAME} "${_CHECKED_ARGS}") endmacro() +set(CLANG_CHECK_SOURCES "") +macro(add_clang_check_sources SOURCES) + foreach(_source ${SOURCES}) + cmake_path(IS_RELATIVE _source _relative_path) + if(${_relative_path}) + list(APPEND _LOCAL_CLANG_CHECK_SOURCES_ ${CMAKE_CURRENT_SOURCE_DIR}/${_source}) + else() + list(APPEND _LOCAL_CLANG_CHECK_SOURCES_ ${_source}) + endif() + endforeach() + set(CLANG_CHECK_SOURCES "${_LOCAL_CLANG_CHECK_SOURCES_};${CLANG_CHECK_SOURCES}" PARENT_SCOPE) +endmacro() + # # Compiler args # @@ -441,3 +454,10 @@ if(DEBUG_BUILD) endif() add_subdirectory(monodroid) + +add_custom_target(run_static_analysis + COMMAND ${ANDROID_TOOLCHAIN_ROOT}/bin/clang-check -analyze -p="${CMAKE_CURRENT_BINARY_DIR}" ${CLANG_CHECK_SOURCES} > ${CMAKE_SOURCE_DIR}/static-analysis.${ANDROID_ABI}.${CMAKE_BUILD_TYPE}.txt 2>&1 + COMMAND_EXPAND_LISTS + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + USES_TERMINAL +) diff --git a/src/native/java-interop/CMakeLists.txt b/src/native/java-interop/CMakeLists.txt index e9d59b5bba1..96510c4925f 100644 --- a/src/native/java-interop/CMakeLists.txt +++ b/src/native/java-interop/CMakeLists.txt @@ -8,6 +8,7 @@ set(JAVA_INTEROP_SOURCES ${JAVA_INTEROP_SRC_PATH}/java-interop-util.cc ${JAVA_INTEROP_SRC_PATH}/java-interop.cc ) +add_clang_check_sources("${JAVA_INTEROP_SOURCES}") add_library( ${LIB_NAME} diff --git a/src/native/monodroid/.gitignore b/src/native/monodroid/.gitignore index 76f4fbd0f2d..b794e58ba97 100644 --- a/src/native/monodroid/.gitignore +++ b/src/native/monodroid/.gitignore @@ -1,2 +1,6 @@ libs sources.projitems +pinvoke-tables.include.generated +pinvoke-tables.include.diff +generate-pinvoke-tables +generate-pinvoke-tables.exe diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index 5d4bf1f723a..ed27b2429d6 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -7,7 +7,6 @@ include(CheckCXXSymbolExists) # Paths -set(SOURCES_DIR ${CMAKE_SOURCE_DIR}/monodroid/jni) set(BIONIC_SOURCES_DIR "${REPO_ROOT_DIR}/src-ThirdParty/bionic") set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map") @@ -45,31 +44,40 @@ string(TOLOWER ${CMAKE_BUILD_TYPE} XAMARIN_MONO_ANDROID_SUFFIX) set(XAMARIN_MONO_ANDROID_LIB "mono-android${CHECKED_BUILD_INFIX}.${XAMARIN_MONO_ANDROID_SUFFIX}") set(XAMARIN_MONODROID_SOURCES - ${SOURCES_DIR}/debug-constants.cc - ${SOURCES_DIR}/debug.cc - ${SOURCES_DIR}/embedded-assemblies-zip.cc - ${SOURCES_DIR}/embedded-assemblies.cc - ${SOURCES_DIR}/globals.cc - ${SOURCES_DIR}/jni-remapping.cc - ${SOURCES_DIR}/mono-log-adapter.cc - ${SOURCES_DIR}/monodroid-glue.cc - ${SOURCES_DIR}/monodroid-networkinfo.cc - ${SOURCES_DIR}/monodroid-tracing.cc - ${SOURCES_DIR}/monovm-properties.cc - ${SOURCES_DIR}/osbridge.cc - ${SOURCES_DIR}/pinvoke-override-api.cc - ${SOURCES_DIR}/runtime-util.cc - ${SOURCES_DIR}/timing.cc - ${SOURCES_DIR}/timezones.cc - ${SOURCES_DIR}/timing-internal.cc - ${SOURCES_DIR}/xamarin_getifaddrs.cc + debug-constants.cc + debug.cc + embedded-assemblies-zip.cc + embedded-assemblies.cc + globals.cc + jni-remapping.cc + mono-log-adapter.cc + monodroid-glue.cc + monodroid-networkinfo.cc + monodroid-tracing.cc + monovm-properties.cc + osbridge.cc + pinvoke-override-api.cc + runtime-util.cc + timing.cc + timezones.cc + timing-internal.cc + xamarin_getifaddrs.cc +) + +list(APPEND LOCAL_CLANG_CHECK_SOURCES + ${XAMARIN_MONODROID_SOURCES} ) if(NOT DEBUG_BUILD) list(APPEND XAMARIN_MONODROID_SOURCES - ${SOURCES_DIR}/xamarin-android-app-context.cc + xamarin-android-app-context.cc + ) + + list(APPEND LOCAL_CLANG_CHECK_SOURCES + xamarin-android-app-context.cc ) endif() +add_clang_check_sources("${LOCAL_CLANG_CHECK_SOURCES}") if(NOT USES_LIBSTDCPP) list(APPEND XAMARIN_MONODROID_SOURCES @@ -78,7 +86,7 @@ if(NOT USES_LIBSTDCPP) endif() # Build -configure_file(jni/host-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/host-config.h) +configure_file(host-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/host-config.h) add_library( ${XAMARIN_MONO_ANDROID_LIB} diff --git a/src/native/monodroid/jni/build-info.hh b/src/native/monodroid/build-info.hh similarity index 100% rename from src/native/monodroid/jni/build-info.hh rename to src/native/monodroid/build-info.hh diff --git a/src/native/monodroid/jni/config.h b/src/native/monodroid/config.h similarity index 100% rename from src/native/monodroid/jni/config.h rename to src/native/monodroid/config.h diff --git a/src/native/monodroid/config.xml b/src/native/monodroid/config.xml deleted file mode 100644 index 5c4917bbfa0..00000000000 --- a/src/native/monodroid/config.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/native/monodroid/jni/debug-constants.cc b/src/native/monodroid/debug-constants.cc similarity index 100% rename from src/native/monodroid/jni/debug-constants.cc rename to src/native/monodroid/debug-constants.cc diff --git a/src/native/monodroid/jni/debug.cc b/src/native/monodroid/debug.cc similarity index 100% rename from src/native/monodroid/jni/debug.cc rename to src/native/monodroid/debug.cc diff --git a/src/native/monodroid/jni/debug.hh b/src/native/monodroid/debug.hh similarity index 100% rename from src/native/monodroid/jni/debug.hh rename to src/native/monodroid/debug.hh diff --git a/src/native/monodroid/jni/designer-assemblies.cc b/src/native/monodroid/designer-assemblies.cc similarity index 100% rename from src/native/monodroid/jni/designer-assemblies.cc rename to src/native/monodroid/designer-assemblies.cc diff --git a/src/native/monodroid/jni/designer-assemblies.hh b/src/native/monodroid/designer-assemblies.hh similarity index 100% rename from src/native/monodroid/jni/designer-assemblies.hh rename to src/native/monodroid/designer-assemblies.hh diff --git a/src/native/monodroid/jni/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc similarity index 100% rename from src/native/monodroid/jni/embedded-assemblies-zip.cc rename to src/native/monodroid/embedded-assemblies-zip.cc diff --git a/src/native/monodroid/jni/embedded-assemblies.cc b/src/native/monodroid/embedded-assemblies.cc similarity index 100% rename from src/native/monodroid/jni/embedded-assemblies.cc rename to src/native/monodroid/embedded-assemblies.cc diff --git a/src/native/monodroid/jni/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh similarity index 100% rename from src/native/monodroid/jni/embedded-assemblies.hh rename to src/native/monodroid/embedded-assemblies.hh diff --git a/src/native/monodroid/jni/generate-pinvoke-tables.cc b/src/native/monodroid/generate-pinvoke-tables.cc similarity index 99% rename from src/native/monodroid/jni/generate-pinvoke-tables.cc rename to src/native/monodroid/generate-pinvoke-tables.cc index 54886c5a48d..0c132d5461b 100644 --- a/src/native/monodroid/jni/generate-pinvoke-tables.cc +++ b/src/native/monodroid/generate-pinvoke-tables.cc @@ -1,7 +1,7 @@ // // To build and run this utility run (on Linux or macOS): // -// ../../../../build-tools/scripts/generate-pinvoke-tables.sh +// ../../../build-tools/scripts/generate-pinvoke-tables.sh // // A reasonable C++20 compiler is required (g++ 10+, clang 11+, on mac it may require XCode 12.5 or newer) // diff --git a/src/native/monodroid/jni/globals.cc b/src/native/monodroid/globals.cc similarity index 100% rename from src/native/monodroid/jni/globals.cc rename to src/native/monodroid/globals.cc diff --git a/src/native/monodroid/jni/globals.hh b/src/native/monodroid/globals.hh similarity index 100% rename from src/native/monodroid/jni/globals.hh rename to src/native/monodroid/globals.hh diff --git a/src/native/monodroid/jni/host-config.h.in b/src/native/monodroid/host-config.h.in similarity index 100% rename from src/native/monodroid/jni/host-config.h.in rename to src/native/monodroid/host-config.h.in diff --git a/src/native/monodroid/jni/internal-pinvoke-api.cc b/src/native/monodroid/internal-pinvoke-api.cc similarity index 100% rename from src/native/monodroid/jni/internal-pinvoke-api.cc rename to src/native/monodroid/internal-pinvoke-api.cc diff --git a/src/native/monodroid/jni/jni-remapping.cc b/src/native/monodroid/jni-remapping.cc similarity index 100% rename from src/native/monodroid/jni/jni-remapping.cc rename to src/native/monodroid/jni-remapping.cc diff --git a/src/native/monodroid/jni/jni-remapping.hh b/src/native/monodroid/jni-remapping.hh similarity index 100% rename from src/native/monodroid/jni/jni-remapping.hh rename to src/native/monodroid/jni-remapping.hh diff --git a/src/native/monodroid/jni/.gitignore b/src/native/monodroid/jni/.gitignore deleted file mode 100644 index 7454689c137..00000000000 --- a/src/native/monodroid/jni/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -Application.mk -config.include -machine.config.include -pinvoke-tables.include.generated -pinvoke-tables.include.diff -generate-pinvoke-tables -generate-pinvoke-tables.exe diff --git a/src/native/monodroid/jni/TODO.md b/src/native/monodroid/jni/TODO.md deleted file mode 100644 index 88c1d04ea86..00000000000 --- a/src/native/monodroid/jni/TODO.md +++ /dev/null @@ -1,11 +0,0 @@ -= Memory management - - * Don't use malloc and friends on pointers which aren't passed to Mono - -= Strings - - * Implement a simple class to perform all string manipulations - -= Warnings - - * Fix all the C++ warnings regarding constant strings diff --git a/src/native/monodroid/machine.config.xml b/src/native/monodroid/machine.config.xml deleted file mode 100644 index 485d8b34170..00000000000 --- a/src/native/monodroid/machine.config.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - -
-
-
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/native/monodroid/jni/mono-image-loader.hh b/src/native/monodroid/mono-image-loader.hh similarity index 100% rename from src/native/monodroid/jni/mono-image-loader.hh rename to src/native/monodroid/mono-image-loader.hh diff --git a/src/native/monodroid/jni/mono-log-adapter.cc b/src/native/monodroid/mono-log-adapter.cc similarity index 100% rename from src/native/monodroid/jni/mono-log-adapter.cc rename to src/native/monodroid/mono-log-adapter.cc diff --git a/src/native/monodroid/jni/mono_android_Runtime.h b/src/native/monodroid/mono_android_Runtime.h similarity index 100% rename from src/native/monodroid/jni/mono_android_Runtime.h rename to src/native/monodroid/mono_android_Runtime.h diff --git a/src/native/monodroid/jni/monodroid-glue-designer.cc b/src/native/monodroid/monodroid-glue-designer.cc similarity index 100% rename from src/native/monodroid/jni/monodroid-glue-designer.cc rename to src/native/monodroid/monodroid-glue-designer.cc diff --git a/src/native/monodroid/jni/monodroid-glue-internal.hh b/src/native/monodroid/monodroid-glue-internal.hh similarity index 100% rename from src/native/monodroid/jni/monodroid-glue-internal.hh rename to src/native/monodroid/monodroid-glue-internal.hh diff --git a/src/native/monodroid/jni/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc similarity index 100% rename from src/native/monodroid/jni/monodroid-glue.cc rename to src/native/monodroid/monodroid-glue.cc diff --git a/src/native/monodroid/jni/monodroid-glue.hh b/src/native/monodroid/monodroid-glue.hh similarity index 100% rename from src/native/monodroid/jni/monodroid-glue.hh rename to src/native/monodroid/monodroid-glue.hh diff --git a/src/native/monodroid/jni/monodroid-networkinfo.cc b/src/native/monodroid/monodroid-networkinfo.cc similarity index 100% rename from src/native/monodroid/jni/monodroid-networkinfo.cc rename to src/native/monodroid/monodroid-networkinfo.cc diff --git a/src/native/monodroid/jni/monodroid-tracing.cc b/src/native/monodroid/monodroid-tracing.cc similarity index 100% rename from src/native/monodroid/jni/monodroid-tracing.cc rename to src/native/monodroid/monodroid-tracing.cc diff --git a/src/native/monodroid/monodroid.csproj b/src/native/monodroid/monodroid.csproj deleted file mode 100644 index 100496fe8fc..00000000000 --- a/src/native/monodroid/monodroid.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - netstandard2.0 - Debug - AnyCPU - Exe - false - - - - - - $(MicrosoftAndroidSdkOutDir)lib\ - - - - - - - - - diff --git a/src/native/monodroid/jni/monodroid.h b/src/native/monodroid/monodroid.h similarity index 100% rename from src/native/monodroid/jni/monodroid.h rename to src/native/monodroid/monodroid.h diff --git a/src/native/monodroid/monodroid.targets b/src/native/monodroid/monodroid.targets deleted file mode 100644 index 7d0c3010bbf..00000000000 --- a/src/native/monodroid/monodroid.targets +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - - - - <_EmbeddedBlobSource Include="config.xml" /> - <_EmbeddedBlobDestination Include="jni\config.include" /> - <_EmbeddedBlobSource Include="machine.config.xml" /> - <_EmbeddedBlobDestination Include="jni\machine.config.include" /> - - - - jni\generate-pinvoke-tables.cc - jni\pinvoke-tables.include - - - - - - - - - - - - - - - - - - - - - - - - - <_ConfigureRuntimesInputs Include="CMakeLists.txt" /> - <_ConfigureRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" /> - <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Debug\CMakeCache.txt')" /> - <_ConfigureRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Release\CMakeCache.txt')" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Debug" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Release" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> - <_OutputDirsToCreate Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Release" Condition="'$(EnableNativeAnalyzers)' == 'true'" /> - - - - - - - - - <_CmakeLibUnwind>-DLIBUNWIND_SOURCE_DIR="$(LibUnwindSourceDirectory)" -DLIBUNWIND_HEADERS_DIR="$(LibUnwindGeneratedHeadersDirectory)" - <_NoInline Condition=" '$(DoNotInlineMonodroid)' == 'true' ">-DDONT_INLINE=ON - <_NoStrip Condition=" '$(DoNotStripMonodroid)' == 'true' ">-DSTRIP_DEBUG=OFF - <_CmakeAndroidFlags>$(_NoInline) $(_NoStrip) --debug-output -GNinja -DCMAKE_MAKE_PROGRAM="$(NinjaPath)" -DXA_BUILD_CONFIGURATION=$(Configuration) -DXA_LIB_TOP_DIR=$(MicrosoftAndroidSdkOutDir) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DMONO_PATH="$(MonoSourceFullPath)" -DANDROID_STL="none" -DANDROID_CPP_FEATURES="no-rtti no-exceptions" -DANDROID_TOOLCHAIN=clang -DCMAKE_TOOLCHAIN_FILE="$(AndroidNdkDirectory)/build/cmake/android.toolchain.cmake" -DANDROID_NDK=$(AndroidNdkDirectory) - - - - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release - - - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Debug - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Debug - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_ASAN=ON -DANDROID_STL="c++_static" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-asan-Release - - <_ConfigureRuntimeCommands Include="@(AndroidSupportedTargetJitAbi)"> - $(CmakePath) - $(_CmakeAndroidFlags) $(_CmakeLibUnwind) -DCONFIGURATION=Debug -DCMAKE_BUILD_TYPE=Release -DENABLE_CLANG_UBSAN=ON -DANDROID_STL="c++_static" -DANDROID_CPP_FEATURES="rtti exceptions" -DANDROID_NATIVE_API_LEVEL=%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_PLATFORM=android-%(AndroidSupportedTargetJitAbi.ApiLevelNET) -DANDROID_ABI=%(AndroidSupportedTargetJitAbi.Identity) -DANDROID_RID=%(AndroidSupportedTargetJitAbi.AndroidRID) -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" -DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$(OutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)" "$(MSBuildThisFileDirectory)" - $(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-ubsan-Release - - - - - - - - - <_MonoDroidSources Include="jni\*.cc;jni\*.h;jni\*.hh;jni\**\*.c;" /> - - - - - - <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Debug\CMakeCache.txt')" /> - <_BuildAndroidRuntimesInputs Include="@(AndroidSupportedTargetJitAbi->'$(IntermediateOutputPath)\%(AndroidRID)-Release\CMakeCache.txt')" /> - <_BuildAndroidRuntimesInputs Include="@(_MonoDroidSources)" /> - <_BuildAndroidRuntimesInputs Include="..\..\build-tools\scripts\Ndk.targets" /> - <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android.debug.so')" /> - <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android.release.so')" /> - <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\Debug\libxamarin-app.so')" /> - <_BuildAndroidRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\Release\libxamarin-app.so')" /> - - - <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+ubsan.debug.so')" /> - <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+asan.debug.so')" /> - <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+asan.release.so')" /> - <_BuildAndroidAnalyzerRuntimesOutputs Include="@(AndroidSupportedTargetJitAbi->'$(OutputPath)\%(AndroidRID)\libmono-android-checked+ubsan.release.so')" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_CompileCommandsDir Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Debug"> - %(AndroidSupportedTargetJitAbi.AndroidRID)-Debug - - <_CompileCommandsDir Include="$(IntermediateOutputPath)%(AndroidSupportedTargetJitAbi.AndroidRID)-Release"> - %(AndroidSupportedTargetJitAbi.AndroidRID)-Release - - - - - - - $(AndroidNdkDirectory)\toolchains\llvm\prebuilt\$(NdkLlvmTag)\bin\clang-tidy - - - - - - - - <_ArmRuntimePackFiles Include="$(OutputPath)\android-arm\*.*" /> - <_Arm64RuntimePackFiles Include="$(OutputPath)\android-arm64\*.*" /> - <_x86RuntimePackFiles Include="$(OutputPath)\android-x86\*.*" /> - <_x64RuntimePackFiles Include="$(OutputPath)\android-x64\*.*" /> - - - - - - - diff --git a/src/native/monodroid/jni/monodroid.x b/src/native/monodroid/monodroid.x similarity index 100% rename from src/native/monodroid/jni/monodroid.x rename to src/native/monodroid/monodroid.x diff --git a/src/native/monodroid/jni/monovm-properties.cc b/src/native/monodroid/monovm-properties.cc similarity index 100% rename from src/native/monodroid/jni/monovm-properties.cc rename to src/native/monodroid/monovm-properties.cc diff --git a/src/native/monodroid/jni/monovm-properties.hh b/src/native/monodroid/monovm-properties.hh similarity index 100% rename from src/native/monodroid/jni/monovm-properties.hh rename to src/native/monodroid/monovm-properties.hh diff --git a/src/native/monodroid/jni/osbridge.cc b/src/native/monodroid/osbridge.cc similarity index 100% rename from src/native/monodroid/jni/osbridge.cc rename to src/native/monodroid/osbridge.cc diff --git a/src/native/monodroid/jni/osbridge.hh b/src/native/monodroid/osbridge.hh similarity index 100% rename from src/native/monodroid/jni/osbridge.hh rename to src/native/monodroid/osbridge.hh diff --git a/src/native/monodroid/jni/pinvoke-override-api.cc b/src/native/monodroid/pinvoke-override-api.cc similarity index 100% rename from src/native/monodroid/jni/pinvoke-override-api.cc rename to src/native/monodroid/pinvoke-override-api.cc diff --git a/src/native/monodroid/jni/pinvoke-tables.include b/src/native/monodroid/pinvoke-tables.include similarity index 100% rename from src/native/monodroid/jni/pinvoke-tables.include rename to src/native/monodroid/pinvoke-tables.include diff --git a/src/native/monodroid/jni/runtime-util.cc b/src/native/monodroid/runtime-util.cc similarity index 100% rename from src/native/monodroid/jni/runtime-util.cc rename to src/native/monodroid/runtime-util.cc diff --git a/src/native/monodroid/jni/runtime-util.hh b/src/native/monodroid/runtime-util.hh similarity index 100% rename from src/native/monodroid/jni/runtime-util.hh rename to src/native/monodroid/runtime-util.hh diff --git a/src/native/monodroid/jni/search.hh b/src/native/monodroid/search.hh similarity index 100% rename from src/native/monodroid/jni/search.hh rename to src/native/monodroid/search.hh diff --git a/src/native/monodroid/jni/startup-aware-lock.hh b/src/native/monodroid/startup-aware-lock.hh similarity index 100% rename from src/native/monodroid/jni/startup-aware-lock.hh rename to src/native/monodroid/startup-aware-lock.hh diff --git a/src/native/monodroid/jni/timezones.cc b/src/native/monodroid/timezones.cc similarity index 100% rename from src/native/monodroid/jni/timezones.cc rename to src/native/monodroid/timezones.cc diff --git a/src/native/monodroid/jni/timing-internal.cc b/src/native/monodroid/timing-internal.cc similarity index 100% rename from src/native/monodroid/jni/timing-internal.cc rename to src/native/monodroid/timing-internal.cc diff --git a/src/native/monodroid/jni/timing-internal.hh b/src/native/monodroid/timing-internal.hh similarity index 100% rename from src/native/monodroid/jni/timing-internal.hh rename to src/native/monodroid/timing-internal.hh diff --git a/src/native/monodroid/jni/timing.cc b/src/native/monodroid/timing.cc similarity index 100% rename from src/native/monodroid/jni/timing.cc rename to src/native/monodroid/timing.cc diff --git a/src/native/monodroid/jni/timing.hh b/src/native/monodroid/timing.hh similarity index 100% rename from src/native/monodroid/jni/timing.hh rename to src/native/monodroid/timing.hh diff --git a/src/native/monodroid/jni/win32/jni_md.h b/src/native/monodroid/win32/jni_md.h similarity index 100% rename from src/native/monodroid/jni/win32/jni_md.h rename to src/native/monodroid/win32/jni_md.h diff --git a/src/native/monodroid/jni/xa-internal-api-impl.hh b/src/native/monodroid/xa-internal-api-impl.hh similarity index 100% rename from src/native/monodroid/jni/xa-internal-api-impl.hh rename to src/native/monodroid/xa-internal-api-impl.hh diff --git a/src/native/monodroid/jni/xa-internal-api.cc b/src/native/monodroid/xa-internal-api.cc similarity index 100% rename from src/native/monodroid/jni/xa-internal-api.cc rename to src/native/monodroid/xa-internal-api.cc diff --git a/src/native/monodroid/jni/xa-internal-api.hh b/src/native/monodroid/xa-internal-api.hh similarity index 100% rename from src/native/monodroid/jni/xa-internal-api.hh rename to src/native/monodroid/xa-internal-api.hh diff --git a/src/native/monodroid/jni/xamarin-android-app-context.cc b/src/native/monodroid/xamarin-android-app-context.cc similarity index 100% rename from src/native/monodroid/jni/xamarin-android-app-context.cc rename to src/native/monodroid/xamarin-android-app-context.cc diff --git a/src/native/monodroid/jni/xamarin_getifaddrs.cc b/src/native/monodroid/xamarin_getifaddrs.cc similarity index 100% rename from src/native/monodroid/jni/xamarin_getifaddrs.cc rename to src/native/monodroid/xamarin_getifaddrs.cc diff --git a/src/native/monodroid/jni/xamarin_getifaddrs.h b/src/native/monodroid/xamarin_getifaddrs.h similarity index 100% rename from src/native/monodroid/jni/xamarin_getifaddrs.h rename to src/native/monodroid/xamarin_getifaddrs.h diff --git a/src/native/native.targets b/src/native/native.targets index 67bb4bb46d9..77965fa9240 100644 --- a/src/native/native.targets +++ b/src/native/native.targets @@ -5,6 +5,22 @@ DependsOnTargets="_ConfigureRuntimes;_BuildAndroidRuntimes;_BuildAndroidAnalyzerRuntimes;_CopyToPackDirs"> + + + + + + + + + <_ConfigureRuntimesInputs Include="CMakeLists.txt" /> @@ -94,7 +110,15 @@ - <_MonoDroidSources Include="jni\*.cc;jni\*.h;jni\*.hh;jni\**\*.c;" /> + <_MonoDroidSources Include="libstub\*.cc;libstub\*.hh" /> + <_MonoDroidSources Include="monodroid\*.cc;monodroid\*.hh" /> + <_MonoDroidSources Include="runtime-base\*.cc;runtime-base\*.hh" /> + <_MonoDroidSources Include="shared\*.cc;shared\*.hh" /> + <_MonoDroidSources Include="tracing\*.cc;tracing\*.hh" /> + <_MonoDroidSources Include="xamarin-app-stub\*.cc;xamarin-app-stub\*.hh" /> + <_MonoDroidSources Include="xamarin-debug-app-helper\*.cc;xamarin-debug-app-helper\*.hh" /> + <_MonoDroidSources Include="$(JavaInteropFullPath)\src\java-interop\*.cc;$(JavaInteropFullPath)\src\java-interop\*.h" /> + <_MonoDroidSources Include="$(LZ4SourceFullPath)\lib\lz4.c;$(LZ4SourceFullPath)\lib\lz4.h" /> @@ -119,7 +143,7 @@ Date: Wed, 24 Apr 2024 16:22:39 +0200 Subject: [PATCH 22/23] Remove unneded include dirs --- src/native/monodroid/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/native/monodroid/CMakeLists.txt b/src/native/monodroid/CMakeLists.txt index ed27b2429d6..a8d067baed5 100644 --- a/src/native/monodroid/CMakeLists.txt +++ b/src/native/monodroid/CMakeLists.txt @@ -138,10 +138,9 @@ target_compile_options( target_include_directories( ${XAMARIN_MONO_ANDROID_LIB} BEFORE PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include ${EXTERNAL_DIR} ${ROBIN_MAP_DIR}/include - jni ) target_include_directories( From ed74cfc387655f7b66c986b02bd407e39b0929cc Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 15 May 2024 21:17:44 +0200 Subject: [PATCH 23/23] Address feedback --- build-tools/cmake/xa_common.cmake | 143 ------------- build-tools/cmake/xa_macros.cmake | 306 ---------------------------- build-tools/cmake/xa_preamble.cmake | 7 - src/native/native.targets | 2 +- 4 files changed, 1 insertion(+), 457 deletions(-) delete mode 100644 build-tools/cmake/xa_common.cmake delete mode 100644 build-tools/cmake/xa_macros.cmake delete mode 100644 build-tools/cmake/xa_preamble.cmake diff --git a/build-tools/cmake/xa_common.cmake b/build-tools/cmake/xa_common.cmake deleted file mode 100644 index 250473e2633..00000000000 --- a/build-tools/cmake/xa_common.cmake +++ /dev/null @@ -1,143 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_C_EXTENSIONS OFF) - -include("${CMAKE_ANDROID_NDK}/build/cmake/abis.cmake") - -if(CMAKE_BUILD_TYPE STREQUAL Debug) - set(DEBUG_BUILD True) -else() - set(DEBUG_BUILD False) -endif() - -set(XA_NO_INLINE "$ENV{XA_NO_INLINE}") -if(XA_NO_INLINE) - set(DONT_INLINE_DEFAULT ON) -else() - set(DONT_INLINE_DEFAULT OFF) -endif() - -set(XA_NO_STRIP "$ENV{XA_NO_STRIP}") -if(XA_NO_STRIP OR DEBUG_BUILD) - set(STRIP_DEBUG_DEFAULT OFF) -endif() - -option(ENABLE_CLANG_ASAN "Enable the clang AddressSanitizer support" OFF) -option(ENABLE_CLANG_UBSAN "Enable the clang UndefinedBehaviorSanitizer support" OFF) - -if(ENABLE_CLANG_ASAN OR ENABLE_CLANG_UBSAN) - set(STRIP_DEBUG_DEFAULT OFF) - set(ANALYZERS_ENABLED ON) -else() - if(NOT XA_NO_STRIP) - set(STRIP_DEBUG_DEFAULT ON) - endif() - set(ANALYZERS_ENABLED OFF) -endif() - -option(COMPILER_DIAG_COLOR "Show compiler diagnostics/errors in color" ON) -option(STRIP_DEBUG "Strip debugging information when linking" ${STRIP_DEBUG_DEFAULT}) -option(DISABLE_DEBUG "Disable the built-in debugging code" OFF) -option(USE_CCACHE "Use ccache, if found, to speed up recompilation" ON) -option(DONT_INLINE "Do not inline any functions which are usually inlined, to get better stack traces" ${DONT_INLINE_DEFAULT}) - -if(USE_CCACHE) - if(CMAKE_CXX_COMPILER MATCHES "/ccache/") - message(STATUS "ccache: compiler already uses ccache") - else() - find_program(CCACHE ccache) - if(CCACHE) - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE}") - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE}") - message(STATUS "ccache: compiler will be lauched with ${CCACHE}") - endif() - endif() -endif() - -if(ANDROID_STL STREQUAL none) - set(USES_LIBSTDCPP False) -else() - set(USES_LIBSTDCPP True) -endif() - -# -# General config -# -if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux) - set(IS_LINUX True) -else() - set(IS_LINUX False) -endif() - -if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) - set(IS_MACOS True) -else() - set(IS_MACOS False) -endif() - -set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}") -include("${XA_BUILD_DIR}/xa_build_configuration.cmake") - -# -# Paths -# -if(ANDROID_ABI MATCHES "^arm64-v8a") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM64}") - set(TOOLCHAIN_TRIPLE "${NDK_ABI_arm64-v8a_TRIPLE}") -elseif(ANDROID_ABI MATCHES "^armeabi-v7a") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_ARM}") - set(TOOLCHAIN_TRIPLE "${NDK_ABI_armeabi-v7a_TRIPLE}") -elseif(ANDROID_ABI MATCHES "^x86_64") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86_64}") - set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_64_TRIPLE}") -elseif(ANDROID_ABI MATCHES "^x86") - set(NET_RUNTIME_DIR "${NETCORE_APP_RUNTIME_DIR_X86}") - set(TOOLCHAIN_TRIPLE "${NDK_ABI_x86_TRIPLE}") -else() - message(FATAL "${ANDROID_ABI} is not supported for .NET 6+ builds") -endif() - -file(REAL_PATH "../../" REPO_ROOT_DIR) -set(EXTERNAL_DIR "${REPO_ROOT_DIR}/external") -set(JAVA_INTEROP_SRC_PATH "${EXTERNAL_DIR}/Java.Interop/src/java-interop") -set(SHARED_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/shared") -set(TRACING_SOURCES_DIR "${REPO_ROOT_DIR}/src/native/tracing") -# -# Include directories -# -include_directories(SYSTEM ${CMAKE_SYSROOT}/usr/include/c++/v1/) -include_directories(SYSTEM "${NET_RUNTIME_DIR}/native/include/mono-2.0") -include_directories("${JAVA_INTEROP_SRC_PATH}") -include_directories("${SHARED_SOURCES_DIR}") -include_directories("${TRACING_SOURCES_DIR}") - -# -# Compiler defines -# -add_compile_definitions(XA_VERSION="${XA_VERSION}") -add_compile_definitions(_REENTRANT) -add_compile_definitions(PLATFORM_ANDROID) - -if(DEBUG_BUILD AND NOT DISABLE_DEBUG) - add_compile_definitions(DEBUG) -endif() - -if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") - add_compile_definitions(ANDROID64) -endif() - -if (ANDROID_NDK_MAJOR LESS 20) - add_compile_definitions(__ANDROID_API_Q__=29) -endif() - -# -# Shared sources -# -set(XA_SHARED_SOURCES - ${SHARED_SOURCES_DIR}/helpers.cc - ${SHARED_SOURCES_DIR}/new_delete.cc -) diff --git a/build-tools/cmake/xa_macros.cmake b/build-tools/cmake/xa_macros.cmake deleted file mode 100644 index 69759acf363..00000000000 --- a/build-tools/cmake/xa_macros.cmake +++ /dev/null @@ -1,306 +0,0 @@ -include(CheckCXXCompilerFlag) -include(CheckCCompilerFlag) -include(CheckLinkerFlag) - -macro(_compiler_has_flag _lang _flag) - string(REGEX REPLACE "-|,|=" "_" _flag_name ${_flag}) - string(TOUPPER "${_lang}" _lang_upper) - - cmake_language(CALL check_${_lang}_compiler_flag "${_flag}" HAS_${_flag_name}_${_lang_upper}) - if(HAS_${_flag_name}_${_lang_upper}) - set(COMPILER_FLAG_FOUND True) - else() - set(COMPILER_FLAG_FOUND False) - endif() -endmacro() - -macro(cxx_compiler_has_flag _flag) - _compiler_has_flag(cxx ${_flag}) -endmacro() - -macro(c_compiler_has_flag _flag) - _compiler_has_flag(c ${_flag}) -endmacro() - -macro(_linker_has_flag _lang _flag) - string(REGEX REPLACE "-|,|=" "_" _flag_name ${_flag}) - string(TOUPPER "${_lang}" _lang_upper) - - check_linker_flag(${_lang} "${_flag}" HAS_${_flag_name}_LINKER_${_lang_upper}) - if(HAS_${_flag_name}_LINKER_${_lang_upper}) - set(LINKER_FLAG_FOUND True) - else() - set(LINKER_FLAG_FOUND False) - endif() -endmacro() - -macro(cxx_linker_has_flag _flag) - _linker_has_flag(CXX ${_flag}) -endmacro() - -macro(c_linker_has_flag _flag) - _linker_has_flag(C ${_flag}) -endmacro() - -# -# Uses ${XA_COMMON_COMPILER_FLAGS}, if defined -# -# ${EXTRA_C_FLAGS} contains a set of additional C compiler flags to check -# -# Sets VARNAME on exit -# -macro(xa_check_c_flags VARNAME EXTRA_C_FLAGS) - set(_CHECKED_FLAGS "") - set(_CHECK_FLAGS ${XA_COMMON_COMPILER_FLAGS} ${EXTRA_C_FLAGS}) - - list(LENGTH _CHECK_FLAGS ARGS_LEN) - if(ARGS_LEN LESS_EQUAL 0) - return() - endif() - - foreach(flag ${_CHECK_FLAGS}) - c_compiler_has_flag(${flag}) - if(COMPILER_FLAG_FOUND) - list(APPEND _CHECKED_FLAGS "${flag}") - endif() - endforeach() - - set(${VARNAME} "${_CHECKED_FLAGS}") -endmacro() - -# -# Uses ${XA_COMMON_COMPILER_FLAGS}, if defined -# -# ${EXTRA_CXX_FLAGS} contains a set of additional C compiler flags to check -# -# Sets VARNAME on exit -# -macro(xa_check_cxx_flags VARNAME EXTRA_CXX_FLAGS) - set(_CHECKED_FLAGS "") - set(_CHECK_FLAGS ${XA_COMMON_COMPILER_FLAGS} ${EXTRA_CXX_FLAGS}) - - list(LENGTH _CHECK_FLAGS ARGS_LEN) - if(ARGS_LEN LESS_EQUAL 0) - return() - endif() - - foreach(flag ${_CHECK_FLAGS}) - cxx_compiler_has_flag(${flag}) - if(COMPILER_FLAG_FOUND) - list(APPEND _CHECKED_FLAGS "${flag}") - endif() - endforeach() - - set(${VARNAME} "${_CHECKED_FLAGS}") -endmacro() - -# -# Uses ${XA_COMMON_LINKER_FLAGS}, if defined -# -# ${EXTRA_C_LINKER_FLAGS} contains a set of additional C linker flags to check -# -# Sets VARNAME on exit -# -macro(xa_check_c_linker_flags VARNAME EXTRA_C_LINKER_FLAGS) - set(_CHECKED_FLAGS "") - set(_CHECK_FLAGS ${XA_COMMON_LINKER_FLAGS} ${EXTRA_C_LINKER_FLAGS}) - - list(LENGTH _CHECK_FLAGS ARGS_LEN) - if(ARGS_LEN LESS_EQUAL 0) - return() - endif() - - foreach(flag ${_CHECK_FLAGS}) - c_linker_has_flag(${flag}) - if(LINKER_FLAG_FOUND) - list(APPEND _CHECKED_FLAGS "${flag}") - endif() - endforeach() - - set(${VARNAME} "${_CHECKED_FLAGS}") -endmacro() - -# -# Uses ${XA_COMMON_LINKER_FLAGS}, if defined -# -# ${EXTRA_CXX_LINKER_FLAGS} contains a set of additional C++ linker flags to check -# -# Sets VARNAME on exit -# -macro(xa_check_cxx_linker_flags VARNAME EXTRA_CXX_LINKER_FLAGS) - set(_CHECKED_FLAGS "") - set(_CHECK_FLAGS ${XA_COMMON_LINKER_FLAGS} ${EXTRA_CXX_LINKER_FLAGS}) - - list(LENGTH _CHECK_FLAGS ARGS_LEN) - if(ARGS_LEN LESS_EQUAL 0) - return() - endif() - - foreach(flag ${_CHECK_FLAGS}) - cxx_linker_has_flag(${flag}) - if(LINKER_FLAG_FOUND) - list(APPEND _CHECKED_FLAGS "${flag}") - endif() - endforeach() - - set(${VARNAME} "${_CHECKED_FLAGS}") -endmacro() - -# -# Uses ${XA_COMMON_COMPILER_FLAGS}, if defined -# -# ${EXTRA_C_FLAGS} contains a set of additional C compiler flags to check -# ${EXTRA_CXX_FLAGS} contains a set of additional C compiler flags to check -# -# Sets VARNAME_CXX on exit -# Sets VARNAME_C on exit -# -macro(xa_check_compiler_flags VARNAME_CXX VARNAME_C EXTRA_CXX_FLAGS EXTRA_C_FLAGS) - xa_check_cxx_flags(${VARNAME_CXX} "${EXTRA_CXX_FLAGS}") - xa_check_c_flags(${VARNAME_C} "${EXTRA_C_FLAGS}") -endmacro() - -# -# Uses ${XA_COMMON_LINKER_FLAGS}, if defined -# -# ${EXTRA_C_LINKER_FLAGS} contains a set of additional C linker flags to check -# ${EXTRA_CXX_LINKER_FLAGS} contains a set of additional C++ linker flags to check -# -# Sets VARNAME_C on exit -# Sets VARNAME_CXX on exit -# -macro(xa_check_linker_flags VARNAME_CXX VARNAME_C EXTRA_CXX_LINKER_FLAGS EXTRA_C_LINKER_FLAGS) - xa_check_cxx_linker_flags(${VARNAME_CXX} "${EXTRA_CXX_LINKER_FLAGS}") - xa_check_c_linker_flags(${VARNAME_C} "${EXTRA_C_LINKER_FLAGS}") -endmacro() - -# -# Sets ${XA_COMMON_COMPILER_FLAGS} to flags that can be shared by C and C++ compilers -# Sets ${XA_COMMON_LINKER_FLAGS} to flags that can be shared by C and C++ linkers -# Sets ${XA_DEFAULT_SYMBOL_VISIBILITY} to the default symbol visibility value -# -# Defines RELEASE and NDEBUG macros for C/C++ builds if the current build type is Release -# -function(xa_common_prepare) - if(NOT DSO_SYMBOL_VISIBILITY) - set(DSO_SYMBOL_VISIBILITY "hidden") - endif() - - # - # Currently not supported by NDK clang, but worth considering when it is eventually supported: - # - # -fsanitize=safe-stack - # - - set(XA_DEFAULT_SYMBOL_VISIBILITY - -fvisibility=${DSO_SYMBOL_VISIBILITY} - PARENT_SCOPE) - - set(XA_COMMON_COMPILER_FLAGS - -fstack-protector-strong - -fstrict-return - -fno-strict-aliasing - -fno-function-sections - -fno-data-sections - -funswitch-loops - -Wa,-noexecstack - -fPIC - -g - -O2 - PARENT_SCOPE - ) - - set(XA_COMMON_LINKER_FLAGS - -fstack-protector-strong - LINKER:-fstrict-return - LINKER:-z,now - LINKER:-z,relro - LINKER:-z,noexecstack - LINKER:--no-undefined - PARENT_SCOPE - ) - - if(MINGW) - list(APPEND XA_COMMON_LINKER_FLAGS - LINKER:--export-all-symbols - ) - else() - list(APPEND XA_COMMON_LINKER_FLAGS - LINKER:--export-dynamic - ) - endif() - - if(CMAKE_BUILD_TYPE STREQUAL Release) - add_compile_definitions(RELEASE NDEBUG) - endif() -endfunction() - -macro(xa_macos_prepare_arm64) - if(APPLE) - set(SDK_SUPPORTS_ARM64 False) - set(SDK_SUPPORTS_X86_64 False) - execute_process( - COMMAND xcode-select -p - RESULT_VARIABLE XCODE_SELECT_RESULT - OUTPUT_VARIABLE XCODE_DEVELOPER_PATH - ) - if(NOT ${XCODE_SELECT_RESULT} EQUAL "0") - message(WARNING "xcode-select failed with result ${XCODE_SELECT_RESULT}") - else() - string(STRIP "${XCODE_DEVELOPER_PATH}" XCODE_DEVELOPER_PATH) - set(SDKSETTINGS_PATH "${XCODE_DEVELOPER_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/SDKSettings.plist") - - # CAUTION: do NOT ever remove the '-o -' parameter, without '-o' plutil will overwrite the .plist file - execute_process( - COMMAND plutil -extract SupportedTargets.macosx.Archs json -o - "${SDKSETTINGS_PATH}" - RESULT_VARIABLE PLUTIL_RESULT - OUTPUT_VARIABLE SDK_ARCHITECTURES - ) - if(NOT ${PLUTIL_RESULT} EQUAL 0) - message(WARNING "plutil failed to read ${SDKSETTINGS_PATH}, returned with result ${PLUTIL_RESULT}") - else() - string(FIND "${SDK_ARCHITECTURES}" "\"arm64\"" ARCH_POS) - if(${ARCH_POS} GREATER_EQUAL 0) - set(SDK_SUPPORTS_ARM64 True) - endif() - - string(FIND "${SDK_ARCHITECTURES}" "\"x86_64\"" ARCH_POS) - if(${ARCH_POS} GREATER_EQUAL 0) - set(SDK_SUPPORTS_X86_64 True) - endif() - endif() - endif() - - unset(XA_OSX_ARCHITECTURES) - if(SDK_SUPPORTS_ARM64) - message(STATUS "SDK at ${XCODE_DEVELOPER_PATH} supports creation of ARM64 binaries") - set(MONOSGEN_DYLIB "${XA_LIB_TOP_DIR}/lib/host-Darwin/libmonosgen-2.0.dylib") - execute_process( - COMMAND lipo -archs ${MONOSGEN_DYLIB} - RESULT_VARIABLE LIPO_RESULT - OUTPUT_VARIABLE LIPO_OUTPUT - ) - set(ADD_ARM64 False) - if(${LIPO_RESULT} EQUAL "0") - string(FIND "${LIPO_OUTPUT}" "\"arm64\"" ARCH_POS) - if(${ARCH_POS} GREATER_EQUAL 0) - set(ADD_ARM64 True) - else() - message(WARNING "lipo reported ${MONOSGEN_DYLIB} does not contain the ARM64 image") - endif() - else() - message(WARNING "lipo check on ${MONOSGEN_DYLIB} failed with exit code ${LIPO_RESULT}") - endif() - - if(ADD_ARM64) - list(APPEND XA_OSX_ARCHITECTURES "arm64") - else() - message(WARNING "Disabling ARM64 build") - endif() - endif() - if(SDK_SUPPORTS_X86_64) - message(STATUS "SDK at ${XCODE_DEVELOPER_PATH} supports creation of X86_64 binaries") - list(APPEND XA_OSX_ARCHITECTURES "x86_64") - endif() - endif() -endmacro() diff --git a/build-tools/cmake/xa_preamble.cmake b/build-tools/cmake/xa_preamble.cmake deleted file mode 100644 index d28fc5e10c4..00000000000 --- a/build-tools/cmake/xa_preamble.cmake +++ /dev/null @@ -1,7 +0,0 @@ -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12) - -# -# Read product version -# -file(STRINGS "../../Directory.Build.props" XA_PRODUCT_VERSION_XML REGEX "^[ \t]*(.*)") -string(REGEX REPLACE "^[ \t]*(.*)" "\\1" XA_VERSION "${XA_PRODUCT_VERSION_XML}") diff --git a/src/native/native.targets b/src/native/native.targets index 77965fa9240..ab4539bd4fa 100644 --- a/src/native/native.targets +++ b/src/native/native.targets @@ -182,7 +182,7 @@ + AfterTargets="Clean">