PATH:
usr
/
src
/
linux-headers-5.4.0-215
/
scripts
#!/usr/bin/perl -w # # kmsg kernel messages check and print tool. # # To check the source code for missing messages the script is called # with check, the name compiler and the compile parameters # kmsg-doc check $(CC) $(c_flags) $< # To create man pages for the messages the script is called with # kmsg-doc print $(CC) $(c_flags) $< # # Copyright IBM Corp. 2008 # Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> # Michael Holzheu <holzheu@linux.vnet.ibm.com> # use Cwd; use bigint; my $errors = 0; my $warnings = 0; my $srctree = ""; my $objtree = ""; my $kmsg_count = 0; sub remove_quotes($) { my ($string) = @_; my $inside = 0; my $slash = 0; my $result = ""; foreach my $str (split(/([\\"])/, $string)) { if ($inside && ($str ne "\"" || $slash)) { $result .= $str; } # Check for backslash before quote if ($str eq "\"") { if (!$slash) { $inside = !$inside; } $slash = 0; } elsif ($str eq "\\") { $slash = !$slash; } elsif ($str ne "") { $slash = 0; } } return $result; } sub string_to_bytes($) { my ($string) = @_; my %is_escape = ('"', 0x22, '\'', 0x27, 'n', 0x0a, 'r', 0x0d, 'b', 0x08, 't', 0x09, 'f', 0x0c, 'a', 0x07, 'v', 0x0b, '?', 0x3f); my (@ar, $slash, $len); # scan string, interpret backslash escapes and write bytes to @ar $len = 0; foreach my $ch (split(//, $string)) { if ($ch eq '\\') { $slash = !$slash; if (!$slash) { $ar[$len] = ord('\\'); $len++; } } elsif ($slash && defined $is_escape{$ch}) { # C99 backslash escapes: \\ \" \' \n \r \b \t \f \a \v \? $ar[$len] = $is_escape{$ch}; $len++; $slash = 0; } elsif ($slash) { # FIXME: C99 backslash escapes \nnn \xhh die("Unknown backslash escape in message $string."); } else { # normal character $ar[$len] = ord($ch); $len++; } } return @ar; } sub calc_jhash($) { my ($string) = @_; my @ar; my ($a, $b, $c, $i, $length, $len); @ar = string_to_bytes($string); $length = @ar; # add dummy elements to @ar to avoid if then else hell push @ar, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); $a = 0x9e3779b9; $b = 0x9e3779b9; $c = 0; $i = 0; for ($len = $length + 12; $len >= 12; $len -= 12) { if ($len < 24) { # add length for last round $c += $length; } $a += $ar[$i] + ($ar[$i+1]<<8) + ($ar[$i+2]<<16) + ($ar[$i+3]<<24); $b += $ar[$i+4] + ($ar[$i+5]<<8) + ($ar[$i+6]<<16) + ($ar[$i+7]<<24); if ($len >= 24) { $c += $ar[$i+8] + ($ar[$i+9]<<8) + ($ar[$i+10]<<16) + ($ar[$i+11]<<24); } else { $c += ($ar[$i+8]<<8) + ($ar[$i+9]<<16) + ($ar[$i+10]<<24); } $a &= 0xffffffff; $b &= 0xffffffff; $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 13); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 8); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 13); $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 12); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 16); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 5); $c &= 0xffffffff; $a -= $b; $a -= $c; $a ^= ($c >> 3); $a &= 0xffffffff; $b -= $c; $b -= $a; $b ^= ($a << 10); $b &= 0xffffffff; $c -= $a; $c -= $b; $c ^= ($b >> 15); $c &= 0xffffffff; $i += 12; } return $c; } sub add_kmsg_desc($$$$$$) { my ($component, $text, $sev, $argv, $desc, $user) = @_; my ($hash, $tag); $text = remove_quotes($text); $hash = substr(sprintf("%08x", calc_jhash($text)), 2, 6); $tag = $component . "." . $hash; if ($kmsg_desc{$tag}) { if ($text ne $kmsg_desc{$tag}->{'TEXT'}) { warn "Duplicate message with tag $tag\n"; warn " --- $kmsg_desc{$tag}->{'TEXT'}\n"; warn " +++ $text\n"; } else { warn "Duplicate message description for \"$text\"\n"; } $errors++; return; } $kmsg_desc{$tag}->{'TEXT'} = $text; $kmsg_desc{$tag}->{'SEV'} = $sev; $kmsg_desc{$tag}->{'ARGV'} = $argv; $kmsg_desc{$tag}->{'DESC'} = $desc; $kmsg_desc{$tag}->{'USER'} = $user; } sub add_kmsg_print($$$$) { my ($component, $sev, $text, $argv) = @_; my ($hash, $tag, $count, $parm); $text = remove_quotes($text); $hash = substr(sprintf("%08x", calc_jhash($text)), 2, 6); $tag = $component . "." . $hash; # Pretty print severity $sev =~ s/"0"/Emerg/; $sev =~ s/"1"/Alert/; $sev =~ s/"2"/Critical/; $sev =~ s/"3"/Error/; $sev =~ s/"4"/Warning/; $sev =~ s/"5"/Notice/; $sev =~ s/"6"/Informational/; $sev =~ s/"7"/Debug/; $kmsg_print{$kmsg_count}->{'TAG'} = $tag; $kmsg_print{$kmsg_count}->{'TEXT'} = $text; $kmsg_print{$kmsg_count}->{'SEV'} = $sev; $kmsg_print{$kmsg_count}->{'ARGV'} = $argv; $kmsg_count += 1; } sub process_source_file($$) { my ($component, $file) = @_; my $state; my ($text, $sev, $argv, $desc, $user); if (!open(FD, "$file")) { return ""; } $state = 0; while (<FD>) { chomp; # kmsg message component: #define KMSG_COMPONENT "<component>" if (/^#define\s+KMSG_COMPONENT\s+\"(.*)\"[^\"]*$/o) { $component = $1; } if ($state == 0) { # single line kmsg for undocumented messages, format: # /*? Text: "<message>" */ if (/^\s*\/\*\?\s*Text:\s*(\".*\")\s*\*\/\s*$/o) { add_kmsg_desc($component, $1, "", "", "", ""); } # kmsg message start: '/*?' if (/^\s*\/\*\?\s*$/o) { $state = 1; ($text, $sev, $argv, $desc, $user) = ( "", "", "", "", "" ); } } elsif ($state == 1) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message text: ' * Text: "<message>"' elsif (/^\s*\*\s*Text:\s*(\".*\")\s*$/o) { $text = $1; } # kmsg message severity: ' * Severity: <sev>' elsif (/^\s*\*\s*Severity:\s*(\S*)\s*$/o) { $sev = $1; } # kmsg message parameter: ' * Parameter: <argv>' elsif (/^\s*\*\s*Parameter:\s*(\S*)\s*$/o) { if (!defined($1)) { $argv = ""; } else { $argv = $1; } $state = 2; } # kmsg message description start: ' * Description:' elsif (/^\s*\*\s*Description:\s*(\S*)\s*$/o) { if (!defined($1)) { $desc = ""; } else { $desc = $1; } $state = 3; } # kmsg has unrecognizable lines else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 2) { # kmsg message end: ' */' if (/^\s*\*\//o) { warn "Warning(${file}:$.): Missing description, skipping message"; $warnings++; $state = 0; } # kmsg message description start: ' * Description:' elsif (/^\s*\*\s*Description:\s*$/o) { $desc = $1; $state = 3; } # kmsg message parameter line: ' * <argv>' elsif (/^\s*\*(.*)$/o) { $argv .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 3) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message description start: ' * User action:' elsif (/^\s*\*\s*User action:\s*$/o) { $user = $1; $state = 4; } # kmsg message description line: ' * <text>' elsif (/^\s*\*\s*(.*)$/o) { $desc .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } elsif ($state == 4) { # kmsg message end: ' */' if (/^\s*\*\/\s*/o) { add_kmsg_desc($component, $text, $sev, $argv, $desc, $user); $state = 0; } # kmsg message user action line: ' * <text>' elsif (/^\s*\*\s*(.*)$/o) { $user .= "\n" . $1; } else { warn "Warning(${file}:$.): Cannot understand $_"; $warnings++; $state = 0; } } } return $component; } sub process_cpp_file($$$$) { my ($cc, $options, $file, $component) = @_; open(FD, "$cc $gcc_options|") or die ("Preprocessing failed."); while (<FD>) { chomp; if (/.*__KMSG_PRINT\(\s*(\S*)\s*(\S*)\s*_FMT_(.*)_ARGS_\s*(.*)?_END_\s*\)/o) { if ($component ne "") { add_kmsg_print($component, $2, $3, $4); } else { warn "Error(${file}:$.): kmsg without component\n"; $errors++; } } elsif (/.*__KMSG_DEV\(\s*(\S*)\s*(\S*)\s*_FMT_(.*)_ARGS_\s*(.*)?_END_\s*\)/o) { if ($component ne "") { add_kmsg_print($component, $2, "\"%s: \"" . $3, $4); } else { warn "Error(${file}:$.): kmsg without component\n"; $errors++; } } } } sub check_messages($) { my $component = "@_"; my $failed = 0; for ($i = 0; $i < $kmsg_count; $i++) { $tag = $kmsg_print{$i}->{'TAG'}; if (!defined($kmsg_desc{$tag})) { add_kmsg_desc($component, "\"" . $kmsg_print{$i}->{'TEXT'} . "\"", $kmsg_print{$i}->{'SEV'}, $kmsg_print{$i}->{'ARGV'}, "Please insert description here", "What is the user supposed to do"); $kmsg_desc{$tag}->{'CHECK'} = 1; $failed = 1; warn "$component: Missing description for: ". $kmsg_print{$i}->{'TEXT'}."\n"; $errors++; next; } if ($kmsg_desc{$tag}->{'SEV'} ne "" && $kmsg_desc{$tag}->{'SEV'} ne $kmsg_print{$i}->{'SEV'}) { warn "Message severity mismatch for \"$kmsg_print{$i}->{'TEXT'}\"\n"; warn " --- $kmsg_desc{$tag}->{'SEV'}\n"; warn " +++ $kmsg_print{$i}->{'SEV'}\n"; } } return $failed; } sub print_templates() { print "Templates for missing messages:\n"; foreach $tag ( sort { $kmsg_desc{$a} <=> $kmsg_desc{$b} } keys %kmsg_desc ) { if (!defined($kmsg_desc{$tag}->{'CHECK'})) { next; } print "/*?\n"; print " * Text: \"$kmsg_desc{$tag}->{'TEXT'}\"\n"; print " * Severity: $kmsg_desc{$tag}->{'SEV'}\n"; $argv = $kmsg_desc{$tag}->{'ARGV'}; if ($argv ne "") { print " * Parameter:\n"; @parms = split(/\s*,\s*/,$kmsg_desc{$tag}->{'ARGV'}); $count = 0; foreach $parm (@parms) { $count += 1; if (!($parm eq "")) { print " * \@$count: $parm\n"; } } } print " * Description:\n"; print " * $kmsg_desc{$tag}->{'DESC'}\n"; print " * User action:\n"; print " * $kmsg_desc{$tag}->{'USER'}\n"; print " */\n\n"; } } sub write_man_pages() { my ($i, $file); for ($i = 0; $i < $kmsg_count; $i++) { $tag = $kmsg_print{$i}->{'TAG'}; if (!defined($kmsg_desc{$tag}) || defined($kmsg_desc{$tag}->{'CHECK'}) || $kmsg_desc{$tag}->{'DESC'} eq "") { next; } $file = $objtree . "man/" . $tag . ".9"; if (!open(WR, ">$file")) { warn "Error: Cannot open file $file\n"; $errors++; return; } print WR ".TH \"$tag\" 9 \"Linux Messages\" LINUX\n"; print WR ".SH Message\n"; print WR $tag . ": " . $kmsg_desc{$tag}->{'TEXT'} . "\n"; print WR ".SH Severity\n"; print WR "$kmsg_desc{$tag}->{'SEV'}\n"; $argv = $kmsg_desc{$tag}->{'ARGV'}; if ($argv ne "") { print WR ".SH Parameters\n"; @parms = split(/\s*\n\s*/,$kmsg_desc{$tag}->{'ARGV'}); foreach $parm (@parms) { $parm =~ s/^\s*(.*)\s*$/$1/; if (!($parm eq "")) { print WR "$parm\n\n"; } } } print WR ".SH Description"; print WR "$kmsg_desc{$tag}->{'DESC'}\n"; $user = $kmsg_desc{$tag}->{'USER'}; if ($user ne "") { print WR ".SH User action"; print WR "$user\n"; } } } if (defined($ENV{'srctree'})) { $srctree = "$ENV{'srctree'}" . "/"; } else { $srctree = getcwd; } if (defined($ENV{'objtree'})) { $objtree = "$ENV{'objtree'}" . "/"; } else { $objtree = getcwd; } if (defined($ENV{'SRCARCH'})) { $srcarch = "$ENV{'SRCARCH'}" . "/"; } else { print "kmsg-doc called without a valid \$SRCARCH\n"; exit 1; } $option = shift; $cc = shift; $gcc_options = "-E -D __KMSG_CHECKER "; foreach $tmp (@ARGV) { $tmp =~ s/\(/\\\(/; $tmp =~ s/\)/\\\)/; $gcc_options .= " $tmp"; $filename = $tmp; } $component = process_source_file("", $filename); if ($component ne "") { process_source_file($component, $srctree . "Documentation/kmsg/" . $srcarch . $component); process_source_file($component, $srctree . "Documentation/kmsg/" . $component); } process_cpp_file($cc, $gcc_options, $filename, $component); if ($option eq "check") { if (check_messages($component)) { print_templates(); } } elsif ($option eq "print") { write_man_pages(); } exit($errors);
[+]
..
[-] ld-version.sh
[edit]
[+]
package
[-] stackusage
[edit]
[-] pnmtologo.c
[edit]
[-] gcc-plugin.sh
[edit]
[-] setlocalversion
[edit]
[-] stackdelta
[edit]
[-] checkkconfigsymbols.py
[edit]
[-] extract-cert.c
[edit]
[-] extract-sys-certs.pl
[edit]
[-] unifdef.c
[edit]
[-] Makefile.extrawarn
[edit]
[-] Makefile.kcov
[edit]
[-] .gitignore
[edit]
[-] documentation-file-ref-check
[edit]
[-] parse-maintainers.pl
[edit]
[-] Makefile.ubsan
[edit]
[+]
atomic
[-] checksyscalls.sh
[edit]
[-] spdxcheck-test.sh
[edit]
[-] recordmcount.h
[edit]
[-] mkuboot.sh
[edit]
[-] kallsyms.c
[edit]
[-] link-vmlinux.sh
[edit]
[-] sortextable.h
[edit]
[-] show_delta
[edit]
[-] Makefile.gcc-plugins
[edit]
[-] ver_linux
[edit]
[-] leaking_addresses.pl
[edit]
[-] subarch.include
[edit]
[-] check_extable.sh
[edit]
[-] gcc-ld
[edit]
[-] diffconfig
[edit]
[-] bpf_helpers_doc.py
[edit]
[-] decode_stacktrace.sh
[edit]
[-] split-man.pl
[edit]
[-] makelst
[edit]
[-] mkcompile_h
[edit]
[-] module-common.lds
[edit]
[-] kmsg-doc
[edit]
[-] Makefile
[edit]
[-] Makefile.modbuiltin
[edit]
[-] gcc-goto.sh
[edit]
[-] mksysmap
[edit]
[-] modules-check.sh
[edit]
[-] nsdeps
[edit]
[-] gcc-x86_64-has-stack-protector.sh
[edit]
[-] ubuntu-retpoline-extract-one
[edit]
[-] gen_compile_commands.py
[edit]
[-] find-unused-docs.sh
[edit]
[-] coccicheck
[edit]
[-] gfp-translate
[edit]
[-] Makefile.kasan
[edit]
[-] config
[edit]
[-] adjust_autoksyms.sh
[edit]
[-] asn1_compiler.c
[edit]
[+]
mod
[-] cc-can-link.sh
[edit]
[+]
selinux
[-] checkpatch.pl
[edit]
[+]
coccinelle
[-] Makefile.modfinal
[edit]
[-] headers_check.pl
[edit]
[-] recordmcount.c
[edit]
[-] sphinx-pre-install
[edit]
[-] Makefile.modsign
[edit]
[-] headers_install.sh
[edit]
[-] patch-kernel
[edit]
[-] xz_wrap.sh
[edit]
[+]
dtc
[+]
basic
[+]
tracing
[-] headerdep.pl
[edit]
[-] const_structs.checkpatch
[edit]
[-] extract_xc3028.pl
[edit]
[-] tags.sh
[edit]
[-] get_dvb_firmware
[edit]
[-] Makefile.build
[edit]
[-] clang-version.sh
[edit]
[-] tools-support-relr.sh
[edit]
[-] gcc-x86_32-has-stack-protector.sh
[edit]
[-] bootgraph.pl
[edit]
[-] gen_ksymdeps.sh
[edit]
[-] Makefile.clean
[edit]
[-] spdxcheck.py
[edit]
[-] decodecode
[edit]
[-] insert-sys-cert.c
[edit]
[-] extract-module-sig.pl
[edit]
[+]
gdb
[-] sortextable.c
[edit]
[-] prune-kernel
[edit]
[+]
kconfig
[-] cleanfile
[edit]
[-] namespace.pl
[edit]
[-] checkincludes.pl
[edit]
[-] faddr2line
[edit]
[-] checkstack.pl
[edit]
[-] mkmakefile
[edit]
[-] Makefile.lib
[edit]
[+]
ksymoops
[-] profile2linkerlist.pl
[edit]
[-] gcc-version.sh
[edit]
[-] Makefile.modpost
[edit]
[-] recordmcount.pl
[edit]
[-] extract-ikconfig
[edit]
[-] bloat-o-meter
[edit]
[-] Makefile.dtbinst
[edit]
[-] kernel-doc
[edit]
[-] Lindent
[edit]
[+]
gcc-plugins
[-] cleanpatch
[edit]
[-] bin2c.c
[edit]
[-] xen-hypercalls.sh
[edit]
[-] markup_oops.pl
[edit]
[-] checkversion.pl
[edit]
[-] conmakehash.c
[edit]
[-] Makefile.headersinst
[edit]
[-] export_report.pl
[edit]
[+]
genksyms
[-] get_abi.pl
[edit]
[-] Makefile.asm-generic
[edit]
[-] objdiff
[edit]
[-] sign-file.c
[edit]
[-] depmod.sh
[edit]
[-] file-size.sh
[edit]
[-] Makefile.modinst
[edit]
[-] Kconfig.include
[edit]
[-] Makefile.host
[edit]
[-] extract-vmlinux
[edit]
[-] get_maintainer.pl
[edit]
[-] Makefile.package
[edit]
[-] spelling.txt
[edit]
[-] Kbuild.include
[edit]