public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/patchelf] rawhide: Update to v0.19.0
@ 2026-06-28 8:48 Jeremy Sanders
0 siblings, 0 replies; only message in thread
From: Jeremy Sanders @ 2026-06-28 8:48 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/patchelf
Branch : rawhide
Commit : 445cd2ab0cf4b4249b34c06d29587aa692d83995
Author : Jeremy Sanders <jeremy@jeremysanders.net>
Date : 2026-06-28T09:47:52+01:00
Stats : +8/-352 in 4 file(s)
URL : https://src.fedoraproject.org/rpms/patchelf/c/445cd2ab0cf4b4249b34c06d29587aa692d83995?branch=rawhide
Log:
Update to v0.19.0
---
diff --git a/.gitignore b/.gitignore
index 11947c8..5aa8d46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
/patchelf-0.17.0.tar.gz
/patchelf-0.17.2.tar.gz
/patchelf-0.18.0.tar.gz
+/patchelf-0.19.0.tar.gz
diff --git a/0001-Allocate-PHT-SHT-at-the-end-of-the-.elf-file.patch b/0001-Allocate-PHT-SHT-at-the-end-of-the-.elf-file.patch
deleted file mode 100644
index 5317f24..0000000
--- a/0001-Allocate-PHT-SHT-at-the-end-of-the-.elf-file.patch
+++ /dev/null
@@ -1,344 +0,0 @@
-From a97399ab349ef06c4f1ebb0ef002a5e6ef17a8d1 Mon Sep 17 00:00:00 2001
-From: Patryk Wychowaniec <pwychowaniec@pm.me>
-Date: Sat, 28 Dec 2024 17:00:44 +0100
-Subject: [PATCH] Allocate PHT & SHT at the end of the *.elf file
-
----
- src/patchelf.cc | 172 ++++++++++++++++++++++-------------
- src/patchelf.h | 3 +-
- tests/grow-file.sh | 5 +-
- tests/repeated-updates.sh | 2 +-
- tests/short-first-segment.sh | 7 +-
- 5 files changed, 120 insertions(+), 69 deletions(-)
-
-diff --git a/src/patchelf.cc b/src/patchelf.cc
-index 82b4b46..074e6d5 100644
---- a/src/patchelf.cc
-+++ b/src/patchelf.cc
-@@ -553,8 +553,7 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, size_t start
-
- assert(splitIndex != -1);
-
-- /* Add a segment that maps the new program/section headers and
-- PT_INTERP segment into memory. Otherwise glibc will choke. */
-+ /* Add another PT_LOAD segment loading the data we've split above. */
- phdrs.resize(rdi(hdr()->e_phnum) + 1);
- wri(hdr()->e_phnum, rdi(hdr()->e_phnum) + 1);
- Elf_Phdr & phdr = phdrs.at(rdi(hdr()->e_phnum) - 1);
-@@ -634,11 +633,19 @@ unsigned int ElfFile<ElfFileParamNames>::getSectionIndex(const SectionName & sec
- }
-
- template<ElfFileParams>
--bool ElfFile<ElfFileParamNames>::haveReplacedSection(const SectionName & sectionName) const
-+bool ElfFile<ElfFileParamNames>::hasReplacedSection(const SectionName & sectionName) const
- {
- return replacedSections.count(sectionName);
- }
-
-+template<ElfFileParams>
-+bool ElfFile<ElfFileParamNames>::canReplaceSection(const SectionName & sectionName) const
-+{
-+ auto shdr = findSectionHeader(sectionName);
-+
-+ return sectionName == ".interp" || rdi(shdr.sh_type) != SHT_PROGBITS;
-+}
-+
- template<ElfFileParams>
- std::string & ElfFile<ElfFileParamNames>::replaceSection(const SectionName & sectionName,
- unsigned int size)
-@@ -819,28 +826,59 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
- unsigned int num_notes = std::count_if(shdrs.begin(), shdrs.end(),
- [this](Elf_Shdr shdr) { return rdi(shdr.sh_type) == SHT_NOTE; });
-
-- /* Because we're adding a new section header, we're necessarily increasing
-- the size of the program header table. This can cause the first section
-- to overlap the program header table in memory; we need to shift the first
-- few segments to someplace else. */
-- /* Some sections may already be replaced so account for that */
-+ /* Compute the total space needed for the replaced sections, pessimistically
-+ assuming we're going to need one more to account for new PT_LOAD covering
-+ relocated PHDR */
-+ off_t phtSize = roundUp((phdrs.size() + num_notes + 1) * sizeof(Elf_Phdr) + sizeof(Elf_Ehdr), sectionAlignment);
-+ off_t shtSize = roundUp(rdi(hdr()->e_shnum) * rdi(hdr()->e_shentsize), sectionAlignment);
-+
-+ /* Check if we can keep PHT at the beginning of the file.
-+
-+ We'd like to do that, because it preverves compatibility with older
-+ kernels¹ - but if the PHT has grown too much, we have no other option but
-+ to move it at the end of the file.
-+
-+ ¹ older kernels had a bug that prevented them from loading ELFs with
-+ PHDRs not located at the beginning of the file; it was fixed over
-+ 0da1d5002745cdc721bc018b582a8a9704d56c42 (2022-03-02) */
-+ bool relocatePht = false;
- unsigned int i = 1;
-- Elf_Addr pht_size = sizeof(Elf_Ehdr) + (phdrs.size() + num_notes + 1)*sizeof(Elf_Phdr);
-- while( i < rdi(hdr()->e_shnum) && rdi(shdrs.at(i).sh_offset) <= pht_size ) {
-- if (not haveReplacedSection(getSectionName(shdrs.at(i))))
-- replaceSection(getSectionName(shdrs.at(i)), rdi(shdrs.at(i).sh_size));
-+
-+ while (i < rdi(hdr()->e_shnum) && ((off_t) rdi(shdrs.at(i).sh_offset)) <= phtSize) {
-+ const auto & sectionName = getSectionName(shdrs.at(i));
-+
-+ if (!hasReplacedSection(sectionName) && !canReplaceSection(sectionName)) {
-+ relocatePht = true;
-+ break;
-+ }
-+
- i++;
- }
-- bool moveHeaderTableToTheEnd = rdi(hdr()->e_shoff) < pht_size;
-+ if (!relocatePht) {
-+ unsigned int i = 1;
-+
-+ while (i < rdi(hdr()->e_shnum) && ((off_t) rdi(shdrs.at(i).sh_offset)) <= phtSize) {
-+ const auto & sectionName = getSectionName(shdrs.at(i));
-+ const auto sectionSize = rdi(shdrs.at(i).sh_size);
-+
-+ if (!hasReplacedSection(sectionName)) {
-+ replaceSection(sectionName, sectionSize);
-+ }
-+
-+ i++;
-+ }
-+ }
-+
-+ /* Calculate how much space we'll need. */
-+ off_t neededSpace = shtSize;
-+
-+ if (relocatePht) {
-+ neededSpace += phtSize;
-+ }
-
-- /* Compute the total space needed for the replaced sections */
-- off_t neededSpace = 0;
- for (auto & s : replacedSections)
- neededSpace += roundUp(s.second.size(), sectionAlignment);
-
-- off_t headerTableSpace = roundUp(rdi(hdr()->e_shnum) * rdi(hdr()->e_shentsize), sectionAlignment);
-- if (moveHeaderTableToTheEnd)
-- neededSpace += headerTableSpace;
- debug("needed space is %d\n", neededSpace);
-
- Elf_Off startOffset = roundUp(fileContents->size(), getPageSize());
-@@ -851,43 +889,29 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
- off_t binutilsQuirkPadding = 1;
- fileContents->resize(startOffset + neededSpace + binutilsQuirkPadding, 0);
-
-- /* Even though this file is of type ET_DYN, it could actually be
-- an executable. For instance, Gold produces executables marked
-- ET_DYN as does LD when linking with pie. If we move PT_PHDR, it
-- has to stay in the first PT_LOAD segment or any subsequent ones
-- if they're continuous in memory due to linux kernel constraints
-- (see BUGS). Since the end of the file would be after bss, we can't
-- move PHDR there, we therefore choose to leave PT_PHDR where it is but
-- move enough following sections such that we can add the extra PT_LOAD
-- section to it. This PT_LOAD segment ensures the sections at the end of
-- the file are mapped into memory for ld.so to process.
-- We can't use the approach in rewriteSectionsExecutable()
-- since DYN executables tend to start at virtual address 0, so
-- rewriteSectionsExecutable() won't work because it doesn't have
-- any virtual address space to grow downwards into. */
-- if (isExecutable && startOffset > startPage) {
-- debug("shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug\n", startOffset - startPage);
-- startPage = startOffset;
-- }
--
-- wri(hdr()->e_phoff, sizeof(Elf_Ehdr));
--
-- bool needNewSegment = true;
- auto& lastSeg = phdrs.back();
-- /* Try to extend the last segment to include replaced sections */
-+ Elf_Addr lastSegAddr = 0;
-+
-+ /* As an optimization, instead of allocating a new PT_LOAD segment, try
-+ expanding the last one */
- if (!phdrs.empty() &&
- rdi(lastSeg.p_type) == PT_LOAD &&
- rdi(lastSeg.p_flags) == (PF_R | PF_W) &&
- 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);
-+
- wri(lastSeg.p_filesz, wri(lastSeg.p_memsz, newSz));
-- needNewSegment = false;
-+
-+ lastSegAddr = rdi(lastSeg.p_vaddr) + newSz - neededSpace;
- }
- }
-
-- if (needNewSegment) {
-+ if (lastSegAddr == 0) {
-+ debug("allocating new PT_LOAD segment\n");
-+
- /* Add a segment that maps the replaced sections into memory. */
- phdrs.resize(rdi(hdr()->e_phnum) + 1);
- wri(hdr()->e_phnum, rdi(hdr()->e_phnum) + 1);
-@@ -898,6 +922,8 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
- wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace));
- wri(phdr.p_flags, PF_R | PF_W);
- wri(phdr.p_align, alignStartPage);
-+
-+ lastSegAddr = startPage;
- }
-
- normalizeNoteSegments();
-@@ -906,17 +932,34 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
- /* Write out the replaced sections. */
- Elf_Off curOff = startOffset;
-
-- if (moveHeaderTableToTheEnd) {
-- debug("Moving the shtable to offset %d\n", curOff);
-- wri(hdr()->e_shoff, curOff);
-- curOff += headerTableSpace;
-+ if (relocatePht) {
-+ debug("rewriting pht from offset 0x%x to offset 0x%x (size %d)\n",
-+ rdi(hdr()->e_phoff), curOff, phtSize);
-+
-+ wri(hdr()->e_phoff, curOff);
-+ curOff += phtSize;
- }
-
-+ // ---
-+
-+ debug("rewriting sht from offset 0x%x to offset 0x%x (size %d)\n",
-+ rdi(hdr()->e_shoff), curOff, shtSize);
-+
-+ wri(hdr()->e_shoff, curOff);
-+ curOff += shtSize;
-+
-+ // ---
-+
-+ /* Write out the replaced sections. */
- writeReplacedSections(curOff, startPage, startOffset);
- assert(curOff == startOffset + neededSpace);
-
- /* Write out the updated program and section headers */
-- rewriteHeaders(firstPage + rdi(hdr()->e_phoff));
-+ if (relocatePht) {
-+ rewriteHeaders(lastSegAddr);
-+ } else {
-+ rewriteHeaders(firstPage + rdi(hdr()->e_phoff));
-+ }
- }
-
- static bool noSort = false;
-@@ -1030,32 +1073,35 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-
- firstPage -= neededPages * getPageSize();
- startOffset += neededPages * getPageSize();
-- } else {
-- Elf_Off rewrittenSectionsOffset = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
-- for (auto& phdr : phdrs)
-- if (rdi(phdr.p_type) == PT_LOAD &&
-- rdi(phdr.p_offset) <= rewrittenSectionsOffset &&
-- rdi(phdr.p_offset) + rdi(phdr.p_filesz) > rewrittenSectionsOffset &&
-- rdi(phdr.p_filesz) < neededSpace)
-- {
-- wri(phdr.p_filesz, neededSpace);
-- wri(phdr.p_memsz, neededSpace);
-- break;
-- }
- }
-
-+ Elf_Off curOff = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
-+
-+ /* Ensure PHDR is covered by a LOAD segment.
-+
-+ Because PHDR is supposed to have been covered by such section before, in
-+ here we assume that we don't have to create any new section, but rather
-+ extend the existing one. */
-+ for (auto& phdr : phdrs)
-+ if (rdi(phdr.p_type) == PT_LOAD &&
-+ rdi(phdr.p_offset) <= curOff &&
-+ rdi(phdr.p_offset) + rdi(phdr.p_filesz) > curOff &&
-+ rdi(phdr.p_filesz) < neededSpace)
-+ {
-+ wri(phdr.p_filesz, neededSpace);
-+ wri(phdr.p_memsz, neededSpace);
-+ break;
-+ }
-
- /* Clear out the free space. */
-- Elf_Off curOff = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
- debug("clearing first %d bytes\n", startOffset - curOff);
- memset(fileContents->data() + curOff, 0, startOffset - curOff);
-
--
- /* Write out the replaced sections. */
- writeReplacedSections(curOff, firstPage, 0);
- assert(curOff == neededSpace);
-
--
-+ /* Write out the updated program and section headers */
- rewriteHeaders(firstPage + rdi(hdr()->e_phoff));
- }
-
-diff --git a/src/patchelf.h b/src/patchelf.h
-index 4e229d6..5ed1b58 100644
---- a/src/patchelf.h
-+++ b/src/patchelf.h
-@@ -120,7 +120,8 @@ private:
- std::string & replaceSection(const SectionName & sectionName,
- unsigned int size);
-
-- [[nodiscard]] bool haveReplacedSection(const SectionName & sectionName) const;
-+ [[nodiscard]] bool hasReplacedSection(const SectionName & sectionName) const;
-+ [[nodiscard]] bool canReplaceSection(const SectionName & sectionName) const;
-
- void writeReplacedSections(Elf_Off & curOff,
- Elf_Addr startAddr, Elf_Off startOffset);
-diff --git a/tests/grow-file.sh b/tests/grow-file.sh
-index ec5957d..29bba59 100755
---- a/tests/grow-file.sh
-+++ b/tests/grow-file.sh
-@@ -7,10 +7,11 @@ mkdir -p "${SCRATCH}"
-
- cp simple-pie "${SCRATCH}/simple-pie"
-
--# Add a 40MB rpath
--tr -cd 'a-z0-9' < /dev/urandom | dd count=40 bs=1000000 > "${SCRATCH}/foo.bin"
-+# Add a large rpath
-+printf '=%.0s' $(seq 1 4096) > "${SCRATCH}/foo.bin"
-
- # Grow the file
- ../src/patchelf --add-rpath @"${SCRATCH}/foo.bin" "${SCRATCH}/simple-pie"
-+
- # Make sure we can still run it
- "${SCRATCH}/simple-pie"
-diff --git a/tests/repeated-updates.sh b/tests/repeated-updates.sh
-index 669b11d..1dc3fa2 100755
---- a/tests/repeated-updates.sh
-+++ b/tests/repeated-updates.sh
-@@ -33,7 +33,7 @@ load_segments_after=$(readelf -W -l libbar.so | grep -c LOAD)
- # To be even more strict, check that we don't add too many extra LOAD entries
- ###############################################################################
- echo "Segments before: ${load_segments_before} and after: ${load_segments_after}"
--if [ "${load_segments_after}" -gt $((load_segments_before + 2)) ]
-+if [ "${load_segments_after}" -gt $((load_segments_before + 3)) ]
- then
- exit 1
- fi
-diff --git a/tests/short-first-segment.sh b/tests/short-first-segment.sh
-index 07019fc..ecdf716 100755
---- a/tests/short-first-segment.sh
-+++ b/tests/short-first-segment.sh
-@@ -24,8 +24,11 @@ cd "${SCRATCH}"
-
- ldd "${EXEC_NAME}"
-
--${PATCHELF} --add-rpath lalalalalalalala --output modified1 "${EXEC_NAME}"
-+
-+${PATCHELF} --set-rpath "$(printf '=%.0s' $(seq 1 4096))" --output modified1 "${EXEC_NAME}"
-+${PATCHELF} --add-rpath "$(printf '=%.0s' $(seq 1 4096))" modified1
-+
- ldd modified1
-
--${PATCHELF} --add-needed "libXcursor.so.1" --output modified2 modified1
-+${PATCHELF} --add-needed "libXcursor.so.1" --output modified2 modified1
- ldd modified2
---
-2.48.1
-
diff --git a/patchelf.spec b/patchelf.spec
index 98e2c6a..17caa53 100644
--- a/patchelf.spec
+++ b/patchelf.spec
@@ -2,8 +2,8 @@
%undefine _hardened_build
Name: patchelf
-Version: 0.18.0
-Release: 10%{?dist}
+Version: 0.19.0
+Release: 1%{?dist}
Summary: A utility for patching ELF binaries
# Automatically converted from old format: GPLv3+ - review is highly recommended.
@@ -11,11 +11,6 @@ License: GPL-3.0-or-later
URL: http://nixos.org/patchelf.html
Source0: https://github.com/NixOS/%{name}/archive/%{version}/%{name}-%{version}.tar.gz
-# Allocate PHT & SHT at the end of the *.elf file
-# This is needed after a change in binutils, see https://bugzilla.redhat.com/2321588
-# Rebased form https://github.com/NixOS/patchelf/commit/43b75fbc9f
-Patch: 0001-Allocate-PHT-SHT-at-the-end-of-the-.elf-file.patch
-
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: make
@@ -60,6 +55,10 @@ rm -rf %{buildroot}/usr/share/doc/%{name}
%{_datadir}/zsh/site-functions/_patchelf
%changelog
+* Sun Jun 28 2026 Jeremy Sanders <jeremy@jeremysanders.net> - 0.19.0-1
+- Update to v0.19.0
+- Fixes: rhbz#2493812
+
* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 0.18.0-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
diff --git a/sources b/sources
index acdd55c..c243c75 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (patchelf-0.18.0.tar.gz) = ff08b24212d90a2d6e5987b181fffaa365efbfe2d4191462dd9d0f6655d78a719df1db0add192764677712e5a37a0efeaafdbaa904021c0d63cf5abfa37ab685
+SHA512 (patchelf-0.19.0.tar.gz) = 86c3457c0c036100856e58ab1e0a4ac157cd9abf749a9b2c50a872f1fd0190be8179d4997d6ab0774722953a4ea5f0e311e8b894cf2f7546e37c27aedd0f2396
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-06-28 8:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-28 8:48 [rpms/patchelf] rawhide: Update to v0.19.0 Jeremy Sanders
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox