Skip to content

Commit

Permalink
Expand LOAD segment to cover new .dynstr and .dynsym sections
Browse files Browse the repository at this point in the history
This is not a robust fix, the first PT_LOAD segment is expanded
forward to cover .dynstr or .dynsym.
  • Loading branch information
ehmry committed Feb 19, 2021
1 parent 0ad9548 commit 55bba25
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,46 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
curOff += roundUp(i.second.size(), sectionAlignment);
}

/* Expand the LOAD segment as neccessary */
for (auto & i : replacedSections) {
std::string sectionName = i.first;

/* If this is the .dynstr or .dynsym section, then a PT_LOAD segment
must contain it. */
if (sectionName == ".dynstr" || sectionName == ".dynsym") {
auto const & shdr = findSection(sectionName);
bool loaded = false;
for (auto & phdr : phdrs) {
if (rdi(phdr.p_type) == PT_LOAD) {
if (rdi(phdr.p_offset) <= rdi(shdr.sh_offset) &&
rdi(shdr.sh_size) <= rdi(phdr.p_filesz)) {
debug("'%s' section is loaded\n", sectionName.c_str());
loaded = true;
break;
}
}
}

if (!loaded) {
debug("'%s' was moved out of a load segment…\n", sectionName.c_str());
for (auto & phdr : phdrs) {
if (rdi(phdr.p_type) == PT_LOAD) {
if (rdi(shdr.sh_offset) < rdi(phdr.p_offset)) {
Elf64_Xword gap = rdi(phdr.p_offset) - rdi(shdr.sh_offset);
debug("grow PT_LOAD segment by 0x%x to cover '%s'\n",
gap, sectionName.c_str());
wri(phdr.p_filesz, rdi(phdr.p_filesz) + gap);
wri(phdr.p_memsz, rdi(phdr.p_memsz) + gap);
phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr;
phdr.p_offset = shdr.sh_offset;
break;
}
}
}
}
}
}

replacedSections.clear();
}

Expand Down

0 comments on commit 55bba25

Please sign in to comment.