mirror of
https://github.com/NixOS/patchelf.git
synced 2025-10-18 00:12:18 +08:00
Add '--allowed-rpath-prefixes' option to '--shrink-rpath'
Fixes #97. In essence, the problem is that some packages in Nixpkgs have RPATHs pointing to both $NIX_BUILD_TOP and $out, e.g.: /tmp/nix-build-openldap-2.4.44.drv-0/openldap-2.4.44/libraries/libldap_r/.libs /tmp/nix-build-openldap-2.4.44.drv-0/openldap-2.4.44/libraries/liblber/.libs /nix/store/bfkmdxmv3a3f0g3d2q8jkdz2wam93c5z-openldap-2.4.44/lib /nix/store/bfkmdxmv3a3f0g3d2q8jkdz2wam93c5z-openldap-2.4.44/lib64 Currently, running `patchelf --shrink-rpath` does the wrong thing by keeping the /tmp/ paths and deleting the /nix/store ones. Now we can fix the problem by using patchelf --shrink-rpath --allowed-rpath-prefixes $NIX_STORE_DIR in the Nixpkgs fixupPhase instead.
This commit is contained in:
8
README
8
README
@@ -19,6 +19,14 @@ libraries. In particular, it can do the following:
|
||||
an RPATH "/lib:/usr/lib:/foo/lib", and libfoo.so can only be found
|
||||
in /foo/lib, then the new RPATH will be "/foo/lib".
|
||||
|
||||
In addition, the '--allowed-rpath-prefixes' option can be used for
|
||||
further rpath tuning. For instance, if an executable has an RPATH
|
||||
"/tmp/build-foo/.libs:/foo/lib", it is probably desirable to keep
|
||||
the "/foo/lib" reference instead of the "/tmp" entry. To accomplish
|
||||
that, use:
|
||||
|
||||
$ patchelf --shrink-rpath --allowed-rpath-prefixes /usr/lib:/foo/lib my-program
|
||||
|
||||
* Remove declared dependencies on dynamic libraries (DT_NEEDED
|
||||
entries):
|
||||
|
||||
|
@@ -53,6 +53,12 @@ For instance, if an executable references one library libfoo.so, has
|
||||
an RPATH "/lib:/usr/lib:/foo/lib", and libfoo.so can only be found
|
||||
in /foo/lib, then the new RPATH will be "/foo/lib".
|
||||
|
||||
.IP "--allowed-rpath-prefixes PREFIXES"
|
||||
Combined with the "--shrink-rpath" option, this can be used for
|
||||
further rpath tuning. For instance, if an executable has an RPATH
|
||||
"/tmp/build-foo/.libs:/foo/lib", it is probably desirable to keep
|
||||
the "/foo/lib" reference instead of the "/tmp" entry.
|
||||
|
||||
.IP --print-rpath
|
||||
Prints the RPATH for an executable or library.
|
||||
|
||||
|
@@ -72,6 +72,13 @@ static vector<string> splitColonDelimitedString(const char * s){
|
||||
return parts;
|
||||
}
|
||||
|
||||
static bool hasAllowedPrefix(const string & s, const vector<string> & allowedPrefixes){
|
||||
for (vector<string>::const_iterator it = allowedPrefixes.begin(); it != allowedPrefixes.end(); ++it) {
|
||||
if (!s.compare(0, it->size(), *it)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int getPageSize(){
|
||||
return pageSize;
|
||||
@@ -185,7 +192,7 @@ public:
|
||||
|
||||
typedef enum { rpPrint, rpShrink, rpSet, rpRemove } RPathOp;
|
||||
|
||||
void modifyRPath(RPathOp op, string newRPath);
|
||||
void modifyRPath(RPathOp op, vector<string> allowedRpathPrefixes, string newRPath);
|
||||
|
||||
void addNeeded(set<string> libs);
|
||||
|
||||
@@ -1043,7 +1050,7 @@ static void concatToRPath(string & rpath, const string & path)
|
||||
|
||||
|
||||
template<ElfFileParams>
|
||||
void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
|
||||
void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, vector<string> allowedRpathPrefixes, string newRPath)
|
||||
{
|
||||
Elf_Shdr & shdrDynamic = findSection(".dynamic");
|
||||
|
||||
@@ -1122,6 +1129,13 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If --allowed-rpath-prefixes was given, reject directories
|
||||
not starting with any of the (colon-delimited) prefixes. */
|
||||
if (!allowedRpathPrefixes.empty() && !hasAllowedPrefix(dirName, allowedRpathPrefixes)) {
|
||||
debug("removing directory '%s' from RPATH because of non-allowed prefix\n", dirName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For each library that we haven't found yet, see if it
|
||||
exists in this directory. */
|
||||
bool libFound = false;
|
||||
@@ -1465,6 +1479,7 @@ static bool setSoname = false;
|
||||
static string newSoname;
|
||||
static string newInterpreter;
|
||||
static bool shrinkRPath = false;
|
||||
static vector<string> allowedRpathPrefixes;
|
||||
static bool removeRPath = false;
|
||||
static bool setRPath = false;
|
||||
static bool printRPath = false;
|
||||
@@ -1493,14 +1508,14 @@ static void patchElf2(ElfFile & elfFile)
|
||||
elfFile.setInterpreter(newInterpreter);
|
||||
|
||||
if (printRPath)
|
||||
elfFile.modifyRPath(elfFile.rpPrint, "");
|
||||
elfFile.modifyRPath(elfFile.rpPrint, vector<string>(), "");
|
||||
|
||||
if (shrinkRPath)
|
||||
elfFile.modifyRPath(elfFile.rpShrink, "");
|
||||
elfFile.modifyRPath(elfFile.rpShrink, allowedRpathPrefixes, "");
|
||||
else if (removeRPath)
|
||||
elfFile.modifyRPath(elfFile.rpRemove, "");
|
||||
elfFile.modifyRPath(elfFile.rpRemove, vector<string>(), "");
|
||||
else if (setRPath)
|
||||
elfFile.modifyRPath(elfFile.rpSet, newRPath);
|
||||
elfFile.modifyRPath(elfFile.rpSet, vector<string>(), newRPath);
|
||||
|
||||
if (printNeeded) elfFile.printNeededLibs();
|
||||
|
||||
@@ -1563,6 +1578,7 @@ void showHelp(const string & progName)
|
||||
[--set-rpath RPATH]\n\
|
||||
[--remove-rpath]\n\
|
||||
[--shrink-rpath]\n\
|
||||
[--allowed-rpath-prefixes PREFIXES]\t\tWith '--shrink-rpath', reject rpath entries not starting with the allowed prefix\n\
|
||||
[--print-rpath]\n\
|
||||
[--force-rpath]\n\
|
||||
[--add-needed LIBRARY]\n\
|
||||
@@ -1614,6 +1630,10 @@ int main(int argc, char * * argv)
|
||||
else if (arg == "--shrink-rpath") {
|
||||
shrinkRPath = true;
|
||||
}
|
||||
else if (arg == "--allowed-rpath-prefixes") {
|
||||
if (++i == argc) error("missing argument");
|
||||
allowedRpathPrefixes = splitColonDelimitedString(argv[i]);
|
||||
}
|
||||
else if (arg == "--set-rpath") {
|
||||
if (++i == argc) error("missing argument");
|
||||
setRPath = true;
|
||||
|
@@ -21,7 +21,7 @@ no_rpath_arch_TESTS = \
|
||||
src_TESTS = \
|
||||
plain-fail.sh plain-run.sh shrink-rpath.sh set-interpreter-short.sh \
|
||||
set-interpreter-long.sh set-rpath.sh no-rpath.sh big-dynstr.sh \
|
||||
set-rpath-library.sh soname.sh
|
||||
set-rpath-library.sh soname.sh shrink-rpath-with-allowed-prefixes.sh
|
||||
|
||||
build_TESTS = \
|
||||
$(no_rpath_arch_TESTS)
|
||||
|
47
tests/shrink-rpath-with-allowed-prefixes.sh
Executable file
47
tests/shrink-rpath-with-allowed-prefixes.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#! /bin/sh -e
|
||||
SCRATCH=scratch/$(basename $0 .sh)
|
||||
|
||||
rm -rf ${SCRATCH}
|
||||
mkdir -p ${SCRATCH}
|
||||
mkdir -p ${SCRATCH}/libsA
|
||||
mkdir -p ${SCRATCH}/libsB
|
||||
|
||||
cp main ${SCRATCH}/
|
||||
cp libfoo.so libbar.so ${SCRATCH}/libsA/
|
||||
cp libfoo.so libbar.so ${SCRATCH}/libsB/
|
||||
|
||||
oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/main)
|
||||
if test -z "$oldRPath"; then oldRPath="/oops"; fi
|
||||
pathA="$(pwd)/${SCRATCH}/libsA"
|
||||
pathB="$(pwd)/${SCRATCH}/libsB"
|
||||
../src/patchelf --force-rpath --set-rpath $oldRPath:$pathA:$pathB ${SCRATCH}/main
|
||||
|
||||
cp ${SCRATCH}/main ${SCRATCH}/mainA
|
||||
cp ${SCRATCH}/main ${SCRATCH}/mainB
|
||||
|
||||
../src/patchelf --shrink-rpath ${SCRATCH}/main
|
||||
../src/patchelf --shrink-rpath --allowed-rpath-prefixes $oldRPath:$pathA ${SCRATCH}/mainA
|
||||
../src/patchelf --shrink-rpath --allowed-rpath-prefixes $oldRPath:$pathB ${SCRATCH}/mainB
|
||||
|
||||
check() {
|
||||
exe=$1
|
||||
mustContain=$2
|
||||
mustNotContain=$3
|
||||
|
||||
rpath=$(../src/patchelf --print-rpath $exe)
|
||||
echo "RPATH of $exe after: $rpath"
|
||||
|
||||
if ! echo "$rpath" | grep -q $mustContain; then
|
||||
echo "RPATH didn't contain '$mustContain' when it should have"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if echo "$rpath" | grep -q $mustNotContain; then
|
||||
echo "RPATH contained '$mustNotContain' when it shouldn't have"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check ${SCRATCH}/main $pathA $pathB
|
||||
check ${SCRATCH}/mainA $pathA $pathB
|
||||
check ${SCRATCH}/mainB $pathB $pathA
|
Reference in New Issue
Block a user