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: Wed, 11 Oct 2023 20:33:19 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Hi Martin.

Please excuse me: I missed this patch!
Comments below.

> diff --git a/dwarf-abbrev.pk b/dwarf-abbrev.pk
> new file mode 100755
> index 0000000..eac1597
> --- /dev/null
> +++ b/dwarf-abbrev.pk
> @@ -0,0 +1,93 @@
> +/*
> + * 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;

I miss a constraint checker for `tag'.  Now that we have a DWARF
"registry", you can add a method to it to check whether the given value
exists.  For example:

  ULEB128 tag : dw_cfg.tag_p (tag.value);


Similarly, you can also add a field pretty-printer using the existing
method get_name of the registry:

  method _print_tag = void:
  {
    printf "#<%s>", cw_cfg.get_name (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;
> +  };
> +
> +
> +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 : name.value != 0;
> +     ULEB128 form : form.value != 0;
> +  };

Are these "attribute specifications" a closed set?  In that case, should
we add them to the DWARF registry so we can check them in a constraint
and print their name in a pretty-printer?

> +
> +type Dwarf_Abbrev_Table_Null_Entry =
> +  struct
> +  {
> +    /*
> +     * A set of Dwarf_Abbrev_Table_Entry items is terminated by
> +     * one Dwarf_Abbrev_Table_Null_Entry
> +     */
> +
> +     ULEB128 name : name.value == 0;
> +     ULEB128 form : form.value == 0;
> +  };
> +
> +
> +
> +type Dwarf_Abbrev_Table =
> +  struct
> +  {
> +    Dwarf_Abbrev_Table_Hdr header;
> +    Dwarf_Abbrev_Table_Entry[] entries = Dwarf_Abbrev_Table_Entry[]();

That initialization value with the constructor should not be necessary.

> +    Dwarf_Abbrev_Table_Null_Entry nullentry;

Is it really worth to define the Dwarf_Abbrev_Table_Null_Entry type?
Why not using something like this:

  type Dwarf_Abbrev_Table =
  struct
   {
      Dwarf_Abbrev_Table_Hdr header;
      Dwarf_Abbrev_Table_Entry[] entries;
      ULEB128 null_name : null_name.value == 0;
      ULEB128 null_form : null_form.value == 0;
      ...
   }

> +
> +    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));
> +          }
> +      }
> +  };
> +
> +type Dwarf_Abbrev_Tables =
> +  struct
> +  {
> +    Dwarf_Abbrev_Table[] abbrev_tables = Dwarf_Abbrev_Table[]();

Again, that initialization value shall not be necessary.

> +  };
> diff --git a/dwarf-config.pk b/dwarf-config.pk
> new file mode 100644
> index 0000000..a41f938
> --- /dev/null
> +++ b/dwarf-config.pk
> @@ -0,0 +1,1544 @@
> +/* 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;
> +        }
> +  };
> +
> +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..178f118 100644
> --- a/test-dwarf.pk.in
> +++ b/test-dwarf.pk.in
> @@ -22,9 +22,53 @@
>  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;
> +        var n = tbl.abbrev_tables[0].nullentry;
> +
> +        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");
> +
> +        assert (n.name.value == 0);
> +        assert (n.form.value == 0);
> +      }
>    },];
>
>  exit (pktest_run (tests) ? 0 : 1);



reply via email to

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