summaryrefslogtreecommitdiffstats
path: root/bin/check-elf-dynamic-objects
diff options
context:
space:
mode:
Diffstat (limited to 'bin/check-elf-dynamic-objects')
-rwxr-xr-xbin/check-elf-dynamic-objects262
1 files changed, 262 insertions, 0 deletions
diff --git a/bin/check-elf-dynamic-objects b/bin/check-elf-dynamic-objects
new file mode 100755
index 000000000..11f587363
--- /dev/null
+++ b/bin/check-elf-dynamic-objects
@@ -0,0 +1,262 @@
+#!/bin/bash
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# verify that ELF NEEDED entries are known-good so hopefully builds run on
+# lots of different GNU/Linux distributions
+
+set -euo pipefail
+
+PARA=1
+check_path="${INSTDIR:-.}"
+
+help()
+{
+ cat << "EOF"
+ -d <dir> directory to check
+ -p run unbound parallel checks
+ -h help
+EOF
+ [ -z "${1:-}" ] && exit 0
+}
+
+die()
+{
+ echo "$1"
+ echo
+ help 1
+ exit 1
+}
+
+while [ "${1:-}" != "" ]; do
+ parm=${1%%=*}
+ arg=${1#*=}
+ has_arg=
+ if [ "${1}" != "${parm?}" ] ; then
+ has_arg=1
+ else
+ arg=""
+ fi
+
+ case "${parm}" in
+ --dir|-d)
+ if [ "$has_arg" ] ; then
+ check_path="$arg"
+ else
+ shift
+ check_path="$1"
+ fi
+ if [ ! -d "$check_path" ]; then
+ die "Invalid directory '$check_path'"
+ fi
+ ;;
+ -h)
+ help
+ ;;
+ -p)
+ # this sounds counter intuitive but the idea
+ # is to possibly support -p <n>
+ # in the meantime: 0 = nolimit and -p 1 would mean
+ # the current default: serialize
+ PARA=0
+ ;;
+ -*)
+ die "Invalid option $1"
+ ;;
+ *)
+ if [ "$DO_NEW" = 1 ] ; then
+ REPO="$1"
+ else
+ die "Invalid argument $1"
+ fi
+ ;;
+ esac
+ shift
+done
+
+
+files=$(find "${check_path}/program" "${check_path}/sdk/bin" -type f)
+# all RPATHs should point to ${INSTDIR}/program so that's the files they find
+programfiles=$(echo ${files} | grep -o '/program/[^/]* ' | xargs -n 1 basename)
+
+# whitelists should contain only system libraries that have a good reputation
+# of maintaining ABI stability
+# allow extending the whitelist using the environment variable to be able to work
+# on the installer stuff without the need for a baseline setup
+globalwhitelist="ld-linux-x86-64.so.2 ld-linux.so.2 libc.so.6 libm.so.6 libdl.so.2 libpthread.so.0 librt.so.1 libutil.so.1 libnsl.so.1 libcrypt.so.1 libgcc_s.so.1 libstdc++.so.6 libz.so.1 libfontconfig.so.1 libfreetype.so.6 libxml2.so.2 libxslt.so.1 libexslt.so.0 ${LO_ELFCHECK_WHITELIST-}"
+x11whitelist="libX11.so.6 libX11-xcb.so.1 libXext.so.6 libSM.so.6 libICE.so.6 libXinerama.so.1 libXrender.so.1 libXrandr.so.2 libcairo.so.2"
+openglwhitelist="libGL.so.1"
+giowhitelist="libgio-2.0.so.0 libgobject-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libglib-2.0.so.0 libdbus-glib-1.so.2 libdbus-1.so.3"
+gstreamerwhitelist="libgstaudio-1.0.so.0 libgstpbutils-1.0.so.0 libgstvideo-1.0.so.0 libgstbase-1.0.so.0 libgstreamer-1.0.so.0"
+gtk3whitelist="libgtk-3.so.0 libgdk-3.so.0 libcairo-gobject.so.2 libpangocairo-1.0.so.0 libfribidi.so.0 libatk-1.0.so.0 libcairo.so.2 libgio-2.0.so.0 libpangoft2-1.0.so.0 libpango-1.0.so.0 libfontconfig.so.1 libfreetype.so.6 libgdk_pixbuf-2.0.so.0 libgobject-2.0.so.0 libglib-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libdbus-glib-1.so.2 libdbus-1.so.3 libharfbuzz.so.0"
+qt5whitelist="libQt5Core.so.5 libQt5Gui.so.5 libQt5Network.so.5 libQt5Widgets.so.5 libQt5X11Extras.so.5 libcairo.so.2 libglib-2.0.so.0 libgobject-2.0.so.0 libxcb.so.1 libxcb-icccm.so.4"
+kf5whitelist="libKF5ConfigCore.so.5 libKF5CoreAddons.so.5 libKF5I18n.so.5 libKF5KIOCore.so.5 libKF5KIOFileWidgets.so.5 libKF5KIOWidgets.so.5 libKF5WindowSystem.so.5"
+avahiwhitelist="libdbus-glib-1.so.2 libdbus-1.so.3 libgobject-2.0.so.0 libgmodule-2.0.so.0 libgthread-2.0.so.0 libglib-2.0.so.0 libavahi-common.so.3 libavahi-client.so.3"
+kerberoswhitelist="libgssapi_krb5.so.2 libcom_err.so.2 libkrb5.so.3"
+dconfwhitelist="libdconf.so.1 libgio-2.0.so.0 libglib-2.0.so.0 libgobject-2.0.so.0"
+
+check_one_file()
+{
+local file="$1"
+
+ skip=0
+ whitelist="${globalwhitelist}"
+ case "${file}" in
+ */sdk/docs/*)
+ # skip the majority of files, no ELF binaries here
+ skip=1
+ ;;
+ */_uuid.cpython-*.so)
+ whitelist="${whitelist} libuuid.so.1"
+ ;;
+ */libcairo.so.2)
+ whitelist="${whitelist} ${x11whitelist} libxcb-shm.so.0 libxcb.so.1 libxcb-render.so.0"
+ ;;
+ */libcairocanvaslo.so)
+ whitelist="${whitelist} libcairo.so.2"
+ ;;
+ */libucpgio1lo.so|*/liblosessioninstalllo.so|*/libevoablo.so)
+ whitelist="${whitelist} ${giowhitelist}"
+ ;;
+ */libavmediagst.so)
+ whitelist="${whitelist} ${gtk3whitelist} ${gstreamerwhitelist}"
+ ;;
+ */libvclplug_kf5lo.so|*/libkf5be1lo.so)
+ if [ "$ENABLE_KF5" = TRUE ]; then
+ whitelist="${whitelist} ${qt5whitelist} ${kf5whitelist}"
+ fi
+ ;;
+ */libvclplug_gtk3lo.so|*/updater)
+ whitelist="${whitelist} ${x11whitelist} ${gtk3whitelist}"
+ ;;
+ */libvclplug_qt5lo.so)
+ if [ "$ENABLE_QT5" = TRUE ]; then
+ whitelist="${whitelist} ${qt5whitelist}"
+ fi
+ ;;
+ */libvclplug_gtk3_kde5lo.so)
+ if [ "$ENABLE_GTK3_KDE5" = TRUE ]; then
+ whitelist="${whitelist} ${x11whitelist} ${gtk3whitelist} ${qt5whitelist} ${kf5whitelist}"
+ fi
+ ;;
+ */lo_kde5filepicker)
+ if [ "$ENABLE_GTK3_KDE5" = TRUE ]; then
+ whitelist="${whitelist} ${x11whitelist} ${gtk3whitelist} ${qt5whitelist} \
+ ${kf5whitelist}"
+ fi
+ ;;
+ */libdesktop_detectorlo.so|*/ui-previewer|*/oosplash|*/gengal.bin)
+ whitelist="${whitelist} ${x11whitelist}"
+ ;;
+ */libvclplug_genlo.so|*/libchartcorelo.so|*/libavmediaogl.so|*/libOGLTranslo.so|*/liboglcanvaslo.so)
+ whitelist="${whitelist} ${x11whitelist} ${openglwhitelist}"
+ ;;
+ */libvcllo.so)
+ whitelist="${whitelist} ${x11whitelist} ${openglwhitelist} ${giowhitelist} libcups.so.2"
+ ;;
+ */libsofficeapp.so)
+ whitelist="${whitelist} ${x11whitelist} ${openglwhitelist} ${giowhitelist} libcups.so.2"
+ ;;
+ */liblibreofficekitgtk.so)
+ whitelist="${whitelist} ${gtk3whitelist}"
+ ;;
+ */libsdlo.so)
+ whitelist="${whitelist} ${avahiwhitelist}"
+ ;;
+ */libskialo.so)
+ whitelist="${whitelist} ${openglwhitelist} ${x11whitelist}"
+ ;;
+ */libofficebean.so)
+ whitelist="${whitelist} libjawt.so"
+ ;;
+ */libpostgresql-sdbc-impllo.so)
+ whitelist="${whitelist} ${kerberoswhitelist}"
+ ;;
+ */libconfigmgrlo.so)
+ if [ "$ENABLE_DCONF" = TRUE ]; then
+ whitelist="${whitelist} ${dconfwhitelist}"
+ fi
+ ;;
+ */libmergedlo.so)
+ whitelist="${whitelist} ${x11whitelist} ${openglwhitelist} ${giowhitelist} libcups.so.2 libcairo.so.2"
+ ;;
+ esac
+ if test "${skip}" = 0 && readelf -d "${file}" &> /dev/null ; then
+ rpath=$(readelf -d "${file}" | grep '(\(RPATH\|RUNPATH\))' || true)
+ neededs=$(readelf -d "${file}" | grep '(NEEDED)' | sed -e 's/.*\[\(.*\)\]$/\1/')
+ neededsinternal=
+ for needed in ${neededs}
+ do
+ if ! echo ${whitelist} | grep -q -w "${needed}" ; then
+ neededsinternal="${neededsinternal} ${needed}"
+ if ! echo ${programfiles} | grep -q -w "${needed}" ; then
+ echo "${file}" has suspicious NEEDED: "${needed}"
+ status=1
+ fi
+ fi
+ done
+ if test -z "${rpath}" ; then
+ case "${file}" in
+ */python-core-*/lib/lib-dynload/*)
+ # python modules don't have RPATH
+ ;;
+ */share/extensions/*)
+ # extension libraries don't have RPATH
+ ;;
+ *)
+ # no NEEDED from instdir, no RPATH needed
+ if test -n "${neededsinternal}" ; then
+ echo "${file}" has no RPATH
+ status=1
+ fi
+ ;;
+ esac
+ else
+ case "$file" in
+ */sdk/bin/*)
+ if echo "${rpath}" | grep -q -v '\[\$ORIGIN/../../program\]$' ; then
+ echo "${file}" has unexpected RPATH "${rpath}"
+ status=1
+ fi
+ ;;
+ *)
+ if echo "${rpath}" | grep -q -v '\[\$ORIGIN\]$' ; then
+ echo "${file}" has unexpected RPATH "${rpath}"
+ status=1
+ fi
+ ;;
+ esac
+ fi
+ fi
+}
+status=0
+
+if [ "$PARA" = "1" ] ; then
+ for file in ${files}
+ do
+ check_one_file $file
+ done
+else
+ rm -f check_elf.out
+ for file in ${files}
+ do
+ (
+ check_one_file $file
+ )>> check_elf.out &
+ done
+
+ wait
+
+ if [ -s check_elf.out ] ; then
+ cat check_elf.out
+ status=1
+ fi
+ rm check_elf.out
+fi
+exit ${status}
+