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 16:24:50 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

> Hi Jose,
>
> Updated patch attached, comments inline ...
>
> On  Fri  2023-10-13  14:09 , Jose E. Marchesi wrote:
>>
>> 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?
>
> Oh ...  Nice; I've dropped this "complex" pretty printer in favor
> of the smaller pretty printers for nested objects, as you
> suggest.

Got an example of how does it looks like with the new pretty printers?

>>
>> > 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?
>
> IMHO having it doesn't hurt.  If you look at the eu-readelf
> output, it will also provide you with translated string values
> for this boolean.  I tend to think that it can stay there.
> I'm happy to remove it though in case you don't like it :)

Ok so you are adding this to the registry in the class "dw-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";

Now, the class dw-children is defined that way as a set of two elements:
DW_CHILDREN_yes and DW_CHILDREN_no.

I think this is a bit overkill, _if_ the class is supposed to be a
boolean set, and only that.  From the DWARF documentation, it seems that
way.  It is reasonable to except that bytes holding booleans will never
have other values than these two.

What is the exact encoding for that byte mandated by the DWARF standard?
Is it 0 = 'false' and 1 = 'true', or (not 0) = 'true'?

If it turns out `children' is a normal boolean that follow
(0=>false,!0=>true) then I would advise to not have it in the registry,
and use a field-specific pretty-printer that would print "#<has
children>" or "#<no children>" or similar.

Also, are DW_CHILDREN_yes and DW_CHILDREN_no usual symbols defined in
DWARF libraries? (dwarf.h)?  We tend to follow the usual C headers when
it comes to define Poke variables and their names.



>>
>> > +       }
>> > +  };
>> > +
>> > +
>> > +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 :)
>
> Gotcha!  As mentioned above, I've dropped the complex pretty
> printer as you suggest.  Didn't realize this, thanks!

Thanks :)

>>
>> > +  };
>> > +
>> > +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  */

Any chance on having the blocks below (calls to dw_cfg) separated by
newlines?

>> > +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:
>
> Yup, I've done this here and in other places where this applies!
>
> [ ... stuff deleted ... ]
>
>
> Thanks
> Martin
>
> commit f745d6ee8b5a838f12dacd61c78ae4336623c8e6
> 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_Table[] @ debug_abbrev_sec.sh_offset;
>     (poke) XXX[0]
>     Dwarf_Abbrev_Table {
>       header=#<1, DW_TAG_compile_unit, DW_CHILDREN_yes>
>     ,
>       entries=[#<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>
>     ],
>       null_name=#<uleb128:0>,
>       null_form=#<uleb128:0>
>     }
>     (poke)
>     (poke)
>     
> ------------------------------------8<------------------------------------------
>
> diff --git a/HACKING b/HACKING
> new file mode 100644
> index 0000000..430f642
> --- /dev/null
> +++ b/HACKING
> @@ -0,0 +1,16 @@
> +To build poke-dwarf you need a working installation of poke.  Then after
> +getting the git-dwarf sources, you can run:
> +
> +  ,----
> +  | $ autoreconf -I /usr/local/share/aclocal/ -i
> +  | $ ./configure ...
> +  `----
> +
> +where the (optional) -I points to the directory containing your aclocal.m4
> +(depending on the poke configure prefix). Finally, run the test suite and
> +install:
> +
> +  ,----
> +  | $ make check && make install
> +  `----
> +
> diff --git a/Makefile.am b/Makefile.am
> index ab59dd3..9b5a774 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -17,7 +17,9 @@
>
>  picklesdir = $(datadir)/poke/pickles
>  dist_pickles_DATA = dwarf.pk \
> +                    dwarf-abbrev.pk \
>                      dwarf-common.pk \
> +                    dwarf-config.pk \
>                      dwarf-expr.pk \
>                      dwarf-frame.pk \
>                      dwarf-info.pk \
> diff --git a/dwarf-abbrev.pk b/dwarf-abbrev.pk
> new file mode 100644
> index 0000000..a73e05b
> --- /dev/null
> +++ b/dwarf-abbrev.pk
> @@ -0,0 +1,81 @@
> +/*
> + * 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>\n", code.value,
> +                                     dw_cfg.get_name ("dw-tag", tag.value),
> +                                     dw_cfg.get_name ("dw-children", 
> children));
> +       }
> +  };
> +
> +
> +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>\n", 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;
> +  };
> diff --git a/dwarf-config.pk b/dwarf-config.pk
> new file mode 100644
> index 0000000..215b45b
> --- /dev/null
> +++ b/dwarf-config.pk
> @@ -0,0 +1,1569 @@
> +/* 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";
> +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)";
> +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";
> +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";
> +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";
> +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)";
> +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)";
> +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..d834fd3 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_Table[] @ data: 0#B;
> +        var h = tbl[0].header;
> +        var e = tbl[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]