Skip to content

Commit 06d6836

Browse files
committed
System.loadLibrary works now
1 parent 96bbe92 commit 06d6836

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

src/native/common/include/runtime-base/dso-loader.hh

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace xamarin::android {
1919
{
2020
jni_env = env;
2121
systemKlass = systemClass;
22-
System_loadLibrary = env->GetMethodID (systemClass, "loadLibrary", "(Ljava/lang/String;)V");
22+
System_loadLibrary = env->GetStaticMethodID (systemClass, "loadLibrary", "(Ljava/lang/String;)V");
2323
if (System_loadLibrary == nullptr) [[unlikely]] {
2424
Helpers::abort_application ("Failed to look up the Java System.loadLibrary method.");
2525
}
@@ -34,7 +34,7 @@ namespace xamarin::android {
3434
return load_jni (path, true /* name_is_path */);
3535
}
3636

37-
log_info (LOG_ASSEMBLY, "Trying to load shared library '{}'", path);
37+
log_info (LOG_ASSEMBLY, "[filesystem] Trying to load shared library '{}'", path);
3838
if constexpr (!SkipExistsCheck) {
3939
if (!AndroidSystem::is_embedded_dso_mode_enabled () && !Util::file_exists (path)) {
4040
log_info (LOG_ASSEMBLY, "Shared library '{}' not found", path);
@@ -53,6 +53,8 @@ namespace xamarin::android {
5353
return load_jni (name, true /* name_is_path */);
5454
}
5555

56+
log_info (LOG_ASSEMBLY, "[apk] Trying to load shared library '{}', offset in the apk == {}", name, offset);
57+
5658
android_dlextinfo dli;
5759
dli.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
5860
dli.library_fd = fd;
@@ -66,6 +68,7 @@ namespace xamarin::android {
6668
static auto log_and_return (void *handle, std::string_view const& full_name) -> void*
6769
{
6870
if (handle != nullptr) [[likely]] {
71+
log_debug (LOG_ASSEMBLY, "Shared library {} loaded (handle {:p})", full_name, handle);
6972
return handle;
7073
}
7174

@@ -85,6 +88,8 @@ namespace xamarin::android {
8588

8689
static auto load_jni (std::string_view const& name, bool name_is_path) -> void*
8790
{
91+
log_debug (LOG_ASSEMBLY, "Loading JNI library {} with System.loadLibrary", name);
92+
8893
if (jni_env == nullptr || systemKlass == nullptr) [[unlikely]] {
8994
Helpers::abort_application ("DSO loader class not initialized properly."sv);
9095
}
@@ -98,34 +103,46 @@ namespace xamarin::android {
98103
if (!is_path) {
99104
name = full_name;
100105
} else {
101-
name = full_name; // TODO: cut the path
102-
}
103-
104-
size_t name_start = 0;
105-
size_t name_end = full_name.length ();
106-
107-
if (name.starts_with ("lib"sv) && name.length () > 3) {
108-
name_start = 3;
106+
name = full_name;
107+
size_t last_slash = name.find_last_of ('/');
108+
if (last_slash != std::string_view::npos) [[likely]] {
109+
last_slash++;
110+
if (last_slash <= name.length ()) {
111+
name.remove_prefix (last_slash);
112+
}
113+
}
109114
}
110115

111-
if (name.ends_with (".so"sv) && name.length () > 3) {
112-
name_end -= 3;
116+
constexpr std::string_view lib_prefix { "lib" };
117+
if (name.starts_with (lib_prefix) && name.length () > 3) {
118+
if (lib_prefix.length () <= name.length ()) {
119+
name.remove_prefix (lib_prefix.length ());
120+
}
113121
}
114122

115-
if (name_start >= name_end) [[unlikely]] {
116-
return name;
123+
constexpr std::string_view lib_ext { ".so" };
124+
if (name.ends_with (lib_ext) && name.length () > 3) {
125+
if (lib_ext.length () <= name.length ()) {
126+
name.remove_suffix (lib_ext.length ());
127+
}
117128
}
118129

119-
return std::move (name.substr (name_start, name.length () - name_end));
130+
return name;
120131
};
121132

122-
const std::string_view undecorated_lib_name = get_undecorated_name (name, name_is_path);
133+
const std::string undecorated_lib_name { get_undecorated_name (name, name_is_path) };
134+
log_debug (LOG_ASSEMBLY, "Undecorated library name: {}", undecorated_lib_name);
123135

124-
jstring lib_name = jni_env->NewStringUTF (undecorated_lib_name.data ());
136+
jstring lib_name = jni_env->NewStringUTF (undecorated_lib_name.c_str ());
137+
if (lib_name == nullptr) [[unlikely]] {
138+
// It's an OOM, there's nothing better we can do
139+
Helpers::abort_application ("Java string allocation failed while loading a shared library.");
140+
}
125141
jni_env->CallStaticVoidMethod (systemKlass, System_loadLibrary, lib_name);
126142

127143
// This is unfortunate, but since `System.loadLibrary` doesn't return the class handle, we must get it this
128144
// way :(
145+
log_debug (LOG_ASSEMBLY, "Attempting to get library {} handle after System.loadLibrary", name);
129146
return log_and_return (dlopen (name.data (), RTLD_NOLOAD), name);
130147
}
131148

0 commit comments

Comments
 (0)