Skip to content

Commit 4f2e1aa

Browse files
committed
Add support for CoreCLR
1 parent 661aa5c commit 4f2e1aa

File tree

7 files changed

+63
-31
lines changed

7 files changed

+63
-31
lines changed

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
344344
<AndroidUseAssemblyStore Condition=" '$(AndroidUseAssemblyStore)' == '' and ('$(EmbedAssembliesIntoApk)' != 'true' or '$(AndroidIncludeDebugSymbols)' == 'true') ">false</AndroidUseAssemblyStore>
345345
<AndroidUseAssemblyStore Condition=" '$(AndroidUseAssemblyStore)' == '' ">true</AndroidUseAssemblyStore>
346346
<_AndroidUseAssemblyStore>$(AndroidUseAssemblyStore)</_AndroidUseAssemblyStore>
347-
348-
<_EmbedAssemblyStoreInRuntime Condition=" '$(_AndroidUseAssemblyStore)' == 'True' And '$(_AndroidEmbedAssemblyStoreInRuntime)' == 'True' ">true</_EmbedAssemblyStoreInRuntime>
349-
<_EmbedAssemblyStoreInRuntime Condition=" '$(_EmbedAssemblyStoreInRuntime)' != 'true' ">false</_EmbedAssemblyStoreInRuntime>
350347
</PropertyGroup>
351348

352349
<!-- For CoreCLR assembly stores are always on, individual assembly entries in the APK aren't supported.
@@ -357,6 +354,9 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
357354
</PropertyGroup>
358355

359356
<PropertyGroup>
357+
<_EmbedAssemblyStoreInRuntime Condition=" '$(_AndroidUseAssemblyStore)' == 'True' And '$(_AndroidEmbedAssemblyStoreInRuntime)' == 'True' ">true</_EmbedAssemblyStoreInRuntime>
358+
<_EmbedAssemblyStoreInRuntime Condition=" '$(_EmbedAssemblyStoreInRuntime)' != 'true' ">false</_EmbedAssemblyStoreInRuntime>
359+
360360
<_AndroidAotStripLibraries Condition=" '$(_AndroidAotStripLibraries)' == '' And '$(AndroidIncludeDebugSymbols)' != 'true' ">True</_AndroidAotStripLibraries>
361361
<AndroidAotEnableLazyLoad Condition=" '$(AndroidAotEnableLazyLoad)' == '' And '$(AotAssemblies)' == 'true' And '$(AndroidIncludeDebugSymbols)' != 'true' ">True</AndroidAotEnableLazyLoad>
362362
<AndroidEnableMarshalMethods Condition=" '$(AndroidEnableMarshalMethods)' == '' and ('$(UsingMicrosoftNETSdkRazor)' == 'true') ">False</AndroidEnableMarshalMethods>
@@ -1774,6 +1774,7 @@ because xbuild doesn't support framework reference assemblies.
17741774
<Output TaskParameter="AssemblySources" ItemName="_MarshalMethodsAssemblySource" />
17751775
</PrepareAbiItems>
17761776
<PrepareAbiItems
1777+
Condition=" '$(_AndroidRuntime)' == 'MonoVM' "
17771778
BuildTargetAbis="@(_BuildTargetAbis)"
17781779
NativeSourcesDir="$(_NativeAssemblySourceDir)"
17791780
Mode="EmbeddedRuntimeConfig">

src/native/clr/host/assembly-store.cc

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -236,35 +236,17 @@ auto AssemblyStore::open_assembly (std::string_view const& name, int64_t &size)
236236
return assembly_data;
237237
}
238238

239-
void AssemblyStore::map (int fd, std::string_view const& apk_path, std::string_view const& store_path, uint32_t offset, uint32_t size) noexcept
239+
[[gnu::always_inline]]
240+
void AssemblyStore::verify_assembly_store_and_set_info (void *data_start, std::string_view const& name) noexcept
240241
{
241-
detail::mmap_info assembly_store_map = Util::mmap_file (fd, offset, size, store_path);
242-
243-
auto [payload_start, payload_size] = Util::get_wrapper_dso_payload_pointer_and_size (assembly_store_map, store_path);
244-
log_debug (LOG_ASSEMBLY, "Adjusted assembly store pointer: {:p}; size: {}"sv, payload_start, payload_size);
245-
auto header = static_cast<AssemblyStoreHeader*>(payload_start);
246-
247-
auto get_full_store_path = [&apk_path, &store_path]() -> std::string {
248-
std::string full_store_path;
249-
250-
if (!apk_path.empty ()) {
251-
full_store_path.append (apk_path);
252-
// store path will be relative, to the apk
253-
full_store_path.append ("!/"sv);
254-
full_store_path.append (store_path);
255-
} else {
256-
full_store_path.append (store_path);
257-
}
258-
259-
return full_store_path;
260-
};
242+
auto header = static_cast<AssemblyStoreHeader*>(data_start);
261243

262244
if (header->magic != ASSEMBLY_STORE_MAGIC) {
263245
Helpers::abort_application (
264246
LOG_ASSEMBLY,
265247
std::format (
266248
"Assembly store '{}' is not a valid .NET for Android assembly store file"sv,
267-
get_full_store_path ()
249+
name
268250
)
269251
);
270252
}
@@ -274,7 +256,7 @@ void AssemblyStore::map (int fd, std::string_view const& apk_path, std::string_v
274256
LOG_ASSEMBLY,
275257
std::format (
276258
"Assembly store '{}' uses format version {:x}, instead of the expected {:x}"sv,
277-
get_full_store_path (),
259+
name,
278260
header->version,
279261
ASSEMBLY_STORE_FORMAT_VERSION
280262
)
@@ -283,11 +265,35 @@ void AssemblyStore::map (int fd, std::string_view const& apk_path, std::string_v
283265

284266
constexpr size_t header_size = sizeof(AssemblyStoreHeader);
285267

286-
assembly_store.data_start = static_cast<uint8_t*>(payload_start);
268+
assembly_store.data_start = static_cast<uint8_t*>(data_start);
287269
assembly_store.assembly_count = header->entry_count;
288270
assembly_store.index_entry_count = header->index_entry_count;
289271
assembly_store.assemblies = reinterpret_cast<AssemblyStoreEntryDescriptor*>(assembly_store.data_start + header_size + header->index_size);
290272
assembly_store_hashes = reinterpret_cast<AssemblyStoreIndexEntry*>(assembly_store.data_start + header_size);
273+
}
274+
275+
void AssemblyStore::map (int fd, std::string_view const& apk_path, std::string_view const& store_path, uint32_t offset, uint32_t size) noexcept
276+
{
277+
detail::mmap_info assembly_store_map = Util::mmap_file (fd, offset, size, store_path);
278+
auto [payload_start, payload_size] = Util::get_wrapper_dso_payload_pointer_and_size (assembly_store_map, store_path);
279+
log_debug (LOG_ASSEMBLY, "Adjusted assembly store pointer: {:p}; size: {}"sv, payload_start, payload_size);
291280

292-
log_debug (LOG_ASSEMBLY, "Mapped assembly store {}"sv, get_full_store_path ());
281+
std::string full_store_path;
282+
if (!apk_path.empty ()) {
283+
full_store_path.append (apk_path);
284+
// store path will be relative, to the apk
285+
full_store_path.append ("!/"sv);
286+
full_store_path.append (store_path);
287+
} else {
288+
full_store_path.append (store_path);
289+
}
290+
291+
verify_assembly_store_and_set_info (payload_start, full_store_path);
292+
log_debug (LOG_ASSEMBLY, "Mapped assembly store {}"sv, full_store_path);
293+
}
294+
295+
void AssemblyStore::map () noexcept
296+
{
297+
verify_assembly_store_and_set_info (embedded_assembly_store, "<embedded>"sv);
298+
log_debug (LOG_ASSEMBLY, "Mapped embedded assembly store");
293299
}

src/native/clr/host/host.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,23 @@ void Host::scan_filesystem_for_assemblies_and_libraries () noexcept
231231

232232
void Host::gather_assemblies_and_libraries (jstring_array_wrapper& runtimeApks, bool have_split_apks)
233233
{
234+
// Embedded assembly takes priority over the one found on the filesystem.
235+
if (found_assembly_store) {
236+
// We have an embedded store, map it
237+
AssemblyStore::map ();
238+
}
239+
234240
if (!AndroidSystem::is_embedded_dso_mode_enabled ()) {
235241
scan_filesystem_for_assemblies_and_libraries ();
236242
return;
237243
}
238244

245+
if (found_assembly_store) {
246+
// In CoreCLR we only look in the APK for the assembly store. Since we have
247+
// an embedded one, though, there's no need to waste time scanning the ZIP.
248+
return;
249+
}
250+
239251
int64_t apk_count = static_cast<int64_t>(runtimeApks.get_length ());
240252
bool got_split_config_abi_apk = false;
241253

src/native/clr/include/host/assembly-store.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace xamarin::android {
1414
public:
1515
static auto open_assembly (std::string_view const& name, int64_t &size) noexcept -> void*;
1616

17+
// Maps the embedded assembly store.
18+
static void map () noexcept;
1719
static void map (int fd, std::string_view const& apk_path, std::string_view const& store_path, uint32_t offset, uint32_t size) noexcept;
1820

1921
static void map (int fd, std::string_view const& file_path, uint32_t offset, uint32_t size) noexcept
@@ -23,6 +25,7 @@ namespace xamarin::android {
2325

2426
private:
2527
static void set_assembly_data_and_size (uint8_t* source_assembly_data, uint32_t source_assembly_data_size, uint8_t*& dest_assembly_data, uint32_t& dest_assembly_data_size) noexcept;
28+
static void verify_assembly_store_and_set_info (void *data_start, std::string_view const& name) noexcept;
2629

2730
// Returns a tuple of <assembly_data_pointer, data_size>
2831
static auto get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, std::string_view const& name) noexcept -> std::tuple<uint8_t*, uint32_t>;

src/native/clr/include/host/host.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99
#include <runtime-base/jni-wrappers.hh>
1010
#include <runtime-base/timing.hh>
11-
#include "../shared/log_types.hh"
11+
#include <shared/log_types.hh>
1212
#include "managed-interface.hh"
13+
#include <xamarin-app.hh>
1314

1415
namespace xamarin::android {
1516
class Host
@@ -53,7 +54,7 @@ namespace xamarin::android {
5354
static inline void *clr_host = nullptr;
5455
static inline unsigned int domain_id = 0;
5556
static inline std::shared_ptr<Timing> _timing{};
56-
static inline bool found_assembly_store = false;
57+
static inline bool found_assembly_store = embedded_assembly_store_size > 0;
5758
static inline jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr;
5859

5960
static inline JavaVM *jvm = nullptr;

src/native/clr/include/xamarin-app.hh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,10 @@ struct MarshalMethodName
427427
#endif // def RELEASE
428428

429429
using get_function_pointer_fn = void(*)(uint32_t mono_image_index, uint32_t class_index, uint32_t method_token, void*& target_ptr);
430-
extern "C" [[gnu::visibility("default")]] void xamarin_app_init (JNIEnv *env, get_function_pointer_fn fn) noexcept;
430+
431+
extern "C" {
432+
[[gnu::visibility("default")]] extern size_t embedded_assembly_store_size;
433+
[[gnu::visibility("default")]] extern uint8_t embedded_assembly_store[];
434+
435+
[[gnu::visibility("default")]] void xamarin_app_init (JNIEnv *env, get_function_pointer_fn fn) noexcept;
436+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,6 @@ const char *init_runtime_property_names[] = {
355355
char *init_runtime_property_values[] {
356356
nullptr,
357357
};
358+
359+
size_t embedded_assembly_store_size = 0;
360+
uint8_t embedded_assembly_store[0];

0 commit comments

Comments
 (0)