diff --git a/patchelf.1 b/patchelf.1 index 6a8a94e1..7abaf593 100644 --- a/patchelf.1 +++ b/patchelf.1 @@ -79,6 +79,10 @@ the "/foo/lib" reference instead of the "/tmp" entry. .IP --print-rpath Prints the DT_RUNPATH or DT_RPATH for an executable or library. +.IP --update-rpath +Updates the DR_RPATH to a DT_RUNTPATH or vice versa if "--force-rpath" is given +too. + .IP --force-rpath Forces the use of the obsolete DT_RPATH in the file instead of DT_RUNPATH. By default DT_RPATH is converted to DT_RUNPATH. diff --git a/src/patchelf.cc b/src/patchelf.cc index 1a90edb1..8bd7893e 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1601,6 +1601,7 @@ void ElfFile::modifyRPath(RPathOp op, newRPath = temp; break; } + case rpUpdate: { break; } /* just update the RPATH to RUNPATH or vice versa */ case rpSet: { break; } /* new rpath was provied as input to this function */ } @@ -1616,6 +1617,10 @@ void ElfFile::modifyRPath(RPathOp op, changed = true; } + if (op == rpUpdate) { + return; + } + if (rpath && rpath == newRPath) { return; } @@ -2306,6 +2311,7 @@ static std::vector allowedRpathPrefixes; static bool removeRPath = false; static bool setRPath = false; static bool addRPath = false; +static bool updateRPath = false; static bool addDebugTag = false; static bool renameDynamicSymbols = false; static bool printRPath = false; @@ -2361,6 +2367,8 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con elfFile.modifyRPath(elfFile.rpSet, {}, newRPath); else if (addRPath) elfFile.modifyRPath(elfFile.rpAdd, {}, newRPath); + else if (updateRPath) + elfFile.modifyRPath(elfFile.rpUpdate, {}, ""); if (printNeeded) elfFile.printNeededLibs(); @@ -2430,6 +2438,7 @@ static void showHelp(const std::string & progName) [--allowed-rpath-prefixes PREFIXES]\t\tWith '--shrink-rpath', reject rpath entries not starting with the allowed prefix\n\ [--print-rpath]\n\ [--force-rpath]\n\ + [--update-rpath]\n\ [--add-needed LIBRARY]\n\ [--remove-needed LIBRARY]\n\ [--replace-needed LIBRARY NEW_LIBRARY]\n\ @@ -2493,6 +2502,9 @@ static int mainWrapped(int argc, char * * argv) else if (arg == "--remove-rpath") { removeRPath = true; } + else if (arg == "--update-rpath") { + updateRPath = true; + } else if (arg == "--shrink-rpath") { shrinkRPath = true; } diff --git a/src/patchelf.h b/src/patchelf.h index 9fab18c0..b69589b8 100644 --- a/src/patchelf.h +++ b/src/patchelf.h @@ -149,7 +149,7 @@ class ElfFile void setInterpreter(const std::string & newInterpreter); - typedef enum { rpPrint, rpShrink, rpSet, rpAdd, rpRemove } RPathOp; + typedef enum { rpPrint, rpUpdate, rpShrink, rpSet, rpAdd, rpRemove } RPathOp; void modifyRPath(RPathOp op, const std::vector & allowedRpathPrefixes, std::string newRPath); std::string shrinkRPath(char* rpath, std::vector &neededLibs, const std::vector & allowedRpathPrefixes); diff --git a/tests/update-rpath.sh b/tests/update-rpath.sh new file mode 100755 index 00000000..3895804d --- /dev/null +++ b/tests/update-rpath.sh @@ -0,0 +1,36 @@ +#! /bin/sh -e +SCRATCH=scratch/$(basename "$0" .sh) +OBJDUMP=${OBJDUMP:-objdump} + +rm -rf "${SCRATCH}" +mkdir -p "${SCRATCH}" + +SCRATCHFILE=${SCRATCH}/libfoo.so +cp libfoo.so "$SCRATCHFILE" + +doit() { + set +x + ../src/patchelf "$@" "$SCRATCHFILE" + set -x +} + +expect() { + out=$("$OBJDUMP" -x "$SCRATCHFILE" | grep PATH || true) + + for i in $out; do + if [ "$i" != "$1" ]; then + echo "Expected '$*' but got '$out'" + exit 1 + fi + shift + done +} + +doit --remove-rpath +expect "" +doit --set-rpath foo +expect RUNPATH foo +doit --update-rpath --force-rpath +expect RPATH foo +doit --update-rpath +expect RUNPATH foo