[PATCH 2/8] doc: support kernel-doc for asm functions

From: Robert Elliott
Date: Thu Dec 15 2022 - 01:39:50 EST


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