Skip to content

Commit aa86a9d

Browse files
committed
Don't allocate memory for ZIP Central Directory data
Instead use `mmap`
1 parent 8d62e3a commit aa86a9d

File tree

2 files changed

+38
-33
lines changed

2 files changed

+38
-33
lines changed

src/native/mono/monodroid/embedded-assemblies-zip.cc

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
using namespace xamarin::android::internal;
1717

18-
[[gnu::always_inline]] bool
19-
EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX> &entry_name, ZipEntryLoadState &state) noexcept
18+
force_inline bool
19+
EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX> &entry_name, ZipEntryLoadState &state) noexcept
2020
{
2121
entry_name.clear ();
2222

@@ -150,8 +150,8 @@ EmbeddedAssemblies::store_individual_assembly_data (dynamic_local_string<SENSIBL
150150
have_and_want_debug_symbols = register_debug_symbols && bundled_debug_data != nullptr;
151151
}
152152

153-
[[gnu::always_inline]] void
154-
EmbeddedAssemblies::zip_load_individual_assembly_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, [[maybe_unused]] monodroid_should_register should_register, ZipEntryLoadState &state) noexcept
153+
force_inline void
154+
EmbeddedAssemblies::zip_load_individual_assembly_entries (std::span<uint8_t> const& buf, uint32_t num_entries, [[maybe_unused]] monodroid_should_register should_register, ZipEntryLoadState &state) noexcept
155155
{
156156
// TODO: do away with all the string manipulation here. Replace it with generating xxhash for the entry name
157157
dynamic_local_string<SENSIBLE_PATH_MAX> entry_name;
@@ -264,8 +264,8 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX>
264264
verify_assembly_store_and_set_info (payload_start, entry_name.get ());
265265
}
266266

267-
[[gnu::always_inline]] void
268-
EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept
267+
force_inline void
268+
EmbeddedAssemblies::zip_load_assembly_store_entries (std::span<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept
269269
{
270270
if (all_required_zip_entries_found ()) {
271271
return;
@@ -344,26 +344,28 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus
344344
)
345345
);
346346
}
347-
#ifdef DEBUG
348-
log_info (LOG_ASSEMBLY, "Central directory offset: {}", cd_offset);
349-
log_info (LOG_ASSEMBLY, "Central directory size: {}", cd_size);
350-
log_info (LOG_ASSEMBLY, "Central directory entries: {}", cd_entries);
351-
#endif
352-
off_t retval = ::lseek (fd, static_cast<off_t>(cd_offset), SEEK_SET);
353-
if (retval < 0) {
354-
Helpers::abort_application (
355-
LOG_ASSEMBLY,
356-
std::format (
357-
"Failed to seek to central directory position in APK: {}. retval={} errno={}, File={}",
358-
std::strerror (errno),
359-
retval,
360-
errno,
361-
optional_string (apk_name)
362-
)
363-
);
364-
}
365347

366-
std::vector<uint8_t> buf (cd_size);
348+
md_mmap_info apk_map = md_mmap_apk_file (fd, cd_offset, cd_size, apk_name);
349+
350+
log_debug (LOG_ASSEMBLY, "Central directory offset: %u", cd_offset);
351+
log_debug (LOG_ASSEMBLY, "Central directory size: %u", cd_size);
352+
log_debug (LOG_ASSEMBLY, "Central directory entries: %u", cd_entries);
353+
354+
// off_t retval = ::lseek (fd, static_cast<off_t>(cd_offset), SEEK_SET);
355+
// if (retval < 0) {
356+
// Helpers::abort_application (
357+
// LOG_ASSEMBLY,
358+
// Util::monodroid_strdup_printf (
359+
// "Failed to seek to central directory position in APK: %s. retval=%d errno=%d, File=%s",
360+
// std::strerror (errno),
361+
// retval,
362+
// errno,
363+
// apk_name
364+
// )
365+
// );
366+
// }
367+
368+
std::span<uint8_t> buf (reinterpret_cast<uint8_t*>(apk_map.area), apk_map.size);
367369
const auto [prefix, prefix_len] = get_assemblies_prefix_and_length ();
368370
ZipEntryLoadState state {
369371
.file_fd = fd,
@@ -399,6 +401,8 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus
399401
} else {
400402
zip_load_individual_assembly_entries (buf, cd_entries, should_register, state);
401403
}
404+
405+
// TODO: unmap here
402406
}
403407

404408
template<bool NeedsNameAlloc>
@@ -660,7 +664,7 @@ EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dy
660664
}
661665

662666
bool
663-
EmbeddedAssemblies::zip_read_entry_info (std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state) noexcept
667+
EmbeddedAssemblies::zip_read_entry_info (std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state)
664668
{
665669
constexpr size_t CD_COMPRESSION_METHOD_OFFSET = 10uz;
666670
constexpr size_t CD_UNCOMPRESSED_SIZE_OFFSET = 24uz;

src/native/mono/monodroid/embedded-assemblies.hh

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <string_view>
1010
#include <tuple>
1111
#include <vector>
12+
#include <span>
1213

1314
#include <dirent.h>
1415
#include <elf.h>
@@ -267,12 +268,12 @@ namespace xamarin::android::internal {
267268
static void get_assembly_data (XamarinAndroidBundledAssembly const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept;
268269
static void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept;
269270

270-
static void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register) noexcept;
271-
static void zip_load_individual_assembly_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept;
272-
static void zip_load_assembly_store_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept;
273-
static bool zip_load_entry_common (size_t entry_index, std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX> &entry_name, ZipEntryLoadState &state) noexcept;
274-
static bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept;
275-
static bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state) noexcept;
271+
void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register);
272+
void zip_load_individual_assembly_entries (std::span<uint8_t> const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept;
273+
void zip_load_assembly_store_entries (std::span<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept;
274+
bool zip_load_entry_common (size_t entry_index, std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX> &entry_name, ZipEntryLoadState &state) noexcept;
275+
bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries);
276+
bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state);
276277

277278
template<size_t BufSize>
278279
static bool zip_extract_cd_info (std::array<uint8_t, BufSize> const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept;
@@ -292,7 +293,7 @@ namespace xamarin::android::internal {
292293
template<ByteArrayContainer T>
293294
static bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string<SENSIBLE_PATH_MAX>& characters) noexcept;
294295

295-
static bool zip_read_entry_info (std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state) noexcept;
296+
bool zip_read_entry_info (std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state);
296297

297298
[[gnu::always_inline]]
298299
static std::tuple<void*, size_t> get_wrapper_dso_payload_pointer_and_size (md_mmap_info const& map_info, const char *file_name) noexcept

0 commit comments

Comments
 (0)