xref: /OK3568_Linux_fs/buildroot/support/scripts/check-bin-arch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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