Support kernel-doc comments in assembly language files for functions called by C functions. The comment must include a line containing: * Prototype: asmlinkage ... rest of C prototype... and that function name must match the name used in line like: SYM_FUNC_START(name) SYM_FUNC_START_SOMETHING(name) or SOMETHING name which is used in a few places in which SYM_FUNC_START is nested. Signed-off-by: Robert Elliott <elliott@xxxxxxx> --- scripts/kernel-doc | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index aea04365bc69..f3a89301e3ab 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -174,6 +174,7 @@ my %nosymbol_table = (); my $declaration_start_line; my ($type, $declaration_name, $return_type); my ($newsection, $newcontents, $prototype, $brcount, %source_map); +my %asmprototypes; if (defined($ENV{'KBUILD_VERBOSE'})) { $verbose = "$ENV{'KBUILD_VERBOSE'}"; @@ -248,7 +249,7 @@ my $doc_decl = $doc_com . '(\w+)'; # while trying to not match literal block starts like "example::" # my $doc_sect = $doc_com . - '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|prototype|notes?|examples?)\s*:([^:].*)?$'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; @@ -277,6 +278,7 @@ my $section_intro = "Introduction"; my $section = $section_default; my $section_context = "Context"; my $section_return = "Return"; +my $section_asmprototype = "Prototype"; my $undescribed = "-- undescribed --"; @@ -468,6 +470,13 @@ sub dump_section { $new_start_line = 0; } } + + if ($name eq $section_asmprototype) { + # extract the function name for future matching to SYM_FUNC_START.*(name) + # since that doesn't include arguments like a C function call + my ($func) = ($contents =~ /^.*\s+(\S+)\(/); + $asmprototypes{$func} = $contents; + } } ## @@ -1848,9 +1857,31 @@ sub syscall_munge() { sub process_proto_function($$) { my $x = shift; my $file = shift; + my $funcname; $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + # support asm functions declared with one of these starting in + # the first column: + # SYM_FUNC_START(name) + # SYM_FUNC_START_LOCAL(name) + # SYM_FUNC_START_WEAK(name) + # or for nested macros: + # SOMESTRING<whitespace>name + if ($file =~ /\.S$/) { + if ($x =~ /^SYM_FUNC_START/) { + ($funcname) = ($x =~ /^SYM_FUNC_START.*\((.*)\)/); + } elsif ($x =~ /^[A-Za-z0-9_]+\s+[A-Za-z0-9_]+/) { + ($funcname) = ($x =~ /^[A-Za-z0-9_]+\s+([A-Za-z0-9_]+)/); + } + } + if (defined $funcname) { + $prototype = $asmprototypes{$funcname}; + dump_function($asmprototypes{$funcname}, $file); + reset_state(); + return; + } + if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { # do nothing } @@ -2085,6 +2116,8 @@ sub process_body($$) { $newsection = $section_default; } elsif ($newsection =~ m/^context$/i) { $newsection = $section_context; + } elsif ($newsection =~ m/^prototype$/i) { + $newsection = $section_asmprototype; } elsif ($newsection =~ m/^returns?$/i) { $newsection = $section_return; } elsif ($newsection =~ m/^\@return$/) { @@ -2135,6 +2168,16 @@ sub process_body($$) { $contents = ""; $new_start_line = $.; $state = STATE_BODY; + } elsif ($section eq $section_asmprototype) { + my ($protoline) = /Prototype:\s+(.+)$/; + my ($funcname) = $protoline =~ /Prototype\.*\s+(\S+)\(/; + + $asmprototypes{$funcname} = $protoline; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + $state = STATE_BODY; } else { if ($section ne $section_default) { $state = STATE_BODY_WITH_BLANK_LINE; @@ -2150,7 +2193,7 @@ sub process_body($$) { $declaration_purpose =~ s/\s+/ /g; } else { my $cont = $1; - if ($section =~ m/^@/ || $section eq $section_context) { + if ($section =~ m/^@/ || $section eq $section_context || $section eq $section_asmprototype) { if (!defined $leading_space) { if ($cont =~ m/^(\s+)/) { $leading_space = $1; @@ -2286,6 +2329,7 @@ sub process_file($) { } # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + # Hand this line to the appropriate state handler if ($state == STATE_NORMAL) { process_normal(); -- 2.38.1