History

livepatch/klp-build: Introduce fix-patch-lines script to avoid __LINE__ diff noise

The __LINE__ macro creates challenges for binary diffing. When a .patch file adds or removes lines, it shifts the line numbers for all code below it. This can cause the code generation of functions using __LINE__ to change due to the line number constant being embedded in a MOV instruction, despite there being no semantic difference. Avoid such false positives by adding a fix-patch-lines script which can be used to insert a #line directive in each patch hunk affecting the line numbering. This script will be used by klp-build, which will be introduced in a subsequent patch.

Josh Poimboeuf committed 1 year ago

Commit abaf1f41 parent f2c356d2 files · +80 −0Browse files

Showing the changes to scripts/livepatch (1 of 2 files). Show all

Unified · Split

scripts/livepatch/fix-patch-lines+79−0
@@ -0,0 +1,79 @@
1+#!/usr/bin/awk -f
2+# SPDX-License-Identifier: GPL-2.0
3+#
4+# Use #line directives to preserve original __LINE__ numbers across patches to
5+# avoid unwanted compilation changes.
6+
7+BEGIN {
8+ in_hunk = 0
9+ skip = 0
10+}
11+
12+/^--- / {
13+ skip = $2 !~ /\.(c|h)$/
14+ print
15+ next
16+}
17+
18+/^@@/ {
19+ if (skip) {
20+ print
21+ next
22+ }
23+
24+ in_hunk = 1
25+
26+ # for @@ -1,3 +1,4 @@:
27+ # 1: line number in old file
28+ # 3: how many lines the hunk covers in old file
29+ # 1: line number in new file
30+ # 4: how many lines the hunk covers in new file
31+
32+ match($0, /^@@ -([0-9]+)(,([0-9]+))? \+([0-9]+)(,([0-9]+))? @@/, m)
33+
34+ # Set 'cur' to the old file's line number at the start of the hunk. It
35+ # gets incremented for every context line and every line removal, so
36+ # that it always represents the old file's current line number.
37+ cur = m[1]
38+
39+ # last = last line number of current hunk
40+ last = cur + (m[3] ? m[3] : 1) - 1
41+
42+ need_line_directive = 0
43+
44+ print
45+ next
46+}
47+
48+{
49+ if (skip || !in_hunk || $0 ~ /^\\ No newline at end of file/) {
50+ print
51+ next
52+ }
53+
54+ # change line
55+ if ($0 ~ /^[+-]/) {
56+ # inject #line after this group of changes
57+ need_line_directive = 1
58+
59+ if ($0 ~ /^-/)
60+ cur++
61+
62+ print
63+ next
64+ }
65+
66+ # If this is the first context line after a group of changes, inject
67+ # the #line directive to force the compiler to correct the line
68+ # numbering to match the original file.
69+ if (need_line_directive) {
70+ print "+#line " cur
71+ need_line_directive = 0
72+ }
73+
74+ if (cur == last)
75+ in_hunk = 0
76+
77+ cur++
78+ print
79+}