All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.objectfile.elf.dwarf.DwarfAbbrevSectionImpl Maven / Gradle / Ivy

There is a newer version: 24.1.1
Show newest version
/*
 * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.oracle.objectfile.elf.dwarf;

import com.oracle.objectfile.elf.dwarf.constants.DwarfAttribute;
import com.oracle.objectfile.elf.dwarf.constants.DwarfForm;
import com.oracle.objectfile.elf.dwarf.constants.DwarfHasChildren;
import com.oracle.objectfile.elf.dwarf.constants.DwarfSectionName;
import com.oracle.objectfile.elf.dwarf.constants.DwarfTag;
import jdk.graal.compiler.debug.DebugContext;
import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.AbbrevCode;

/**
 * Section generator for debug_abbrev section. That section defines the layout of the
 * DWARF Information Entries (DIEs) used to model Java debug info. Top level DIEs define Java
 * Compile Units (CUs). Embedded DIEs describe the content of the CU: types, code, variable, etc.
 * These definitions are used to interpret the DIE content inserted into the debug_info
 * section.
 * 

* * An abbrev table contains abbrev entries for one or more DIEs, the last one being a null entry. *

* * A null entry consists of just a 0 abbrev code. * *

    * *
  • LEB128 abbrev_code; ...... == 0 * *
* * Non-null entries have the following format: * *
    * *
  • LEB128 abbrev_code; ......unique code for this layout != 0 * *
  • LEB128 tag; .............. defines the type of the DIE (class, subprogram, var * etc) * *
  • uint8 has_chldren; ....... is the DIE followed by child DIEs or a sibling * DIE * *
  • attribute_spec* .......... zero or more attributes * *
  • null_attribute_spec ...... terminator * *
* * An attribute_spec consists of an attribute name and form: * *
    * *
  • LEB128 attr_name; ........ 0 for the null attribute name * *
  • LEB128 attr_form; ........ 0 for the null attribute form * *
* * For the moment we only use one abbrev table with two types of CU. There is one occurrence of the * BUILTIN_UNIT CU which includes definitions of Java primitive value types and the * struct type used to model a Java object header. There are multiple occurrences of the * CLASS_UNIT CU, one for each Java class, interface or array class included in the * generated native image binary. The latter describes the class, array or interface layout and * defines a class, interface or array reference pointer type. It provides declarations for instance * and static methods and static fields of a class, and methods of an interface. In the case of a * class it may also include definitions of static fields (i.e. location info) and for a class or * interface definitions of compiled methods (i.e. code address locations). The latter may include * details of inlined method frames and top level or inlined parameter or local variable locations. *

* * These two CUs include the following top level and nested DIES *

* * Level 0 DIEs * *

    * *
  • abbrev_code == null, tag == null - empty terminator * *
  • abbrev_code == BUILTIN_UNIT, tag == DW_TAG_compilation_unit - CU that defines * the Java object header struct and all Java primitive types. * *
  • abbrev_code == CLASS_UNIT, tag == DW_TAG_compilation_unit - CU that defines a * specific Java object, interface or array type. * *
* * Level 1 DIES * *
    * *
  • abbrev_code == PRIMITIVE_TYPE, tag == DW_TAG_base_type, parent = BUILTIN_UNIT - * Java primitive type (non-void) * *
  • abbrev_code == VOID_TYPE, tag == DW_TAG_unspecified_type, parent = BUILTIN_UNIT * - Java void type * *
  • abbrev_code == OBJECT_HEADER, tag == DW_TAG_structure_type, parent = BUILTIN_UNIT * - Java object header * *
  • abbrev_code == CLASS_LAYOUT, tag == DW_TAG_class_type, parent = CLASS_UNIT - * Java instance type structure definition * *
  • abbrev_code == CLASS_POINTER, tag == DW_TAG_pointer_type, parent = CLASS_UNIT - * Java instance ref type * *
  • abbrev_code == METHOD_LOCATION, tag == DW_TAG_subprogram , parent = CLASS_UNIT - * Java method code definition (i.e. location of code) * *
  • abbrev_code == STATIC_FIELD_LOCATION, tag == DW_TAG_variable, parent = CLASS_UNIT * - Java static field definition (i.e. location of data) * *
  • abbrev_code == ARRAY_LAYOUT, tag == DW_TAG_structure_type, parent = CLASS_UNIT - * Java array type structure definition * *
  • abbrev_code == ARRAY_POINTER, tag == DW_TAG_pointer_type, parent = CLASS_UNIT - * Java array ref type * *
  • abbrev_code == INTERFACE_LAYOUT, tag == DW_TAG_union_type, parent = CLASS_UNIT - * Java array type structure definition * *
  • abbrev_code == INTERFACE_POINTER, tag == DW_TAG_pointer_type, parent = CLASS_UNIT * - Java interface ref type * *
  • abbrev_code == INDIRECT_LAYOUT, tag == DW_TAG_class_type, parent = CLASS_UNIT - * wrapper layout attaches address rewriting logic to the layout types that it wraps using a * data_location attribute * *
  • abbrev_code == INDIRECT_POINTER, tag == DW_TAG_pointer_type, parent = CLASS_UNIT * - indirect ref type used to type indirect oops that encode the address of an object, whether by * adding tag bits or representing the address as an offset from some base address. these are used * to type object references stored in static and instance fields. They are not needed when typing * local vars and parameters held in registers or on the stack as they appear as raw addresses. * *
  • abbrev_code == NAMESPACE, tag == DW_TAG_namespace, parent = CLASS_UNIT - a * wrap-around DIE that is used to embed all the normal level 1 DIEs of a CLASS_UNIT in * a namespace. This is needed when the corresponding class/interface or array base element type * have been loaded by a loader with a non-empty loader in order to ensure that mangled names for * the class and its members can legitimately employ the loader id as a namespace prefix. Note that * use of a namespace wrapper DIE causes all the embedded level 1+ DIEs documented above and all * their children to be generated at a level one greater than documented here. * *
* * Level 2 DIEs * *
    * *
  • abbrev_code == HEADER_FIELD, tag == DW_TAG_member, parent = OBJECT_HEADER - * object/array header field * *
  • abbrev_code == METHOD_DECLARATION/METHOD_DECLARATION_STATIC, tag == DW_TAG_subprogram, * parent = CLASS_LAYOUT, INTERFACE_LAYOUT * *
  • abbrev_code == FIELD_DECLARATION_1/2/3/4, tag == DW_TAG_member, parent = CLASS_LAYOUT * - instance field declaration (i.e. specification of properties) * *
  • abbrev_code == SUPER_REFERENCE, tag == DW_TAG_inheritance, parent = CLASS_LAYOUT, * ARRAY_LAYOUT - reference to super class layout or to appropriate header struct for {code * java.lang.Object} or arrays. * *
  • abbrev_code == INTERFACE_IMPLEMENTOR, tag == DW_TAG_member, parent = INTERFACE_LAYOUT * - union member typed using class layout of a given implementing class * *
  • abbrev_code == INLINED_SUBROUTINE/INLINED_SUBROUTINE_WITH_CHILDREN, tag == DW_TAG_subprogram, * parent = METHOD_LOCATION/INLINED_SUBROUTINE_WITH_CHILDREN - provides range and * abstract origin for an inlined subroutine * *
  • abbrev_code == METHOD_PARAMETER_DECLARATION_1/2/3, tag == DW_TAG_formal_parameter, parent = * METHOD_DECLARATION/METHOD_DECLARATION_STATIC - details of method parameters * *
  • abbrev_code == METHOD_LOCAL_DECLARATION_1/2, tag == DW_TAG_variable, parent = * METHOD_DECLARATION/METHOD_DECLARATION_STATIC - details of method local vars * *
* * Level 3 DIEs * *
    * *
  • abbrev_code == METHOD_LOCAL_LOCATION, tag == DW_TAG_formal_parameter, parent = * METHOD_LOCATION - details of method parameter or local locations * *
* * Detailed layouts of the DIEs listed above are as follows: *

* * A single instance of the level 0 BUILTIN_UNIT compile unit provide details of all * Java primitive types and the struct type used to model a Java object header * *

    * *
  • abbrev_code == BUILTIN_UNIT, tag == DW_TAG_compilation_unit, * has_children * *
  • DW_AT_language : ... DW_FORM_data1 * *
  • DW_AT_name : ....... DW_FORM_strp * *
  • DW_AT_use_UTF8 : ... DW_FORM_flag * *
* * Instances of the level 0 CLASS_UNIT compile unit provide details of all Java object * types and compiled code. * *
    * *
  • abbrev_code == CLASS_UNIT1/2, tag == DW_TAG_compilation_unit, * has_children * *
  • DW_AT_language : ... DW_FORM_data1 * *
  • DW_AT_name : ....... DW_FORM_strp * *
  • DW_AT_comp_dir : ... DW_FORM_strp * *
  • DW_AT_low_pc : ..... DW_FORM_address only for CLASS_UNIT1 * *
  • DW_AT_hi_pc : ...... DW_FORM_address only for CLASS_UNIT1 * *
  • DW_AT_use_UTF8 : ... DW_FORM_flag * *
  • DW_AT_stmt_list : .. DW_FORM_sec_offset * *
* * Primitive Types: For each non-void Java primitive type there is a level 1 DIE defining a base * type * *
    * *
  • abbrev_code == primitive_type, tag == DW_TAG_base_type, no_children * *
  • DW_AT_byte_size : ... DW_FORM_data1 (or data2 ???) * *
  • DW_AT_bit_size : .... DW_FORM_data1 (or data2 ???) * *
  • DW_AT_encoding : .... DW_FORM_data1 * *
  • DW_AT_name : ........ DW_FORM_strp * *
* *
    * * The void type is defined as an unspecified type * *
  • abbrev_code == VOID_TYPE, tag == DW_TAG_unspecified_type, no_children * *
  • DW_AT_name : ........ DW_FORM_strp * *
* * Header Struct: There is a level 1 DIE defining a structure type which models the header * information embedded at the start of every instance or array (all instances embed the same object * header). Child DIEs are employed to define the name, type and layout of fields in the header. * *
    * *
  • abbrev_code == OBJECT_HEADER, tag == DW_TAG_structure_type, has_children * *
  • DW_AT_name : ........ DW_FORM_strp "oop" * *
  • DW_AT_byte_size : ... DW_FORM_data1 "oop" * *
* * Header Data: A level 2 DIE of type member is used to describe the fields of both object and array * headers. This includes the type tag and other tag bits in all objects and the length field in all * arrays. * *
    * *
  • abbrev_code = HEADER_FIELD, tag == DW_TAG_member, no_children * *
  • Dw_AT_name : ................... DW_FORM_strp * *
  • Dw_AT_type : ................... DW_FORM_ref_addr * *
  • Dw_AT_data_member_location : ... DW_FORM_data1 * *
  • Dw_AT_accessibility : .......... DW_FORM_data1 * *
* * Namespace embedding for Java class DIEs: *

* * When the class loader associated with a class defined in the Java class compile unit has a * non-empty loader id string then a namespace DIE is used to wrap the level 1 DIEs that define the * class layout, methods etc. Otherwise, these children are embedded directly in the Java class * compile unit. The namespace DIE has a single attribute defining the namespace's name as the * loader id string. * *

  • abbrev_code == NAMESPACE, tag == DW_TAG_namespace, parent = CLASS_UNIT, has_children * *
  • DW_AT_name : ....... DW_FORM_strp * * * * Instance Classes: For each instance class type there is a sequence of up to four level 1 DIEs * defining the class. *

    * * Instance Class Structure: Each java class is described by a series of level 1 DIEs. The first one * describes the class layout. The normal layout does not include a data_location * attribute. However, an alternative layout, including that extra attribute, is provided to deal * with a single special case, java.lang.Class. Oop references to instances of this * class are encoded using tag bits. The data_location attribute defines masking logic * which a debugger can use to decode the oop pointer to a raw address. n.b. this only applies in * the case where normal oop references are raw addresses (no compressed oops, no isolates). If a * heapbase register is being used then decoding logic is encoded for both normal classes and for * java.lang.Class using an indirect layout (see below). * *

      * *
    • abbrev_code == CLASS_LAYOUT1/CLASS_LAYOUT2, tag == DW_TAG_class_type, * has_children * *
    • Dw_AT_name : ........ DW_FORM_strp * *
    • Dw_AT_byte_size : ... DW_FORM_data1/2 * *
    • Dw_AT_decl_file : ... DW_FORM_data1/2 * *
    • Dw_AT_decl_line : ... DW_FORM_data1/2 * *
    • Dw_AT_data_location : ... DW_FORM_expr_loc n.b. only for CLASS_LAYOUT2 * *
    * * Instance Class members: A level 1 CLASS_LAYOUT DIE includes a level 2 child for each * of the class's methods and fields. The first type declares a method but omits details of * the location of the code that implements the method. The second type declares an * instance or static field. A CLASS_LAYOUT DIE also contains a level 2 DIE specifying the type from * which it inherits superclass structure. In the case of class Object structure is * inherited from the object header structure type. * * n.b. Code implementation details for each method (i.e. the method definition) are * provided in an auxiliary level 1 METHOD_LOCATION DIE that follows the * CLASS_LAYOUT DIE. Instance field declarations need no auxiliary level 1 DIE as all * relevant details, including size and offset in the instance, are specified in the field * declaration DIE. Static field locations (i.e. the field definition) are provided in an * auxiliary level 1 STATIC_FIELD_LOCATION DIE that follows the * CLASS_LAYOUT DIE. * *
      * *
    • abbrev_code == METHOD_DECLARATION/METHOD_DECLARATION_STATIC, tag == DW_TAG_subprogram, * has_children * *
    • DW_AT_external : .......... DW_FORM_flag * *
    • Dw_AT_name : .............. DW_FORM_strp * *
    • DW_AT_decl_file : ......... DW_FORM_data1/2 * *
    • DW_AT_decl_line : ......... DW_FORM_data1/2 * *
    • Dw_AT_linkage_name : ...... DW_FORM_strp * *
    • Dw_AT_type : .............. DW_FORM_ref_addr (optional!!) * *
    • DW_AT_artificial : ........ DW_FORM_flag * *
    • DW_AT_accessibility : ..... DW_FORM_data1 * *
    • DW_AT_declaration : ....... DW_FORM_flag * *
    • Dw_AT_object_pointer : .... DW_FORM_ref4 n.b. only for METHOD_DECLARATION, * points to param 0 DIE * *
    • DW_AT_virtuality : ........ DW_FORM_data1 (for override methods) * *
    • DW_AT_containing_type : ... DW_FORM_ref4 (for override methods) * *
    * *
      * *
    • abbrev_code == FIELD_DECLARATION_1/2/3/4, tag == DW_TAG_member, no_children * *
    • Dw_AT_name : ................... DW_FORM_strp * *
    • DW_AT_decl_file : .............. DW_FORM_data1/2 n.b. only for * FIELD_DECLARATION_2/4 * *
    • DW_AT_decl_line : .............. DW_FORM_data1/2 n.b. only for * FIELD_DECLARATION_2/4 * *
    • Dw_AT_type : ................... DW_FORM_ref_addr * *
    • Dw_AT_data_member_location : ... DW_FORM_data1/2 (n.b. nly for * FIELD_DECLARATION_1/2 instance * *
    • Dw_AT_artificial : ............. DW_FORM_flag * *
    • Dw_AT_accessibility : .......... DW_FORM_data1 * *
    • Dw_AT_external : ............... DW_FORM_flag (n.b. only for * FIELD_DECLARATION_3/4 static * *
    • Dw_AT_declaration : ............ DW_FORM_flag n.b. only for * FIELD_DECLARATION_3/4 static * *
    * *
      * *
    • abbrev_code == SUPER_REFERENCE, tag == DW_TAG_inheritance, no_children * *
    • Dw_AT_type : ................... DW_FORM_ref_addr * *
    • Dw_AT_data_member_location : ... DW_FORM_data1/2 * *
    • Dw_AT_accessibility :........... DW_FORM_data1 * *
    * * Method Parameters: Level 2 METHOD_DECLARATION/METHOD_DECLARATION_STATIC DIEs may include level 3 * DIEs that describe their parameters and/or their local variables. n.b. these two DIEs only differ * in the value of their tag. * *
      * *
    • abbrev_code == METHOD_PARAMETER_DECLARATION_1/2/3, tag == * DW_TAG_formal_parameter, no_children * *
    • Dw_AT_name : ... DW_FORM_strp (may be empty string) * *
    • Dw_AT_file : ... DW_FORM_data1/2 n.b. only for METHOD_PARAMETER_DECLARATION_2 * *
    • Dw_AT_line : ... DW_FORM_data1/2 n.b. only for METHOD_PARAMETER_DECLARATION_2 * *
    • Dw_AT_type : ... DW_FORM_ref_addr * *
    • Dw_AT_artificial : ... DW_FORM_flag n.b. only for METHOD_PARAMETER_DECLARATION_1 * used for this and access vars * *
    • Dw_AT_declaration : ... DW_FORM_flag * *
    * *
  • abbrev_code == METHOD_LOCAL_DECLARATION_1/2, tag == DW_TAG_variable, * no_children * *
  • Dw_AT_name : ... DW_FORM_strp (may be empty string) * *
  • Dw_AT_file : ... DW_FORM_data1/2 n.b. only for METHOD_PARAMETER_DECLARATION_1 * *
  • Dw_AT_line : ... DW_FORM_data1/2 n.b. only for METHOD_PARAMETER_DECLARATION_1 * *
  • Dw_AT_type : ... DW_FORM_ref_addr * *
  • Dw_AT_declaration : ... DW_FORM_flag * * * * Indirect Instance Class Structure: The level 1 class layout DIE may be followed by a level 1 * INDIRECT_LAYOUT DIE. The indirect layout is only needed when a heapbase register is * in use (isolates or compressed oops are enabled). This means that oop fields will hold encoded * oops. The indirect layout defines an empty wrapper class which declares the previous layout as * its super class. This wrapper type also supplies a data_location attribute, ensuring * that indirect pointers to the class (see next item) are translated to raw addresses. The name of * the indirect type is constructed by prefixing the class name with * DwarfDebugInfo.INDIRECT_PREFIX. This DIE has only one child DIE with type * SUPER_REFERENCE (see above). This effectively embeds the standard layout type in the indirect * layout as a type compatible referent for the Java oop. The size of the indirect layout is the * same as the size of the class layout. * *
      * *
    • abbrev_code == INDIRECT_LAYOUT, tag == DW_TAG_class_type, has_children * *
    • Dw_AT_name : ........ DW_FORM_strp * *
    • Dw_AT_byte_size : ... DW_FORM_data1/2 * *
    • Dw_AT_data_location : ... DW_FORM_expr_loc * *
    * * Instance Class Reference Types: The level 1 CLASS_LAYOUT and * INDIRECT_LAYOUT DIEs are followed by level 1 DIEs defining pointers to the * respective class layouts. A CLASS_POINTER DIE defines a pointer type for the * CLASS_LAYOUT type and is used to type pointers which directly address an instance. * It is used to type local and parameter var references whether located in a register or on the * stack. It may be followed by an INDIRECT_POINTER DIE which defines a pointer type * for the class's INDIRECT_LAYOUT type. This is used to type references to instances * of the class located in a static or instance field. These latter references require address * translation by masking off tag bits and/or rebasing from an offset to a raw address. The logic * for this translation is encoded in the data_location attribute of the corresponding * INDIRECT_LAYOUT DIE. * *
      * *
    • abbrev_code == CLASS_POINTER, tag == DW_TAG_pointer_type, no_children * *
    • Dw_AT_byte_size : ... DW_FORM_data1 * *
    • Dw_AT_type : ........ DW_FORM_ref4 * *
    * *
      * *
    • abbrev_code == INDIRECT_POINTER, tag == DW_TAG_pointer_type, no_children * *
    • Dw_AT_byte_size : ... DW_FORM_data1 * *
    • Dw_AT_type : ........ DW_FORM_ref4 * *
    * * n.b. the name used in the CLASS_LAYOUT DIE is the Java class name. This is * deliberately inconsistent with the Java naming where the name refers to the pointer * type. In consequence when gdb displays Java types and signatures oop references appear as pointer * types. So, for example the Java String class looks like *

    * *

     *   class java.lang.String : public java.lang.Object {
     *    private:
     *     byte[] value;
     *     ...
     *    public:
     *     ...
     *     java.lang.String *concat(java.lang.String *)
     *     ...
     * 
    * * Method Code Locations: For each level 2 method declaration which has been compiled as a * top-level method (i.e. not just occurring inline) there will be a corresponding level 1 method * definition DIE providing details of the location of the compiled code. The two DIEs are * cross-referenced using a specification attribute. This cross-reference means that * the location DIE inherits attributes from the method_definition DIE, including * attributes specified int the latter's child DIEs, such as parameter and local variable * declarations. * *
      * *
    • abbrev_code == DW_ABBREV_CODE_METHOD_LOCATION, tag == DW_TAG_subprogram, * has_children * *
    • DW_AT_low_pc : .......... DW_FORM_addr * *
    • DW_AT_hi_pc : ........... DW_FORM_addr * *
    • DW_AT_external : ........ DW_FORM_flag * *
    • DW_AT_specification : ... DW_FORM_ref4 * *
    * * Method local locations: A method location may be followed by zero or more * METHOD_LOCAL_LOCATION DIEs which identify the in-memory location of parameter and/or * local values during execution of the compiled code. A METHOD_LOCAL_LOCATION DIE * references the corresponding METHOD_PARAMETER_DECLARATION or * * METHOD_LOCAL_DECLARATION. It also specifies a location list which defines address * ranges where the parameter or local is valid and provides details of where to find the value of * the parameter or local in memory. Likewise, an inlined subroutine DIE is followed by zero or more * METHOD_LOCAL_LOCATION DIEs, providing details of where to find the specification of * inlined parameters or locals and their value in memory. * *
      * *
    • abbrev_code == DW_ABBREV_CODE_METHOD_LOCAL_LOCATION1/2, tag == * DW_TAG_formal_parameter, no_children * *
    • DW_AT_specification : .......... DW_FORM_ref4 * *
    • DW_AT_location: ................ DW_FORM_sec_offset n.b. only for * METHOD_LOCAL_LOCATION2 * *
    * * Abstract Inline Methods: For any method m' which has been inlined into a top level compiled * method m there will be an abstract_inline_method DIE for m' at level 1 DIE in the CU to which m * belongs. The declaration serves as an abstract_origin for any corresponding inlined method DIEs * appearing as children of m. The abstract_inline_method DIE will inherit attributes from the * method_definition DIE referenced as its specification attribute without the need to repeat them, * including attributes specified in child DIEs of the method_definition. However, it is actually * necessary to replicate the method_parameter/local_declaration DIEs of the specification as * children of the abstract_inline_method DIE. This provides a CU-local target for references from * the corresponding method_parameter/local_location DIEs that sit below the INLINED_SUBROUTINE DIEs * in the inlined subroutine tree. This is needed because some tools require the location DIEs * abstract_origin attribute that links the location to specification to be a CU-relative offset * (FORM_Ref4) rather than a relocatable cross-CU info section offset. This has the added benefit * that repeated reference to abstract inline methods or parameters from inlined subroutine DIEs or * parameter or local location DIES only avoids the cost of tracking separate relocatable reference. * *
      * *
    • abbrev_code == DW_ABBREV_CODE_abstract_inline_method, tag == DW_TAG_subprogram, * has_children * *
    • DW_AT_inline : .......... DW_FORM_data1 * *
    • DW_AT_external : ........ DW_FORM_flag * *
    • DW_AT_specification : ... DW_FORM_ref_addr * *
    * * Inlined subroutine DIEs are nested as a tree of children under the METHOD_LOCATION DIE for the * method into which they have been inlined. Each inlined subroutine DIE defines an address range * that is a subrange of its parent DIE. A METHOD_LOCATION DIE occurs at depth 1 in a compile unit * (CLASS_UNIT). So, this means that for any method which has been inlined into a compiled method at * depth K in the inline frame stack there will be a corresponding level 2+K DIE that identifies the * method that was inlined (by referencing the corresponding method declaration DIE) and locates the * call point by citing the file index and line number of its caller. So, if compiled method M * inlines a call to m1 at source position f0:l0, m1 inlines a call to method m2 at source position * f1:l1 and m2 inlines a call to m3 at source position f2:l2 then there will be a level 2 DIE for * the inline code range derived from m1 referencing the declaration DIE for m1 with f0 and l0 as * file and line, a level 3 DIE for the inline code range derived from m2 referencing the * declaration DIE for m2 with f1 and l1 as file and line and a level 3 DIE for the inline code * range derived from m3 referencing the declaration DIE for m3 with f2 and l2 as file and line. * *
      * *
    • abbrev_code == DW_ABBREV_CODE_INLINED_SUBROUTINE, tag == DW_TAG_subprogram, * no_children * *
    • abbrev_code == DW_ABBREV_CODE_INLINED_SUBROUTINE_WITH_CHILDREN, tag == * DW_TAG_subprogram, has_children * *
    • DW_AT_abstract_origin : ... DW_FORM_ref4 * *
    • DW_AT_low_pc : ............ DW_FORM_addr * *
    • DW_AT_hi_pc : ............. DW_FORM_addr * *
    • DW_AT_call_file : ......... DW_FORM_data4 * *
    • DW_AT_call_line : ......... DW_FORM_data4 * *
    * * Static Field Locations: For each static field within the class there is a level 1 field * definition DIE providing details of the static field location * *
      * *
    • abbrev_code == STATIC_FIELD_LOCATION, tag == DW_TAG_variable, * no_children * *
    • DW_AT_specification : ... DW_FORM_ref4 * *
    • DW_AT_linkage_name : .... DW_FORM_strp * *
    • DW_AT_location : ........ DW_FORM_expr_loc * *
    * * Arrays: For each array type there is a sequence of up to five level 1 DIEs defining the array. *

    * * Array Layout: The first array DIE describes the array layout. It has three children. The first is * a SUPER_REFERENCE DIE (see above) to class java.lang.Object. The other * two children are field declarations, a length field that overlays the Java array length field and * an array data field which aligns with the element 0 of the Java array's data area. The data field * type is typed (via a later level 1 DIE) as a DWARF array, i.e. it is a data block embedded * directly in the layout, with a nominal element count of 0. The elements of this DWARF array are * typed using the DWARF type corresponding to the Java array's element type. It is either a Java * primitive type or a Java reference type (i.e. the pointer type ot the underlying layout type). A * nominal array length of zero means that this second data field does not actually add any extra * size to the array layout. So, all array types have the same length. *

    * * Note that when the base element type of the array is a class whose loader has an associated * loader id the array type and associated types are embedded in a namespace DIE. This is needed * because the encoded type name for the array will include a namespace prefix in order to guarantee * that it remains unique. * *

      * *
    • abbrev_code == ARRAY_LAYOUT, tag == DW_TAG_class_type, has_children * *
    • Dw_AT_name : ........ DW_FORM_strp * *
    • Dw_AT_byte_size : ... DW_FORM_data1/2 * *
    * * The immediately following DIE is an INDIRECT_LAYOUT (see above) that wraps the array layout as * its super type (just as with class layouts). The wrapper type supplies a data_location attribute, * allowing indirect pointers to the array to be translated to raw addresses. The name of the * indirect array type is constructed by prefixing the array name with * DwarfDebugInfo.INDIRECT_PREFIX. This DIE has only one child DIE with type * SUPER_REFERENCE (see above). The latter references the array layout DIE, effectively * embedding the standard array layout type in the indirect layout. The size of the indirect layout * is the same as the size of the array layout. *

    * * The third and fourth DIEs define array reference types as a pointers to the underlying structure * layout types. As with classes, there is an ARRAY_POINTER type for raw address references used to * type local and param vars and an INDIRECT_POINTER type (see above) for array references stored in * static and instance fields. * *

      * *
    • abbrev_code == ARRAY_POINTER, tag == DW_TAG_pointer_type, no_children * *
    • Dw_AT_byte_size : ... DW_FORM_data1 * *
    • Dw_AT_type : ........ DW_FORM_ref4 * *
    * * n.b. the name used in the ARRAY_LAYOUT DIE is the Java array name. This is deliberately * inconsistent with the Java naming where the name refers to the pointer type. As with normal * objects an array reference in a Java signature appears as a pointer to an array layout when * printed by gdb. * * Array members: The level 1 ARRAY_LAYOUT DIE includes a member field DIE that defines the layout * of the array data. The type of this embedded field is declared by a fifth level 1 DIE, a * array_data_type DIE (with DWARF tag array_type). * *
      * *
    • abbrev_code == array_data_type, tag == DW_TAG_array_type, no_children * *
    • Dw_AT_byte_size : ... DW_FORM_data1 * *
    • Dw_AT_type : ........ DW_FORM_ref_addr * *
    * * Interfaces: For each interface there is a sequence of DIEs defining the interface. *

    * * Interface Layout and Reference Types: An interface is primarily modeled by a level 1 DIE defining * its layout as a union of all the layouts for the classes which implement the interface. The size * of the interface layout is the maximum of the sizes for the implementing classes. A DWARF union * type is used to ensure that the resulting layout is overlay type compatible with all its * implementors. This also means that a reference to an instance of the interface can be cast to a * reference to any of the implementors. * *

      * *
    • abbrev_code == INTERFACE_LAYOUT, DW_TAG_union_type, has_children * *
    • Dw_AT_name : ....... DW_FORM_strp * *
    * * A second level 1 DIE provides an indirect layout that wraps the interface layout as its super * type (just as with class layouts). The wrapper type supplies a data_location * attribute, allowing indirect pointers to the interface to be translated to raw addresses. The * name of the indirect interface type is constructed by prefixing the interface name with * DwarfDebugInfo.INDIRECT_PREFIX. This DIE has only one child DIE with type * sup[er_reference (see above). The latter references the interface layout DIE, * effectively embedding the standard interface layout type in the indirect layout. The size of the * indirect layout is the same as the size of the interface layout. * * The third and fourth DIEs define interface reference types as a pointers to the underlying * structure layout types. As with classes, there is an INTERFACE_POINTER type for raw address * references used to type local and param vars and an INDIRECT_POINTER type (see above) for * interface references stored in static and instance fields. * * A second level 1 defines a pointer to this layout type. * * n.b. the name used in the INTERFACE_LAYOUT DIE is the Java array name. This is * deliberately inconsistent with the Java naming where the name refers to the pointer type. As with * normal objects an interface reference in a Java signature appears as a pointer to an interface * layout when printed by gdb. * *
      * *
    • abbrev_code == INTERFACE_POINTER, tag == DW_TAG_pointer_type, has_children * *
    • Dw_AT_byte_size : ... DW_FORM_data1 * *
    • DW_AT_TYPE : ....... DW_FORM_ref4 * *
    * * The union type embeds level 2 DIEs with tag member. There is a member for each implementing * class, typed using the layout. * *
      * *
    • abbrev_code == INTERFACE_IMPLEMENTOR, tag == DW_TAG_member, no_children * *
    • Dw_AT_name : ................... DW_FORM_strp * *
    • Dw_AT_type : ................... DW_FORM_ref_addr * *
    • Dw_AT_accessibility : .......... DW_FORM_data1 * *
    * * The union member name is constructed by appending an '_' to the Java* name of the implementing * class. So, this means that, for example, the Java interface java.lang.CharSequence will include * members for String, StringBuffer etc as follows * *
     *   union java.lang.CharSequence {
     *     java.lang.String _java.lang.String;
     *     java.lang.StringBuffer _java.lang.StringBuffer;
     *     ...
     *   };
     * 
    * */ public class DwarfAbbrevSectionImpl extends DwarfSectionImpl { public DwarfAbbrevSectionImpl(DwarfDebugInfo dwarfSections) { // abbrev section depends on ranges section super(dwarfSections, DwarfSectionName.DW_ABBREV_SECTION, DwarfSectionName.DW_RANGES_SECTION); } @Override public void createContent() { assert !contentByteArrayCreated(); /* */ int pos = 0; pos = writeAbbrevs(null, null, pos); byte[] buffer = new byte[pos]; super.setContent(buffer); } @Override public void writeContent(DebugContext context) { assert contentByteArrayCreated(); byte[] buffer = getContent(); int size = buffer.length; int pos = 0; enableLog(context, pos); pos = writeAbbrevs(context, buffer, pos); assert pos == size; } public int writeAbbrevs(DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeCompileUnitAbbrevs(context, buffer, pos); pos = writePrimitiveTypeAbbrev(context, buffer, pos); pos = writeVoidTypeAbbrev(context, buffer, pos); pos = writeObjectHeaderAbbrev(context, buffer, pos); pos = writeNamespaceAbbrev(context, buffer, pos); pos = writeClassLayoutAbbrevs(context, buffer, pos); pos = writeClassReferenceAbbrev(context, buffer, pos); pos = writeMethodDeclarationAbbrevs(context, buffer, pos); pos = writeFieldDeclarationAbbrevs(context, buffer, pos); pos = writeClassConstantAbbrev(context, buffer, pos); pos = writeArrayLayoutAbbrev(context, buffer, pos); pos = writeArrayReferenceAbbrev(context, buffer, pos); pos = writeInterfaceLayoutAbbrev(context, buffer, pos); pos = writeInterfaceReferenceAbbrev(context, buffer, pos); pos = writeForeignReferenceAbbrev(context, buffer, pos); pos = writeForeignTypedefAbbrev(context, buffer, pos); pos = writeForeignStructAbbrev(context, buffer, pos); pos = writeHeaderFieldAbbrev(context, buffer, pos); pos = writeArrayDataTypeAbbrevs(context, buffer, pos); pos = writeArraySubrangeTypeAbbrev(context, buffer, pos); pos = writeMethodLocationAbbrev(context, buffer, pos); pos = writeAbstractInlineMethodAbbrev(context, buffer, pos); pos = writeStaticFieldLocationAbbrev(context, buffer, pos); pos = writeSuperReferenceAbbrev(context, buffer, pos); pos = writeInterfaceImplementorAbbrev(context, buffer, pos); pos = writeInlinedSubroutineAbbrev(buffer, pos, false); pos = writeInlinedSubroutineAbbrev(buffer, pos, true); /* * if we address rebasing is required then then we need to use indirect layout types * supplied with a suitable data_location attribute and indirect pointer types to ensure * that gdb converts offsets embedded in static or instance fields to raw pointers. * Transformed addresses are typed using pointers to the underlying layout. * * if address rebasing is not required then we a data_location attribute on the layout type * will ensure that address tag bits are removed. */ if (dwarfSections.useHeapBase()) { pos = writeIndirectLayoutAbbrev(context, buffer, pos); pos = writeIndirectReferenceAbbrev(context, buffer, pos); } pos = writeParameterDeclarationAbbrevs(context, buffer, pos); pos = writeLocalDeclarationAbbrevs(context, buffer, pos); pos = writeParameterLocationAbbrevs(context, buffer, pos); pos = writeLocalLocationAbbrevs(context, buffer, pos); /* write a null abbrev to terminate the sequence */ pos = writeNullAbbrev(context, buffer, pos); return pos; } private int writeAttrType(DwarfAttribute attribute, byte[] buffer, int pos) { return writeULEB(attribute.value(), buffer, pos); } private int writeAttrForm(DwarfForm dwarfForm, byte[] buffer, int pos) { return writeULEB(dwarfForm.value(), buffer, pos); } private int writeHasChildren(DwarfHasChildren hasChildren, byte[] buffer, int pos) { return writeByte(hasChildren.value(), buffer, pos); } private int writeCompileUnitAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeCompileUnitAbbrev(context, AbbrevCode.BUILTIN_UNIT, buffer, pos); pos = writeCompileUnitAbbrev(context, AbbrevCode.CLASS_UNIT_1, buffer, pos); pos = writeCompileUnitAbbrev(context, AbbrevCode.CLASS_UNIT_2, buffer, pos); return pos; } private int writeCompileUnitAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_compile_unit, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_language, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_use_UTF8, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_comp_dir, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); if (abbrevCode == AbbrevCode.CLASS_UNIT_2) { pos = writeAttrType(DwarfAttribute.DW_AT_ranges, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_sec_offset, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_low_pc, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_stmt_list, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_sec_offset, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writePrimitiveTypeAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.PRIMITIVE_TYPE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_base_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_bit_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_encoding, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeVoidTypeAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.VOID_TYPE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_unspecified_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeObjectHeaderAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.OBJECT_HEADER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_structure_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeNamespaceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.NAMESPACE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_namespace, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeClassLayoutAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_1, buffer, pos); if (!dwarfSections.useHeapBase()) { pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_2, buffer, pos); } return pos; } private int writeClassLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_class_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); /*- * At present we definitely don't have a line number for the class itself. pos = writeAttrType(DwarfDebugInfo.DW_AT_decl_line, buffer, pos); pos = writeAttrForm(DwarfDebugInfo.DW_FORM_data2, buffer, pos); */ if (abbrevCode == AbbrevCode.CLASS_LAYOUT_2) { pos = writeAttrType(DwarfAttribute.DW_AT_data_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeClassReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* A pointer to the class struct type. */ pos = writeAbbrevCode(AbbrevCode.CLASS_POINTER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeMethodDeclarationAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeMethodDeclarationAbbrev(context, AbbrevCode.METHOD_DECLARATION, buffer, pos); pos = writeMethodDeclarationAbbrev(context, AbbrevCode.METHOD_DECLARATION_STATIC, buffer, pos); return pos; } private int writeMethodDeclarationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_subprogram, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_external, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_decl_line, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_linkage_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_artificial, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); /* This is not in DWARF2 */ // pos = writeAttrType(DW_AT_virtuality, buffer, pos); // pos = writeAttrForm(DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_containing_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_DECLARATION) { pos = writeAttrType(DwarfAttribute.DW_AT_object_pointer, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeFieldDeclarationAbbrevs(DebugContext context, byte[] buffer, int p) { int pos = p; /* An instance field no line and file. */ pos = writeFieldDeclarationAbbrev(context, AbbrevCode.FIELD_DECLARATION_1, buffer, pos); /* An instance field with line and file. */ pos = writeFieldDeclarationAbbrev(context, AbbrevCode.FIELD_DECLARATION_2, buffer, pos); /* A static field no line and file. */ pos = writeFieldDeclarationAbbrev(context, AbbrevCode.FIELD_DECLARATION_3, buffer, pos); /* A static field with line and file. */ pos = writeFieldDeclarationAbbrev(context, AbbrevCode.FIELD_DECLARATION_4, buffer, pos); return pos; } private int writeFieldDeclarationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_member, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* We may not have a file and line for a field. */ if (abbrevCode == AbbrevCode.FIELD_DECLARATION_2 || abbrevCode == AbbrevCode.FIELD_DECLARATION_4) { pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); /* At present we definitely don't have line numbers. */ // pos = writeAttrType(DwarfDebugInfo.DW_AT_decl_line, buffer, pos); // pos = writeAttrForm(DwarfDebugInfo.DW_FORM_data2, buffer, pos); } pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); if (abbrevCode == AbbrevCode.FIELD_DECLARATION_1 || abbrevCode == AbbrevCode.FIELD_DECLARATION_2) { /* Instance fields have a member offset relocated relative to the heap base register. */ pos = writeAttrType(DwarfAttribute.DW_AT_data_member_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); } pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* Static fields are only declared here and are external. */ if (abbrevCode == AbbrevCode.FIELD_DECLARATION_3 || abbrevCode == AbbrevCode.FIELD_DECLARATION_4) { pos = writeAttrType(DwarfAttribute.DW_AT_external, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeClassConstantAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.CLASS_CONSTANT, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_constant, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* We may not have a file and line for a field. */ pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_external, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeArrayLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.ARRAY_LAYOUT, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_class_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeArrayReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.ARRAY_POINTER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeInterfaceLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.INTERFACE_LAYOUT, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_union_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeInterfaceReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.INTERFACE_POINTER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeInterfaceImplementorAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.INTERFACE_IMPLEMENTOR, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_member, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeForeignReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* A pointer to the class struct type. */ pos = writeAbbrevCode(AbbrevCode.FOREIGN_POINTER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); // n.b we use a (relocatable) ref_addr here rather than a (CU-relative) ref4 // because an unknown foreign pointer type will reference void which is not // local to the current CU. pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeForeignTypedefAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* A pointer to the class struct type. */ pos = writeAbbrevCode(AbbrevCode.FOREIGN_TYPEDEF, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_typedef, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeForeignStructAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* A pointer to the class struct type. */ pos = writeAbbrevCode(AbbrevCode.FOREIGN_STRUCT, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_structure_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeHeaderFieldAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.HEADER_FIELD, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_member, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_data_member_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeArrayDataTypeAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeArrayDataTypeAbbrev(context, AbbrevCode.ARRAY_DATA_TYPE_1, buffer, pos); pos = writeArrayDataTypeAbbrev(context, AbbrevCode.ARRAY_DATA_TYPE_2, buffer, pos); return pos; } private int writeArrayDataTypeAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_array_type, buffer, pos); boolean hasChildren = (abbrevCode == AbbrevCode.ARRAY_DATA_TYPE_2); pos = writeHasChildren((hasChildren ? DwarfHasChildren.DW_CHILDREN_yes : DwarfHasChildren.DW_CHILDREN_no), buffer, pos); if (abbrevCode == AbbrevCode.ARRAY_DATA_TYPE_2) { pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data4, buffer, pos); } // n.b we use a (relocatable) ref_addr here rather than a (CU-relative) ref4 // because a foreign array type can reference another foreign type which is // not in the current CU. pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeArraySubrangeTypeAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.ARRAY_SUBRANGE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_subrange_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_count, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeMethodLocationAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.METHOD_LOCATION, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_subprogram, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_low_pc, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_hi_pc, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_external, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_specification, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeAbstractInlineMethodAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.ABSTRACT_INLINE_METHOD, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_subprogram, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_inline, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_external, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_specification, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeStaticFieldLocationAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.STATIC_FIELD_LOCATION, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_variable, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_specification, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); // pos = writeAttrType(DwarfDebugInfo.DW_AT_linkage_name, buffer, pos); // pos = writeAttrForm(DwarfDebugInfo.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeSuperReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.SUPER_REFERENCE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_inheritance, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_data_member_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeIndirectLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* * oops are not necessarily raw addresses. they may contains pointer bits or be offsets from * a base register. An indirect layout wraps a standard layout adding a data_location that * translates indirect an oop to a raw address. It is used as the base for an indirect * pointer type that is used to type values that need translation to a raw address i.e. * values stored in static and instance fields. */ /* the type for an indirect layout that includes address translation info */ pos = writeAbbrevCode(AbbrevCode.INDIRECT_LAYOUT, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_class_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); /* Add a data location expression to rebase oop pointers stored as offsets. */ pos = writeAttrType(DwarfAttribute.DW_AT_data_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeIndirectReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; /* The type for a pointer to the indirect layout type. */ pos = writeAbbrevCode(AbbrevCode.INDIRECT_POINTER, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeParameterDeclarationAbbrevs(DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeParameterDeclarationAbbrev(context, AbbrevCode.METHOD_PARAMETER_DECLARATION_1, buffer, pos); pos = writeParameterDeclarationAbbrev(context, AbbrevCode.METHOD_PARAMETER_DECLARATION_2, buffer, pos); pos = writeParameterDeclarationAbbrev(context, AbbrevCode.METHOD_PARAMETER_DECLARATION_3, buffer, pos); return pos; } private int writeParameterDeclarationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_formal_parameter, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_PARAMETER_DECLARATION_2) { /* Line numbers for parameter declarations are not (yet?) available. */ pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_decl_line, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); } pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_PARAMETER_DECLARATION_1) { /* Only this parameter is artificial and it has no line. */ pos = writeAttrType(DwarfAttribute.DW_AT_artificial, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); } pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeLocalDeclarationAbbrevs(DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeLocalDeclarationAbbrev(context, AbbrevCode.METHOD_LOCAL_DECLARATION_1, buffer, pos); pos = writeLocalDeclarationAbbrev(context, AbbrevCode.METHOD_LOCAL_DECLARATION_2, buffer, pos); return pos; } private int writeLocalDeclarationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_variable, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_LOCAL_DECLARATION_1) { /* Line numbers for parameter declarations are not (yet?) available. */ pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_decl_line, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos); } pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos); /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeParameterLocationAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeParameterLocationAbbrev(context, AbbrevCode.METHOD_PARAMETER_LOCATION_1, buffer, pos); pos = writeParameterLocationAbbrev(context, AbbrevCode.METHOD_PARAMETER_LOCATION_2, buffer, pos); return pos; } private int writeLocalLocationAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeLocalLocationAbbrev(context, AbbrevCode.METHOD_LOCAL_LOCATION_1, buffer, pos); pos = writeLocalLocationAbbrev(context, AbbrevCode.METHOD_LOCAL_LOCATION_2, buffer, pos); return pos; } private int writeParameterLocationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_formal_parameter, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_abstract_origin, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_PARAMETER_LOCATION_2) { pos = writeAttrType(DwarfAttribute.DW_AT_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_sec_offset, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeLocalLocationAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(abbrevCode, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_variable, buffer, pos); pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_abstract_origin, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); if (abbrevCode == AbbrevCode.METHOD_LOCAL_LOCATION_2) { pos = writeAttrType(DwarfAttribute.DW_AT_location, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_sec_offset, buffer, pos); } /* * Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } private int writeNullAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) { int pos = p; pos = writeAbbrevCode(AbbrevCode.NULL, buffer, pos); return pos; } private int writeInlinedSubroutineAbbrev(byte[] buffer, int p, boolean withChildren) { int pos = p; pos = writeAbbrevCode(withChildren ? AbbrevCode.INLINED_SUBROUTINE_WITH_CHILDREN : AbbrevCode.INLINED_SUBROUTINE, buffer, pos); pos = writeTag(DwarfTag.DW_TAG_inlined_subroutine, buffer, pos); pos = writeHasChildren(withChildren ? DwarfHasChildren.DW_CHILDREN_yes : DwarfHasChildren.DW_CHILDREN_no, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_abstract_origin, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_ref4, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_low_pc, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_hi_pc, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_addr, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_call_file, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data4, buffer, pos); pos = writeAttrType(DwarfAttribute.DW_AT_call_line, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_data4, buffer, pos); /* Now terminate. */ pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos); pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos); return pos; } }