Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/clr/host/assembly-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ namespace {
return;
}

std::string const& code_cache_dir = AndroidSystem::get_app_code_cache_dir ();
if (code_cache_dir.empty ()) {
const char *code_cache_dir = AndroidSystem::get_app_code_cache_dir ();
if (*code_cache_dir == '\0') {
return;
}

Expand Down
18 changes: 9 additions & 9 deletions src/native/clr/host/fastdev-assemblies.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ auto FastDevAssemblies::open_assembly (std::string_view const& name, int64_t &si
return nullptr;
}

std::string const& override_dir_path = AndroidSystem::get_primary_override_dir ();
const char *override_dir_path = AndroidSystem::get_primary_override_dir ();
if (!Util::dir_exists (override_dir_path)) [[unlikely]] {
log_debugf (LOG_ASSEMBLY, "Override directory '%s' does not exist", override_dir_path.c_str ());
log_debugf (LOG_ASSEMBLY, "Override directory '%s' does not exist", override_dir_path);
return nullptr;
}

Expand All @@ -47,9 +47,9 @@ auto FastDevAssemblies::open_assembly (std::string_view const& name, int64_t &si
if (override_dir_fd < 0) [[unlikely]] {
pthread_mutex_lock (&override_dir_lock);
if (override_dir_fd < 0) [[likely]] {
override_dir = opendir (override_dir_path.c_str ());
override_dir = opendir (override_dir_path);
if (override_dir == nullptr) [[unlikely]] {
log_warnf (LOG_ASSEMBLY, "Failed to open override dir '%s'. %s", override_dir_path.c_str (), strerror (errno));
log_warnf (LOG_ASSEMBLY, "Failed to open override dir '%s'. %s", override_dir_path, strerror (errno));
pthread_mutex_unlock (&override_dir_lock);
return nullptr;
}
Expand All @@ -62,7 +62,7 @@ auto FastDevAssemblies::open_assembly (std::string_view const& name, int64_t &si
LOG_ASSEMBLY,
"Attempting to load FastDev assembly '%.*s' from override directory '%s'",
static_cast<int>(name.length ()), name.data (),
override_dir_path.c_str ()
override_dir_path
);

if (!Util::file_exists (override_dir_fd, name)) {
Expand Down Expand Up @@ -135,14 +135,14 @@ auto FastDevAssemblies::build_tpa_list (std::string &tpa_list) noexcept -> bool
{
tpa_list.clear ();

std::string const& override_dir_path = AndroidSystem::get_primary_override_dir ();
const char *override_dir_path = AndroidSystem::get_primary_override_dir ();
if (!Util::dir_exists (override_dir_path)) {
return false;
}

DIR *dir = opendir (override_dir_path.c_str ());
DIR *dir = opendir (override_dir_path);
if (dir == nullptr) {
log_warnf (LOG_ASSEMBLY, "FastDev: failed to open override dir '%s'. %s", override_dir_path.c_str (), std::strerror (errno));
log_warnf (LOG_ASSEMBLY, "FastDev: failed to open override dir '%s'. %s", override_dir_path, std::strerror (errno));
return false;
}

Expand Down Expand Up @@ -185,7 +185,7 @@ auto FastDevAssemblies::build_tpa_list (std::string &tpa_list) noexcept -> bool
LOG_ASSEMBLY,
"FastDev: built TPA list with %zu assemblies from '%s' (corelib=%s, r2r=%s)",
count,
override_dir_path.c_str (),
override_dir_path,
found_corelib ? "true" : "false",
found_r2r ? "true" : "false"
);
Expand Down
16 changes: 8 additions & 8 deletions src/native/clr/host/host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ bool Host::clr_external_assembly_probe (const char *path, void **data_start, int
[[gnu::always_inline]]
void Host::scan_filesystem_for_assemblies_and_libraries () noexcept
{
std::string const& native_lib_dir = AndroidSystem::get_native_libraries_dir ();
log_debugf (LOG_ASSEMBLY, "Looking for assemblies in '%s'", native_lib_dir.c_str ());
const char *native_lib_dir = AndroidSystem::get_native_libraries_dir ();
log_debugf (LOG_ASSEMBLY, "Looking for assemblies in '%s'", native_lib_dir);

DIR *lib_dir = opendir (native_lib_dir.c_str ());
DIR *lib_dir = opendir (native_lib_dir);
if (lib_dir == nullptr) [[unlikely]] {
Helpers::abort_applicationf (
LOG_ASSEMBLY,
std::source_location::current (),
"Unable to open native library directory '%s'. %s",
native_lib_dir.c_str (),
native_lib_dir,
std::strerror (errno)
);
}
Expand All @@ -111,7 +111,7 @@ void Host::scan_filesystem_for_assemblies_and_libraries () noexcept
LOG_ASSEMBLY,
std::source_location::current (),
"Unable to obtain file descriptor for opened directory '%s'. %s",
native_lib_dir.c_str (),
native_lib_dir,
std::strerror (errno)
);
}
Expand All @@ -121,7 +121,7 @@ void Host::scan_filesystem_for_assemblies_and_libraries () noexcept
dirent *cur = readdir (lib_dir);
if (cur == nullptr) {
if (errno != 0) {
log_warnf (LOG_ASSEMBLY, "Failed to open a directory entry from '%s': %s", native_lib_dir.c_str (), std::strerror (errno));
log_warnf (LOG_ASSEMBLY, "Failed to open a directory entry from '%s': %s", native_lib_dir, std::strerror (errno));
continue; // No harm, keep going
}
break; // we're done
Expand All @@ -138,7 +138,7 @@ void Host::scan_filesystem_for_assemblies_and_libraries () noexcept
continue;
}

log_debugf (LOG_ASSEMBLY, "Found assembly store in '%s/%s'", native_lib_dir.c_str (), Constants::assembly_store_file_name.data ());
log_debugf (LOG_ASSEMBLY, "Found assembly store in '%s/%s'", native_lib_dir, Constants::assembly_store_file_name.data ());

std::string store_path = native_lib_dir;
store_path.append ("/"sv);
Expand Down Expand Up @@ -338,7 +338,7 @@ void Host::Java_mono_android_Runtime_initInternal (
AndroidSystem::set_app_code_cache_dir (applicationDirs[Constants::APP_DIRS_CODE_CACHE_DIR_INDEX]);
AndroidSystem::create_update_dir (AndroidSystem::get_primary_override_dir ());
AndroidSystem::setup_environment ();
Logger::init_reference_logging (AndroidSystem::get_primary_override_dir ().c_str ());
Logger::init_reference_logging (AndroidSystem::get_primary_override_dir ());

jstring_array_wrapper runtimeApks (env, runtimeApksJava);
AndroidSystem::setup_app_library_directories (runtimeApks, applicationDirs, haveSplitApks);
Expand Down
2 changes: 1 addition & 1 deletion src/native/clr/include/host/host-environment.hh
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace xamarin::android {
[[gnu::flatten, gnu::always_inline]]
static void create_xdg_directory (jstring_wrapper &home, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept
{
std::string_view home_path = home.get_string_view ();
const char *home_path = home.get_cstr ();
char stack_buffer [Util::LocalPathBufferSize];
ssize_t result = Util::format_joined_path (stack_buffer, sizeof (stack_buffer), home_path, relative_path);
abort_unless (result >= 0, "XDG directory path is too long");
Expand Down
87 changes: 34 additions & 53 deletions src/native/clr/include/runtime-base/android-system.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <cstdio>
#include <limits>
#include <span>
#include <string>
#include <string_view>

#include "../constants.hh"
Expand Down Expand Up @@ -32,11 +31,11 @@ namespace xamarin::android {
#if !defined (XA_HOST_NATIVEAOT)
// 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;
inline static const char *single_app_lib_directory [1] { "" };
inline static std::span<const char*> app_lib_directories;

// TODO: override dirs not implemented
inline static std::array<std::string, 1> override_dirs{};
inline static const char *override_dirs [1] { "" };

static constexpr std::array<std::string_view, 7> android_abi_names {
std::string_view { "unknown" }, // CPU_KIND_UNKNOWN
Expand Down Expand Up @@ -73,45 +72,47 @@ namespace xamarin::android {
running_in_emulator = yesno;
}

#if defined (XA_HOST_NATIVEAOT)
static auto get_primary_override_dir () noexcept -> const char*
{
return primary_override_dir;
}
#else
static auto get_primary_override_dir () noexcept -> std::string const&
{
return primary_override_dir;
}
#endif

static void set_primary_override_dir (jstring_wrapper& home) noexcept
{
#if defined (XA_HOST_NATIVEAOT)
ssize_t result = format_primary_override_dir (home, primary_override_dir, sizeof (primary_override_dir));
abort_unless (result >= 0, "Primary override directory path is too long");
#else
primary_override_dir = determine_primary_override_dir (home);
#endif
char stack_buffer [Constants::SENSIBLE_PATH_MAX];
char *path = stack_buffer;
ssize_t result = format_primary_override_dir (home, path, sizeof (stack_buffer));
if (result < 0) {
size_t required_capacity = static_cast<size_t>(-result);
path = static_cast<char*> (std::malloc (required_capacity));
abort_unless (path != nullptr, "Failed to allocate primary override directory path");
result = format_primary_override_dir (home, path, required_capacity);
}
abort_unless (result >= 0, "Failed to format primary override directory path using the required capacity");

primary_override_dir = Util::duplicate_string (path);
if (path != stack_buffer) {
std::free (path);
}
}

#if !defined (XA_HOST_NATIVEAOT)
static auto get_app_code_cache_dir () noexcept -> std::string const&
static auto get_app_code_cache_dir () noexcept -> const char*
{
return app_code_cache_dir;
}

static void set_app_code_cache_dir (jstring_wrapper& code_cache_dir) noexcept
{
app_code_cache_dir.assign (code_cache_dir.get_cstr ());
app_code_cache_dir = Util::duplicate_string (code_cache_dir.get_cstr ());
}

static auto get_native_libraries_dir () noexcept -> std::string const&
static auto get_native_libraries_dir () noexcept -> const char*
{
return native_libraries_dir;
}

static void create_update_dir (std::string const& override_dir) noexcept
static void create_update_dir (const char *override_dir) noexcept
{
if constexpr (Constants::is_release_build) {
/*
Expand All @@ -127,8 +128,8 @@ namespace xamarin::android {
}
}

log_debugf (LOG_DEFAULT, "Creating public update directory: `%s`", override_dir.c_str ());
Util::create_public_directory (override_dir.c_str ());
log_debugf (LOG_DEFAULT, "Creating public update directory: `%s`", override_dir);
Util::create_public_directory (override_dir);
}
#endif

Expand All @@ -152,9 +153,9 @@ namespace xamarin::android {
static auto load_dso_from_any_directories (std::string_view const& name, int dl_flags, bool is_jni) noexcept -> void*;

private:
static auto format_full_dso_path (std::string const& base_dir, std::string_view const& dso_path, char *buffer, size_t buffer_size) noexcept -> ssize_t;
static auto format_full_dso_path (const char *base_dir, std::string_view const& dso_path, char *buffer, size_t buffer_size) noexcept -> ssize_t;

static auto get_full_dso_path (std::string const& base_dir, std::string_view const& dso_path, char *stack_buffer, size_t stack_buffer_size) noexcept -> char*
static auto get_full_dso_path (const char *base_dir, std::string_view const& dso_path, char *stack_buffer, size_t stack_buffer_size) noexcept -> char*
{
ssize_t result = format_full_dso_path (base_dir, dso_path, stack_buffer, stack_buffer_size);
if (result >= 0) {
Expand Down Expand Up @@ -213,38 +214,18 @@ namespace xamarin::android {
return static_cast<ssize_t>(length);
}

#if !defined (XA_HOST_NATIVEAOT)
static auto determine_primary_override_dir (jstring_wrapper &home) noexcept -> std::string
{
char stack_buffer [Constants::SENSIBLE_PATH_MAX];
char *name = stack_buffer;
ssize_t result = format_primary_override_dir (home, name, sizeof (stack_buffer));
if (result < 0) {
size_t required_capacity = static_cast<size_t>(-result);
name = static_cast<char*> (std::malloc (required_capacity));
abort_unless (name != nullptr, "Failed to allocate primary override directory path");
result = format_primary_override_dir (home, name, required_capacity);
}
abort_unless (result >= 0, "Failed to format primary override directory path using the required capacity");

std::string path { name, static_cast<size_t>(result) };
if (name != stack_buffer) {
std::free (name);
}
return path;
}
#endif

private:
static inline long max_gref_count = 0;
static inline bool running_in_emulator = false;
static inline bool embedded_dso_mode_enabled = false;
#if defined (XA_HOST_NATIVEAOT)
static inline char primary_override_dir[Constants::SENSIBLE_PATH_MAX] {};
#else
static inline std::string primary_override_dir;
static inline std::string native_libraries_dir;
static inline std::string app_code_cache_dir;
// These are set once, early during startup, and are read for as long as the process lives.
// They are plain pointers so that they are constant-initialized: a `std::string` here would
// make the compiler emit a guard variable and an `atexit` registration in every translation
// unit which includes this header.
static inline const char *primary_override_dir = "";
#if !defined (XA_HOST_NATIVEAOT)
static inline const char *native_libraries_dir = "";
static inline const char *app_code_cache_dir = "";

#if defined (DEBUG)
static inline BundledProperty *bundled_properties = nullptr;
Expand Down
29 changes: 29 additions & 0 deletions src/native/clr/include/runtime-base/util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ namespace xamarin::android {
public:
static constexpr size_t LocalPathBufferSize = Constants::SENSIBLE_PATH_MAX;

// Returns a copy of `str` allocated with `malloc`, aborting the application if the
// allocation fails. Used for values which are set once, early during startup, and which
// then live for as long as the process does - the copies are never freed.
static auto duplicate_string (const char *str) noexcept -> char*
{
char *ret = strdup (str);
if (ret == nullptr) [[unlikely]] {
Helpers::abort_application (LOG_DEFAULT, "Unable to allocate memory for a string copy");
}

return ret;
}

static int create_directory (const char *pathname, mode_t mode);

static auto create_directory (std::string_view const& dir, mode_t mode) noexcept -> int
Expand Down Expand Up @@ -310,6 +323,22 @@ namespace xamarin::android {
return !path.empty () && path.contains ('/');
}

[[gnu::flatten, gnu::always_inline]]
static auto ends_with (const char *value, const char *suffix) noexcept -> bool
{
if (value == nullptr || suffix == nullptr) {
return false;
}

size_t value_length = strlen (value);
size_t suffix_length = strlen (suffix);
if (suffix_length > value_length) {
return false;
}

return memcmp (value + value_length - suffix_length, suffix, suffix_length) == 0;
}

// Returns the path length excluding NUL, or the negative required capacity including NUL.
static auto format_joined_path (char *buffer, size_t buffer_size, std::string_view first, std::string_view second) noexcept -> ssize_t
{
Expand Down
Loading
Loading