kabi检查

kabi检测脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3

import os
import sys
import argparse

WHITELIST_PATH = 'scripts/abicheck/whitelist.pgx'
BASELINE_PATH = 'scripts/abicheck/baseline.abi.pgx'
DEFAULT_SYMVERS = 'Module.symvers'

def parse_symvers(symvers_file):
syms = {}
with open(symvers_file, 'r') as f:
for line in f:
parts = line.strip().split()
if len(parts) < 2:
continue
crc = int(parts[0], 16)
sym = parts[1]
syms[sym] = crc
return syms

def load_whitelist(path):
whitelist = set()
if not os.path.exists(path):
return whitelist
with open(path, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#') or line.startswith('['):
continue
parts = line.split()
if parts:
whitelist.add(parts[0])
return whitelist

def load_baseline(path):
baseline = {}
if not os.path.exists(path):
return baseline
with open(path, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split()
if len(parts) != 2:
continue
sym, crc_str = parts
crc = int(crc_str, 16)
baseline[sym] = crc
return baseline

def compare_kabi(current, baseline, whitelist):
added, removed, changed = [], [], []

for sym in whitelist:
if sym in current:
if sym not in baseline:
added.append(sym)
elif current[sym] != baseline[sym]:
changed.append(sym)

for sym in whitelist:
if sym in baseline and sym not in current:
removed.append(sym)

return added, removed, changed

def main():
parser = argparse.ArgumentParser(description='Check kernel ABI stability')
parser.add_argument('--symvers', default=DEFAULT_SYMVERS,
help='Path to Module.symvers file (default: ./Module.symvers)')
parser.add_argument('--baseline', default=BASELINE_PATH,
help='Baseline ABI file to compare with')
parser.add_argument('--whitelist', default=WHITELIST_PATH,
help='Symbol whitelist file')
args = parser.parse_args()

if not os.path.exists(args.symvers):
print(f"Error: Cannot find Module.symvers at {args.symvers}", file=sys.stderr)
return 1

current_abi = parse_symvers(args.symvers)
whitelist = load_whitelist(args.whitelist)
baseline_abi = load_baseline(args.baseline)

added, removed, changed = compare_kabi(current_abi, baseline_abi, whitelist)

print('\n=== ABI Changes (Only in Whitelist) =======')
if added:
print(f'Added symbols ({len(added)}):')
for sym in added:
print(f' + {sym}')
if removed:
print(f'Removed symbols ({len(removed)}):')
for sym in removed:
print(f' - {sym}')
if changed:
print(f'Changed symbols ({len(changed)}):')
for sym in changed:
old_crc = baseline_abi[sym]
new_crc = current_abi[sym]
print(f' {sym}: {hex(old_crc)} -> {hex(new_crc)}')

if not (added or removed or changed):
print('No ABI change detected in whitelist symbols')
print('===========================================')

return 1 if (added or removed or changed) else 0

if __name__ == '__main__':
sys.exit(main())


kabi检查
https://tomwithkernel.github.io/CICD/kabi检查/
作者
Tom
发布于
2025年5月7日
更新于
2025年5月7日
许可协议