#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # # A function's checksum must not depend on where the function sits. # # A jump or call without a relocation encodes its target as an offset from the # instruction. Hashing those bytes makes the checksum change whenever anything # ahead of the function changes size -- so an unrelated edit elsewhere in the # file reports this function as changed too, and the patch grows to include it # and everything it references. Nothing fails; the livepatch is just larger and # riskier than the patch it came from. # # Here the "patch" moves target() away from callee() and changes nothing else: # both are aligned to 64 in the patched build, which shifts them apart without # touching a byte of either. See the fixture for why it is done that way. . "$(dirname "$0")/../lib.sh" setup # -fno-function-sections, or each function is at offset 0 of its own section # and target() never moves. build_pair checksum_position.c -fno-function-sections assert_input_symbol target # The fixture is only meaningful if the displacement target's calls encode # actually changed, and that is the distance to callee() -- not target's own # offset. A compiler which shifted the two by the same amount would move # target and leave the distance alone, and then the bytes are identical and # the checksum matches for the uninteresting reason. Ask about the distance. sym_off() # $1 object, $2 symbol { in_symbols "$1" | awk -v n="$2" '$NF == n { print $2; exit }' } orig_t="$(sym_off orig.o target)"; orig_c="$(sym_off orig.o callee)" new_t="$(sym_off patched.o target)"; new_c="$(sym_off patched.o callee)" [ -n "$orig_t" ] && [ -n "$orig_c" ] && [ -n "$new_t" ] && [ -n "$new_c" ] || fail "target or callee missing from one of the objects" orig_gap=$(( 16#$orig_t - 16#$orig_c )) new_gap=$(( 16#$new_t - 16#$new_c )) [ "$orig_gap" != "$new_gap" ] || probe_skip "this compiler kept target() and callee() the same distance" \ "apart; the call displacement did not change" assert_checksum_matches target pass "checksum unchanged when the function only moves"