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.
Showing the changes to scripts/livepatch (1 of 2 files). Show all
Unified · Split
| @@ -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 | |||
| 15 | next | ||
| 16 | } | ||
| 17 | |||
| 18 | /^@@/ { | ||
| 19 | if (skip) { | ||
| 20 | |||
| 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 | |||
| 45 | next | ||
| 46 | } | ||
| 47 | |||
| 48 | { | ||
| 49 | if (skip || !in_hunk || $0 ~ /^\\ No newline at end of file/) { | ||
| 50 | |||
| 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 | |||
| 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 | |||
| 79 | } | ||