From 9558db65fe2a9e10fe9b62e9c02edc6552ad4f4a Mon Sep 17 00:00:00 2001 From: conao3 Date: Wed, 7 Jan 2026 10:21:13 +0900 Subject: [PATCH] add --force option to write ELF binary without changes This option forces patchelf to write out the ELF binary even when no modifications were made. This is useful for fixing ELF binaries that have issues like "Program headers not in the first page" on FreeBSD. --- patchelf.1 | 5 +++++ src/patchelf.cc | 4 ++++ tests/Makefile.am | 1 + tests/force.sh | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100755 tests/force.sh diff --git a/patchelf.1 b/patchelf.1 index 7bb94f7f..38e93220 100644 --- a/patchelf.1 +++ b/patchelf.1 @@ -143,6 +143,11 @@ Use sparingly and with caution. .IP "--output FILE" Set the output file name. If not specified, the input will be modified in place. +.IP --force +Force write-out of the ELF binary even when no changes were made. +This is useful for fixing ELF binaries that have issues like +"Program headers not in the first page". + .IP --debug Prints details of the changes made to the input file. diff --git a/src/patchelf.cc b/src/patchelf.cc index 73f1b8d3..3f430dd2 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -2564,6 +2564,7 @@ static void showHelp(const std::string & progName) [--rename-dynamic-symbols NAME_MAP_FILE]\tRenames dynamic symbols. The map file should contain two symbols (old_name new_name) per line\n\ [--no-clobber-old-sections]\t\tDo not clobber old section values - only use when the binary expects to find section info at the old location.\n\ [--output FILE]\n\ + [--force]\t\tForce write-out even if no changes were made\n\ [--debug]\n\ [--version]\n\ FILENAME...\n", progName.c_str()); @@ -2685,6 +2686,9 @@ static int mainWrapped(int argc, char * * argv) outputFileName = resolveArgument(argv[i]); alwaysWrite = true; } + else if (arg == "--force") { + alwaysWrite = true; + } else if (arg == "--debug") { debugMode = true; } diff --git a/tests/Makefile.am b/tests/Makefile.am index b08929f1..2b8ea134 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,6 +25,7 @@ src_TESTS = \ set-rpath-library.sh soname.sh shrink-rpath-with-allowed-prefixes.sh \ set-rpath-rel-map.sh \ force-rpath.sh \ + force.sh \ plain-needed.sh \ output-flag.sh \ too-many-strtab.sh \ diff --git a/tests/force.sh b/tests/force.sh new file mode 100755 index 00000000..24f87944 --- /dev/null +++ b/tests/force.sh @@ -0,0 +1,33 @@ +#! /bin/sh -e +SCRATCH=scratch/$(basename "$0" .sh) + +rm -rf "${SCRATCH}" +mkdir -p "${SCRATCH}" + +cp simple "${SCRATCH}/" + +../src/patchelf --force "${SCRATCH}/simple" + +exitCode=0 +"${SCRATCH}/simple" || exitCode=$? + +if test "$exitCode" != 0; then + echo "bad exit code after --force!" + exit 1 +fi + +cp simple "${SCRATCH}/simple2" +../src/patchelf --force --output "${SCRATCH}/simple2-out" "${SCRATCH}/simple2" + +if ! test -f "${SCRATCH}/simple2-out"; then + echo "--force with --output did not create output file!" + exit 1 +fi + +exitCode=0 +"${SCRATCH}/simple2-out" || exitCode=$? + +if test "$exitCode" != 0; then + echo "bad exit code after --force --output!" + exit 1 +fi