Skip to content

Commit

Permalink
Actually use the embedded assembly store
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Oct 10, 2024
1 parent 207b58d commit c854efa
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 27 deletions.
8 changes: 8 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ public class BuildApk : AndroidTask
[Required]
public string CompressedAssembliesDir { get; set; }

[Required]
public bool AssemblyStoreEmbeddedInRuntime { get; set; }

[Output]
public ITaskItem[] OutputFiles { get; set; }

Expand Down Expand Up @@ -430,6 +433,11 @@ void AddAssemblies (ZipArchiveEx apk, bool debug, bool compress, IDictionary<And
AssemblyStoreBuilder? storeBuilder = null;

if (UseAssemblyStore) {
if (AssemblyStoreEmbeddedInRuntime) {
// We don't need to do anything here, the store is in `libxamarin-app.so`
return;
}

storeBuilder = new AssemblyStoreBuilder (Log);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,8 @@ because xbuild doesn't support framework reference assemblies.
ZipFlushSizeLimit="$(_ZipFlushSizeLimit)"
ZipAlignmentPages="$(AndroidZipAlignment)"
UseAssemblyStore="$(AndroidUseAssemblyStore)"
CompressedAssembliesDir="$(_AndroidCompressedAssembliesDir)">
CompressedAssembliesDir="$(_AndroidCompressedAssembliesDir)"
AssemblyStoreEmbeddedInRuntime="$(_AndroidEmbedAssemblyStoreInRuntime)">
<Output TaskParameter="OutputFiles" ItemName="ApkFiles" />
</BuildApk>
<BuildBaseAppBundle
Expand Down Expand Up @@ -2154,7 +2155,8 @@ because xbuild doesn't support framework reference assemblies.
ZipFlushSizeLimit="$(_ZipFlushSizeLimit)"
ZipAlignmentPages="$(AndroidZipAlignment)"
UseAssemblyStore="$(AndroidUseAssemblyStore)"
CompressedAssembliesDir="$(_AndroidCompressedAssembliesDir)">
CompressedAssembliesDir="$(_AndroidCompressedAssembliesDir)"
AssemblyStoreEmbeddedInRuntime="$(_AndroidEmbedAssemblyStoreInRuntime)">
<Output TaskParameter="OutputFiles" ItemName="BaseZipFile" />
</BuildBaseAppBundle>
<BuildAppBundle
Expand Down
63 changes: 38 additions & 25 deletions src/native/monodroid/embedded-assemblies-zip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,35 @@ EmbeddedAssemblies::zip_load_individual_assembly_entries (std::vector<uint8_t> c
}
}


[[gnu::always_inline]] void
EmbeddedAssemblies::verify_assembly_store_and_set_info (void *data_start, const char *name) noexcept
{
auto header = static_cast<AssemblyStoreHeader*>(data_start);

if (header->magic != ASSEMBLY_STORE_MAGIC) {
log_fatal (LOG_ASSEMBLY, "Assembly store '%s' is not a valid .NET for Android assembly store file", name);
Helpers::abort_application ();
}

if (header->version != ASSEMBLY_STORE_FORMAT_VERSION) {
log_fatal (LOG_ASSEMBLY, "Assembly store '%s' uses format version 0x%x, instead of the expected 0x%x", name, header->version, ASSEMBLY_STORE_FORMAT_VERSION);
Helpers::abort_application ();
}

constexpr size_t header_size = sizeof(AssemblyStoreHeader);

assembly_store.data_start = static_cast<uint8_t*>(data_start);
assembly_store.assembly_count = header->entry_count;
assembly_store.index_entry_count = header->index_entry_count;
assembly_store.assemblies = reinterpret_cast<AssemblyStoreEntryDescriptor*>(assembly_store.data_start + header_size + header->index_size);
assembly_store_hashes = reinterpret_cast<AssemblyStoreIndexEntry*>(assembly_store.data_start + header_size);

number_of_found_assemblies += assembly_store.assembly_count;
number_of_mapped_assembly_stores++;
have_and_want_debug_symbols = register_debug_symbols;
}

inline void
EmbeddedAssemblies::map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name, ZipEntryLoadState &state) noexcept
{
Expand Down Expand Up @@ -189,29 +218,7 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX>

auto [payload_start, payload_size] = get_wrapper_dso_payload_pointer_and_size (assembly_store_map, entry_name.get ());
log_debug (LOG_ASSEMBLY, "Adjusted assembly store pointer: %p; size: %zu", payload_start, payload_size);
auto header = static_cast<AssemblyStoreHeader*>(payload_start);

if (header->magic != ASSEMBLY_STORE_MAGIC) {
log_fatal (LOG_ASSEMBLY, "Assembly store '%s' is not a valid .NET for Android assembly store file", entry_name.get ());
Helpers::abort_application ();
}

if (header->version != ASSEMBLY_STORE_FORMAT_VERSION) {
log_fatal (LOG_ASSEMBLY, "Assembly store '%s' uses format version 0x%x, instead of the expected 0x%x", entry_name.get (), header->version, ASSEMBLY_STORE_FORMAT_VERSION);
Helpers::abort_application ();
}

constexpr size_t header_size = sizeof(AssemblyStoreHeader);

assembly_store.data_start = static_cast<uint8_t*>(payload_start);
assembly_store.assembly_count = header->entry_count;
assembly_store.index_entry_count = header->index_entry_count;
assembly_store.assemblies = reinterpret_cast<AssemblyStoreEntryDescriptor*>(assembly_store.data_start + header_size + header->index_size);
assembly_store_hashes = reinterpret_cast<AssemblyStoreIndexEntry*>(assembly_store.data_start + header_size);

number_of_found_assemblies += assembly_store.assembly_count;
number_of_mapped_assembly_stores++;
have_and_want_debug_symbols = register_debug_symbols;
verify_assembly_store_and_set_info (payload_start, entry_name.get ());
}

