Add support for expanding DW_TAG_subroutine_type and the parameters
in DW_TAG_formal_parameter. Use also to expand subprograms.

Example output with --debug:

  subprogram(
    formal_parameter base_type usize byte_size(8),
    formal_parameter base_type usize byte_size(8),
  )
  -> base_type void;

Signed-off-by: Sami Tolvanen <samitolva...@google.com>
---
 tools/gendwarfksyms/gendwarfksyms.h |  1 +
 tools/gendwarfksyms/types.c         | 58 ++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/tools/gendwarfksyms/gendwarfksyms.h 
b/tools/gendwarfksyms/gendwarfksyms.h
index 43eff91e2f2f..03d8a4a039c3 100644
--- a/tools/gendwarfksyms/gendwarfksyms.h
+++ b/tools/gendwarfksyms/gendwarfksyms.h
@@ -52,6 +52,7 @@ extern bool no_pretty_print;
        })
 
 /* Consistent aliases (DW_TAG_<type>_type) for DWARF tags */
+#define DW_TAG_formal_parameter_type DW_TAG_formal_parameter
 #define DW_TAG_typedef_type DW_TAG_typedef
 
 /*
diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c
index 74b3755c3e16..a56aeaa4f3a1 100644
--- a/tools/gendwarfksyms/types.c
+++ b/tools/gendwarfksyms/types.c
@@ -169,6 +169,15 @@ static int process_fqn(struct state *state, struct 
cached_die *cache,
 DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment)
 DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size)
 
+/* Match functions -- die_match_callback_t */
+#define DEFINE_MATCH(type)                                     \
+       static bool match_##type##_type(Dwarf_Die *die)        \
+       {                                                      \
+               return dwarf_tag(die) == DW_TAG_##type##_type; \
+       }
+
+DEFINE_MATCH(formal_parameter)
+
 bool match_all(Dwarf_Die *die)
 {
        return true;
@@ -206,6 +215,25 @@ static int process_type_attr(struct state *state, struct 
cached_die *cache,
        return check(process(state, cache, "base_type void"));
 }
 
+/* Comma-separated with DW_AT_type */
+static int __process_list_type(struct state *state, struct cached_die *cache,
+                              Dwarf_Die *die, const char *type)
+{
+       check(process(state, cache, type));
+       check(process_type_attr(state, cache, die));
+       check(process(state, cache, ","));
+       return check(process_linebreak(cache, 0));
+}
+
+#define DEFINE_PROCESS_LIST_TYPE(type)                                         
\
+       static int process_##type##_type(                                      \
+               struct state *state, struct cached_die *cache, Dwarf_Die *die) \
+       {                                                                      \
+               return __process_list_type(state, cache, die, #type " ");      \
+       }
+
+DEFINE_PROCESS_LIST_TYPE(formal_parameter)
+
 /* Container types with DW_AT_type */
 static int __process_type(struct state *state, struct cached_die *cache,
                          Dwarf_Die *die, const char *type)
@@ -240,6 +268,30 @@ DEFINE_PROCESS_TYPE(shared)
 DEFINE_PROCESS_TYPE(volatile)
 DEFINE_PROCESS_TYPE(typedef)
 
+static int __process_subroutine_type(struct state *state,
+                                    struct cached_die *cache, Dwarf_Die *die,
+                                    const char *type)
+{
+       check(process(state, cache, type));
+       check(process(state, cache, "("));
+       check(process_linebreak(cache, 1));
+       /* Parameters */
+       check(process_die_container(state, cache, die, process_type,
+                                   match_formal_parameter_type));
+       check(process_linebreak(cache, -1));
+       check(process(state, cache, ")"));
+       process_linebreak(cache, 0);
+       /* Return type */
+       check(process(state, cache, "-> "));
+       return check(process_type_attr(state, cache, die));
+}
+
+static int process_subroutine_type(struct state *state,
+                                  struct cached_die *cache, Dwarf_Die *die)
+{
+       return check(__process_subroutine_type(state, cache, die,
+                                              "subroutine_type"));
+}
 static int process_base_type(struct state *state, struct cached_die *cache,
                             Dwarf_Die *die)
 {
@@ -324,8 +376,11 @@ static int process_type(struct state *state, struct 
cached_die *parent,
        PROCESS_TYPE(rvalue_reference)
        PROCESS_TYPE(shared)
        PROCESS_TYPE(volatile)
+       /* Subtypes */
+       PROCESS_TYPE(formal_parameter)
        /* Other types */
        PROCESS_TYPE(base)
+       PROCESS_TYPE(subroutine)
        PROCESS_TYPE(typedef)
        default:
                debug("unimplemented type: %x", tag);
@@ -346,7 +401,8 @@ static int process_type(struct state *state, struct 
cached_die *parent,
  */
 static int process_subprogram(struct state *state, Dwarf_Die *die)
 {
-       return check(process(state, NULL, "subprogram;\n"));
+       check(__process_subroutine_type(state, NULL, die, "subprogram"));
+       return check(process(state, NULL, ";\n"));
 }
 
 static int process_variable(struct state *state, Dwarf_Die *die)
-- 
2.45.2.627.g7a2c4fd464-goog


Reply via email to