Skip to content

Commit 5cc7999

Browse files
committed
Should work now
1 parent 795e722 commit 5cc7999

File tree

5 files changed

+96
-11
lines changed

5 files changed

+96
-11
lines changed

src/native/monodroid/monodroid-glue-internal.hh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,16 @@ namespace xamarin::android::internal
239239
}
240240

241241
static void* monodroid_dlopen_ignore_component_or_load (hash_t hash, const char *name, int flags, char **err) noexcept;
242-
static void* monodroid_dlopen (const char *name, int flags, char **err) noexcept;
242+
static void* monodroid_dlopen (const char *name, int flags, char **err, bool use_aot_cache) noexcept;
243243
static void* monodroid_dlopen (const char *name, int flags, char **err, void *user_data) noexcept;
244244
static void* monodroid_dlsym (void *handle, const char *name, char **err, void *user_data);
245245
static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, bool need_api_init = false);
246-
static DSOCacheEntry* find_dso_cache_entry (hash_t hash) noexcept;
246+
247+
template<bool AotCache>
248+
static DSOCacheEntry* find_dso_cache_entry_common (hash_t hash) noexcept;
249+
static DSOCacheEntry* find_only_aot_cache_entry (hash_t hash) noexcept;
250+
static DSOCacheEntry* find_only_dso_cache_entry (hash_t hash) noexcept;
251+
static DSOCacheEntry* find_any_dso_cache_entry (hash_t hash) noexcept;
247252

248253
int LocalRefsAreIndirect (JNIEnv *env, jclass runtimeClass, int version);
249254
void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept;

src/native/monodroid/monodroid-glue.cc

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,19 +1012,69 @@ MonodroidRuntime::convert_dl_flags (int flags)
10121012
return lflags;
10131013
}
10141014

1015-
force_inline DSOCacheEntry*
1016-
MonodroidRuntime::find_dso_cache_entry (hash_t hash) noexcept
1015+
template<bool AotCache>
1016+
[[gnu::always_inline, gnu::flatten]]
1017+
DSOCacheEntry*
1018+
MonodroidRuntime::find_dso_cache_entry_common (hash_t hash) noexcept
10171019
{
1020+
DSOCacheEntry *arr;
1021+
size_t arr_size;
1022+
1023+
if constexpr (AotCache) {
1024+
log_debug (LOG_ASSEMBLY, "Looking for hash 0x%x in AOT cache", hash);
1025+
arr = aot_dso_cache;
1026+
arr_size = application_config.number_of_aot_cache_entries;
1027+
} else {
1028+
log_debug (LOG_ASSEMBLY, "Looking for hash 0x%x in DSO cache", hash);
1029+
arr = dso_cache;
1030+
arr_size = application_config.number_of_dso_cache_entries;
1031+
}
1032+
10181033
auto equal = [](DSOCacheEntry const& entry, hash_t key) -> bool { return entry.hash == key; };
10191034
auto less_than = [](DSOCacheEntry const& entry, hash_t key) -> bool { return entry.hash < key; };
1020-
ssize_t idx = Search::binary_search<DSOCacheEntry, equal, less_than> (hash, dso_cache, application_config.number_of_dso_cache_entries);
1035+
1036+
ssize_t idx = Search::binary_search<DSOCacheEntry, equal, less_than> (hash, arr, arr_size);
10211037
if (idx >= 0) {
1022-
return &dso_cache[idx];
1038+
return &arr[idx];
10231039
}
10241040

10251041
return nullptr;
10261042
}
10271043

