public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Jeremy Sanders <jeremy@jeremysanders.net>
To: git-commits@fedoraproject.org
Subject: [rpms/patchelf] rawhide: Update to v0.19.0
Date: Sun, 28 Jun 2026 08:48:34 GMT	[thread overview]
Message-ID: <178263651472.1.4395832816101651512.rpms-patchelf-445cd2ab0cf4@fedoraproject.org> (raw)

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

                 reply	other threads:[~2026-06-28  8:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178263651472.1.4395832816101651512.rpms-patchelf-445cd2ab0cf4@fedoraproject.org \
    --to=jeremy@jeremysanders.net \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox