poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Introduce dwarf-abbrev.pk pickle for decoding the .debug_abbrev sect


From: Jose E. Marchesi
Subject: Re: Introduce dwarf-abbrev.pk pickle for decoding the .debug_abbrev section
Date: Fri, 13 Oct 2023 14:09:51 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Hi Martin.
Thanks for the new version of the patch.

See comments below.

> commit a9a5ee60a599cbc0da56fc3d04a26b046c387f52
> Author: Martin Cermak <marticak@gmx.com>
> Date:   Fri Oct 13 12:23:42 2023 +0200
>
>     Introduce dwarf-abbrev pickle
>
>     2023-10-12 Martin Cermak <marticak@gmx.com>
>
>     Introduce dwarf-abbrev pickle covering the .dwarf_abbrev section.
>
>     Changed files:
>
>     HACKING:  Note re building the poke-dwarf content
>     Makefile.am:  Add new files dwarf-abbrev.pk and dwarf-config.pk
>     dwarf-abbrev.pk:  Structures needed for decoding .dwarf_abbrev
>     dwarf-config.pk:  The dwarf pickles config stuff
>     dwarf.pk:  Load new pickles dwarf-config.pk and dwarf-abbrev.pk
>     test-dwarf.pk.in:  Related test coverage
>
>     Short demo:
>
>     
> ------------------------------------8<------------------------------------------
>     $ dwarfdump -b prog5 | head -15
>
>     .debug_abbrev
>     <    1><0x00000000><code:   1> DW_TAG_compile_unit         DW_children_yes
>            <0x00000003>              DW_AT_producer              DW_FORM_strp
>            <0x00000005>              DW_AT_language              DW_FORM_data1
>            <0x00000007>              DW_AT_name                  
> DW_FORM_line_strp
>            <0x00000009>              DW_AT_comp_dir              
> DW_FORM_line_strp
>            <0x0000000b>              DW_AT_low_pc                DW_FORM_addr
>            <0x0000000d>              DW_AT_high_pc               DW_FORM_data8
>            <0x0000000f>              DW_AT_stmt_list             
> DW_FORM_sec_offset
>     <    2><0x00000013><code:   2> DW_TAG_subprogram           DW_children_no
>            <0x00000016>              DW_AT_external              
> DW_FORM_flag_present
>            <0x00000018>              DW_AT_name                  DW_FORM_strp
>            <0x0000001a>              DW_AT_decl_file             DW_FORM_data1
>            <0x0000001c>              DW_AT_decl_line             DW_FORM_data1
>     $ poke --quiet prog5
>     (poke) load elf
>     (poke) load dwarf
>     (poke) var elf = Elf64_File @ 0#B;
>     (poke) var debug_abbrev_sec = elf.get_sections_by_name 
> (".debug_abbrev")[0];
>     (poke) var XXX = Dwarf_Abbrev_Tables @ debug_abbrev_sec.sh_offset;
>     (poke) XXX
>     Dwarf_Abbrev_Tables {
>       abbrev_tables=[1, DW_TAG_compile_unit, DW_CHILDREN_yes
>             DW_AT_producer, DW_FORM_strp
>             DW_AT_language, DW_FORM_data1
>             DW_AT_name, DW_FORM_line_strp
>             DW_AT_comp_dir, DW_FORM_line_strp
>             DW_AT_low_pc, DW_FORM_addr
>             DW_AT_high_pc, DW_FORM_data8
>             DW_AT_stmt_list, DW_FORM_sec_offset
>     ,2, DW_TAG_subprogram, DW_CHILDREN_no
>             DW_AT_external, DW_FORM_flag_present
>             DW_AT_name, DW_FORM_strp
>             DW_AT_decl_file, DW_FORM_data1
>             DW_AT_decl_line, DW_FORM_data1
>             DW_AT_decl_column, DW_FORM_data1
>             DW_AT_type, DW_FORM_ref4
>             DW_AT_low_pc, DW_FORM_addr
>             DW_AT_high_pc, DW_FORM_data8
>             DW_AT_frame_base, DW_FORM_exprloc
>             DW_AT_call_all_tail_calls, DW_FORM_flag_present
>     ,3, DW_TAG_base_type, DW_CHILDREN_no
>             DW_AT_byte_size, DW_FORM_data1
>             DW_AT_encoding, DW_FORM_data1
>             DW_AT_name, DW_FORM_string
>     ,4, DW_TAG_subprogram, DW_CHILDREN_yes
>             DW_AT_external, DW_FORM_flag_present
>             DW_AT_name, DW_FORM_strp
>             DW_AT_decl_file, DW_FORM_data1
>             DW_AT_decl_line, DW_FORM_data1
>             DW_AT_decl_column, DW_FORM_data1
>             DW_AT_prototyped, DW_FORM_flag_present
>             DW_AT_type, DW_FORM_ref4
>             DW_AT_low_pc, DW_FORM_addr
>             DW_AT_high_pc, DW_FORM_data8
>             DW_AT_frame_base, DW_FORM_exprloc
>             DW_AT_call_all_calls, DW_FORM_flag_present
>     ,5, DW_TAG_formal_parameter, DW_CHILDREN_no
>             DW_AT_name, DW_FORM_string
>             DW_AT_decl_file, DW_FORM_data1
>             DW_AT_decl_line, DW_FORM_data1
>             DW_AT_decl_column, DW_FORM_data1
>             DW_AT_type, DW_FORM_ref4
>             DW_AT_location, DW_FORM_exprloc
>     ]
>     }
>     (poke)

How does it look like with pretty-printing on?

