diff --git a/releng/scripts/check_code_cleanliness.sh b/releng/scripts/check_code_cleanliness.sh index 62890189b07..0d23a82f3e7 100755 --- a/releng/scripts/check_code_cleanliness.sh +++ b/releng/scripts/check_code_cleanliness.sh @@ -146,6 +146,17 @@ else exit 1 fi +## +# Error out if there are dependencies that are not allowed in the dlls, exes, sos +## +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +echo "Checking dependencies of all .dll, .exe and .so files in CDT to make" +echo "sure no dependencies on unexpected or newer libraries are accidentally" +echo "introduced." +${DIR}/check_dll_dependencies.sh +${DIR}/check_glibc_dependencies.sh + + ## # Make sure all versions have been bumped appropriately compared to the baseline ## diff --git a/releng/scripts/check_dll_dependencies.sh b/releng/scripts/check_dll_dependencies.sh new file mode 100755 index 00000000000..ec945cdbbe6 --- /dev/null +++ b/releng/scripts/check_dll_dependencies.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -eu + +# This is the current set of allowed DLL dependencies for CDT code. Additional entries here are permitted, +# provided they are found on all Windows machines by default. +ALLOWED_DLLS="KERNEL32.DLL MSVCRT.DLL USER32.DLL PSAPI.DLL SHELL32.DLL ADVAPI32.DLL" +# In addition, the WINPTY.DLL is something CDT ships so is allowed to be a dependency +ALLOWED_DLLS+=" WINPTY.DLL" + +exit_code=0 +while read line; do + while read import; do + dllname=${import//DLL Name: /} + dllname_upper=${dllname^^} + if [[ ! " ${ALLOWED_DLLS} " =~ " ${dllname_upper} " ]]; then + echo "ERROR: $line has illegal import of ${dllname}" + exit_code=1 + fi + done <<<$(x86_64-w64-mingw32-objdump -p $line | grep "DLL Name") +done <<<$(git ls-files -- \*.exe \*.dll) + +exit ${exit_code} diff --git a/releng/scripts/check_glibc_dependencies.sh b/releng/scripts/check_glibc_dependencies.sh new file mode 100755 index 00000000000..d64aff6c23e --- /dev/null +++ b/releng/scripts/check_glibc_dependencies.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -eu + + +### +# Check that all .so files in CDT for a given ${ARCH} (using ${PREFIX} toolchain) +# use glibc symbols no greater than ${ALLOWED_GLIBC_VERSION} and depend on +# no libs other than ${ALLOWED_LIBS} +function check { + ARCH=$1; shift + PREFIX=$1; shift + ALLOWED_GLIBC_VERSION=$1; shift + ALLOWED_LIBS="$@"; shift + ret_code=0 + while read line; do + ${PREFIX}-linux-gnu-readelf -d ${line} | grep -E '\(NEEDED\)' | while read needed; do + needed=${needed//*Shared library: [/} + needed=${needed//]*/} + if [[ ! " ${ALLOWED_LIBS} " =~ " ${needed} " ]]; then + echo "ERROR: $line has illegal dependency of ${needed}" + ret_code=1 + fi + done + + # The way the version check is done is that all symbol version info is extracted + # from relocations match @GLIBC_*, the versions are sorted with the max + # allowed version added to the list too. And then we check the last entry in + # the list to make sure it is == to max allowed version. + ${PREFIX}-linux-gnu-objdump -R ${line} | grep @GLIBC_ | while read version; do + echo ${version//*@GLIBC_} + done > /tmp/version_check + echo ${ALLOWED_GLIBC_VERSION} >> /tmp/version_check + max_version_in_use=$(cat /tmp/version_check | sort --unique --version-sort | tail -n1) + if [ "$max_version_in_use" != "$ALLOWED_GLIBC_VERSION" ]; then + echo "ERROR: $line has dependency on glibc greater than allowed version of ${ALLOWED_GLIBC_VERSION} for at least the following symbols" + # This only lists greatest version number symbols + ${PREFIX}-linux-gnu-objdump -R ${line} | grep @GLIBC_${max_version_in_use} + ret_code=1 + fi + done <<<$(git ls-files **/linux/${ARCH}/\*.so) + return ${ret_code} +} + + +exit_code=0 +# This is the current set of allowed so dependencies for CDT code. Additional entries here are permitted, +# provided they are found on all Linux machines by default. +check aarch64 aarch64 2.17 libc.so.6 ld-linux-aarch64.so.1 || exit_code=1 +check x86_64 x86_64 2.4 libc.so.6 || exit_code=1 +check ppc64le powerpc64le 2.17 libc.so.6 || exit_code=1 + +exit ${exit_code}