From 2ac206b3bae51e0843e858bb0332aff8786ba3d0 Mon Sep 17 00:00:00 2001 From: Artem Savkov Date: Wed, 14 Mar 2018 10:37:10 +0100 Subject: [PATCH] Undefined reference failure logic rework Don't die outright when encountering an 'undefined reference' error, instead write those down and check if needed symbols are provided by the resulting module or core kpatch module. Fixes #783. v2: - make undefined_references and new_symbols unique before comparing - remove leftover $KMOD_PATH from new_symbols readelf Signed-off-by: Artem Savkov --- kpatch-build/kpatch-build | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index 61009f0..24647b4 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -713,8 +713,13 @@ export KPATCH_GCC_TEMPDIR CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \ KBUILD_MODPOST_WARN=1 \ make "-j$CPUS" $TARGETS 2>&1 | logger || die -grep "undefined reference" "$LOGFILE" | grep -qv kpatch_shadow && die -grep "undefined!" "$LOGFILE" | grep -qv kpatch_shadow && die + +# source.c:(.section+0xFF): undefined reference to `symbol' +grep "undefined reference" "$LOGFILE" | sed -r "s/^.*\`(.*)'$/\1/" \ + >${TEMPDIR}/undefined_references + +# WARNING: "symbol" [path/to/module.ko] undefined! +grep "undefined!" "$LOGFILE" | cut -d\" -f2 >>${TEMPDIR}/undefined_references if [[ ! -e "$TEMPDIR/changed_objs" ]]; then die "no changed objects found" @@ -854,6 +859,27 @@ if ! "$KPATCH_MODULE"; then check_pipe_status create-klp-module fi +readelf --wide --symbols "$TEMPDIR/patch/$MODNAME.ko" 2>/dev/null | \ + awk '($4=="FUNC" || $4=="OBJECT") && ($5=="GLOBAL" || $5=="WEAK") && $7!="UND" {print $NF}' \ + >${TEMPDIR}/new_symbols + +if "$KPATCH_MODULE"; then + cat >>${TEMPDIR}/new_symbols <<-EOF + kpatch_shadow_free + kpatch_shadow_alloc + kpatch_register + kpatch_shadow_get + kpatch_unregister + kpatch_root_kobj + EOF +fi + +# Compare undefined_references and new_symbols files and print only the first +# column containing lines unique to first file. +UNDEFINED=$(comm -23 <(sort -u ${TEMPDIR}/undefined_references) \ + <(sort -u ${TEMPDIR}/new_symbols) | tr '\n' ' ') +[[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED" + cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die [[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE"