summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Laucius <andrewla@gmail.com>2021-09-10 19:28:32 +0000
committerAndrew Laucius <andrewla@gmail.com>2021-09-10 19:28:32 +0000
commitd69bafc3b3d87a4adc44ff69269bffd65cbf7129 (patch)
treee4006200e2db800266ab4aff65104bf9ea1907e3
parentc62988a2a89a282e31d0e204cc2a3710da912f04 (diff)
downloadpatchelf-d69bafc3b3d87a4adc44ff69269bffd65cbf7129.tar.gz
Allow string arguments to be read from files.
If a string argument to an option is prefixed with @, then a file with the following name will be read into that string.
-rw-r--r--patchelf.124
-rw-r--r--src/patchelf.cc25
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/external.sh13
4 files changed, 53 insertions, 10 deletions
diff --git a/patchelf.1 b/patchelf.1
index 1016f69..d6ab167 100644
--- a/patchelf.1
+++ b/patchelf.1
@@ -23,6 +23,9 @@ of executables and change the RPATH of executables and libraries.
The single option given operates on each FILE, editing in place.
+Any option taking a string argument can also take a file by prefixing the
+argument with the @ symbol. See EXAMPLES
+
.IP "--page-size SIZE"
Uses the given page size instead of the default.
@@ -72,11 +75,11 @@ DT_RUNPATH. By default DT_RPATH is converted to DT_RUNPATH.
.IP "--add-needed LIBRARY"
Adds a declared dependency on a dynamic library (DT_NEEDED).
-This option can be give multiple times.
+This option can be given multiple times.
.IP "--replace-needed LIB_ORIG LIB_NEW"
Replaces a declared dependency on a dynamic library with another one (DT_NEEDED).
-This option can be give multiple times.
+This option can be given multiple times.
.IP "--remove-needed LIBRARY"
Removes a declared dependency on LIBRARY (DT_NEEDED entry). This
@@ -95,6 +98,23 @@ Prints details of the changes made to the input file.
.IP --version
Shows the version of patchelf.
+.SH EXAMPLES
+
+To use the contents on an external file as a parameter:
+
+.RS
+$ patchelf a.out --add-rpath @/tmp/generated-rpath.bin
+.RE
+
+To change the RPATH of a binary. Note that
+.BR $ORIGIN
+is a special symbol used by the loader, so must be quoted.
+
+.RS
+patchelf --set-rpath '$ORIGIN/../lib64' a.out
+.RE
+
+
.SH AUTHOR
Eelco Dolstra <e.dolstra@tudelft.nl>
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 3ca16c7..9518d4f 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -1870,6 +1870,15 @@ static void patchElf()
}
}
+std::string resolveArgument(const char *arg) {
+ if (strlen(arg) > 0 && arg[0] == '@') {
+ FileContents cnts = readFile(arg + 1);
+ return std::string((char *)cnts->data(), cnts->size());
+ }
+
+ return std::string(arg);
+}
+
void showHelp(const std::string & progName)
{
@@ -1914,7 +1923,7 @@ int mainWrapped(int argc, char * * argv)
std::string arg(argv[i]);
if (arg == "--set-interpreter" || arg == "--interpreter") {
if (++i == argc) error("missing argument");
- newInterpreter = argv[i];
+ newInterpreter = resolveArgument(argv[i]);
}
else if (arg == "--page-size") {
if (++i == argc) error("missing argument");
@@ -1930,7 +1939,7 @@ int mainWrapped(int argc, char * * argv)
else if (arg == "--set-soname") {
if (++i == argc) error("missing argument");
setSoname = true;
- newSoname = argv[i];
+ newSoname = resolveArgument(argv[i]);
}
else if (arg == "--remove-rpath") {
removeRPath = true;
@@ -1945,12 +1954,12 @@ int mainWrapped(int argc, char * * argv)
else if (arg == "--set-rpath") {
if (++i == argc) error("missing argument");
setRPath = true;
- newRPath = argv[i];
+ newRPath = resolveArgument(argv[i]);
}
else if (arg == "--add-rpath") {
if (++i == argc) error("missing argument");
addRPath = true;
- newRPath = argv[i];
+ newRPath = resolveArgument(argv[i]);
}
else if (arg == "--print-rpath") {
printRPath = true;
@@ -1974,11 +1983,11 @@ int mainWrapped(int argc, char * * argv)
}
else if (arg == "--add-needed") {
if (++i == argc) error("missing argument");
- neededLibsToAdd.insert(argv[i]);
+ neededLibsToAdd.insert(resolveArgument(argv[i]));
}
else if (arg == "--remove-needed") {
if (++i == argc) error("missing argument");
- neededLibsToRemove.insert(argv[i]);
+ neededLibsToRemove.insert(resolveArgument(argv[i]));
}
else if (arg == "--replace-needed") {
if (i+2 >= argc) error("missing argument(s)");
@@ -1987,11 +1996,11 @@ int mainWrapped(int argc, char * * argv)
}
else if (arg == "--clear-symbol-version") {
if (++i == argc) error("missing argument");
- symbolsToClearVersion.insert(argv[i]);
+ symbolsToClearVersion.insert(resolveArgument(argv[i]));
}
else if (arg == "--output") {
if (++i == argc) error("missing argument");
- outputFileName = argv[i];
+ outputFileName = resolveArgument(argv[i]);
alwaysWrite = true;
}
else if (arg == "--debug") {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 46589ea..0622dbf 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -36,6 +36,7 @@ src_TESTS = \
contiguous-note-sections.sh \
no-gnu-hash.sh \
no-dynamic-section.sh \
+ external.sh \
basic-flags.sh
build_TESTS = \
diff --git a/tests/external.sh b/tests/external.sh
new file mode 100755
index 0000000..0123692
--- /dev/null
+++ b/tests/external.sh
@@ -0,0 +1,13 @@
+#! /bin/sh -e
+SCRATCH=scratch/$(basename $0 .sh)
+
+rm -rf ${SCRATCH}
+mkdir -p ${SCRATCH}
+
+cp main ${SCRATCH}/
+RANDOM_PATH=$(pwd)/${SCRATCH}/$RANDOM
+echo -n ${RANDOM_PATH} >> ${SCRATCH}/add-rpath
+
+! ../src/patchelf --print-rpath ${SCRATCH}/main | grep $RANDOM_PATH
+../src/patchelf --add-rpath @${SCRATCH}/add-rpath ${SCRATCH}/main
+../src/patchelf --print-rpath ${SCRATCH}/main | grep $RANDOM_PATH