diff options
author | Jörg Thalheim <joerg@thalheim.io> | 2022-11-05 09:08:17 -0400 |
---|---|---|
committer | Jörg Thalheim <joerg@thalheim.io> | 2022-11-05 14:12:11 +0100 |
commit | 42394e880bc5524122234fe2c2eaa043063ac581 (patch) | |
tree | bcf87a7839c61deee4e3a0103ceacc07d89b2a02 /src | |
parent | 7c18779e852e102faebcfdf63ffd250dccdcf4a3 (diff) | |
download | patchelf-42394e880bc5524122234fe2c2eaa043063ac581.tar.gz |
write out replace sections in original order
Libc and other programs sometimes make assumption in which order
sections.
i.e. glibc expects that the strtab is after the symtab section: https://github.com/bminor/glibc/blob/9cc9d61ee12f2f8620d8e0ea3c42af02bf07fe1e/elf/dl-fptr.c#L179
To decrease the likelyhood of breakages we keep the relative order the
same when replacing section.
Diffstat (limited to 'src')
-rw-r--r-- | src/patchelf.cc | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc index baf1d03..eac156d 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -601,20 +601,26 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff, } std::set<unsigned int> noted_phdrs = {}; - for (auto & i : replacedSections) { - const std::string & sectionName = i.first; - auto & shdr = findSectionHeader(sectionName); + + /* We iterate over the sorted section headers here, so that the relative + position between replaced sections stays the same. */ + for (auto & shdr : shdrs) { + std::string sectionName = getSectionName(shdr); + auto i = replacedSections.find(sectionName); + if (i == replacedSections.end()) + continue; + Elf_Shdr orig_shdr = shdr; debug("rewriting section '%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n", - sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i.second.size()); + sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i->second.size()); - memcpy(fileContents->data() + curOff, (unsigned char *) i.second.c_str(), - i.second.size()); + memcpy(fileContents->data() + curOff, (unsigned char *) i->second.c_str(), + i->second.size()); /* Update the section header for this section. */ wri(shdr.sh_offset, curOff); wri(shdr.sh_addr, startAddr + (curOff - startOffset)); - wri(shdr.sh_size, i.second.size()); + wri(shdr.sh_size, i->second.size()); wri(shdr.sh_addralign, sectionAlignment); /* If this is the .interp section, then the PT_INTERP segment @@ -704,7 +710,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff, } } - curOff += roundUp(i.second.size(), sectionAlignment); + curOff += roundUp(i->second.size(), sectionAlignment); } replacedSections.clear(); |