Skip to content

Commit 3b8fff6

Browse files
committed
Don't allocate memory for ZIP Central Directory data
Instead use `mmap`
1 parent 689c9eb commit 3b8fff6

File tree

2 files changed

+47
-40
lines changed

2 files changed

+47
-40
lines changed

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

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ using namespace xamarin::android::internal;
1717
using read_count_type = size_t;
1818

1919
force_inline bool
20-
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
20+
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
2121
{
2222
entry_name.clear ();
2323

@@ -143,7 +143,7 @@ EmbeddedAssemblies::store_individual_assembly_data (dynamic_local_string<SENSIBL
143143
}
144144

145145
force_inline void
146-
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
146+
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
147147
{
148148
// TODO: do away with all the string manipulation here. Replace it with generating xxhash for the entry name
149149
dynamic_local_string<SENSIBLE_PATH_MAX> entry_name;
@@ -257,7 +257,7 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX>
257257
}
258258

259259
force_inline void
260-
EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept
260+
EmbeddedAssemblies::zip_load_assembly_store_entries (std::span<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept
261261
{
262262
if (all_required_zip_entries_found ()) {
263263
return;
@@ -328,26 +328,28 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus
328328
)
329329
);
330330
}
331-
#ifdef DEBUG
332-
log_info (LOG_ASSEMBLY, "Central directory offset: %u", cd_offset);
333-
log_info (LOG_ASSEMBLY, "Central directory size: %u", cd_size);
334-
log_info (LOG_ASSEMBLY, "Central directory entries: %u", cd_entries);
335-
#endif
336-
off_t retval = ::lseek (fd, static_cast<off_t>(cd_offset), SEEK_SET);
337-
if (retval < 0) {
338-
Helpers::abort_application (
339-
LOG_ASSEMBLY,
340-
Util::monodroid_strdup_printf (
341-
"Failed to seek to central directory position in APK: %s. retval=%d errno=%d, File=%s",
342-
std::strerror (errno),
343-
retval,
344-
errno,
345-
apk_name
346-
)
347-
);
348-
}
349331

350-
std::vector<uint8_t> buf (cd_size);
332+
md_mmap_info apk_map = md_mmap_apk_file (fd, cd_offset, cd_size, apk_name);
333+
334+
log_debug (LOG_ASSEMBLY, "Central directory offset: %u", cd_offset);
335+
log_debug (LOG_ASSEMBLY, "Central directory size: %u", cd_size);
336+
log_debug (LOG_ASSEMBLY, "Central directory entries: %u", cd_entries);
337+
338+
// off_t retval = ::lseek (fd, static_cast<off_t>(cd_offset), SEEK_SET);
339+
// if (retval < 0) {
340+
// Helpers::abort_application (
341+
// LOG_ASSEMBLY,
342+
// Util::monodroid_strdup_printf (
343+
// "Failed to seek to central directory position in APK: %s. retval=%d errno=%d, File=%s",
344+
// std::strerror (errno),
345+
// retval,
346+
// errno,
347+
// apk_name
348+
// )
349+
// );
350+
// }
351+
352+
std::span<uint8_t> buf (reinterpret_cast<uint8_t*>(apk_map.area), apk_map.size);
351353
const auto [prefix, prefix_len] = get_assemblies_prefix_and_length ();
352354
ZipEntryLoadState state {
353355
.file_fd = fd,
@@ -364,25 +366,29 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus
364366
.max_assembly_file_name_size = 0,
365367
};
366368

367-
ssize_t nread = read (fd, buf.data (), static_cast<read_count_type>(buf.size ()));
368-
if (static_cast<size_t>(nread) != cd_size) {
369-
Helpers::abort_application (
370-
LOG_ASSEMBLY,
371-
Util::monodroid_strdup_printf (
372-
"Failed to read Central Directory from APK: %s. nread=%d errno=%d File=%s",
373-
std::strerror (errno),
374-
nread,
375-
errno,
376-
apk_name
377-
)
378-
);
379-
}
369+
// ssize_t nread = read (fd, buf.data (), static_cast<read_count_type>(buf.size ()));
370+
// if (static_cast<size_t>(nread) != cd_size) {
371+
// log_fatal (LOG_ASSEMBLY, "Failed to read Central Directory from the APK archive %s. %s (nread: %d; errno: %d)", apk_name, std::strerror (errno), nread, errno);
372+
// Helpers::abort_application ();
373+
// Helpers::abort_application (
374+
// LOG_ASSEMBLY,
375+
// Util::monodroid_strdup_printf (
376+
// "Failed to read Central Directory from APK: %s. nread=%d errno=%d File=%s",
377+
// std::strerror (errno),
378+
// nread,
379+
// errno,
380+
// apk_name
381+
// )
382+
// );
383+
// }
380384

381385
if (application_config.have_assembly_store) {
382386
zip_load_assembly_store_entries (buf, cd_entries, state);
383387
} else {
384388
zip_load_individual_assembly_entries (buf, cd_entries, should_register, state);
385389
}
390+
391+
// TODO: unmap here
386392
}
387393

388394
template<bool NeedsNameAlloc>
@@ -638,7 +644,7 @@ EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dy
638644
}
639645

640646
bool
641-
EmbeddedAssemblies::zip_read_entry_info (std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state)
647+
EmbeddedAssemblies::zip_read_entry_info (std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state)
642648
{
643649
constexpr size_t CD_COMPRESSION_METHOD_OFFSET = 10;
644650
constexpr size_t CD_UNCOMPRESSED_SIZE_OFFSET = 24;

src/native/monodroid/embedded-assemblies.hh

Lines changed: 5 additions & 4 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>
@@ -248,9 +249,9 @@ namespace xamarin::android::internal {
248249
void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept;
249250

250251
void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register);
251-
void zip_load_individual_assembly_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept;
252-
void zip_load_assembly_store_entries (std::vector<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept;
253-
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;
252+
void zip_load_individual_assembly_entries (std::span<uint8_t> const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept;
253+
void zip_load_assembly_store_entries (std::span<uint8_t> const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept;
254+
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;
254255
bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries);
255256
bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state);
256257

@@ -272,7 +273,7 @@ namespace xamarin::android::internal {
272273
template<ByteArrayContainer T>
273274
bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string<SENSIBLE_PATH_MAX>& characters) const noexcept;
274275

275-
bool zip_read_entry_info (std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state);
276+
bool zip_read_entry_info (std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state);
276277

277278
[[gnu::always_inline]]
278279
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)