When a static variable is defined in a function, clang(1) emits the following DWARF:
<1><90>: Abbrev Number: 9 (DW_TAG_subprogram) DW_AT_name : (indirect string, offset: 0x213b): pageflttrap [...] <2><af>: Abbrev Number: 10 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0xc9): faultbuf [...] <2><c4>: Abbrev Number: 11 (DW_TAG_formal_parameter) DW_AT_name : (indirect string, offset: 0x217d): frame [...] <2><d3>: Abbrev Number: 11 (DW_TAG_formal_parameter) DW_AT_name : (indirect string, offset: 0x2183): usermode [...] As you can see the function arguments are placed *after* the local static variable. ctfconv(1) currently stops parsing a `DW_TAG_subprogram' section as soon as it find a variable definition. That means with modern clang(1) functions like panic(9) or pageflttrap() are incorrectly identified as having no argument. Diff below fixes that, ok? Index: parse.c =================================================================== RCS file: /cvs/src/usr.bin/ctfconv/parse.c,v retrieving revision 1.11 diff -u -p -r1.11 parse.c --- parse.c 31 Jan 2018 14:47:13 -0000 1.11 +++ parse.c 6 Nov 2019 13:43:32 -0000 @@ -1138,12 +1142,19 @@ subparse_arguments(struct dwdie *die, si * Nested declaration. * * This matches the case where a ``struct'', ``union'', - * ``enum'' or ``typedef'' is first declared "inside" a - * function declaration. + * ``enum'', ``typedef'' or ``static'' variable is first + * declared inside a function declaration. */ - if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type || - tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef) + switch (tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_typedef: + case DW_TAG_variable: continue; + default: + break; + } if (tag != DW_TAG_formal_parameter) break;