force_inline void
Expand All @@ -222,9 +229,15 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector<uint8_t> const&
}

dynamic_local_string<SENSIBLE_PATH_MAX> entry_name;
bool assembly_store_found = false;
bool assembly_store_found = embedded_assembly_store_size != 0;
if (assembly_store_found) {
log_debug (LOG_ASSEMBLY, "Got embedded assembly store, size %zu", embedded_assembly_store_size);
verify_assembly_store_and_set_info (embedded_assembly_store, "embedded");
log_debug (LOG_ASSEMBLY, "Looking for DSOs in APK");
} else {
log_debug (LOG_ASSEMBLY, "Looking for assembly store ('%s') and DSOs in APK", assembly_store_file_path.data ());
}

log_debug (LOG_ASSEMBLY, "Looking for assembly stores in APK ('%s)", assembly_store_file_path.data ());
for (size_t i = 0; i < num_entries; i++) {
if (all_required_zip_entries_found ()) {
need_to_scan_more_apks = false;
Expand Down
2 changes: 2 additions & 0 deletions src/native/monodroid/embedded-assemblies.hh
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ namespace xamarin::android::internal {
void set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name) noexcept;
void set_assembly_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name) noexcept;
void set_debug_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name) noexcept;

void verify_assembly_store_and_set_info (void *data_start, const char *name) noexcept;
void map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name, ZipEntryLoadState &state) noexcept;
const AssemblyStoreIndexEntry* find_assembly_store_entry (hash_t hash, const AssemblyStoreIndexEntry *entries, size_t entry_count) noexcept;
void store_individual_assembly_data (dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name, ZipEntryLoadState const& state, monodroid_should_register should_register) noexcept;
Expand Down
3 changes: 3 additions & 0 deletions src/native/xamarin-app-stub/application_dso_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,6 @@ const JniRemappingTypeReplacementEntry jni_remapping_type_replacements[] = {

size_t embedded_runtime_config_size = 0;
uint8_t embedded_runtime_config[0];

size_t embedded_assembly_store_size = 0;
uint8_t embedded_assembly_store[0];
3 changes: 3 additions & 0 deletions src/native/xamarin-app-stub/xamarin-app.hh
Original file line number Diff line number Diff line change
Expand Up @@ -398,4 +398,7 @@ MONO_API MONO_API_EXPORT void xamarin_app_init (JNIEnv *env, get_function_pointe

MONO_API MONO_API_EXPORT size_t embedded_runtime_config_size;
MONO_API MONO_API_EXPORT uint8_t embedded_runtime_config[];

MONO_API MONO_API_EXPORT size_t embedded_assembly_store_size;
MONO_API MONO_API_EXPORT uint8_t embedded_assembly_store[];
#endif // __XAMARIN_ANDROID_TYPEMAP_H

0 comments on commit c854efa

Please sign in to comment.