> diff --git a/dwarf-abbrev.pk b/dwarf-abbrev.pk
> new file mode 100644
> index 0000000..8b6f0ef
> --- /dev/null
> +++ b/dwarf-abbrev.pk
> @@ -0,0 +1,99 @@
> +/*
> + * 7.5.3 Abbreviations Tables @ https://dwarfstd.org/doc/DWARF5.pdf
> + *
> + * Elfutils example .debug_abbrev parser in libdw/dwarf_getabbrev.c (l~40)
> + * 
> https://sourceware.org/git/?p=elfutils.git;a=blob;f=libdw/dwarf_getabbrev.c#l38
> + *
> + * Binutils example .debug_abbrev parser in binutils/dwarf.c (l~980)
> + * 
> https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=binutils/dwarf.c#l975
> + */
> +
> +load leb128;
> +load "dwarf-info.pk";
> +load "dwarf-config.pk";
> +
> +type Dwarf_Abbrev_Table_Hdr =
> +  struct
> +  {
> +    /*
> +     * 7.5.3 Abbreviations Tables
> +     * [...] Each declaration begins with an unsigned LEB128 number
> +     * representing the abbreviation code itself.  [...]  The
> +     * abbreviation code is followed by another unsigned LEB128
> +     * number that encodes the entry's tag.  [...]
> +     */
> +
> +     ULEB128 code : code.value != 0;
> +     ULEB128 tag : dw_cfg.entry_p ("dw-tag", tag.value);
> +
> +    /*
> +     * [...] Following the tag encoding is a 1-byte value that
> +     * determines whether a debugging information entry using this
> +     * abbreviation has child entries or not. [...]
> +     */
> +
> +     uint<8> children;
> +
> +     method _print = void:
> +       {
> +         printf ("#<%u64d, %s, %s>", code.value,
> +                                     dw_cfg.get_name ("dw-tag", tag.value),
> +                                     dw_cfg.get_name ("dw-children", 
> children));

Hmm, `children' above is just a boolean, so I would say
self-explanatory.

1. Is it really worth it to have a "dw-children" class for a boolean in
   the registry?

2. If not, wouldn't it be better to have a field pretty-printer for
  `tag', _print_tag = void: {...}, and let value and children stand for
  themselves as obvious?

> +       }
> +  };
> +
> +
> +type Dwarf_Abbrev_Table_Entry =
> +  struct
> +  {
> +    /*
> +     * 7.5.3 Abbreviations Tables
> +     * [...] Finally, the child encoding is followed by a series of
> +     * attribute specifications. Each attribute specification
> +     * consists of two parts. The first part is an unsigned LEB128
> +     * number representing the attribute's name. The second part is
> +     * an unsigned LEB128 number representing the attribute's form.
> +     */
> +
> +     ULEB128 name : dw_cfg.entry_p ("dw-at", name.value);
> +     ULEB128 form : dw_cfg.entry_p ("dw-form", form.value);
> +
> +     method _print = void:
> +       {
> +        printf("#<%s, %s>", dw_cfg.get_name ("dw-at", name.value),
> +                            dw_cfg.get_name ("dw-form", form.value));
> +       }
> +  };
> +type Dwarf_Abbrev_Table =
> +  struct
> +  {
> +    Dwarf_Abbrev_Table_Hdr header;
> +    Dwarf_Abbrev_Table_Entry[] entries;
> +
> +    /*
> +     * A set of Dwarf_Abbrev_Table_Entry items is terminated by
> +     * a null_name and a null_form.
> +     */
> +
> +    ULEB128 null_name : null_name.value == 0;
> +    ULEB128 null_form : null_form.value == 0;

Very nice :)

> +    method _print = void:
> +      {
> +        printf ("%u64d, %s, %s\n", header.code.value,
> +                                     dw_cfg.get_name ("dw-tag", 
> header.tag.value),
> +                                     dw_cfg.get_name ("dw-children", 
> header.children));
> +        for (entry in entries)
> +          {
> +            printf ("\t%s, %s\n", dw_cfg.get_name ("dw-at", 
> entry.name.value),
> +                    dw_cfg.get_name ("dw-form", entry.form.value));
> +          }
> +      }

