@@ -49,6 +49,9 @@ constexpr uint32_t elf_flags_mips64r6el = EF_MIPS_ARCH_64R6 | EF_MIPS_NAN2008;
4949
5050constexpr uint32_t elf_min_size = sizeof (Elf32_Ehdr);
5151
52+ // 4KiB.
53+ constexpr size_t min_map_size = 4 * (1 << 20 );
54+
5255enum class Endianness : bool {
5356 Little = true ,
5457 Big = false ,
@@ -394,9 +397,36 @@ const AOSCArch detect_architecture(Elf *elf_file, GElf_Ehdr &elf_ehdr,
394397 }
395398}
396399
397- static ELFParseResult identify_binary_data (const char *data,
398- const size_t size) {
400+ class MappedFile {
401+ public:
402+ MappedFile (int fd, size_t size) : m_fd{fd}, m_size{size} {
403+ if (m_fd == -1 ) {
404+ m_addr = MAP_FAILED;
405+ return ;
406+ }
407+ m_addr = mmap (nullptr , m_size, PROT_READ, MAP_PRIVATE, m_fd, 0 );
408+ }
409+ ~MappedFile () {
410+ if (m_addr != MAP_FAILED)
411+ munmap (m_addr, m_size);
412+ if (m_fd >= 0 )
413+ close (m_fd);
414+ }
415+ inline void *addr () const { return m_addr; }
416+ inline size_t size () const { return m_size; }
417+
418+ private:
419+ int m_fd;
420+ void *m_addr;
421+ size_t m_size;
422+ };
423+
424+ static ELFParseResult identify_binary_data (const char *path, int fd,
425+ const struct stat *st) {
399426 ELFParseResult result{};
427+ size_t size = st->st_size > min_map_size ? min_map_size : st->st_size ;
428+ const MappedFile file{fd, size};
429+ const char *data = static_cast <const char *>(file.addr ());
400430 const bool is_static_library =
401431 (size >= 8 && memcmp (data, ar_magic.data (), ar_magic.size ()) == 0 ) ||
402432 (size >= 8 &&
@@ -422,8 +452,19 @@ static ELFParseResult identify_binary_data(const char *data,
422452 result.bin_type = BinaryType::Invalid;
423453 return result;
424454 }
425-
426- Elf *elf_file = elf_memory (const_cast <char *>(data), size);
455+ /*
456+ * NOTE: Do not mmap entire files in parallel on 32-bit targets, since
457+ * they have much less address space to work with.
458+ */
459+ #ifdef __LP64__
460+ size_t full_size = st->st_size ;
461+ const MappedFile full_file = {fd, full_size};
462+ const char *full_data = static_cast <const char *>(full_file.addr ());
463+ Elf *elf_file = elf_memory (const_cast <char *>(full_data), full_size);
464+ #else
465+ elf_version (EV_CURRENT);
466+ Elf *elf_file = elf_begin (fd, ELF_C_READ, nullptr );
467+ #endif
427468 GElf_Ehdr elf_ehdr{};
428469 gelf_getehdr (elf_file, &elf_ehdr);
429470 const char *shstr_start = nullptr ;
@@ -504,30 +545,6 @@ inline static fs::path get_filename_from_build_id(const std::string &build_id,
504545 return final_path;
505546}
506547
507- class MappedFile {
508- public:
509- MappedFile (int fd, size_t size) : m_fd{fd}, m_size{size} {
510- if (m_fd == -1 ) {
511- m_addr = MAP_FAILED;
512- return ;
513- }
514- m_addr = mmap (nullptr , m_size, PROT_READ, MAP_PRIVATE, m_fd, 0 );
515- }
516- ~MappedFile () {
517- if (m_addr != MAP_FAILED)
518- munmap (m_addr, m_size);
519- if (m_fd >= 0 )
520- close (m_fd);
521- }
522- inline void *addr () const { return m_addr; }
523- inline size_t size () const { return m_size; }
524-
525- private:
526- int m_fd;
527- void *m_addr;
528- size_t m_size;
529- };
530-
531548static inline int forked_execvp (const char *path, char *const argv[]) {
532549 const pid_t pid = fork ();
533550 if (pid == 0 ) {
@@ -646,15 +663,13 @@ int elf_copy_debug_symbols(const char *src_path, const char *dst_path,
646663 perror (" fstat" );
647664 return -1 ;
648665 }
649- const size_t size = st.st_size ;
650- const MappedFile file{fd, size};
666+
651667 std::vector<const char *> args{" " , " --remove-section=.comment" ,
652668 " --remove-section=.note" };
653669 std::vector<const char *> extra_args{}; // for binutils
654670 args.reserve (8 );
655671 extra_args.reserve (1 );
656- const char *data = static_cast <const char *>(file.addr ());
657- const ELFParseResult result = identify_binary_data (data, size);
672+ const ELFParseResult result = identify_binary_data (src_path, fd, &st);
658673
659674 constexpr const char *base_path = " /usr/lib/" ;
660675 constexpr const size_t base_len = sizeof (base_path);
0 commit comments