diff mbox

[LEDE-DEV] scripts/rstrip.sh fix patchelf invocation

Message ID 20170623130138.GA30877@hotdamn.lan
State Changes Requested
Delegated to: John Crispin
Headers show

Commit Message

Sebastian Kemper June 23, 2017, 1:01 p.m. UTC
When rstrip.sh finds a bogus rpath, it removes it, while keeping the
sane rpaths.

Example of two rpaths:

/home/sk/tmp/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/lib
/usr/lib/perl5/5.22/CORE

rstrip.sh now calls patchelf:

$PATCHELF --set-rpath "/usr/lib/perl5/5.22/CORE" mod_perl.so

Unfortunately the rpath is now broken:

readelf -d mod_perl.so
<snip>
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x0000000e (SONAME)                     Library soname: [mod_perl.so]
 0x1d000000 (<unknown>: 1d000000)        0x1399
 0x0000000c (INIT)                       0x46a8
<snip>

The patchelf README says:

"If only DT_RPATH is present, it is converted to DT_RUNPATH unless
`--force-rpath' is specified."

As no DT_RUNPATH element is visible either, I think we can assume this
doesn't quite work.

But when patchelf is invoked with --force-rpath in front of --set-rpath,
then the result is fine:

readelf -d mod_perl.so
<snip>
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x0000000e (SONAME)                     Library soname: [mod_commands.so]
 0x0000000f (RPATH)                      Library rpath: [/usr/lib/perl5/5.22/CORE]
 0x0000000c (INIT)                       0x3ec4
 0x0000000d (FINI)                       0x13f50
<snip>

An alternative would be to first remove DT_RPATH and then add it again,
because that works and the DT_RPATH is actually added as DT_RUNPATH.

patchelf --remove-rpath mod_perl.so
patchelf --set-rpath /usr/lib/perl5/5.22/CORE  mod_perl.so
readelf -d mod_perl.so
<snip>
 0x0000001d (RUNPATH)                    Library runpath: [/usr/lib/perl5/5.22/CORE]
 0x00000001 (NEEDED)                     Shared library: [libperl.so]
 0x00000001 (NEEDED)                     Shared library: [libgdbm.so.4]
<snip>


But as rstrip.sh only calls patchelf if it finds something it doesn't
like, I don't see the point of currently doing that, because we'd have
some binaries using DT_RUNPATH, others DT_RPATH. OTOH rstrip.sh could
always remove DT_RPATH and add it again, so all binaries would use
DT_RUNPATH.

Anyway, I don't know the preference of OpenWrt/LEDE devs, so attached a
patch with the quick fix that doesn't change the old behavior.

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
---
diff mbox

Patch

diff --git a/scripts/rstrip.sh b/scripts/rstrip.sh
index 55caefc1a8..6edafe536a 100755
--- a/scripts/rstrip.sh
+++ b/scripts/rstrip.sh
@@ -38,7 +38,7 @@  find $TARGETS -type f -a -exec file {} \; | \
 					*) echo "$SELF: $F: removing rpath $path" ;;
 				esac
 			done
-			[ "$new_rpath" = "$old_rpath" ] || $PATCHELF --set-rpath "$new_rpath" $F
+			[ "$new_rpath" = "$old_rpath" ] || $PATCHELF --force-rpath --set-rpath "$new_rpath" $F
 		}
 		eval "$STRIP $F"
 		a=$(stat -c '%a' $F)