-
Notifications
You must be signed in to change notification settings - Fork 540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLR hosting bits #9778
Merged
Merged
CLR hosting bits #9778
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
#pragma once | ||
|
||
#include <fcntl.h> | ||
#include <sys/system_properties.h> | ||
|
||
#include <string_view> | ||
|
||
#include <shared/cpp-util.hh> | ||
|
||
namespace xamarin::android { | ||
class Constants | ||
{ | ||
#if INTPTR_MAX == INT64_MAX | ||
static inline constexpr std::string_view BITNESS { "64bit" }; | ||
#else | ||
static inline constexpr std::string_view BITNESS { "32bit" }; | ||
#endif | ||
|
||
public: | ||
#if INTPTR_MAX == INT64_MAX | ||
static inline constexpr bool is_64_bit_target = true; | ||
#else | ||
static inline constexpr bool is_64_bit_target = false; | ||
#endif | ||
|
||
#if defined(RELEASE) | ||
static constexpr bool is_release_build = true; | ||
static constexpr bool is_debug_build = false; | ||
#else | ||
static constexpr bool is_release_build = false; | ||
static constexpr bool is_debug_build = true; | ||
#endif | ||
static constexpr std::string_view MANGLED_ASSEMBLY_NAME_EXT { ".so" }; | ||
|
||
private: | ||
static constexpr std::string_view RUNTIME_CONFIG_BLOB_BASE_NAME { "libarc.bin" }; | ||
static constexpr size_t runtime_config_blob_name_size = calc_size (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); | ||
static constexpr auto RUNTIME_CONFIG_BLOB_NAME_ARRAY = concat_string_views<runtime_config_blob_name_size> (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); | ||
|
||
public: | ||
// .data() must be used otherwise string_view length will include the trailing \0 in the array | ||
static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { RUNTIME_CONFIG_BLOB_NAME_ARRAY.data () }; | ||
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" }; | ||
|
||
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*" }; | ||
|
||
#if defined(__arm__) | ||
static constexpr std::string_view android_abi { "armeabi_v7a" }; | ||
static constexpr std::string_view android_lib_abi { "armeabi-v7a" }; | ||
static constexpr std::string_view runtime_identifier { "android-arm" }; | ||
#elif defined(__aarch64__) | ||
static constexpr std::string_view android_abi { "arm64_v8a" }; | ||
static constexpr std::string_view android_lib_abi { "arm64-v8a" }; | ||
static constexpr std::string_view runtime_identifier { "android-arm64" }; | ||
#elif defined(__x86_64__) | ||
static constexpr std::string_view android_abi { "x86_64" }; | ||
static constexpr std::string_view android_lib_abi { "x86_64" }; | ||
static constexpr std::string_view runtime_identifier { "android-x64" }; | ||
#elif defined(__i386__) | ||
static constexpr std::string_view android_abi { "x86" }; | ||
static constexpr std::string_view android_lib_abi { "x86" }; | ||
static constexpr std::string_view runtime_identifier { "android-x86" }; | ||
#endif | ||
|
||
static constexpr std::string_view split_config_prefix { "/split_config." }; | ||
static constexpr std::string_view split_config_extension { ".apk" }; | ||
|
||
private: | ||
static constexpr size_t split_config_abi_apk_name_size = calc_size (split_config_prefix, android_abi, split_config_extension); | ||
|
||
public: | ||
static constexpr auto split_config_abi_apk_name = concat_string_views<split_config_abi_apk_name_size> (split_config_prefix, android_abi, split_config_extension); | ||
|
||
// | ||
// Indexes must match these of trhe `appDirs` array in src/java-runtime/mono/android/MonoPackageManager.java | ||
// | ||
static constexpr size_t APP_DIRS_FILES_DIR_INDEX = 0uz; | ||
static constexpr size_t APP_DIRS_CACHE_DIR_INDEX = 1uz; | ||
static constexpr size_t APP_DIRS_DATA_DIR_INDEX = 2uz; | ||
|
||
static inline constexpr size_t PROPERTY_VALUE_BUFFER_LEN = PROP_VALUE_MAX + 1uz; | ||
|
||
// 64-bit unsigned or 64-bit signed with sign | ||
static constexpr size_t MAX_INTEGER_DIGIT_COUNT_BASE10 = 21uz; | ||
static constexpr size_t INTEGER_BASE10_BUFFER_SIZE = MAX_INTEGER_DIGIT_COUNT_BASE10 + 1uz; | ||
|
||
// Documented in NDK's <android/log.h> comments | ||
static constexpr size_t MAX_LOGCAT_MESSAGE_LENGTH = 1023uz; | ||
|
||
// PATH_MAX is always 4096 on Linux, but for our purposes it's most likely too much and since | ||
// we use this value to allocate stack variables mostly, let's downsize it a bit to what the | ||
// _XOPEN_PATH_MAX is set to | ||
static constexpr size_t SENSIBLE_PATH_MAX = 1024uz; | ||
|
||
static constexpr int DEFAULT_DIRECTORY_MODE = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; | ||
|
||
#if defined (DEBUG) | ||
static constexpr std::string_view OVERRIDE_ENVIRONMENT_FILE_NAME { "environment" }; | ||
static constexpr uint32_t OVERRIDE_ENVIRONMENT_FILE_HEADER_SIZE = 22; | ||
#endif | ||
|
||
static constexpr std::string_view MONO_ANDROID_ASSEMBLY_NAME { "Mono.Android" }; | ||
static constexpr std::string_view ANDROID_RUNTIME_NS_NAME { "Android.Runtime" }; | ||
static constexpr std::string_view JNIENVINIT_CLASS_NAME { "JNIEnvInit" }; | ||
static constexpr std::string_view JNIENV_CLASS_NAME { "JNIEnv" }; | ||
|
||
private: | ||
static constexpr size_t JNIENVINIT_FULL_TYPE_NAME_SIZE = calc_size (ANDROID_RUNTIME_NS_NAME, "."sv, JNIENVINIT_CLASS_NAME); | ||
static constexpr auto JNIENVINIT_FULL_TYPE_NAME_ARRAY = concat_string_views<JNIENVINIT_FULL_TYPE_NAME_SIZE> (ANDROID_RUNTIME_NS_NAME, "."sv, JNIENVINIT_CLASS_NAME); | ||
|
||
public: | ||
static constexpr std::string_view JNIENVINIT_FULL_TYPE_NAME { JNIENVINIT_FULL_TYPE_NAME_ARRAY.data () }; | ||
|
||
static constexpr std::string_view ANDROID_ENVIRONMENT_CLASS_NAME { "AndroidEnvironment" }; | ||
static constexpr std::string_view ANDROID_RUNTIME_INTERNAL_CLASS_NAME { "AndroidRuntimeInternal" }; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#pragma once | ||
|
||
#include <array> | ||
#include <limits> | ||
#include <string> | ||
#include <string_view> | ||
#include <unordered_map> | ||
|
||
#include "../constants.hh" | ||
#include "../shared/log_types.hh" | ||
#include "../runtime-base/cpu-arch.hh" | ||
#include <runtime-base/jni-wrappers.hh> | ||
#include <runtime-base/strings.hh> | ||
#include "util.hh" | ||
|
||
struct BundledProperty; | ||
|
||
namespace xamarin::android { | ||
class AndroidSystem | ||
{ | ||
// 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<std::string, 1> single_app_lib_directory{}; | ||
inline static std::span<std::string> app_lib_directories; | ||
|
||
// TODO: override dirs not implemented | ||
inline static std::array<std::string, 1> override_dirs{}; | ||
|
||
static constexpr std::array<std::string_view, 7> android_abi_names { | ||
std::string_view { "unknown" }, // CPU_KIND_UNKNOWN | ||
std::string_view { "armeabi-v7a" }, // CPU_KIND_ARM | ||
std::string_view { "arm64-v8a" }, // CPU_KIND_ARM64 | ||
std::string_view { "mips" }, // CPU_KIND_MIPS | ||
std::string_view { "x86" }, // CPU_KIND_X86 | ||
std::string_view { "x86_64" }, // CPU_KIND_X86_64 | ||
std::string_view { "riscv" }, // CPU_KIND_RISCV | ||
}; | ||
|
||
public: | ||
static auto get_gref_gc_threshold () noexcept -> long | ||
{ | ||
if (max_gref_count == std::numeric_limits<int>::max ()) { | ||
return max_gref_count; | ||
} | ||
return static_cast<int> ((max_gref_count * 90LL) / 100LL); | ||
} | ||
|
||
static auto get_max_gref_count () noexcept -> long | ||
{ | ||
return max_gref_count; | ||
} | ||
|
||
static void init_max_gref_count () noexcept | ||
{ | ||
max_gref_count = get_max_gref_count_from_system (); | ||
} | ||
|
||
static void set_running_in_emulator (bool yesno) noexcept | ||
{ | ||
running_in_emulator = yesno; | ||
} | ||
|
||
static auto get_primary_override_dir () noexcept -> std::string const& | ||
{ | ||
return primary_override_dir; | ||
} | ||
|
||
static void set_primary_override_dir (jstring_wrapper& home) noexcept | ||
{ | ||
primary_override_dir = determine_primary_override_dir (home); | ||
} | ||
|
||
static void create_update_dir (std::string const& override_dir) noexcept | ||
{ | ||
if constexpr (Constants::is_release_build) { | ||
/* | ||
* Don't create .__override__ on Release builds, because Google requires | ||
* that pre-loaded apps not create world-writable directories. | ||
* | ||
* However, if any logging is enabled (which should _not_ happen with | ||
* pre-loaded apps!), we need the .__override__ directory... | ||
*/ | ||
dynamic_local_string<Constants::PROPERTY_VALUE_BUFFER_LEN> value; | ||
if (log_categories == 0 && monodroid_get_system_property (Constants::DEBUG_MONO_PROFILE_PROPERTY, value) == 0) [[likely]] { | ||
return; | ||
} | ||
} | ||
|
||
Util::create_public_directory (override_dir); | ||
log_warn (LOG_DEFAULT, "Creating public update directory: `{}`", override_dir); | ||
} | ||
|
||
static auto is_embedded_dso_mode_enabled () noexcept -> bool | ||
{ | ||
return embedded_dso_mode_enabled; | ||
} | ||
|
||
static auto monodroid_get_system_property (std::string_view const& name, dynamic_local_string<Constants::PROPERTY_VALUE_BUFFER_LEN> &value) noexcept -> int; | ||
static void detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept; | ||
static void setup_environment () noexcept; | ||
static void setup_app_library_directories (jstring_array_wrapper& runtimeApks, jstring_array_wrapper& appDirs, bool have_split_apks) noexcept; | ||
static auto load_dso (const char *path, unsigned int dl_flags, bool skip_exists_check) noexcept -> void*; | ||
static auto load_dso_from_any_directories (const char *name, unsigned int dl_flags) noexcept -> void*; | ||
|
||
private: | ||
static auto get_full_dso_path (std::string const& base_dir, const char *dso_path, dynamic_local_string<SENSIBLE_PATH_MAX>& path) noexcept -> bool; | ||
|
||
template<class TContainer> // TODO: replace with a concept | ||
static auto load_dso_from_specified_dirs (TContainer directories, const char *dso_name, unsigned int dl_flags) noexcept -> void*; | ||
static auto load_dso_from_app_lib_dirs (const char *name, unsigned int dl_flags) noexcept -> void*; | ||
static auto load_dso_from_override_dirs (const char *name, unsigned int dl_flags) noexcept -> void*; | ||
static auto lookup_system_property (std::string_view const &name, size_t &value_len) noexcept -> const char*; | ||
static auto monodroid__system_property_get (std::string_view const&, char *sp_value, size_t sp_value_len) noexcept -> int; | ||
static auto get_max_gref_count_from_system () noexcept -> long; | ||
static void add_apk_libdir (std::string_view const& apk, size_t &index, std::string_view const& abi) noexcept; | ||
static void setup_apk_directories (unsigned short running_on_cpu, jstring_array_wrapper &runtimeApks, bool have_split_apks) noexcept; | ||
#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 (dynamic_local_string<Constants::SENSIBLE_PATH_MAX> const& path) noexcept; | ||
#endif | ||
|
||
static void set_embedded_dso_mode_enabled (bool yesno) noexcept | ||
{ | ||
embedded_dso_mode_enabled = yesno; | ||
} | ||
|
||
static auto determine_primary_override_dir (jstring_wrapper &home) noexcept -> std::string | ||
{ | ||
dynamic_local_string<SENSIBLE_PATH_MAX> name { home.get_cstr () }; | ||
name.append ("/") | ||
.append (Constants::OVERRIDE_DIRECTORY_NAME) | ||
.append ("/") | ||
.append (Constants::android_lib_abi); | ||
|
||
return {name.get (), name.length ()}; | ||
} | ||
|
||
private: | ||
static inline long max_gref_count = 0; | ||
static inline bool running_in_emulator = false; | ||
static inline bool embedded_dso_mode_enabled = false; | ||
static inline std::string primary_override_dir; | ||
|
||
#if defined (DEBUG) | ||
static inline std::unordered_map<std::string, std::string> bundled_properties; | ||
#endif | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
static inline constexpr uint16_t CPU_KIND_UNKNOWN = 0; | ||
static inline constexpr uint16_t CPU_KIND_ARM = 1; | ||
static inline constexpr uint16_t CPU_KIND_ARM64 = 2; | ||
static inline constexpr uint16_t CPU_KIND_MIPS = 3; | ||
static inline constexpr uint16_t CPU_KIND_X86 = 4; | ||
static inline constexpr uint16_t CPU_KIND_X86_64 = 5; | ||
static inline constexpr uint16_t CPU_KIND_RISCV = 6; | ||
|
||
void _monodroid_detect_cpu_and_architecture (uint16_t &built_for_cpu, uint16_t &running_on_cpu, bool &is64bit); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need to care about this at this time. CoreCLR only supports 64-bit ABIs on Linux, and this is unlikely to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Au contraire. The 32-bit support is nearly working except for corehost build (which is not used on Android anyway), for both x86 and arm32. (linux-x86/android-x86 is on community support; linux-arm32 is supported and tested platform, there's no blocker for android-arm32 aside from packaging and build scripts, for NativeAOT the linux-bionix-arm32 runtime packs were released since .NET 9)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it wasn't working when I started to work on #9572 but the goal is that it'll work, so we should always keep 32-bit runtimes in mind here.