summaryrefslogtreecommitdiff
path: root/scripts/bpf_doc.py
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-05-28 15:52:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-05-28 15:52:42 -0700
commit90b83efa6701656e02c86e7df2cb1765ea602d07 (patch)
tree59ac0306b5fe287af6691717ebcdbcc96163c3ca /scripts/bpf_doc.py
parent1b98f357dadd6ea613a435fbaef1a5dd7b35fd21 (diff)
parentc5cebb241e27ed0c3f4c1d2ce63089398e0ed17e (diff)
Merge tag 'bpf-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Pull bpf updates from Alexei Starovoitov: - Fix and improve BTF deduplication of identical BTF types (Alan Maguire and Andrii Nakryiko) - Support up to 12 arguments in BPF trampoline on arm64 (Xu Kuohai and Alexis Lothoré) - Support load-acquire and store-release instructions in BPF JIT on riscv64 (Andrea Parri) - Fix uninitialized values in BPF_{CORE,PROBE}_READ macros (Anton Protopopov) - Streamline allowed helpers across program types (Feng Yang) - Support atomic update for hashtab of BPF maps (Hou Tao) - Implement json output for BPF helpers (Ihor Solodrai) - Several s390 JIT fixes (Ilya Leoshkevich) - Various sockmap fixes (Jiayuan Chen) - Support mmap of vmlinux BTF data (Lorenz Bauer) - Support BPF rbtree traversal and list peeking (Martin KaFai Lau) - Tests for sockmap/sockhash redirection (Michal Luczaj) - Introduce kfuncs for memory reads into dynptrs (Mykyta Yatsenko) - Add support for dma-buf iterators in BPF (T.J. Mercier) - The verifier support for __bpf_trap() (Yonghong Song) * tag 'bpf-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (135 commits) bpf, arm64: Remove unused-but-set function and variable. selftests/bpf: Add tests with stack ptr register in conditional jmp bpf: Do not include stack ptr register in precision backtracking bookkeeping selftests/bpf: enable many-args tests for arm64 bpf, arm64: Support up to 12 function arguments bpf: Check rcu_read_lock_trace_held() in bpf_map_lookup_percpu_elem() bpf: Avoid __bpf_prog_ret0_warn when jit fails bpftool: Add support for custom BTF path in prog load/loadall selftests/bpf: Add unit tests with __bpf_trap() kfunc bpf: Warn with __bpf_trap() kfunc maybe due to uninitialized variable bpf: Remove special_kfunc_set from verifier selftests/bpf: Add test for open coded dmabuf_iter selftests/bpf: Add test for dmabuf_iter bpf: Add open coded dmabuf iterator bpf: Add dmabuf iterator dma-buf: Rename debugfs symbols bpf: Fix error return value in bpf_copy_from_user_dynptr libbpf: Use mmap to parse vmlinux BTF from sysfs selftests: bpf: Add a test for mmapable vmlinux BTF btf: Allow mmap of vmlinux btf ...
Diffstat (limited to 'scripts/bpf_doc.py')
-rwxr-xr-xscripts/bpf_doc.py119
1 files changed, 99 insertions, 20 deletions
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index e74a01a85070..c77dc40f7689 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -8,6 +8,7 @@
from __future__ import print_function
import argparse
+import json
import re
import sys, os
import subprocess
@@ -37,11 +38,17 @@ class APIElement(object):
@desc: textual description of the symbol
@ret: (optional) description of any associated return value
"""
- def __init__(self, proto='', desc='', ret='', attrs=[]):
+ def __init__(self, proto='', desc='', ret=''):
self.proto = proto
self.desc = desc
self.ret = ret
- self.attrs = attrs
+
+ def to_dict(self):
+ return {
+ 'proto': self.proto,
+ 'desc': self.desc,
+ 'ret': self.ret
+ }
class Helper(APIElement):
@@ -51,8 +58,9 @@ class Helper(APIElement):
@desc: textual description of the helper function
@ret: description of the return value of the helper function
"""
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ def __init__(self, proto='', desc='', ret='', attrs=[]):
+ super().__init__(proto, desc, ret)
+ self.attrs = attrs
self.enum_val = None
def proto_break_down(self):
@@ -81,6 +89,12 @@ class Helper(APIElement):
return res
+ def to_dict(self):
+ d = super().to_dict()
+ d["attrs"] = self.attrs
+ d.update(self.proto_break_down())
+ return d
+
ATTRS = {
'__bpf_fastcall': 'bpf_fastcall'
@@ -675,7 +689,7 @@ COMMANDS
self.print_elem(command)
-class PrinterHelpers(Printer):
+class PrinterHelpersHeader(Printer):
"""
A printer for dumping collected information about helpers as C header to
be included from BPF program.
@@ -896,6 +910,43 @@ class PrinterHelpers(Printer):
print(') = (void *) %d;' % helper.enum_val)
print('')
+
+class PrinterHelpersJSON(Printer):
+ """
+ A printer for dumping collected information about helpers as a JSON file.
+ @parser: A HeaderParser with Helper objects
+ """
+
+ def __init__(self, parser):
+ self.elements = parser.helpers
+ self.elem_number_check(
+ parser.desc_unique_helpers,
+ parser.define_unique_helpers,
+ "helper",
+ "___BPF_FUNC_MAPPER",
+ )
+
+ def print_all(self):
+ helper_dicts = [helper.to_dict() for helper in self.elements]
+ out_dict = {'helpers': helper_dicts}
+ print(json.dumps(out_dict, indent=4))
+
+
+class PrinterSyscallJSON(Printer):
+ """
+ A printer for dumping collected syscall information as a JSON file.
+ @parser: A HeaderParser with APIElement objects
+ """
+
+ def __init__(self, parser):
+ self.elements = parser.commands
+ self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd')
+
+ def print_all(self):
+ syscall_dicts = [syscall.to_dict() for syscall in self.elements]
+ out_dict = {'syscall': syscall_dicts}
+ print(json.dumps(out_dict, indent=4))
+
###############################################################################
# If script is launched from scripts/ from kernel tree and can access
@@ -905,9 +956,17 @@ script = os.path.abspath(sys.argv[0])
linuxRoot = os.path.dirname(os.path.dirname(script))
bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h')
+# target -> output format -> printer
printers = {
- 'helpers': PrinterHelpersRST,
- 'syscall': PrinterSyscallRST,
+ 'helpers': {
+ 'rst': PrinterHelpersRST,
+ 'json': PrinterHelpersJSON,
+ 'header': PrinterHelpersHeader,
+ },
+ 'syscall': {
+ 'rst': PrinterSyscallRST,
+ 'json': PrinterSyscallJSON
+ },
}
argParser = argparse.ArgumentParser(description="""
@@ -917,6 +976,8 @@ rst2man utility.
""")
argParser.add_argument('--header', action='store_true',
help='generate C header file')
+argParser.add_argument('--json', action='store_true',
+ help='generate a JSON')
if (os.path.isfile(bpfh)):
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h',
default=bpfh)
@@ -924,17 +985,35 @@ else:
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
argParser.add_argument('target', nargs='?', default='helpers',
choices=printers.keys(), help='eBPF API target')
-args = argParser.parse_args()
-
-# Parse file.
-headerParser = HeaderParser(args.filename)
-headerParser.run()
-# Print formatted output to standard output.
-if args.header:
- if args.target != 'helpers':
- raise NotImplementedError('Only helpers header generation is supported')
- printer = PrinterHelpers(headerParser)
-else:
- printer = printers[args.target](headerParser)
-printer.print_all()
+def error_die(message: str):
+ argParser.print_usage(file=sys.stderr)
+ print('Error: {}'.format(message), file=sys.stderr)
+ exit(1)
+
+def parse_and_dump():
+ args = argParser.parse_args()
+
+ # Parse file.
+ headerParser = HeaderParser(args.filename)
+ headerParser.run()
+
+ if args.header and args.json:
+ error_die('Use either --header or --json, not both')
+
+ output_format = 'rst'
+ if args.header:
+ output_format = 'header'
+ elif args.json:
+ output_format = 'json'
+
+ try:
+ printer = printers[args.target][output_format](headerParser)
+ # Print formatted output to standard output.
+ printer.print_all()
+ except KeyError:
+ error_die('Unsupported target/format combination: "{}", "{}"'
+ .format(args.target, output_format))
+
+if __name__ == "__main__":
+ parse_and_dump()