summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJörg Thalheim <joerg@thalheim.io>2022-11-05 09:08:17 -0400
committerJörg Thalheim <joerg@thalheim.io>2022-11-05 14:12:11 +0100
commit42394e880bc5524122234fe2c2eaa043063ac581 (patch)
treebcf87a7839c61deee4e3a0103ceacc07d89b2a02 /src
parent7c18779e852e102faebcfdf63ffd250dccdcf4a3 (diff)
downloadpatchelf-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.cc22
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();