Instead of having a complex pretty-printer for Dwarf_Abbrev_Table, with
loop and all, would't it be better to just rely on the pretty-printer
for the header and for each entry in `entries'?  Then you can rely on
poke's printer for array values regarding indentation and the like.

In other words: given good pretty-printers for the elements of this
struct, it is probably better for the struct to not have any
pretty-printer on its own :)

> +  };
> +
> +type Dwarf_Abbrev_Tables =
> +  struct
> +  {
> +    Dwarf_Abbrev_Table[] abbrev_tables;
> +  };

I wonder if having this type is necessary at all.  Writing the array
type form Dwarf_Abbrev_Table[] is simple enough?

> diff --git a/dwarf-config.pk b/dwarf-config.pk
> new file mode 100644
> index 0000000..50de8f1
> --- /dev/null
> +++ b/dwarf-config.pk
> @@ -0,0 +1,1554 @@
> +/* dwarf-config.pk - The DWARF configuration parameters.  */
> +
> +/* Copyright (C) 2023 Jose E. Marchesi.  */
> +
> +/*
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/*
> + * This file implements a type Dwarf_Config holding various DWARF
> + * configuration parameters
> + */
> +
> +load "dwarf-info.pk";
> +
> +type Dwarf_Config =
> +  struct
> +  {
> +    type Entry =
> +      struct
> +        {
> +          string class : class in ["dw-tag", "dw-at", "dw-form", 
> "dw-children"];
> +          uint<64> tag;
> +          string name;
> +          string doc;
> +        };
> +
> +      Entry[] entries = Entry[]();
> +
> +      method add = (string class, uint<64> tag, string name, string doc = 
> name) void:
> +        {
> +          apush (entries, Entry { class = class,
> +                                  tag = tag,
> +                                  name = name,
> +                                  doc = doc });
> +        }
> +
> +      method get_name = (string class, uint<64> tag) string:
> +        {
> +          for(entry in entries where entry.class == class && entry.tag == 
> tag)
> +            return entry.name;
> +          raise E_inval;
> +        }
> +
> +      method get_doc = (string class, uint<64> tag) string:
> +        {
> +          for(entry in entries where entry.class == class && entry.tag == 
> tag)
> +            return entry.doc;
> +          raise E_inval;
> +        }
> +
> +      method entry_p = (string class, uint<64> tag) int<32>:
> +        {
> +          var entry = "";
> +
> +          try entry = get_name (class, tag);
> +          catch if E_inval { return 0; }
> +
> +          return entry'length;
> +        }
> +  };
> +
> +var dw_cfg = Dwarf_Config {};
> +
> +/* DWARF Tags  */
> +
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_access_declaration
> +  :name "DW_TAG_access_declaration";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_array_type
> +  :name "DW_TAG_array_type"
> +  :doc "Describes array types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_atomic_type
> +  :name "DW_TAG_atomic_type"
> +  :doc "Represents atomic types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_base_type
> +  :name "DW_TAG_base_type"
> +  :doc "Describes basic data types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_call_site
> +  :name "DW_TAG_call_site"
> +  :doc "Represents a call site";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_call_site_parameter
> +  :name "DW_TAG_call_site_parameter"
> +  :doc "Describes parameters at a call site";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_catch_block
> +  :name "DW_TAG_catch_block"
> +  :doc "Represents catch blocks";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_class_template
> +  :name "DW_TAG_class_template";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_class_type
> +  :name "DW_TAG_class_type"
> +  :doc "Represents class types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_coarray_type
> +  :name "DW_TAG_coarray_type"
> +  :doc "Describes coarray types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_common_block
> +  :name "DW_TAG_common_block"
> +  :doc "Represents common blocks";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_common_inclusion
> +  :name "DW_TAG_common_inclusion"
> +  :doc "Represents common block inclusions";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_compile_unit
> +  :name "DW_TAG_compile_unit"
> +  :doc "Represents compilation units";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_condition
> +  :name "DW_TAG_condition"
> +  :doc "Represents conditions";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_constant
> +  :name "DW_TAG_constant"
> +  :doc "Represents constants";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_const_type
> +  :name "DW_TAG_const_type"
> +  :doc "Describes constant types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_dwarf_procedure
> +  :name "DW_TAG_dwarf_procedure"
> +  :doc "Describes Dwarf procedures";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_dynamic_type
> +  :name "DW_TAG_dynamic_type"
> +  :doc "Describes dynamic types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_entry_point
> +  :name "DW_TAG_entry_point"
> +  :doc "Represents entry points";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_enumeration_type
> +  :name "DW_TAG_enumeration_type"
> +  :doc "Describes enumeration types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_enumerator
> +  :name "DW_TAG_enumerator"
> +  :doc "Represents enumerators";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_file_type
> +  :name "DW_TAG_file_type"
> +  :doc "Describes file types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_formal_parameter
> +  :name "DW_TAG_formal_parameter"
> +  :doc "Describes formal parameters";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_format_label
> +  :name "DW_TAG_format_label";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_friend
> +  :name "DW_TAG_friend"
> +  :doc "Describes friend declarations";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_function_template
> +  :name "DW_TAG_function_template";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_generic_subrange
> +  :name "DW_TAG_generic_subrange"
> +  :doc "Describes generic subranges";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_BINCL
> +  :name "DW_TAG_GNU_BINCL";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_call_site
> +  :name "DW_TAG_GNU_call_site";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_call_site_parameter
> +  :name "DW_TAG_GNU_call_site_parameter";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_EINCL
> +  :name "DW_TAG_GNU_EINCL";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_formal_parameter_pack
> +  :name "DW_TAG_GNU_formal_parameter_pack";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_template_parameter_pack
> +  :name "DW_TAG_GNU_template_parameter_pack";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_GNU_template_template_param
> +  :name "DW_TAG_GNU_template_template_param";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_hi_user
> +  :name "DW_TAG_hi_user";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_immutable_type
> +  :name "DW_TAG_immutable_type"
> +  :doc "Describes immutable types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_imported_declaration
> +  :name "DW_TAG_imported_declaration"
> +  :doc "Represents imported declarations";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_imported_module
> +  :name "DW_TAG_imported_module"
> +  :doc "Represents imported modules";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_imported_unit
> +  :name "DW_TAG_imported_unit"
> +  :doc "Represents imported units";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_inheritance
> +  :name "DW_TAG_inheritance"
> +  :doc "Describes inheritance relationships";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_inlined_subroutine
> +  :name "DW_TAG_inlined_subroutine"
> +  :doc "Represents inlined subroutines";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_interface_type
> +  :name "DW_TAG_interface_type"
> +  :doc "Describes interface types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_label
> +  :name "DW_TAG_label"
> +  :doc "Represents labels";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_lexical_block
> +  :name "DW_TAG_lexical_block"
> +  :doc "Describes lexical blocks";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_lo_user
> +  :name "DW_TAG_lo_user";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_member
> +  :name "DW_TAG_member"
> +  :doc "Represents members of a class";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_MIPS_loop
> +  :name "DW_TAG_MIPS_loop";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_module
> +  :name "DW_TAG_module"
> +  :doc "Describes modules";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_namelist_item
> +  :name "DW_TAG_namelist_item"
> +  :doc "Represents namelist items";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_namelist
> +  :name "DW_TAG_namelist"
> +  :doc "Represents namelists";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_namespace
> +  :name "DW_TAG_namespace"
> +  :doc "Describes namespaces";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_packed_type
> +  :name "DW_TAG_packed_type"
> +  :doc "Describes packed types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_partial_unit
> +  :name "DW_TAG_partial_unit"
> +  :doc "Represents partial compilation units";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_pointer_type
> +  :name "DW_TAG_pointer_type"
> +  :doc "Describes pointer types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_ptr_to_member_type
> +  :name "DW_TAG_ptr_to_member_type"
> +  :doc "Describes pointer-to-member types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_reference_type
> +  :name "DW_TAG_reference_type"
> +  :doc "Describes reference types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_restrict_type
> +  :name "DW_TAG_restrict_type"
> +  :doc "Describes restrict-qualified types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_rvalue_reference_type
> +  :name "DW_TAG_rvalue_reference_type"
> +  :doc "Describes rvalue reference types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_set_type
> +  :name "DW_TAG_set_type"
> +  :doc "Describes set types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_shared_type
> +  :name "DW_TAG_shared_type"
> +  :doc "Describes shared types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_skeleton_unit
> +  :name "DW_TAG_skeleton_unit"
> +  :doc "Represents skeleton compilation units";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_string_type
> +  :name "DW_TAG_string_type"
> +  :doc "Describes string types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_structure_type
> +  :name "DW_TAG_structure_type"
> +  :doc "Represents structure types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_subprogram
> +  :name "DW_TAG_subprogram"
> +  :doc "Describes subprograms (functions/methods)";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_subrange_type
> +  :name "DW_TAG_subrange_type"
> +  :doc "Describes subrange types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_subroutine_type
> +  :name "DW_TAG_subroutine_type"
> +  :doc "Describes subroutine types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_template_alias
> +  :name "DW_TAG_template_alias"
> +  :doc "Represents template aliases";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_template_type_parameter
> +  :name "DW_TAG_template_type_parameter"
> +  :doc "Describes template type parameters";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_template_value_parameter
> +  :name "DW_TAG_template_value_parameter"
> +  :doc "Describes template value parameters";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_thrown_type
> +  :name "DW_TAG_thrown_type"
> +  :doc "Describes thrown types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_try_block
> +  :name "DW_TAG_try_block"
> +  :doc "Represents try blocks in exception handling";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_typedef
> +  :name "DW_TAG_typedef"
> +  :doc "Describes typedefs";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_type_unit
> +  :name "DW_TAG_type_unit"
> +  :doc "Represents type units";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_union_type
> +  :name "DW_TAG_union_type"
> +  :doc "Represents union types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_unspecified_parameters
> +  :name "DW_TAG_unspecified_parameters"
> +  :doc "Describes unspecified function parameters";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_unspecified_type
> +  :name "DW_TAG_unspecified_type"
> +  :doc "Represents unspecified types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_variable
> +  :name "DW_TAG_variable"
> +  :doc "Describes variables";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_variant
> +  :name "DW_TAG_variant"
> +  :doc "Represents variants";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_variant_part
> +  :name "DW_TAG_variant_part"
> +  :doc "Describes variant parts";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_volatile_type
> +  :name "DW_TAG_volatile_type"
> +  :doc "Describes volatile-qualified types";
> +dw_cfg.add
> +  :class "dw-tag"
> +  :tag DW_TAG_with_stmt
> +  :name "DW_TAG_with_stmt"
> +  :doc "Represents 'with' statements";
> +
> +/* DWARF Attributes  */
> +
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_abstract_origin
> +  :name "DW_AT_abstract_origin"
> +  :doc "Inline instances of inline subprograms Out-of-line instances of 
> inline subprograms";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_accessibility
> +  :name "DW_AT_accessibility"
> +  :doc "Access declaration (C++, Ada), Accessibility of base or inherited 
> class (C++), Accessibility of data member or member function";

Note that you can split single logic lines into multiple physical ones
like this:

  :doc "Access declaration (C++, Ada), Accessibility of base or \
inherited class (C++), Accessibility of data member or member function";

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_addr_base
> +  :name "DW_AT_addr_base"
> +  :doc "Base offset for address table";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_address_class
> +  :name "DW_AT_address_class"
> +  :doc "Pointer or reference typesi, Subroutine or subroutine type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_alignment
> +  :name "DW_AT_alignment"
> +  :doc "Non-default alignment of type, subprogram or variable";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_allocated
> +  :name "DW_AT_allocated"
> +  :doc "Allocation status of types";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_artificial
> +  :name "DW_AT_artificial"
> +  :doc "Objects or types that are not actually declared in the source";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_associated
> +  :name "DW_AT_associated"
> +  :doc "Association status of types";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_base_types
> +  :name "DW_AT_base_types"
> +  :doc "Primitive data types of compilation unit";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_binary_scale
> +  :name "DW_AT_binary_scale"
> +  :doc "Binary scale factor for fixed-point type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_bit_offset
> +  :name "DW_AT_bit_offset";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_bit_size
> +  :name "DW_AT_bit_size"
> +  :doc "Size of a base type in bits, Size of a data member in bits";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_bit_stride
> +  :name "DW_AT_bit_stride"
> +  :doc "Array element stride (of array type), Subrange stride (dimension of 
> array type), Enumeration stride (dimension of array type)";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_body_begin
> +  :name "DW_AT_body_begin";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_body_end
> +  :name "DW_AT_body_end";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_byte_size
> +  :name "DW_AT_byte_size"
> +  :doc "Size of a data object or data type in bytes";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_byte_stride
> +  :name "DW_AT_byte_stride"
> +  :doc "Array element stride (of array type), Subrange stride (dimension of 
> array type), Enumeration stride (dimension of array type)";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_all_calls
> +  :name "DW_AT_call_all_calls"
> +  :doc "All tail and normal calls in a subprogram are described by call site 
> entries";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_all_source_calls
> +  :name "DW_AT_call_all_source_calls"
> +  :doc "All tail, normal and inlined calls in a subprogram are described by 
> call site and inlined subprogram entries";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_all_tail_calls
> +  :name "DW_AT_call_all_tail_calls"
> +  :doc "All tail calls in a subprogram are described by call site entries";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_column
> +  :name "DW_AT_call_column"
> +  :doc "Column position of inlined subroutine call, Column position of call 
> site of non-inlined call";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_data_location
> +  :name "DW_AT_call_data_location"
> +  :doc "Address of the value pointed to by an argument passed in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_data_value
> +  :name "DW_AT_call_data_value"
> +  :doc "Value pointed to by an argument passed in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_file
> +  :name "DW_AT_call_file"
> +  :doc "File containing inlined subroutine call, File containing call site 
> of non-inlined call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_calling_convention
> +  :name "DW_AT_calling_convention";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_line
> +  :name "DW_AT_call_line"
> +  :doc "Line number of inlined subroutine call, Line containing call site of 
> non-inlined call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_origin
> +  :name "DW_AT_call_origin"
> +  :doc "Subprogram called in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_parameter
> +  :name "DW_AT_call_parameter"
> +  :doc "Parameter entry in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_pc
> +  :name "DW_AT_call_pc"
> +  :doc "Address of the call instruction in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_return_pc
> +  :name "DW_AT_call_return_pc"
> +  :doc "Return address from a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_tail_call
> +  :name "DW_AT_call_tail_call"
> +  :doc "Call is a tail call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_target_clobbered
> +  :name "DW_AT_call_target_clobbered"
> +  :doc "Address of called routine, which may be clobbered, in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_target
> +  :name "DW_AT_call_target"
> +  :doc "Address of called routine in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_call_value
> +  :name "DW_AT_call_value"
> +  :doc "Argument value passed in a call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_common_reference
> +  :name "DW_AT_common_reference"
> +  :doc "Common block usage";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_comp_dir
> +  :name "DW_AT_comp_dir"
> +  :doc "Compilation directory";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_const_expr
> +  :name "DW_AT_const_expr"
> +  :doc "Compile-time constant object, Compile-time constant function";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_const_value
> +  :name "DW_AT_const_value"
> +  :doc "Constant object, Enumeration literal value, Template value 
> parameter";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_containing_type
> +  :name "DW_AT_containing_type"
> +  :doc "Containing type of pointer to member type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_count
> +  :name "DW_AT_count"
> +  :doc "Elements of subrange type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_data_bit_offset
> +  :name "DW_AT_data_bit_offset"
> +  :doc "Base type bit location, Data member bit location";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_data_location
> +  :name "DW_AT_data_location"
> +  :doc "Indirection to actual data";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_data_member_location
> +  :name "DW_AT_data_member_location"
> +  :doc "Data member location, Inherited member location";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_decimal_scale
> +  :name "DW_AT_decimal_scale"
> +  :doc "Decimal scale factor";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_decimal_sign
> +  :name "DW_AT_decimal_sign"
> +  :doc "Decimal sign representation";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_declaration
> +  :name "DW_AT_declaration"
> +  :doc "Incomplete, non-defining, or separate entity, declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_decl_column
> +  :name "DW_AT_decl_column"
> +  :doc "Column position of source declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_decl_file
> +  :name "DW_AT_decl_file"
> +  :doc "File containing source declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_decl_line
> +  :name "DW_AT_decl_line"
> +  :doc "Line number of source declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_defaulted
> +  :name "DW_AT_defaulted"
> +  :doc "Whether a member function has been declared as default";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_default_value
> +  :name "DW_AT_default_value"
> +  :doc "Default value of parameter";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_deleted
> +  :name "DW_AT_deleted"
> +  :doc "Whether a member has been declared as deleted";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_description
> +  :name "DW_AT_description"
> +  :doc "Artificial name or description";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_digit_count
> +  :name "DW_AT_digit_count"
> +  :doc "Digit count for packed decimal or numeric string type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_discr_list
> +  :name "DW_AT_discr_list"
> +  :doc "List of discriminant values";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_discr
> +  :name "DW_AT_discr"
> +  :doc "Discriminant of variant part";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_discr_value
> +  :name "DW_AT_discr_value"
> +  :doc "Discriminant value";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_dwo_name
> +  :name "DW_AT_dwo_name"
> +  :doc "Name of split DWARF object file";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_elemental
> +  :name "DW_AT_elemental"
> +  :doc "Elemental property of a subroutine";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_encoding
> +  :name "DW_AT_encoding"
> +  :doc "Encoding of base type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_endianity
> +  :name "DW_AT_endianity"
> +  :doc "Endianity of data";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_entry_pc
> +  :name "DW_AT_entry_pc"
> +  :doc "Entry address of a scope (compilation unit, subprogram, and so on)";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_enum_class
> +  :name "DW_AT_enum_class"
> +  :doc "Type safe enumeration definition";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_explicit
> +  :name "DW_AT_explicit"
> +  :doc "Explicit property of member function";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_export_symbols
> +  :name "DW_AT_export_symbols"
> +  :doc "Export (inline) symbols of namespace, Export symbols of a structure, 
> union or class";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_extension
> +  :name "DW_AT_extension"
> +  :doc "Previous namespace extension or original namespace";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_external
> +  :name "DW_AT_external"
> +  :doc "External subroutine, External variable";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_frame_base
> +  :name "DW_AT_frame_base"
> +  :doc "Subroutine frame base address";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_friend
> +  :name "DW_AT_friend"
> +  :doc "Friend relationship";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_addr_base
> +  :name "DW_AT_GNU_addr_base";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_all_call_sites
> +  :name "DW_AT_GNU_all_call_sites";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_all_source_call_sites
> +  :name "DW_AT_GNU_all_source_call_sites";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_all_tail_call_sites
> +  :name "DW_AT_GNU_all_tail_call_sites";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_bias
> +  :name "DW_AT_GNU_bias";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_bias
> +  :name "DW_AT_GNU_bias";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_call_site_data_value
> +  :name "DW_AT_GNU_call_site_data_value";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_call_site_target_clobbered
> +  :name "DW_AT_GNU_call_site_target_clobbered";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_call_site_target
> +  :name "DW_AT_GNU_call_site_target";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_call_site_value
> +  :name "DW_AT_GNU_call_site_value";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_deleted
> +  :name "DW_AT_GNU_deleted";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_denominator
> +  :name "DW_AT_GNU_denominator";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_dwo_id
> +  :name "DW_AT_GNU_dwo_id";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_dwo_name
> +  :name "DW_AT_GNU_dwo_name";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_entry_view
> +  :name "DW_AT_GNU_entry_view";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_exclusive_locks_required
> +  :name "DW_AT_GNU_exclusive_locks_required";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_guarded_by
> +  :name "DW_AT_GNU_guarded_by";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_guarded
> +  :name "DW_AT_GNU_guarded";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_locks_excluded
> +  :name "DW_AT_GNU_locks_excluded";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_locviews
> +  :name "DW_AT_GNU_locviews";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_macros
> +  :name "DW_AT_GNU_macros";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_numerator
> +  :name "DW_AT_GNU_numerator";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_odr_signature
> +  :name "DW_AT_GNU_odr_signature";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_pt_guarded_by
> +  :name "DW_AT_GNU_pt_guarded_by";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_pt_guarded
> +  :name "DW_AT_GNU_pt_guarded";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_pubnames
> +  :name "DW_AT_GNU_pubnames";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_pubtypes
> +  :name "DW_AT_GNU_pubtypes";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_ranges_base
> +  :name "DW_AT_GNU_ranges_base";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_shared_locks_required
> +  :name "DW_AT_GNU_shared_locks_required";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_tail_call
> +  :name "DW_AT_GNU_tail_call";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_template_name
> +  :name "DW_AT_GNU_template_name";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_GNU_vector
> +  :name "DW_AT_GNU_vector";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_high_pc
> +  :name "DW_AT_high_pc"
> +  :doc "Contiguous range of code addresses";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_hi_user
> +  :name "DW_AT_hi_user";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_identifier_case
> +  :name "DW_AT_identifier_case"
> +  :doc "Identifier case rule";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_import
> +  :name "DW_AT_import"
> +  :doc "Imported declaration, Imported unit, Namespace alias, Namespace 
> using declaration, Namespace using directive";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_inline
> +  :name "DW_AT_inline"
> +  :doc "Abstract instance, Inlined subroutine";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_is_optional
> +  :name "DW_AT_is_optional"
> +  :doc "Optional parameter";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_language
> +  :name "DW_AT_language"
> +  :doc "Programming language";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_linkage_name
> +  :name "DW_AT_linkage_name"
> +  :doc "Object file linkage name of an entity";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_location
> +  :name "DW_AT_location"
> +  :doc "Data object location";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_loclists_base
> +  :name "DW_AT_loclists_base"
> +  :doc "Location lists base";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_lo_user
> +  :name "DW_AT_lo_user";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_lower_bound
> +  :name "DW_AT_lower_bound"
> +  :doc "Lower bound of subrange";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_low_pc
> +  :name "DW_AT_low_pc"
> +  :doc "Code address or range of addresses, Base address of scope";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_mac_info
> +  :name "DW_AT_mac_info";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_macro_info
> +  :name "DW_AT_macro_info"
> +  :doc "Macro preprocessor information (legacy), (reserved for coexistence 
> with DWARF Version 4, and earlier)";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_macros
> +  :name "DW_AT_macros"
> +  :doc "Macro preprocessor information (#define, #undef, and so on in C, C++ 
> and similar languages)";

Likewise.

> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_main_subprogram
> +  :name "DW_AT_main_subprogram"
> +  :doc "Main or starting subprogram, Unit containing main or starting 
> subprogram";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_abstract_name
> +  :name "DW_AT_MIPS_abstract_name";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_allocatable_dopetype
> +  :name "DW_AT_MIPS_allocatable_dopetype";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_assumed_shape_dopetype
> +  :name "DW_AT_MIPS_assumed_shape_dopetype";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_assumed_size
> +  :name "DW_AT_MIPS_assumed_size";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_clone_origin
> +  :name "DW_AT_MIPS_clone_origin";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_epilog_begin
> +  :name "DW_AT_MIPS_epilog_begin";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_fde
> +  :name "DW_AT_MIPS_fde";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_has_inlines
> +  :name "DW_AT_MIPS_has_inlines";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_linkage_name
> +  :name "DW_AT_MIPS_linkage_name";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_loop_begin
> +  :name "DW_AT_MIPS_loop_begin";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_loop_unroll_factor
> +  :name "DW_AT_MIPS_loop_unroll_factor";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_ptr_dopetype
> +  :name "DW_AT_MIPS_ptr_dopetype";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_software_pipeline_depth
> +  :name "DW_AT_MIPS_software_pipeline_depth";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_stride_byte
> +  :name "DW_AT_MIPS_stride_byte";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_stride_elem
> +  :name "DW_AT_MIPS_stride_elem";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_stride
> +  :name "DW_AT_MIPS_stride";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_MIPS_tail_loop_begin
> +  :name "DW_AT_MIPS_tail_loop_begin";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_mutable
> +  :name "DW_AT_mutable"
> +  :doc "Mutable property of member data";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_namelist_item
> +  :name "DW_AT_namelist_item"
> +  :doc "Namelist item";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_name
> +  :name "DW_AT_name"
> +  :doc "Name of declaration, Path name of compilation source";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_noreturn
> +  :name "DW_AT_noreturn"
> +  :doc "“no return” property of a subprogram";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_object_pointer
> +  :name "DW_AT_object_pointer"
> +  :doc "Object (this, self) pointer of member function";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_ordering
> +  :name "DW_AT_ordering"
> +  :doc "Array row/column ordering";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_picture_string
> +  :name "DW_AT_picture_string"
> +  :doc "Picture string for numeric string type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_priority
> +  :name "DW_AT_priority"
> +  :doc "Module priority";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_producer
> +  :name "DW_AT_producer"
> +  :doc "Compiler identification";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_prototyped
> +  :name "DW_AT_prototyped"
> +  :doc "Subroutine prototype";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_pure
> +  :name "DW_AT_pure"
> +  :doc "Pure property of a subroutine";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_ranges
> +  :name "DW_AT_ranges"
> +  :doc "Non-contiguous range of code addresses";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_rank
> +  :name "DW_AT_rank"
> +  :doc "Dynamic number of array dimensions";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_recursive
> +  :name "DW_AT_recursive"
> +  :doc "Recursive property of a subroutine";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_reference
> +  :name "DW_AT_reference"
> +  :doc "&-qualified non-static member function (C++)";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_return_addr
> +  :name "DW_AT_return_addr"
> +  :doc "Subroutine return address save location";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_rnglists_base
> +  :name "DW_AT_rnglists_base"
> +  :doc "Base offset for range lists";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_rvalue_reference
> +  :name "DW_AT_rvalue_reference"
> +  :doc "&&-qualified non-static member function (C++)";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_segment
> +  :name "DW_AT_segment"
> +  :doc "Addressing information";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_sf_names
> +  :name "DW_AT_sf_names";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_sibling
> +  :name "DW_AT_sibling"
> +  :doc "Debugging information entry relationship";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_signature
> +  :name "DW_AT_signature"
> +  :doc "Type signature";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_small
> +  :name "DW_AT_small"
> +  :doc "Scale factor for fixed-point type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_specification
> +  :name "DW_AT_specification"
> +  :doc "Incomplete, non-defining, or separate declaration corresponding to a 
> declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_src_coords
> +  :name "DW_AT_src_coords";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_src_info
> +  :name "DW_AT_src_info";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_start_scope
> +  :name "DW_AT_start_scope"
> +  :doc "Reduced scope of declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_static_link
> +  :name "DW_AT_static_link"
> +  :doc "Location of uplevel frame";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_stmt_list
> +  :name "DW_AT_stmt_list"
> +  :doc "Line number information for unit";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_string_length_bit_size
> +  :name "DW_AT_string_length_bit_size"
> +  :doc "Size of string length of string type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_string_length_byte_size
> +  :name "DW_AT_string_length_byte_size"
> +  :doc "Size of string length of string type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_string_length
> +  :name "DW_AT_string_length"
> +  :doc "String length of string type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_str_offsets_base
> +  :name "DW_AT_str_offsets_base"
> +  :doc "Base of string offsets table";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_threads_scaled
> +  :name "DW_AT_threads_scaled"
> +  :doc "Array bound THREADS scale factor (UPC)";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_trampoline
> +  :name "DW_AT_trampoline"
> +  :doc "Target subroutine";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_type
> +  :name "DW_AT_type"
> +  :doc "Type of call site, Type of string type components, Type of 
> subroutine return, Type of declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_upper_bound
> +  :name "DW_AT_upper_bound"
> +  :doc "Upper bound of subrange";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_use_location
> +  :name "DW_AT_use_location"
> +  :doc "Member location for pointer to member type";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_use_UTF8
> +  :name "DW_AT_use_UTF8"
> +  :doc "Compilation unit uses UTF-8 strings";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_variable_parameter
> +  :name "DW_AT_variable_parameter"
> +  :doc "Non-constant parameter flag";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_virtuality
> +  :name "DW_AT_virtuality"
> +  :doc "Virtuality attribute";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_visibility
> +  :name "DW_AT_visibility"
> +  :doc "Visibility of declaration";
> +dw_cfg.add
> +  :class "dw-at"
> +  :tag DW_AT_vtable_elem_location
> +  :name "DW_AT_vtable_elem_location"
> +  :doc "Virtual function vtable slot";
> +
> +/* DWARF forms  */
> +
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addr
> +  :name "DW_FORM_addr"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addrx1
> +  :name "DW_FORM_addrx1"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addrx2
> +  :name "DW_FORM_addrx2"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addrx3
> +  :name "DW_FORM_addrx3"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addrx4
> +  :name "DW_FORM_addrx4"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_addrx
> +  :name "DW_FORM_addrx"
> +  :doc "Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_block1
> +  :name "DW_FORM_block1"
> +  :doc "Block";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_block2
> +  :name "DW_FORM_block2"
> +  :doc "Block";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_block4
> +  :name "DW_FORM_block4"
> +  :doc "Block";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_block
> +  :name "DW_FORM_block"
> +  :doc "Block";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_data16
> +  :name "DW_FORM_data16"
> +  :doc "Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_data1
> +  :name "DW_FORM_data1"
> +  :doc "Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_data2
> +  :name "DW_FORM_data2"
> +  :doc "Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_data4
> +  :name "DW_FORM_data4"
> +  :doc "Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_data8
> +  :name "DW_FORM_data8"
> +  :doc "Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_exprloc
> +  :name "DW_FORM_exprloc"
> +  :doc "Expression Location";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_flag
> +  :name "DW_FORM_flag"
> +  :doc "Flag";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_flag_present
> +  :name "DW_FORM_flag_present"
> +  :doc "Flag (Implicitly present)";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_GNU_addr_index
> +  :name "DW_FORM_GNU_addr_index";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_GNU_ref_alt
> +  :name "DW_FORM_GNU_ref_alt";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_GNU_str_index
> +  :name "DW_FORM_GNU_str_index";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_GNU_strp_alt
> +  :name "DW_FORM_GNU_strp_alt";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_implicit_const
> +  :name "DW_FORM_implicit_const"
> +  :doc "Implicit Constant";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_indirect
> +  :name "DW_FORM_indirect"
> +  :doc "Indirect Form";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_line_strp
> +  :name "DW_FORM_line_strp"
> +  :doc "Offset into a string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_loclistx
> +  :name "DW_FORM_loclistx"
> +  :doc "Index into the .debug_loclists section";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref1
> +  :name "DW_FORM_ref1"
> +  :doc "Reference";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref2
> +  :name "DW_FORM_ref2"
> +  :doc "Reference";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref4
> +  :name "DW_FORM_ref4"
> +  :doc "Reference";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref8
> +  :name "DW_FORM_ref8"
> +  :doc "Reference";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref_addr
> +  :name "DW_FORM_ref_addr"
> +  :doc "Reference Address";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref_sig8
> +  :name "DW_FORM_ref_sig8"
> +  :doc "Reference Signature";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref_sup4
> +  :name "DW_FORM_ref_sup4"
> +  :doc "Reference Supplemental Data 4";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref_sup8
> +  :name "DW_FORM_ref_sup8"
> +  :doc "Reference Supplemental Data 8";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_ref_udata
> +  :name "DW_FORM_ref_udata"
> +  :doc "Reference (Unsigned)";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_rnglistx
> +  :name "DW_FORM_rnglistx"
> +  :doc "Range List";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_sdata
> +  :name "DW_FORM_sdata"
> +  :doc "Signed Data";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_sec_offset
> +  :name "DW_FORM_sec_offset"
> +  :doc "Section Offset";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_string
> +  :name "DW_FORM_string"
> +  :doc "String";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strp
> +  :name "DW_FORM_strp"
> +  :doc "As an offset into a string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strp_sup
> +  :name "DW_FORM_strp_sup"
> +  :doc "String Pointer (Supplementary)";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strx1
> +  :name "DW_FORM_strx1"
> +  :doc "Indirect offset into the string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strx2
> +  :name "DW_FORM_strx2"
> +  :doc "Indirect offset into the string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strx3
> +  :name "DW_FORM_strx3"
> +  :doc "Indirect offset into the string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strx4
> +  :name "DW_FORM_strx4"
> +  :doc "Indirect offset into the string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_strx
> +  :name "DW_FORM_strx"
> +  :doc "Indirect offset into the string table";
> +dw_cfg.add
> +  :class "dw-form"
> +  :tag DW_FORM_udata
> +  :name "DW_FORM_udata"
> +  :doc "Data";
> +
> +/* DWARF DIE Children */
> +
> +var DW_CHILDREN_no = 0x00,
> +    DW_CHILDREN_yes = 0x01;
> +
> +dw_cfg.add
> +  :class "dw-children"
> +  :tag DW_CHILDREN_no
> +  :name "DW_CHILDREN_no"
> +  :doc "DIE not having children";
> +dw_cfg.add
> +  :class "dw-children"
> +  :tag DW_CHILDREN_yes
> +  :name "DW_CHILDREN_yes"
> +  :doc "DIE having children";
> +
> +
> diff --git a/dwarf.pk b/dwarf.pk
> index 1d3f8c4..609c8f9 100644
> --- a/dwarf.pk
> +++ b/dwarf.pk
> @@ -17,6 +17,8 @@
>   */
>
>  load "dwarf-common.pk";
> +load "dwarf-config.pk";
> +load "dwarf-abbrev.pk";
>  load "dwarf-info.pk";
>  load "dwarf-expr.pk";
>  load "dwarf-frame.pk";
> diff --git a/test-dwarf.pk.in b/test-dwarf.pk.in
> index 788cc86..dadb33d 100644
> --- a/test-dwarf.pk.in
> +++ b/test-dwarf.pk.in
> @@ -22,9 +22,49 @@
>  load pktest;
>  load dwarf;
>
> +var data = open ("*data*");
> +
> +uint<8>[19] @ data : 0#B = [
> +  0x01UB, 0x11UB, 0x01UB, 0x25UB, 0x0eUB, 0x13UB, 0x0bUB, 0x03UB, 0x1fUB,
> +  0x1bUB, 0x1fUB, 0x11UB, 0x01UB, 0x12UB, 0x07UB, 0x10UB, 0x17UB, 0x00UB,
> +  0x00UB
> +];
> +
>  var tests = [
>    PkTest {
> -    name = "load dwarf pickle",
> +    name = "dwarf-abbrev test",
> +    todo = "WIP",
> +    func = lambda (string name) void:
> +      {
> +        var tbl = Dwarf_Abbrev_Tables @ data: 0#B;
> +        var h = tbl.abbrev_tables[0].header;
> +        var e = tbl.abbrev_tables[0].entries;
> +
> +        assert (h.code.value == 1);
> +        assert (dw_cfg.get_name ("dw-tag", h.tag.value) == 
> "DW_TAG_compile_unit");
> +        assert (dw_cfg.get_name ("dw-children", h.children) == 
> "DW_CHILDREN_yes");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[0].name.value) == 
> "DW_AT_producer");
> +        assert (dw_cfg.get_name ("dw-form", e[0].form.value) == 
> "DW_FORM_strp");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[1].name.value) == 
> "DW_AT_language");
> +        assert (dw_cfg.get_name ("dw-form", e[1].form.value) == 
> "DW_FORM_data1");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[2].name.value) == "DW_AT_name");
> +        assert (dw_cfg.get_name ("dw-form", e[2].form.value) == 
> "DW_FORM_line_strp");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[3].name.value) == 
> "DW_AT_comp_dir");
> +        assert (dw_cfg.get_name ("dw-form", e[3].form.value) == 
> "DW_FORM_line_strp");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[4].name.value) == 
> "DW_AT_low_pc");
> +        assert (dw_cfg.get_name ("dw-form", e[4].form.value) == 
> "DW_FORM_addr");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[5].name.value) == 
> "DW_AT_high_pc");
> +        assert (dw_cfg.get_name ("dw-form", e[5].form.value) == 
> "DW_FORM_data8");
> +
> +        assert (dw_cfg.get_name ("dw-at", e[6].name.value) == 
> "DW_AT_stmt_list");
> +        assert (dw_cfg.get_name ("dw-form", e[6].form.value) == 
> "DW_FORM_sec_offset");
> +      }
>    },];
>
>  exit (pktest_run (tests) ? 0 : 1);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]