summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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