1044+
[[gnu::always_inline, gnu::flatten]]
1045+
DSOCacheEntry*
1046+
MonodroidRuntime::find_only_aot_cache_entry (hash_t hash) noexcept
1047+
{
1048+
constexpr bool IsAotCache = true;
1049+
return find_dso_cache_entry_common<IsAotCache> (hash);
1050+
}
1051+
1052+
[[gnu::always_inline, gnu::flatten]]
1053+
DSOCacheEntry*
1054+
MonodroidRuntime::find_only_dso_cache_entry (hash_t hash) noexcept
1055+
{
1056+
constexpr bool IsAotCache = false;
1057+
return find_dso_cache_entry_common<IsAotCache> (hash);
1058+
}
1059+
1060+
[[gnu::always_inline, gnu::flatten]]
1061+
DSOCacheEntry*
1062+
MonodroidRuntime::find_any_dso_cache_entry (hash_t hash) noexcept
1063+
{
1064+
// If we're asked to look in the AOT DSO cache, do it first. This is because we're likely called from the
1065+
// MonoVM's dlopen fallback handler and it will not be a request to resolved a p/invoke, but most likely to
1066+
// find and load an AOT image for a managed assembly. Since there might be naming/hash conflicts in this
1067+
// scenario, we look at the AOT cache first.
1068+
//
1069+
// See: https://github.com/dotnet/android/issues/9081
1070+
DSOCacheEntry *ret = find_only_aot_cache_entry (hash);
1071+
if (ret != nullptr) {
1072+
return ret;
1073+
}
1074+
1075+
return find_only_dso_cache_entry (hash);
1076+
}
1077+
10281078
force_inline void*
10291079
MonodroidRuntime::monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory, [[maybe_unused]] bool need_api_init)
10301080
{
@@ -1087,12 +1137,13 @@ MonodroidRuntime::monodroid_dlopen_ignore_component_or_load ([[maybe_unused]] ha
10871137
return monodroid_dlopen_log_and_return (handle, err, name, false /* name_needs_free */);
10881138
}
10891139

1090-
force_inline void*
1091-
MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err) noexcept
1140+
[[gnu::always_inline, gnu::flatten]]
1141+
void*
1142+
MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, bool use_aot_cache) noexcept
10921143
{
10931144
hash_t name_hash = xxhash::hash (name, strlen (name));
10941145
log_debug (LOG_ASSEMBLY, "monodroid_dlopen: hash for name '%s' is 0x%zx", name, name_hash);
1095-
DSOCacheEntry *dso = find_dso_cache_entry (name_hash);
1146+
DSOCacheEntry *dso = use_aot_cache ? find_any_dso_cache_entry (name_hash) : find_only_dso_cache_entry (name_hash);
10961147
log_debug (LOG_ASSEMBLY, "monodroid_dlopen: hash match %sfound, DSO name is '%s'", dso == nullptr ? "not " : "", dso == nullptr ? "<unknown>" : dso->name);
10971148

10981149
if (dso == nullptr) {
@@ -1149,7 +1200,10 @@ MonodroidRuntime::monodroid_dlopen (const char *name, int flags, char **err, [[m
11491200
return nullptr;
11501201
}
11511202

1152-
return monodroid_dlopen (name, flags, err);
1203+
// We're called by MonoVM via a callback, we might need to return an AOT DSO.
1204+
// See: https://github.com/dotnet/android/issues/9081
1205+
constexpr bool USE_AOT_CACHE = true;
1206+
return monodroid_dlopen (name, flags, err, USE_AOT_CACHE);
11531207
}
11541208

11551209
void*

src/native/monodroid/pinvoke-override-api.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,14 @@ MonodroidRuntime::load_library_symbol (const char *library_name, const char *sym
376376
void *lib_handle = dso_handle == nullptr ? nullptr : *dso_handle;
377377

378378
if (lib_handle == nullptr) {
379-
lib_handle = monodroid_dlopen (library_name, MONO_DL_LOCAL, nullptr, nullptr);
379+
if (library_name == nullptr) {
380+
log_warn (LOG_ASSEMBLY, "load_library_symbol got a NULL library name, not able to look up a symbol");
381+
return nullptr;
382+
}
383+
// In p/invoke mode we don't need to consult the AOT DSO cache. Saves time and removes potential ambiguities
384+
// See: https://github.com/dotnet/android/issues/9081
385+
constexpr bool USE_AOT_CACHE = false;
386+
lib_handle = monodroid_dlopen (library_name, MONO_DL_LOCAL, nullptr, USE_AOT_CACHE);
380387
if (lib_handle == nullptr) {
381388
log_warn (LOG_ASSEMBLY, "Shared library '%s' not loaded, p/invoke '%s' may fail", library_name, symbol_name);
382389
return nullptr;

src/native/xamarin-app-stub/application_dso_stub.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,24 @@ DSOCacheEntry dso_cache[] = {
145145
},
146146
};
147147

148+
DSOCacheEntry aot_dso_cache[] = {
149+
{
150+
.hash = xamarin::android::xxhash::hash (fake_dso_name, sizeof(fake_dso_name) - 1),
151+
.real_name_hash = xamarin::android::xxhash::hash (fake_dso_name, sizeof(fake_dso_name) - 1),
152+
.ignore = true,
153+
.name = fake_dso_name,
154+
.handle = nullptr,
155+
},
156+
157+
{
158+
.hash = xamarin::android::xxhash::hash (fake_dso_name2, sizeof(fake_dso_name2) - 1),
159+
.real_name_hash = xamarin::android::xxhash::hash (fake_dso_name2, sizeof(fake_dso_name2) - 1),
160+
.ignore = true,
161+
.name = fake_dso_name2,
162+
.handle = nullptr,
163+
},
164+
};
165+
148166
DSOApkEntry dso_apk_entries[2] {};
149167

150168
//

src/native/xamarin-app-stub/xamarin-app.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ MONO_API MONO_API_EXPORT AssemblyStoreSingleAssemblyRuntimeData assembly_store_b
340340
MONO_API MONO_API_EXPORT AssemblyStoreRuntimeData assembly_store;
341341

342342
MONO_API MONO_API_EXPORT DSOCacheEntry dso_cache[];
343+
MONO_API MONO_API_EXPORT DSOCacheEntry aot_dso_cache[];
343344
MONO_API MONO_API_EXPORT DSOApkEntry dso_apk_entries[];
344345

345346
//

0 commit comments

Comments
 (0)