1*4882a593Smuzhiyun#!/usr/bin/env bash 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# List of hardcoded paths that should be ignored, as they may 4*4882a593Smuzhiyun# contain binaries for an architecture different from the 5*4882a593Smuzhiyun# architecture of the target. 6*4882a593Smuzhiyundeclare -a IGNORES=( 7*4882a593Smuzhiyun # Skip firmware files, they could be ELF files for other 8*4882a593Smuzhiyun # architectures 9*4882a593Smuzhiyun "/lib/firmware" 10*4882a593Smuzhiyun "/usr/lib/firmware" 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun # Skip kernel modules 13*4882a593Smuzhiyun # When building a 32-bit userland on 64-bit architectures, the kernel 14*4882a593Smuzhiyun # and its modules may still be 64-bit. To keep the basic 15*4882a593Smuzhiyun # check-bin-arch logic simple, just skip this directory. 16*4882a593Smuzhiyun "/lib/modules" 17*4882a593Smuzhiyun "/usr/lib/modules" 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun # Skip files in /usr/share, several packages (qemu, 20*4882a593Smuzhiyun # pru-software-support) legitimately install ELF binaries that 21*4882a593Smuzhiyun # are not for the target architecture 22*4882a593Smuzhiyun "/usr/share" 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun # Skip files in {/usr,}/lib/grub, since it is possible to have 25*4882a593Smuzhiyun # it for a different architecture (e.g. i386 grub on x86_64). 26*4882a593Smuzhiyun "/lib/grub" 27*4882a593Smuzhiyun "/usr/lib/grub" 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun # Guile modules are ELF files, with a "None" machine 30*4882a593Smuzhiyun "/usr/lib/guile" 31*4882a593Smuzhiyun) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyunwhile getopts p:l:r:a:i: OPT ; do 34*4882a593Smuzhiyun case "${OPT}" in 35*4882a593Smuzhiyun p) package="${OPTARG}";; 36*4882a593Smuzhiyun l) pkg_list="${OPTARG}";; 37*4882a593Smuzhiyun r) readelf="${OPTARG}";; 38*4882a593Smuzhiyun a) arch_name="${OPTARG}";; 39*4882a593Smuzhiyun i) 40*4882a593Smuzhiyun # Ensure we do have single '/' as separators, 41*4882a593Smuzhiyun # and that we have a leading and a trailing one. 42*4882a593Smuzhiyun pattern="$(sed -r -e 's:/+:/:g; s:^/*:/:; s:/*$:/:;' <<<"${OPTARG}")" 43*4882a593Smuzhiyun IGNORES+=("${pattern}") 44*4882a593Smuzhiyun ;; 45*4882a593Smuzhiyun :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";; 46*4882a593Smuzhiyun \?) error "unknown option '%s'\n" "${OPTARG}";; 47*4882a593Smuzhiyun esac 48*4882a593Smuzhiyundone 49*4882a593Smuzhiyun 50*4882a593Smuzhiyunif test -z "${package}" -o -z "${pkg_list}" -o -z "${readelf}" -o -z "${arch_name}" ; then 51*4882a593Smuzhiyun echo "Usage: $0 -p <pkg> -l <pkg-file-list> -r <readelf> -a <arch name> [-i PATH ...]" 52*4882a593Smuzhiyun exit 1 53*4882a593Smuzhiyunfi 54*4882a593Smuzhiyun 55*4882a593Smuzhiyunexitcode=0 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun# Only split on new lines, for filenames-with-spaces 58*4882a593SmuzhiyunIFS=" 59*4882a593Smuzhiyun" 60*4882a593Smuzhiyun 61*4882a593Smuzhiyunwhile read f; do 62*4882a593Smuzhiyun for ignore in "${IGNORES[@]}"; do 63*4882a593Smuzhiyun if [[ "${f}" =~ ^"${ignore}" ]]; then 64*4882a593Smuzhiyun continue 2 65*4882a593Smuzhiyun fi 66*4882a593Smuzhiyun done 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun # Skip symlinks. Some symlinks may have absolute paths as 69*4882a593Smuzhiyun # target, pointing to host binaries while we're building. 70*4882a593Smuzhiyun if [[ -L "${TARGET_DIR}/${f}" ]]; then 71*4882a593Smuzhiyun continue 72*4882a593Smuzhiyun fi 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun # Get architecture using readelf. We pipe through 'head -1' so 75*4882a593Smuzhiyun # that when the file is a static library (.a), we only take 76*4882a593Smuzhiyun # into account the architecture of the first object file. 77*4882a593Smuzhiyun arch=$(LC_ALL=C ${readelf} -h "${TARGET_DIR}/${f}" 2>&1 | \ 78*4882a593Smuzhiyun sed -r -e '/^ Machine: +(.+)/!d; s//\1/;' | head -1) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun # If no architecture found, assume it was not an ELF file 81*4882a593Smuzhiyun if test "${arch}" = "" ; then 82*4882a593Smuzhiyun continue 83*4882a593Smuzhiyun fi 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun # Architecture is correct 86*4882a593Smuzhiyun if test "${arch}" = "${arch_name}" ; then 87*4882a593Smuzhiyun continue 88*4882a593Smuzhiyun fi 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun printf 'ERROR: architecture for "%s" is "%s", should be "%s"\n' \ 91*4882a593Smuzhiyun "${f}" "${arch}" "${arch_name}" 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun exitcode=1 94*4882a593Smuzhiyundone < <( sed -r -e "/^${package},\.(.+)$/!d; s//\1/;" ${pkg_list} ) 95*4882a593Smuzhiyun 96*4882a593Smuzhiyunexit ${exitcode} 97