summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBreno Rodrigues Guimaraes <brenorg@gmail.com>2023-03-07 18:46:25 -0300
committerBreno Rodrigues Guimaraes <brenorg@gmail.com>2023-03-07 21:10:26 -0300
commit9f1c0af97b947687d3f916e10baa405b11d57584 (patch)
treec5742295b3f622b3877f4fab613b43cea65761a4
parentea2fca765c440fff1ff74e1463444dea7b819db2 (diff)
downloadpatchelf-9f1c0af97b947687d3f916e10baa405b11d57584.tar.gz
Set the alignment of the new LOAD segment the same as others
-rw-r--r--.github/workflows/publish.yml2
-rw-r--r--src/patchelf.cc11
-rw-r--r--tests/Makefile.am5
-rwxr-xr-xtests/set-rpath-library.sh10
4 files changed, 23 insertions, 5 deletions
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 0e600c3..c7ed337 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -89,7 +89,7 @@ jobs:
rm -f dist/*
cd patchelf-*
./configure --prefix /patchelf
- make check
+ make check || (cat tests/test-suite.log; exit 1)
make install-strip
cd -
tar -czf ./dist/patchelf-\$(cat patchelf-*/version)-\$(uname -m).tar.gz -C /patchelf .
diff --git a/src/patchelf.cc b/src/patchelf.cc
index d814d3f..62af389 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -800,12 +800,17 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
page of other segments. */
Elf_Addr startPage = 0;
Elf_Addr firstPage = 0;
+ unsigned alignStartPage = getPageSize();
for (auto & phdr : phdrs) {
- Elf_Addr thisPage = roundUp(rdi(phdr.p_vaddr) + rdi(phdr.p_memsz), getPageSize());
+ Elf_Addr thisPage = rdi(phdr.p_vaddr) + rdi(phdr.p_memsz);
if (thisPage > startPage) startPage = thisPage;
if (rdi(phdr.p_type) == PT_PHDR) firstPage = rdi(phdr.p_vaddr) - rdi(phdr.p_offset);
+ unsigned thisAlign = rdi(phdr.p_align);
+ alignStartPage = std::max(alignStartPage, thisAlign);
}
+ startPage = roundUp(startPage, alignStartPage);
+
debug("last page is 0x%llx\n", (unsigned long long) startPage);
debug("first page is 0x%llx\n", (unsigned long long) firstPage);
@@ -873,7 +878,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
if (!phdrs.empty() &&
rdi(lastSeg.p_type) == PT_LOAD &&
rdi(lastSeg.p_flags) == (PF_R | PF_W) &&
- rdi(lastSeg.p_align) == getPageSize()) {
+ rdi(lastSeg.p_align) == alignStartPage) {
auto segEnd = roundUp(rdi(lastSeg.p_offset) + rdi(lastSeg.p_memsz), getPageSize());
if (segEnd == startOffset) {
auto newSz = startOffset + neededSpace - rdi(lastSeg.p_offset);
@@ -892,7 +897,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, getPageSize());
+ wri(phdr.p_align, alignStartPage);
}
normalizeNoteSegments();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 55a8f75..4ae540a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -119,7 +119,7 @@ check_DATA = libbig-dynstr.debug
# - with libtool, it is difficult to control options
# - with libtool, it is not possible to compile convenience *dynamic* libraries :-(
check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libsimple-execstack.so libbuildid.so libtoomanystrtab.so \
- phdr-corruption.so many-syms-main libmany-syms.so
+ phdr-corruption.so many-syms-main libmany-syms.so liboveralign.so
libbuildid_so_SOURCES = simple.c
libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,--build-id
@@ -143,6 +143,9 @@ libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib)
libsimple_so_SOURCES = simple.c
libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-z,noexecstack
+liboveralign_so_SOURCES = simple.c
+liboveralign_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-z,max-page-size=0x10000
+
libsimple_execstack_so_SOURCES = simple.c
libsimple_execstack_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-z,execstack
diff --git a/tests/set-rpath-library.sh b/tests/set-rpath-library.sh
index 55661a1..55a4c16 100755
--- a/tests/set-rpath-library.sh
+++ b/tests/set-rpath-library.sh
@@ -14,6 +14,7 @@ mkdir -p "${SCRATCH}/libsB"
cp main-scoped "${SCRATCH}/"
cp libfoo-scoped.so "${SCRATCH}/libsA/"
cp libbar-scoped.so "${SCRATCH}/libsB/"
+cp liboveralign.so "${SCRATCH}/"
oldRPath=$(../src/patchelf --print-rpath "${SCRATCH}"/main-scoped)
if test -z "$oldRPath"; then oldRPath="/oops"; fi
@@ -56,3 +57,12 @@ if test "$exitCode" != 46; then
echo "bad exit code!"
exit 1
fi
+
+# ALL loads should have the same alignment
+lib="${SCRATCH}/liboveralign.so"
+../src/patchelf --set-rpath "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "$lib"
+num_alignments=$(${READELF} -W -l "${lib}" | grep LOAD | awk '{ print $NF }' | sort -u | wc -l)
+echo "$num_alignments"
+if test "${num_alignments}" -ne "1"; then
+ exit 1
+fi