@@ -221,22 +221,17 @@ const char* ElfReader::get_string(ElfW(Word) index) const {
221221}
222222
223223bool ElfReader::ReadElfHeader () {
224- size_t map_size = file_size_ - file_offset_;
225- if (map_size < sizeof (header_)) {
226- DL_ERR (" \" %s\" is too small to be an ELF executable: only found %zd bytes" , name_.c_str (),
227- map_size);
224+ ssize_t rc = TEMP_FAILURE_RETRY (pread64 (fd_, &header_, sizeof (header_), file_offset_));
225+ if (rc < 0 ) {
226+ DL_ERR (" can't read file \" %s\" : %s" , name_.c_str (), strerror (errno));
228227 return false ;
229228 }
230229
231- // Map at most 1MiB which should cover most cases
232- map_size = std::min (map_size, static_cast <size_t >(1 * 1024 * 1024 ));
233-
234- if (!file_fragment_.Map (fd_, file_offset_, 0 , map_size)) {
235- DL_ERR (" \" %s\" header mmap failed: %m" , name_.c_str ());
230+ if (rc != sizeof (header_)) {
231+ DL_ERR (" \" %s\" is too small to be an ELF executable: only found %zd bytes" , name_.c_str (),
232+ static_cast <size_t >(rc));
236233 return false ;
237234 }
238-
239- header_ = *static_cast <ElfW (Ehdr)*>(file_fragment_.data ());
240235 return true ;
241236}
242237
@@ -345,24 +340,6 @@ bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment)
345340 ((offset % alignment) == 0 );
346341}
347342
348- void * ElfReader::MapData (MappedFileFragment* fragment, off64_t offset, off64_t size) {
349- off64_t end;
350- CHECK (safe_add (&end, offset, size));
351-
352- // If the data is already mapped just return it
353- if (static_cast <off64_t >(file_fragment_.size ()) >= end) {
354- return static_cast <char *>(file_fragment_.data ()) + offset;
355- }
356- // Use the passed-in fragment if area is not mapped. We can't remap the original fragment
357- // because that invalidates all previous pointers if the file is remapped to a different
358- // virtual address. A local variable can't be used in place of the passed-in fragment because
359- // the area would be unmapped as soon as the local object goes out of scope.
360- if (fragment->Map (fd_, file_offset_, offset, size)) {
361- return fragment->data ();
362- }
363- return nullptr ;
364- }
365-
366343// Loads the program header table from an ELF file into a read-only private
367344// anonymous mmap-ed block.
368345bool ElfReader::ReadProgramHeaders () {
@@ -385,13 +362,12 @@ bool ElfReader::ReadProgramHeaders() {
385362 return false ;
386363 }
387364
388- void * phdr_data = MapData (&phdr_fragment_, header_.e_phoff , size);
389- if (phdr_data == nullptr ) {
365+ if (!phdr_fragment_.Map (fd_, file_offset_, header_.e_phoff , size)) {
390366 DL_ERR (" \" %s\" phdr mmap failed: %m" , name_.c_str ());
391367 return false ;
392368 }
393369
394- phdr_table_ = static_cast <ElfW (Phdr)*>(phdr_data );
370+ phdr_table_ = static_cast <ElfW (Phdr)*>(phdr_fragment_. data () );
395371 return true ;
396372}
397373
@@ -412,13 +388,12 @@ bool ElfReader::ReadSectionHeaders() {
412388 return false ;
413389 }
414390
415- void * shdr_data = MapData (&shdr_fragment_, header_.e_shoff , size);
416- if (shdr_data == nullptr ) {
391+ if (!shdr_fragment_.Map (fd_, file_offset_, header_.e_shoff , size)) {
417392 DL_ERR (" \" %s\" shdr mmap failed: %m" , name_.c_str ());
418393 return false ;
419394 }
420395
421- shdr_table_ = static_cast <const ElfW (Shdr)*>(shdr_data );
396+ shdr_table_ = static_cast <const ElfW (Shdr)*>(shdr_fragment_. data () );
422397 return true ;
423398}
424399
@@ -506,28 +481,26 @@ bool ElfReader::ReadDynamicSection() {
506481 return false ;
507482 }
508483
509- void * dynamic_data = MapData (&dynamic_fragment_, dynamic_shdr->sh_offset , dynamic_shdr->sh_size );
510- if (dynamic_data == nullptr ) {
484+ if (!dynamic_fragment_.Map (fd_, file_offset_, dynamic_shdr->sh_offset , dynamic_shdr->sh_size )) {
511485 DL_ERR (" \" %s\" dynamic section mmap failed: %m" , name_.c_str ());
512486 return false ;
513487 }
514488
515- dynamic_ = static_cast <const ElfW (Dyn)*>(dynamic_data );
489+ dynamic_ = static_cast <const ElfW (Dyn)*>(dynamic_fragment_. data () );
516490
517491 if (!CheckFileRange (strtab_shdr->sh_offset , strtab_shdr->sh_size , alignof (const char ))) {
518492 DL_ERR_AND_LOG (" \" %s\" has invalid offset/size of the .strtab section linked from .dynamic section" ,
519493 name_.c_str ());
520494 return false ;
521495 }
522496
523- void * strtab_data = MapData (&strtab_fragment_, strtab_shdr->sh_offset , strtab_shdr->sh_size );
524- if (strtab_data == nullptr ) {
497+ if (!strtab_fragment_.Map (fd_, file_offset_, strtab_shdr->sh_offset , strtab_shdr->sh_size )) {
525498 DL_ERR (" \" %s\" strtab section mmap failed: %m" , name_.c_str ());
526499 return false ;
527500 }
528501
529- strtab_ = static_cast <const char *>(strtab_data );
530- strtab_size_ = strtab_shdr-> sh_size ;
502+ strtab_ = static_cast <const char *>(strtab_fragment_. data () );
503+ strtab_size_ = strtab_fragment_. size () ;
531504 return true ;
532505}
533506
@@ -783,8 +756,7 @@ bool ElfReader::ReadPadSegmentNote() {
783756 // note_fragment is scoped to within the loop so that there is
784757 // at most 1 PT_NOTE mapped at anytime during this search.
785758 MappedFileFragment note_fragment;
786- void * note_data = MapData (¬e_fragment, phdr->p_offset , phdr->p_memsz );
787- if (note_data == nullptr ) {
759+ if (!note_fragment.Map (fd_, file_offset_, phdr->p_offset , phdr->p_memsz )) {
788760 DL_ERR (" \" %s\" : PT_NOTE mmap(nullptr, %p, PROT_READ, MAP_PRIVATE, %d, %p) failed: %m" ,
789761 name_.c_str (), reinterpret_cast <void *>(phdr->p_memsz ), fd_,
790762 reinterpret_cast <void *>(page_start (file_offset_ + phdr->p_offset )));
@@ -794,7 +766,7 @@ bool ElfReader::ReadPadSegmentNote() {
794766 const ElfW (Nhdr)* note_hdr = nullptr ;
795767 const char * note_desc = nullptr ;
796768 if (!__get_elf_note (NT_ANDROID_TYPE_PAD_SEGMENT, " Android" ,
797- reinterpret_cast <ElfW (Addr)>(note_data ),
769+ reinterpret_cast <ElfW (Addr)>(note_fragment. data () ),
798770 phdr, ¬e_hdr, ¬e_desc)) {
799771 continue ;
800772 }
0 commit comments