summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--src/patchelf.cc48
2 files changed, 30 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac
index bdda1a6..bfd3b6e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([patchelf], m4_esyscmd([echo -n $(cat ./version)]))
+AC_INIT([patchelf], m4_esyscmd([printf $(cat ./version)]))
AC_CONFIG_SRCDIR([src/patchelf.cc])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 foreign color-tests parallel-tests])
@@ -6,5 +6,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 foreign color-tests parallel-tests])
AM_PROG_CC_C_O
AC_PROG_CXX
+AC_CHECK_FUNCS([sysconf])
+
AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile patchelf.spec])
AC_OUTPUT
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 80b2aa0..06cd1e3 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -22,12 +22,6 @@
using namespace std;
-#ifdef MIPSEL
-/* The lemote fuloong 2f kernel defconfig sets a page size of 16KB */
-const unsigned int pageSize = 4096*4;
-#else
-const unsigned int pageSize = 4096;
-#endif
static bool debugMode = false;
@@ -45,6 +39,16 @@ unsigned char * contents = 0;
#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym
+static unsigned int getPageSize(){
+#if (defined HAVE_SYSCONF)
+ // if present, use sysconf to get kernel page size
+ return sysconf(_SC_PAGESIZE);
+#else
+ return 4096;
+#endif
+}
+
+
template<ElfFileParams>
class ElfFile
{
@@ -394,9 +398,9 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr sta
/* Move the entire contents of the file `extraPages' pages
further. */
unsigned int oldSize = fileSize;
- unsigned int shift = extraPages * pageSize;
- growFile(fileSize + extraPages * pageSize);
- memmove(contents + extraPages * pageSize, contents, oldSize);
+ unsigned int shift = extraPages * getPageSize();
+ growFile(fileSize + extraPages * getPageSize());
+ memmove(contents + extraPages * getPageSize(), contents, oldSize);
memset(contents + sizeof(Elf_Ehdr), 0, shift - sizeof(Elf_Ehdr));
/* Adjust the ELF header. */
@@ -413,8 +417,8 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr sta
if (rdi(phdrs[i].p_align) != 0 &&
(rdi(phdrs[i].p_vaddr) - rdi(phdrs[i].p_offset)) % rdi(phdrs[i].p_align) != 0) {
debug("changing alignment of program header %d from %d to %d\n", i,
- rdi(phdrs[i].p_align), pageSize);
- wri(phdrs[i].p_align, pageSize);
+ rdi(phdrs[i].p_align), getPageSize());
+ wri(phdrs[i].p_align, getPageSize());
}
}
@@ -428,7 +432,7 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr sta
wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage));
wri(phdr.p_filesz, wri(phdr.p_memsz, shift));
wri(phdr.p_flags, PF_R | PF_W);
- wri(phdr.p_align, pageSize);
+ wri(phdr.p_align, getPageSize());
}
@@ -557,7 +561,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
page of other segments. */
Elf_Addr startPage = 0;
for (unsigned int i = 0; i < phdrs.size(); ++i) {
- Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), pageSize);
+ Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), getPageSize());
if (thisPage > startPage) startPage = thisPage;
}
@@ -573,7 +577,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
debug("needed space is %d\n", neededSpace);
- size_t startOffset = roundUp(fileSize, pageSize);
+ size_t startOffset = roundUp(fileSize, getPageSize());
growFile(startOffset + neededSpace);
@@ -597,7 +601,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
size_t hole = startPage - startOffset;
/* Print a warning, because the hole could be very big. */
fprintf(stderr, "warning: working around a Linux kernel bug by creating a hole of %zu bytes in ā€˜%sā€™\n", hole, fileName.c_str());
- assert(hole % pageSize == 0);
+ assert(hole % getPageSize() == 0);
/* !!! We could create an actual hole in the file here,
but it's probably not worth the effort. */
growFile(fileSize + hole);
@@ -617,7 +621,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage));
wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace));
wri(phdr.p_flags, PF_R | PF_W);
- wri(phdr.p_align, pageSize);
+ wri(phdr.p_align, getPageSize());
/* Write out the replaced sections. */
@@ -688,7 +692,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
debug("first reserved offset/addr is 0x%x/0x%llx\n",
startOffset, (unsigned long long) startAddr);
- assert(startAddr % pageSize == startOffset % pageSize);
+ assert(startAddr % getPageSize() == startOffset % getPageSize());
Elf_Addr firstPage = startAddr - startOffset;
debug("first page is 0x%llx\n", (unsigned long long) firstPage);
@@ -717,13 +721,13 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
neededSpace += sizeof(Elf_Phdr);
debug("needed space is %d\n", neededSpace);
- unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize;
+ unsigned int neededPages = roundUp(neededSpace - startOffset, getPageSize()) / getPageSize();
debug("needed pages is %d\n", neededPages);
- if (neededPages * pageSize > firstPage)
+ if (neededPages * getPageSize() > firstPage)
error("virtual address space underrun!");
- firstPage -= neededPages * pageSize;
- startOffset += neededPages * pageSize;
+ firstPage -= neededPages * getPageSize();
+ startOffset += neededPages * getPageSize();
shiftFile(neededPages, firstPage);
}
@@ -1365,6 +1369,8 @@ static void patchElf()
if (!printInterpreter && !printRPath && !printSoname)
debug("patching ELF file `%s'\n", fileName.c_str());
+ debug("Kernel page size is %u bytes\n", getPageSize());
+
mode_t fileMode;
readFile(fileName, &fileMode);