Use the new "objtool klp checksum" subcommand instead of injecting
--checksum into every objtool invocation via OBJTOOL_ARGS during the
kernel build.

This decouples checksum generation from the build, running it in
separate post-build passes, making the code (and the patch generation
pipeline itself) more modular.

Signed-off-by: Josh Poimboeuf <[email protected]>
---
 scripts/livepatch/klp-build | 93 +++++++++++++++++++++++++------------
 1 file changed, 64 insertions(+), 29 deletions(-)

diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 84053e8aadd3..d29ef3022556 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -39,10 +39,12 @@ OBJ="$(pwd)"
 CONFIG="$OBJ/.config"
 TMP_DIR="$OBJ/klp-tmp"
 
-ORIG_DIR="$TMP_DIR/orig"
-PATCHED_DIR="$TMP_DIR/patched"
-DIFF_DIR="$TMP_DIR/diff"
-KMOD_DIR="$TMP_DIR/kmod"
+ORIG_DIR="$TMP_DIR/1-orig"
+PATCHED_DIR="$TMP_DIR/2-patched"
+ORIG_CSUM_DIR="$TMP_DIR/3-checksum-orig"
+PATCHED_CSUM_DIR="$TMP_DIR/3-checksum-patched"
+DIFF_DIR="$TMP_DIR/4-diff"
+KMOD_DIR="$TMP_DIR/5-kmod"
 
 STASH_DIR="$TMP_DIR/stash"
 TIMESTAMP="$TMP_DIR/timestamp"
@@ -138,10 +140,11 @@ Options:
 Advanced Options:
    -d, --debug                 Show symbol/reloc cloning decisions
    -S, --short-circuit=STEP    Start at build step (requires prior --keep-tmp)
-                                  1|orig       Build original kernel (default)
-                                  2|patched    Build patched kernel
-                                  3|diff       Diff objects
-                                  4|kmod       Build patch module
+                                  1|orig               Build original kernel 
(default)
+                                  2|patched            Build patched kernel
+                                  3|checksum           Generate checksums
+                                  4|diff               Diff objects
+                                  5|kmod               Build patch module
    -T, --keep-tmp              Preserve tmp dir on exit
 
 EOF
@@ -205,10 +208,11 @@ process_args() {
                                [[ ! -d "$TMP_DIR" ]] && die "--short-circuit 
requires preserved klp-tmp dir"
                                keep_tmp=1
                                case "$2" in
-                                       1 | orig)       SHORT_CIRCUIT=1; ;;
-                                       2 | patched)    SHORT_CIRCUIT=2; ;;
-                                       3 | diff)       SHORT_CIRCUIT=3; ;;
-                                       4 | mod)        SHORT_CIRCUIT=4; ;;
+                                       1 | orig)               
SHORT_CIRCUIT=1; ;;
+                                       2 | patched)            
SHORT_CIRCUIT=2; ;;
+                                       3 | checksum)           
SHORT_CIRCUIT=3; ;;
+                                       4 | diff)               
SHORT_CIRCUIT=4; ;;
+                                       5 | kmod)               
SHORT_CIRCUIT=5; ;;
                                        *)              die "invalid 
short-circuit step '$2'" ;;
                                esac
                                shift 2
@@ -519,11 +523,8 @@ clean_kernel() {
 build_kernel() {
        local build="$1"
        local log="$TMP_DIR/build.log"
-       local objtool_args=()
        local cmd=()
 
-       objtool_args=("--checksum")
-
        cmd=("make")
 
        # When a patch to a kernel module references a newly created unexported
@@ -550,7 +551,6 @@ build_kernel() {
        fi
        cmd+=("-j$JOBS")
        cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
-       cmd+=("OBJTOOL_ARGS=${objtool_args[*]}")
        cmd+=("vmlinux")
        cmd+=("modules")
 
@@ -582,7 +582,7 @@ copy_orig_objects() {
 
        find_objects | mapfile -t files
 
-       xtrace_save "copying orig objects"
+       xtrace_save "copying original objects"
        for _file in "${files[@]}"; do
                local rel_file="${_file/.ko/.o}"
                local file="$OBJ/$rel_file"
@@ -638,6 +638,35 @@ copy_patched_objects() {
        mv -f "$TMP_DIR/build.log" "$PATCHED_DIR"
 }
 
+# Copy .o files to a separate directory and run "objtool klp checksum" on each
+# copy.  The checksums are written to a .discard.sym_checksum section.
+#
+# If match_dir is given, only process files which also exist there.
+generate_checksums() {
+       local src_dir="$1"
+       local dest_dir="$2"
+       local match_dir="${3:-}"
+       local files=()
+       local file
+
+       rm -rf "$dest_dir"
+       mkdir -p "$dest_dir"
+
+       find "$src_dir" -type f -name "*.o" | mapfile -t files
+       for file in "${files[@]}"; do
+               local rel="${file#"$src_dir"/}"
+               local dest="$dest_dir/$rel"
+
+               [[ -n "$match_dir" && ! -f "$match_dir/$rel" ]] && continue
+
+               mkdir -p "$(dirname "$dest")"
+               cp -f "$file" "$dest"
+               "$SRC/tools/objtool/objtool" klp checksum "$dest"
+       done
+
+       touch "$dest_dir/.complete"
+}
+
 # Diff changed objects, writing output object to $DIFF_DIR
 diff_objects() {
        local log="$KLP_DIFF_LOG"
@@ -647,16 +676,16 @@ diff_objects() {
        rm -rf "$DIFF_DIR"
        mkdir -p "$DIFF_DIR"
 
-       find "$PATCHED_DIR" -type f -name "*.o" | mapfile -t files
+       find "$PATCHED_CSUM_DIR" -type f -name "*.o" | mapfile -t files
        [[ ${#files[@]} -eq 0 ]] && die "no changes detected"
 
        [[ -v DEBUG_CLONE ]] && opts=("--debug")
 
        # Diff all changed objects
        for file in "${files[@]}"; do
-               local rel_file="${file#"$PATCHED_DIR"/}"
+               local rel_file="${file#"$PATCHED_CSUM_DIR"/}"
                local orig_file="$rel_file"
-               local patched_file="$PATCHED_DIR/$rel_file"
+               local patched_file="$PATCHED_CSUM_DIR/$rel_file"
                local out_file="$DIFF_DIR/$rel_file"
                local filter=()
                local cmd=()
@@ -680,7 +709,7 @@ diff_objects() {
                fi
 
                (
-                       cd "$ORIG_DIR"
+                       cd "$ORIG_CSUM_DIR"
                        [[ -v VERBOSE ]] && echo "${cmd[@]}"
                        "${cmd[@]}"                                             
        \
                                1> >(tee -a "$log")                             
        \
@@ -690,9 +719,9 @@ diff_objects() {
        done
 }
 
-# For each changed object, run objtool with --debug-checksum to get the
-# per-instruction checksums, and then diff those to find the first changed
-# instruction for each function.
+# For each changed object, run "objtool klp checksum" with --debug-checksum to
+# get the per-instruction checksums, and then diff those to find the first
+# changed instruction for each function.
 diff_checksums() {
        local orig_log="$ORIG_DIR/checksum.log"
        local patched_log="$PATCHED_DIR/checksum.log"
@@ -717,8 +746,7 @@ diff_checksums() {
        done
 
        cmd=("$SRC/tools/objtool/objtool")
-       cmd+=("--checksum")
-       cmd+=("--link")
+       cmd+=("klp" "checksum")
        cmd+=("--dry-run")
 
        for file in "${!funcs[@]}"; do
@@ -727,11 +755,11 @@ diff_checksums() {
                (
                        cd "$ORIG_DIR"
                        "${cmd[@]}" "$opt" "$file" &> "$orig_log" || \
-                               ( cat "$orig_log" >&2; die "objtool 
--debug-checksum failed" )
+                               ( cat "$orig_log" >&2; die "objtool klp 
checksum failed" )
 
                        cd "$PATCHED_DIR"
                        "${cmd[@]}" "$opt" "$file" &> "$patched_log" || \
-                               ( cat "$patched_log" >&2; die "objtool 
--debug-checksum failed" )
+                               ( cat "$patched_log" >&2; die "objtool klp 
checksum failed" )
                )
 
                for func in ${funcs[$file]}; do
@@ -872,6 +900,13 @@ if (( SHORT_CIRCUIT <= 2 )); then
 fi
 
 if (( SHORT_CIRCUIT <= 3 )); then
+       status "Generating original checksums"
+       generate_checksums "$ORIG_DIR" "$ORIG_CSUM_DIR" "$PATCHED_DIR"
+       status "Generating patched checksums"
+       generate_checksums "$PATCHED_DIR" "$PATCHED_CSUM_DIR"
+fi
+
+if (( SHORT_CIRCUIT <= 4 )); then
        status "Diffing objects"
        diff_objects
        if [[ -v DIFF_CHECKSUM ]]; then
@@ -880,7 +915,7 @@ if (( SHORT_CIRCUIT <= 3 )); then
        fi
 fi
 
-if (( SHORT_CIRCUIT <= 4 )); then
+if (( SHORT_CIRCUIT <= 5 )); then
        status "Building patch module: $OUTFILE"
        build_patch_module
 fi
-- 
2.53.0


Reply via email to