#!/bin/bash report() { [[ -n "$SKIP" ]] && exit echo -en "$OBJ\tDID_DEEP_FIND=${DID_DEEP_FIND}\t" if [[ -n "$ERROR" ]] ; then echo "$ERROR" else echo "$KOBJFILE" fi } die() { ERROR="${1// /_}" exit 1 } # From kpatch-build filter_parent_obj() { local dir="${1}" local file="${2}" grep -v "\.mod\.cmd$" | grep -Fv "${dir}/.${file}.cmd" } # From kpatch-build find_parent_obj() { dir="$(dirname "$1")" absdir="$(readlink -f "$dir")" pwddir="$(readlink -f .)" pdir="${absdir#$pwddir/}" file="$(basename "$1")" grepname="${1%.o}" grepname="$grepname\\.o" if [[ "$DEEP_FIND" -eq 1 ]]; then DID_DEEP_FIND=1 num=0 if [[ -n "$last_deep_find" ]]; then parent="$(grep -lw -e "$grepname" -e " $file" "$last_deep_find"/.*.cmd | filter_parent_obj "${pdir}" "${file}" | head -n1)" num="$(grep -lw -e "$grepname" -e " $file" "$last_deep_find"/.*.cmd | filter_parent_obj "${pdir}" "${file}" | wc -l)" fi if [[ "$num" -eq 0 ]]; then parent="$(find . -name ".*.cmd" -print0 | xargs -0 grep -lw "$grepname" | filter_parent_obj "${pdir}" "${file}" | cut -c3- | head -n1)" num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -lw "$grepname" | filter_parent_obj "${pdir}" "${file}" | wc -l)" [[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")" fi else parent="$(grep -lw -e "$grepname" -e " $file" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | head -n1)" num="$(grep -lw -e "$grepname" -e " $file" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | wc -l)" fi [[ "$num" -eq 0 ]] && PARENT="" && return [[ "$num" -gt 1 ]] && ERROR_IF_DIFF="two parent matches for $1" dir="$(dirname "$parent")" PARENT="$(basename "$parent")" PARENT="${PARENT#.}" PARENT="${PARENT%.cmd}" [[ $dir != "." ]] && PARENT="$dir/$PARENT" [[ ! -e "$PARENT" ]] && die "ERROR: can't find parent $PARENT for $1" } # From kpatch-build find_kobj() { arg="$1" KOBJFILE="$arg" DEEP_FIND=0 DID_DEEP_FIND=0 ERROR_IF_DIFF= while true; do find_parent_obj "$KOBJFILE" [[ -n "$PARENT" ]] && DEEP_FIND=0 if [[ -z "$PARENT" ]]; then [[ "$KOBJFILE" = *.ko ]] && return case "$KOBJFILE" in */built-in.o|\ */built-in.a|\ arch/x86/lib/lib.a|\ arch/x86/kernel/head*.o|\ arch/x86/kernel/ebda.o|\ arch/x86/kernel/platform-quirks.o|\ lib/lib.a) KOBJFILE=vmlinux return esac if [[ "$DEEP_FIND" -eq 0 ]]; then DEEP_FIND=1 continue; fi die "invalid ancestor $KOBJFILE for $arg" fi KOBJFILE="$PARENT" done } trap report EXIT INT TERM HUP OBJ="${1/.\//}" # From kpatch-cc case "$OBJ" in *.mod.o|\ *built-in.o|\ *built-in.a|\ vmlinux.o|\ .tmp_kallsyms1.o|\ .tmp_kallsyms2.o|\ init/version.o|\ arch/x86/boot/version.o|\ arch/x86/boot/compressed/eboot.o|\ arch/x86/boot/header.o|\ arch/x86/boot/compressed/efi_stub_64.o|\ arch/x86/boot/compressed/piggy.o|\ kernel/system_certificates.o|\ arch/x86/vdso/*|\ arch/x86/entry/vdso/*|\ drivers/firmware/efi/libstub/*|\ arch/powerpc/kernel/prom_init.o|\ arch/powerpc/kernel/vdso64/*|\ arch/s390/boot/*|\ arch/s390/purgatory/*|\ arch/s390/kernel/vdso64/*|\ lib/*|\ scripts/*|\ arch/x86/boot/*|\ arch/x86/tools/*|\ .*.o|\ */.lib_exports.o) SKIP=1 exit ;; *.o) find_kobj "$OBJ" exit ;; *) SKIP=1 exit ;; esac