Hook Wine execv syscall to use special ld.so in order to make it fully relocateable- WORK IN PROGRESS
We want to make a fully portable of 32-bit Wine that can run on any Linux system, without the need for 32-bit compatibility libraries to be installed in the system (which is a hassle).
32-bit Wine is needed to run 32-bit Windows applications (as were the norm until very recently).
5$ find . -type f -exec file {} 2>&1 \; | grep "ld-"
./bin/wine: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=8b26c8c6685ea1ed987a21ef30b48823e844e858, stripped
./bin/winedump: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=6fc5973f83404c829810008d000671373860cb6f, stripped
./bin/wmc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=30688d1dcd7ce51705571a891c8d6cf028dd6d0a, stripped
./bin/wrc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=5c24139c3c19ddc6c26778afe204d60ab78c3911, stripped
./bin/winegcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=fa60ca2fb4322cc8c4d3c45e7bbfb11f1fab17eb, stripped
./bin/winebuild: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=29fb932cea712078706b973f5c14c11c41a2cc2c, stripped
./bin/wineserver: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=b72ce157533fbe10b42ec00e7518ff17011df558, stripped
./bin/widl: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=14b9c572d68809513bd0c43fb61073be71ca7fd1, stripped
It would be best if we could rewrite the ELF executables to not search for /lib/ld-linux.so.2
on the system (which is not there on most 64-bit systems), but in a custom location, e.g., in $ORIGIN/../lib
which should resolve, in our example, to ./lib/ld-linux.so.2
. Unfortunately this does not work. Why?
It is possible to use a custom loader by invoking ELF binaries like this:
./lib/ld-linux.so.2 --library-path $(readlink -f ./lib/):$LD_LIBRARY_PATH ./bin/wine
However, there are two issues with this:
- Wine launches subprocesses, which in turn would try to use
./lib/ld-linux.so.2
again ./lib/ld-linux.so.2
may still try to load libraries and other stuff from the system/lib
, which we must avoid. Ideally we could patch./lib/ld-linux.so.2
to load its stuff from$ORIGIN/i386-linux-gnu/
. Unfortunately there seems to be no way to achieve this apart from binary-patchingld-linux.so.2
- why?
See winedeploy.sh.
wget -c https://github.com/probonopd/libhookexecv/releases/download/continuous/Wine_Windows_Program_Loader-3.5-x86_64.AppImage
chmod +x Wine*.AppImage
wget -c https://github.com/probonopd/libhookexecv/releases/download/continuous/wineprefix.tar.gz
tar xf wineprefix.tar.gz
WINEPREFIX=$(readlink -f wineprefix) ./Wine_Windows_Program_Loader-3.5-x86_64.AppImage notepad++
mkdir squashfs-root
sudo mount -t tmpfs tmpfs squashfs-root/ -o strictatime,nodiratime
./Downloads/NotepadPlusPlus-3.5-x86_64.AppImage --appimage-extract
touch test
./squashfs-root/AppRun # Without existing WINEPREFIX overlay
./squashfs-root/AppRun # With existing WINEPREFIX overlay
find squashfs-root/ -mindepth 3 -anewer test -not -path '*/share/icons/*' -not -path '*/share/applications/*' -not -path '*/share/metainfo/*'
find squashfs-root/ -mindepth 3 -not -anewer test -not -path '*/share/icons/*' -not -path '*/share/applications/*' -not -path '*/share/metainfo/*' -delete || true
find squashfs-root/ -type d -empty -delete
./squashfs-root/AppRun
# Does it still run when thinned?
# Make minimized AppImage
ARCH=x86_64 ./appimagetool-x86_64.AppImage ./squashfs-root/
What if we need to use a local developer machine to determine the set of needed files but want to generate the minimized AppDir on a build machine? Use a MANIFEST
file that specifies the wanted files:
# Make a MANIFEST (on a local developer machine)
( cd squashfs-root/ ; find . -type f -or -type s | sort | uniq > ../MANIFEST )
# Delete everything from the AppDir that is not in the MANIFEST
( cd appdir/ ; find . -type f -or -type s | sort | uniq > ../ALLFILES ; diff --new-line-format="" --unchanged-line-format="" ../ALLFILES ../MANIFEST | xargs -r rm )
find appdir/ -type d -empty -delete