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;