Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit c16828b

Browse files
Revert "linker: map large portion of ELF file to read its fragments"
This reverts commit ea5dd95. Reason for revert: checking if this patch contributes to the regression in b/355950821 Change-Id: Iec2e335ab5a17d5b2724818259cab524b2780486
1 parent 8232cb9 commit c16828b

File tree

2 files changed

+17
-48
lines changed

2 files changed

+17
-48
lines changed

linker/linker_phdr.cpp

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -221,22 +221,17 @@ const char* ElfReader::get_string(ElfW(Word) index) const {
221221
}
222222

223223
bool 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.
368345
bool 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(&note_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, &note_hdr, &note_desc)) {
799771
continue;
800772
}

linker/linker_phdr.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class ElfReader {
7373
[[nodiscard]] bool FindGnuPropertySection();
7474
[[nodiscard]] bool CheckPhdr(ElfW(Addr));
7575
[[nodiscard]] bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment);
76-
[[nodiscard]] void* MapData(MappedFileFragment* fragment, off64_t offset, off64_t size);
7776

7877
bool did_read_;
7978
bool did_load_;
@@ -82,8 +81,6 @@ class ElfReader {
8281
off64_t file_offset_;
8382
off64_t file_size_;
8483

85-
MappedFileFragment file_fragment_;
86-
8784
ElfW(Ehdr) header_;
8885
size_t phdr_num_;
8986

0 commit comments

Comments
 (0)