summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tuegel <ttuegel@gmail.com>2014-09-11 21:04:26 (GMT)
committerThomas Tuegel <ttuegel@gmail.com>2014-09-12 20:24:35 (GMT)
commit4e8c47fa84b858bd13770bb1bff4b0072e56e03d (patch)
tree0f0f463ebc4b73295883c66eea911f2d7a6522ed
parentbf4b579d636ea8437cc763a1aa203d2a5764a037 (diff)
downloadpatchelf-4e8c47fa84b858bd13770bb1bff4b0072e56e03d.zip
patchelf-4e8c47fa84b858bd13770bb1bff4b0072e56e03d.tar.gz
patchelf-4e8c47fa84b858bd13770bb1bff4b0072e56e03d.tar.bz2
Move section headers if they would be overwritten
When rewriting the sections of an executable, it can happen that the section headers occur too early in the file and would be overwritten by the replaced sections. If this would happen, we move the section headers to the end of the file.
-rw-r--r--src/patchelf.cc21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 731b9ad..4a9aad7 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -711,11 +711,22 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
Elf_Addr firstPage = startAddr - startOffset;
debug("first page is 0x%llx\n", (unsigned long long) firstPage);
- /* Right now we assume that the section headers are somewhere near
- the end, which appears to be the case most of the time.
- Therefore they're not accidentally overwritten by the replaced
- sections. !!! Fix this. */
- assert((off_t) rdi(hdr->e_shoff) >= startOffset);
+ if ((off_t) rdi(hdr->e_shoff) < startOffset) {
+ /* The section headers occur too early in the file and would be
+ overwritten by the replaced sections. Move them to the end of the file
+ before proceeding. */
+ off_t shoffNew = fileSize;
+ off_t shSize = rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * rdi(hdr->e_shentsize);
+ growFile (fileSize + shSize);
+ wri(hdr->e_shoff, shoffNew);
+
+ /* Rewrite the section header table. For neatness, keep the
+ sections sorted. */
+ assert(rdi(hdr->e_shnum) == shdrs.size());
+ sortShdrs();
+ for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+ * ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i) = shdrs[i];
+ }
/* Compute the total space needed for the replaced sections, the