Skip to content

Commit 841daa1

Browse files
committed
Restore changes that somehow went AWOL...
...and caused the ILStrip tests to fail. Doh.
1 parent 8d648c4 commit 841daa1

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

src/native/pinvoke-override/pinvoke-override-api-impl.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ namespace xamarin::android {
1919
void *lib_handle = dso_handle == nullptr ? nullptr : *dso_handle;
2020

2121
if (lib_handle == nullptr) {
22-
lib_handle = internal::MonodroidDl::monodroid_dlopen (library_name, MONO_DL_LOCAL, nullptr, nullptr);
22+
// We're being called as part of the p/invoke mechanism, we don't need to look in the AOT cache
23+
constexpr bool USE_AOT_CACHE = false;
24+
lib_handle = internal::MonodroidDl::monodroid_dlopen (library_name, MONO_DL_LOCAL, nullptr, USE_AOT_CACHE);
2325
if (lib_handle == nullptr) {
2426
log_warn (LOG_ASSEMBLY, "Shared library '%s' not loaded, p/invoke '%s' may fail", library_name, symbol_name);
2527
return nullptr;

src/native/runtime-base/monodroid-dl.hh

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,65 @@ namespace xamarin::android::internal
2929
return lflags;
3030
}
3131

32-
static DSOCacheEntry* find_dso_cache_entry (hash_t hash) noexcept
32+
template<bool AotCache>
33+
[[gnu::always_inline, gnu::flatten]]
34+
static DSOCacheEntry* find_dso_cache_entry_common (hash_t hash) noexcept
3335
{
36+
DSOCacheEntry *arr;
37+
size_t arr_size;
38+
39+
if constexpr (AotCache) {
40+
log_debug (LOG_ASSEMBLY, "Looking for hash 0x%x in AOT cache", hash);
41+
arr = aot_dso_cache;
42+
arr_size = application_config.number_of_aot_cache_entries;
43+
} else {
44+
log_debug (LOG_ASSEMBLY, "Looking for hash 0x%x in DSO cache", hash);
45+
arr = dso_cache;
46+
arr_size = application_config.number_of_dso_cache_entries;
47+
}
48+
3449
auto equal = [](DSOCacheEntry const& entry, hash_t key) -> bool { return entry.hash == key; };
3550
auto less_than = [](DSOCacheEntry const& entry, hash_t key) -> bool { return entry.hash < key; };
36-
ssize_t idx = Search::binary_search<DSOCacheEntry, equal, less_than> (hash, dso_cache, application_config.number_of_dso_cache_entries);
51+
ssize_t idx = Search::binary_search<DSOCacheEntry, equal, less_than> (hash, arr, arr_size);
52+
3753
if (idx >= 0) {
38-
return &dso_cache[idx];
54+
return &arr[idx];
3955
}
4056

4157
return nullptr;
4258
}
4359

60+
[[gnu::always_inline, gnu::flatten]]
61+
static DSOCacheEntry* find_only_aot_cache_entry (hash_t hash) noexcept
62+
{
63+
constexpr bool IsAotCache = true;
64+
return find_dso_cache_entry_common<IsAotCache> (hash);
65+
}
66+
67+
[[gnu::always_inline, gnu::flatten]]
68+
static DSOCacheEntry* find_only_dso_cache_entry (hash_t hash) noexcept
69+
{
70+
constexpr bool IsAotCache = false;
71+
return find_dso_cache_entry_common<IsAotCache> (hash);
72+
}
73+
74+
[[gnu::always_inline, gnu::flatten]]
75+
static DSOCacheEntry* find_any_dso_cache_entry (hash_t hash) noexcept
76+
{
77+
// If we're asked to look in the AOT DSO cache, do it first. This is because we're likely called from the
78+
// MonoVM's dlopen fallback handler and it will not be a request to resolved a p/invoke, but most likely to
79+
// find and load an AOT image for a managed assembly. Since there might be naming/hash conflicts in this
80+
// scenario, we look at the AOT cache first.
81+
//
82+
// See: https://github.com/dotnet/android/issues/9081
83+
DSOCacheEntry *ret = find_only_aot_cache_entry (hash);
84+
if (ret != nullptr) {
85+
return ret;
86+
}
87+
88+
return find_only_dso_cache_entry (hash);
89+
}
90+
4491
static void* monodroid_dlopen_log_and_return (void *handle, char **err, const char *full_name, bool free_memory)
4592
{
4693
if (handle == nullptr && err != nullptr) {
@@ -103,7 +150,7 @@ namespace xamarin::android::internal
103150

104151
public:
105152
[[gnu::flatten]]
106-
static void* monodroid_dlopen (const char *name, int flags, char **err, [[maybe_unused]] void *user_data) noexcept
153+
static void* monodroid_dlopen (const char *name, int flags, char **err, bool use_aot_cache) noexcept
107154
{
108155
if (name == nullptr) {
109156
log_warn (LOG_ASSEMBLY, "monodroid_dlopen got a null name. This is not supported in NET+");
@@ -112,7 +159,7 @@ namespace xamarin::android::internal
112159

113160
hash_t name_hash = xxhash::hash (name, strlen (name));
114161
log_debug (LOG_ASSEMBLY, "monodroid_dlopen: hash for name '%s' is 0x%zx", name, name_hash);
115-
DSOCacheEntry *dso = find_dso_cache_entry (name_hash);
162+
DSOCacheEntry *dso = use_aot_cache ? find_any_dso_cache_entry (name_hash) : find_only_dso_cache_entry (name_hash);
116163
log_debug (LOG_ASSEMBLY, "monodroid_dlopen: hash match %sfound, DSO name is '%s'", dso == nullptr ? "not " : "", dso == nullptr ? "<unknown>" : dso->name);
117164

118165
if (dso == nullptr) {
@@ -161,6 +208,15 @@ namespace xamarin::android::internal
161208
return monodroid_dlopen_log_and_return (dso->handle, err, name, false /* name_needs_free */);
162209
}
163210

211+
[[gnu::flatten]]
212+
static void* monodroid_dlopen (const char *name, int flags, char **err, [[maybe_unused]] void *user_data) noexcept
213+
{
214+
// We're called by MonoVM via a callback, we might need to return an AOT DSO.
215+
// See: https://github.com/dotnet/android/issues/9081
216+
constexpr bool USE_AOT_CACHE = true;
217+
return monodroid_dlopen (name, flags, err, USE_AOT_CACHE);
218+
}
219+
164220
[[gnu::flatten]]
165221
static void* monodroid_dlsym (void *handle, const char *name, char **err, [[maybe_unused]] void *user_data)
166222
{

0 commit comments

Comments
 (0)