Skip to content

Commit 8cf6dc4

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

File tree

2 files changed

+32
-27
lines changed

2 files changed

+32
-27
lines changed

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

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
using namespace xamarin::android::internal;
1616

1717
force_inline bool
18-
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+
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
1919
{
2020
entry_name.clear ();
2121

@@ -141,7 +141,7 @@ EmbeddedAssemblies::store_individual_assembly_data (dynamic_local_string<SENSIBL
141141
}
142142

143143
force_inline void
144-
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
144+
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
145145
{
146146
// TODO: do away with all the string manipulation here. Replace it with generating xxhash for the entry name
147147
dynamic_local_string<SENSIBLE_PATH_MAX> entry_name;
@@ -255,7 +255,7 @@ EmbeddedAssemblies::map_assembly_store (dynamic_local_string<SENSIBLE_PATH_MAX>
255255
}
256256

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

348-
std::vector<uint8_t> buf (cd_size);
330+
md_mmap_info apk_map = md_mmap_apk_file (fd, cd_offset, cd_size, apk_name);
331+
332+
log_debug (LOG_ASSEMBLY, "Central directory offset: %u", cd_offset);
333+
log_debug (LOG_ASSEMBLY, "Central directory size: %u", cd_size);
334+
log_debug (LOG_ASSEMBLY, "Central directory entries: %u", cd_entries);
335+
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+
// }
349+
350+
std::span<uint8_t> buf (reinterpret_cast<uint8_t*>(apk_map.area), apk_map.size);
349351
const auto [prefix, prefix_len] = get_assemblies_prefix_and_length ();
350352
ZipEntryLoadState state {
351353
.file_fd = fd,
@@ -381,6 +383,8 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unus
381383
} else {
382384
zip_load_individual_assembly_entries (buf, cd_entries, should_register, state);
383385
}
386+
387+
// TODO: unmap here
384388
}
385389

386390
template<bool NeedsNameAlloc>
@@ -636,7 +640,7 @@ EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dy
636640
}
637641

638642
bool
639-
EmbeddedAssemblies::zip_read_entry_info (std::vector<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state)
643+
EmbeddedAssemblies::zip_read_entry_info (std::span<uint8_t> const& buf, dynamic_local_string<SENSIBLE_PATH_MAX>& file_name, ZipEntryLoadState &state)
640644
{
641645
constexpr size_t CD_COMPRESSION_METHOD_OFFSET = 10uz;
642646
constexpr size_t CD_UNCOMPRESSED_SIZE_OFFSET = 24uz;

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)