diff --git a/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md b/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md index 53ce8cb8b3a952..36b57a22980da3 100644 --- a/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md +++ b/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md @@ -1,33 +1,88 @@ # Allow Location Descriptions on the DWARF Expression Stack -- [Extension](#extension) -- [Heterogeneous Computing Devices](#heterogeneous-computing-devices) -- [DWARF 5](#dwarf-5) - - [How DWARF Maps Source Language To Hardware](#how-dwarf-maps-source-language-to-hardware) - - [Examples](#examples) - - [Dynamic Array Size](#dynamic-array-size) - - [Variable Location in Register](#variable-location-in-register) - - [Variable Location in Memory](#variable-location-in-memory) - - [Variable Spread Across Different Locations](#variable-spread-across-different-locations) - - [Offsetting a Composite Location](#offsetting-a-composite-location) - - [Limitations](#limitations) -- [Extension Solution](#extension-solution) - - [Location Description](#location-description) - - [Stack Location Description Operations](#stack-location-description-operations) - - [Examples](#examples-1) - - [Source Language Variable Spilled to Part of a Vector Register](#source-language-variable-spilled-to-part-of-a-vector-register) - - [Source Language Variable Spread Across Multiple Vector Registers](#source-language-variable-spread-across-multiple-vector-registers) - - [Source Language Variable Spread Across Multiple Kinds of Locations](#source-language-variable-spread-across-multiple-kinds-of-locations) - - [Address Spaces](#address-spaces) - - [Bit Offsets](#bit-offsets) - - [Call Frame Information (CFI)](#call-frame-information-cfi) - - [Objects Not In Byte Aligned Global Memory](#objects-not-in-byte-aligned-global-memory) - - [Higher Order Operations](#higher-order-operations) - - [Objects In Multiple Places](#objects-in-multiple-places) -- [Conclusion](#conclusion) -- [Further Information](#further-information) - -# Extension +- [1. Extension](#extension) +- [2. Heterogeneous Computing Devices](#heterogeneous-computing-devices) +- [3. DWARF 5](#dwarf-5) + - [3.1 How DWARF Maps Source Language To Hardware](#how-dwarf-maps-source-language-to-hardware) + - [3.2 Examples](#examples) + - [3.2.1 Dynamic Array Size](#dynamic-array-size) + - [3.2.2 Variable Location in Register](#variable-location-in-register) + - [3.2.3 Variable Location in Memory](#variable-location-in-memory) + - [3.2.4 Variable Spread Across Different Locations](#variable-spread-across-different-locations) + - [3.2.5 Offsetting a Composite Location](#offsetting-a-composite-location) + - [3.3 Limitations](#limitations) +- [4. Extension Solution](#extension-solution) + - [4.1 Location Description](#location-description) + - [4.2 Stack Location Description Operations](#stack-location-description-operations) + - [4.3 Examples](#examples-1) + - [4.3.1 Source Language Variable Spilled to Part of a Vector Register](#source-language-variable-spilled-to-part-of-a-vector-register) + - [4.3.2 Source Language Variable Spread Across Multiple Vector Registers](#source-language-variable-spread-across-multiple-vector-registers) + - [4.3.3 Source Language Variable Spread Across Multiple Kinds of Locations](#source-language-variable-spread-across-multiple-kinds-of-locations) + - [4.3.4 Address Spaces](#address-spaces) + - [4.3.5 Bit Offsets](#bit-offsets) + - [4.4 Call Frame Information (CFI)](#call-frame-information-cfi) + - [4.5 Objects Not In Byte Aligned Global Memory](#objects-not-in-byte-aligned-global-memory) + - [4.6 Higher Order Operations](#higher-order-operations) + - [4.7 Objects In Multiple Places](#objects-in-multiple-places) +- [5. Conclusion](#conclusion) +- [A. Changes to DWARF Debugging Information Format Version 5](#a-changes-to-dwarf-debugging-information-format-version-5) + - [A.2 General Description](#a-2-general-description) + - [A.2.5 DWARF Expressions](#a-2-5-dwarf-expressions) + - [A.2.5.1 DWARF Expression Evaluation Context](#a-2-5-1-dwarf-expression-evaluation-context) + - [A.2.5.2 DWARF Expression Value](#a-2-5-2-dwarf-expression-value) + - [A.2.5.3 DWARF Location Description](#a-2-5-3-dwarf-location-description) + - [A.2.5.4 DWARF Operation Expressions](#a-2-5-4-dwarf-operation-expressions) + - [A.2.5.4.1 Stack Operations](#a-2-5-4-1-stack-operations) + - [A.2.5.4.2 Control Flow Operations](#a-2-5-4-2-control-flow-operations) + - [A.2.5.4.3 Value Operations](#a-2-5-4-3-value-operations) + - [A.2.5.4.3.1 Literal Operations](#a-2-5-4-3-1-literal-operations) + - [A.2.5.4.3.2 Arithmetic and Logical Operations](#a-2-5-4-3-2-arithmetic-and-logical-operations) + - [A.2.5.4.3.3 Type Conversion Operations](#a-2-5-4-3-3-type-conversion-operations) + - [A.2.5.4.3.4 Special Value Operations](#a-2-5-4-3-4-special-value-operations) + - [A.2.5.4.4 Location Description Operations](#a-2-5-4-4-location-description-operations) + - [A.2.5.4.4.1 General Location Description Operations](#a-2-5-4-4-1-general-location-description-operations) + - [A.2.5.4.4.2 Undefined Location Description Operations](#a-2-5-4-4-2-undefined-location-description-operations) + - [A.2.5.4.4.3 Memory Location Description Operations](#a-2-5-4-4-3-memory-location-description-operations) + - [A.2.5.4.4.4 Register Location Description Operations](#a-2-5-4-4-4-register-location-description-operations) + - [A.2.5.4.4.5 Implicit Location Description Operations](#a-2-5-4-4-5-implicit-location-description-operations) + - [A.2.5.4.4.6 Composite Location Description Operations](#a-2-5-4-4-6-composite-location-description-operations) + - [A.2.5.5 DWARF Location List Expressions](#a-2-5-5-dwarf-location-list-expressions) + - [A.3 Program Scope Entries](#a-3-program-scope-entries) + - [A.3.3 Subroutine and Entry Point Entries](#a-3-3-subroutine-and-entry-point-entries) + - [A.3.3.5 Low-Level Information](#a-3-3-5-low-level-information) + - [A.3.4 Call Site Entries and Parameters](#a-3-4-call-site-entries-and-parameters) + - [A.3.4.2 Call Site Parameters](#a-3-4-2-call-site-parameters) + - [A.3.5 Lexical Block Entries](#a-3-5-lexical-block-entries) + - [A.4 Data Object and Object List Entries](#a-4-data-object-and-object-list-entries) + - [A.4.1 Data Object Entries](#a-4-1-data-object-entries) + - [A.5 Type Entries](#a-5-type-entries) + - [A.5.7 Structure, Union, Class and Interface Type Entries](#a-5-7-structure-union-class-and-interface-type-entries) + - [A.5.7.3 Derived or Extended Structures, Classes and Interfaces](#a-5-7-3-derived-or-extended-structures-classes-and-interfaces) + - [A.5.7.8 Member Function Entries](#a-5-7-8-member-function-entries) + - [A.5.14 Pointer to Member Type Entries](#a-5-14-pointer-to-member-type-entries) + - [A.5.16 Dynamic Type Entries](#a-5-16-dynamic-type-entries) + - [A.6 Other Debugging Information](#a-6-other-debugging-information) + - [A.6.2 Line Number Information](#a-6-2-line-number-information) + - [A.6.4 Call Frame Information](#a-6-4-call-frame-information) + - [A.6.4.1 Structure of Call Frame Information](#a-6-4-1-structure-of-call-frame-information) + - [A.6.4.2 Call Frame Instructions](#a-6-4-2-call-frame-instructions) + - [A.6.4.2.1 Row Creation Instructions](#a-6-4-2-1-row-creation-instructions) + - [A.6.4.2.2 CFA Definition Instructions](#a-6-4-2-2-cfa-definition-instructions) + - [A.6.4.2.3 Register Rule Instructions](#a-6-4-2-3-register-rule-instructions) + - [A.6.4.2.4 Row State Instructions](#a-6-4-2-4-row-state-instructions) + - [A.6.4.2.5 Padding Instruction](#a-6-4-2-5-padding-instruction) + - [A.6.4.3 Call Frame Instruction Usage](#a-6-4-3-call-frame-instruction-usage) + - [A.6.4.4 Call Frame Calling Address](#a-6-4-4-call-frame-calling-address) + - [A.7 Data Representation](#a-7-data-representation) + - [A.7.4 32-Bit and 64-Bit DWARF Formats](#a-7-4-32-bit-and-64-bit-dwarf-formats) + - [A.7.5 Format of Debugging Information](#a-7-5-format-of-debugging-information) + - [A.7.5.5 Classes and Forms](#a-7-5-5-classes-and-forms) + - [A.7.7 DWARF Expressions](#a-7-7-dwarf-expressions) + - [A.7.7.1 Operation Expressions](#a-7-7-1-operation-expressions) + - [A.7.7.3 Location List Expressions](#a-7-7-3-location-list-expressions) +- [B. Further Information](#b-further-information) + +# 1. Extension In DWARF 5, expressions are evaluated using a typed value stack, a separate location area, and an independent loclist mechanism. This extension unifies all @@ -54,15 +109,22 @@ specialized context sensitive operations are harder for both produces and consumers than a smaller number of general composable operations that have consistent semantics regardless of context. -The following sections first describe heterogeneous devices and the features -they have that are not addressed by DWARF 5. Then a brief simplified overview of -the DWARF 5 expression evaluation model is presented that highlights the -difficulties for supporting the heterogeneous features. Finally, an overview of -the extension is presented, using simplified examples to illustrate how it can -address the issues of heterogeneous devices and also benefit non-heterogeneous -devices. References to further information are provided. - -# Heterogeneous Computing Devices +First, section [2. Heterogeneous Computing +Devices](#heterogeneous-computing-devices) describes heterogeneous devices and +the features they have that are not addressed by DWARF 5. Then section [3. DWARF +5](#dwarf-5) presents a brief simplified overview of the DWARF 5 expression +evaluation model that highlights the difficulties for supporting the +heterogeneous features. Next, section [4. Extension +Solution](#extension-solution) provides an overview of the proposal, using +simplified examples to illustrate how it can address the issues of heterogeneous +devices and also benefit non-heterogeneous devices. Then overall conclusions are +covered in section [5. Conclusion](#conclusion). Appendix [A. Changes to DWARF +Debugging Information Format Version +5](#a-changes-to-dwarf-debugging-information-format-version-5) gives changes +relative to the DWARF Version 5 standard. Finally, appendix [B. Further +Information](#b-further-information) has references to further information. + +# 2. Heterogeneous Computing Devices GPUs and other heterogeneous computing devices have features not common to CPU computing devices. @@ -101,13 +163,13 @@ of runtime defined pieces of vector registers. With the more complex locations, there is a benefit to be able to factorize their calculation which requires all location kinds to be supported uniformly, otherwise duplication is necessary. -# DWARF 5 +# 3. DWARF 5 Before presenting the proposed solution to supporting heterogeneous devices, a brief overview of the DWARF 5 expression evaluation model will be given to highlight the aspects being addressed by the extension. -## How DWARF Maps Source Language To Hardware +## 3.1 How DWARF Maps Source Language To Hardware DWARF is a standardized way to specify debug information. It describes source language entities such as compilation units, functions, types, variables, etc. @@ -158,13 +220,13 @@ may include: value or with the location of a base object that is available using the DW_OP_push_object_address operation. -## Examples +## 3.2 Examples The following examples illustrate how DWARF expressions involving operations are evaluated in DWARF 5. DWARF also has expressions involving location lists that are not covered in these examples. -### Dynamic Array Size +### 3.2.1 Dynamic Array Size The first example is for an operation expression associated with a DIE attribute that provides the number of elements in a dynamic array type. Such an attribute @@ -211,7 +273,7 @@ The evaluation stops when it reaches the end of the expression. The result of an expression that is evaluated with a value result kind context is the top element of the stack, which provides the value and its type. -### Variable Location in Register +### 3.2.2 Variable Location in Register This example is for an operation expression associated with a DIE attribute that provides the location of a source language variable. Such an attribute dictates @@ -244,7 +306,7 @@ Again, evaluation stops when it reaches the end of the expression. The result of an expression that is evaluated with a location result kind context is the location description in the location area. -### Variable Location in Memory +### 3.2.3 Variable Location in Memory The next example is for an operation expression associated with a DIE attribute that provides the location of a source language variable that is allocated in a @@ -285,7 +347,7 @@ location area. ![Variable Location in Memory Example: Step 4](images/03-memory.example.frame.4.png) -### Variable Spread Across Different Locations +### 3.2.4 Variable Spread Across Different Locations This example is for a source variable that is partly in a register, partly undefined, and partly in memory. @@ -349,11 +411,12 @@ of the expression is the location description in the location area. ![Variable Spread Across Different Locations Example: Step 7](images/04-composite.example.frame.7.png) -### Offsetting a Composite Location +### 3.2.5 Offsetting a Composite Location This example attempts to extend the previous example to offset the composite -location description it created. The *Variable Location in Memory* example -conveniently used the DW_OP_plus operation to offset a memory address. +location description it created. The [3.2.3 Variable Location in +Memory](#variable-location-in-memory) example conveniently used the DW_OP_plus +operation to offset a memory address. DW_OP_regx SGPR3 DW_OP_piece 4 @@ -380,7 +443,7 @@ the offset. For example: This illustrates that operations on stack values are not composable with operations on location descriptions. -## Limitations +## 3.3 Limitations DWARF 5 is unable to describe variables in runtime indexed parts of registers. This is required to describe a source variable that is located in a lane of a @@ -406,7 +469,7 @@ Bit field offsets are only supported in a limited way for register locations. Supporting them in a uniform manner for all location kinds is required to support languages with bit sized entities. -# Extension Solution +# 4. Extension Solution This section outlines the extension to generalize the DWARF expression evaluation model to allow location descriptions to be manipulated on the stack. It presents @@ -414,7 +477,7 @@ a number of simplified examples to demonstrate the benefits and how the extensio solves the issues of heterogeneous devices. It presents how this is done in a manner that is backwards compatible with DWARF 5. -## Location Description +## 4.1 Location Description In order to have consistent, composable operations that act on location descriptions, the extension defines a uniform way to handle all location kinds. @@ -437,7 +500,7 @@ storage). undefined. - For composite, it is a linear stream of bytes defined by the composite's parts. -## Stack Location Description Operations +## 4.2 Stack Location Description Operations The DWARF expression stack is extended to allow each stack entry to either be a value or a location description. @@ -475,12 +538,12 @@ A DW_OP_undefined operation can be defined that explicitly creates the undefined location description. Currently this is only possible as a piece of a composite when the stack is empty. -## Examples +## 4.3 Examples This section provides some motivating examples to illustrate the benefits that result from allowing location descriptions on the stack. -### Source Language Variable Spilled to Part of a Vector Register +### 4.3.1 Source Language Variable Spilled to Part of a Vector Register A compiler generating code for a GPU may allocate a source language variable that it proves has the same value for every lane of a SIMT thread in a scalar @@ -522,7 +585,7 @@ GPUs due to the sheer number of registers that would have to be defined. It would also not permit a runtime index into part of the whole register to be used as shown in the next example. -### Source Language Variable Spread Across Multiple Vector Registers +### 4.3.2 Source Language Variable Spread Across Multiple Vector Registers A compiler may generate SIMT code for a GPU. Each source language thread of execution is mapped to a single lane of the GPU thread. Source language @@ -623,7 +686,7 @@ description and returned as the result. ![Source Language Variable Spread Across Multiple Vector Registers Example: Step 14](images/07-extension-multi-lane-vgpr.example.frame.14.png) -### Source Language Variable Spread Across Multiple Kinds of Locations +### 4.3.3 Source Language Variable Spread Across Multiple Kinds of Locations This example is the same as the previous one, except the first 2 bytes of the second vector register have been spilled to memory, and the last 2 bytes have @@ -683,7 +746,7 @@ beneficial to factor the incrementally creation of location descriptions. ![Source Language Variable Spread Across Multiple Kinds of Locations Example: Step 12](images/08-extension-mixed-composite.example.frame.7.png) -### Address Spaces +### 4.3.4 Address Spaces Heterogeneous devices can have multiple hardware supported address spaces which use specific hardware instructions to access them. @@ -752,7 +815,7 @@ address spaces. For example, this can happen when parts of a source variable allocated in a register are spilled to a stack frame that resides in the non-global address space. -### Bit Offsets +### 4.3.5 Bit Offsets With the generalization of location descriptions on the stack, it is possible to define a DW_OP_bit_offset operation that adjusts the offset of any kind of @@ -792,7 +855,7 @@ The ordering of bits within a byte, like byte ordering, is defined by the target architecture. A base type could be extended to specify bit ordering in addition to byte ordering. -## Call Frame Information (CFI) +## 4.4 Call Frame Information (CFI) DWARF defines call frame information (CFI) that can be used to virtually unwind the subprogram call stack. This involves determining the location where register @@ -804,7 +867,7 @@ spaces, or even a composite of different location kinds. Therefore, the extension extends the CFI rules to support any kind of location description, and operations to create locations in address spaces. -## Objects Not In Byte Aligned Global Memory +## 4.5 Objects Not In Byte Aligned Global Memory DWARF 5 only effectively supports byte aligned memory locations on the stack by using a global memory address as a proxy for a memory location description. This @@ -842,7 +905,7 @@ expressions that support all of these. Full general support for bit fields and implicit locations benefits optimizations on any target. -## Higher Order Operations +## 4.6 Higher Order Operations The generalization allows an elegant way to add higher order operations that create location descriptions out of other location descriptions in a general @@ -876,7 +939,7 @@ to efficiently express a source language array that has had a set of elements promoted into a vector register when executing a set of iterations of a loop in a SIMD manner. -## Objects In Multiple Places +## 4.7 Objects In Multiple Places A compiler may allocate a source variable in stack frame memory, but for some range of code may promote it to a register. If the generated code does not @@ -922,7 +985,7 @@ evaluation of a DWARF expression results in multiple single location descriptions, the consumer can ensure any updates are done to all of them, and any reads can use any one of them. -# Conclusion +# 5. Conclusion A strength of DWARF is that it has generally sought to provide generalized composable solutions that address many problems, rather than solutions that only @@ -932,17 +995,2705 @@ significant family of issues. It addresses the specific issues present for heterogeneous computing devices, provides benefits for non-heterogeneous devices, and can help address a number of other previously reported issues. -# Further Information +# A. Changes to DWARF Debugging Information Format Version 5 + +> NOTE: This appendix provides changes relative to DWARF Version 5. It has been +> defined such that it is backwards compatible with DWARF Version 5. +> Non-normative text is shown in italics. The section numbers generally +> correspond to those in the DWARF Version 5 standard unless specified +> otherwise. Definitions are given to clarify how existing expression +> operations, CFI operations, and attributes behave with respect to generalized +> location descriptions that support multiple places. +> +> > NOTE: Notes are included to describe how the changes are to be applied to +> > the DWARF Version 5 standard. They also describe rational and issues that +> > may need further consideration. + +## A.2 General Description + +### A.2.5 DWARF Expressions + +> NOTE: This section, and its nested sections, replaces DWARF Version 5 section +> 2.5 and section 2.6. It is based on the text of the existing DWARF Version 5 +> standard. + +DWARF expressions describe how to compute a value or specify a location. + +The evaluation of a DWARF expression can provide the location of an object, +the value of an array bound, the length of a dynamic string, the desired value +itself, and so on. + +If the evaluation of a DWARF expression does not encounter an error, then it can +either result in a value (see [2.5.2 DWARF Expression +Value](#dwarf-expression-value)) or a location description (see [2.5.3 DWARF +Location Description](#dwarf-location-description)). When a DWARF expression +is evaluated, it may be specified whether a value or location description is +required as the result kind. + +If a result kind is specified, and the result of the evaluation does not match +the specified result kind, then the implicit conversions described in [2.5.4.4.3 +Memory Location Description +Operations](#memory-location-description-operations) are performed if +valid. Otherwise, the DWARF expression is ill-formed. + +If the evaluation of a DWARF expression encounters an evaluation error, then the +result is an evaluation error. + +> NOTE: Decided to define the concept of an evaluation error. An alternative is +> to introduce an undefined value base type in a similar way to location +> descriptions having an undefined location description. Then operations that +> encounter an evaluation error can return the undefined location description or +> value with an undefined base type. +> +> All operations that act on values would return an undefined entity if given an +> undefined value. The expression would then always evaluate to completion, and +> can be tested to determine if it is an undefined entity. +> +> However, this would add considerable additional complexity and does not match +> that GDB throws an exception when these evaluation errors occur. + +If a DWARF expression is ill-formed, then the result is undefined. + +The following sections detail the rules for when a DWARF expression is +ill-formed or results in an evaluation error. + +A DWARF expression can either be encoded as an operation expression (see [2.5.4 +DWARF Operation Expressions](#dwarf-operation-expressions)), or as a +location list expression (see [2.5.5 DWARF Location List +Expressions](#dwarf-location-list-expressions)). + +#### A.2.5.1 DWARF Expression Evaluation Context + +A DWARF expression is evaluated in a context that can include a number of +context elements. If multiple context elements are specified then they must be +self consistent or the result of the evaluation is undefined. The context +elements that can be specified are: + +1. A current result kind + + The kind of result required by the DWARF expression evaluation. If specified + it can be a location description or a value. + +2. A current thread + + The target architecture thread identifier of the source program thread of + execution for which a user presented expression is currently being + evaluated. + + It is required for operations that are related to target architecture + threads. + + For example, the `DW_OP_regval_type` operation. + +3. A current call frame + + The target architecture call frame identifier. It identifies a call frame + that corresponds to an active invocation of a subprogram in the current + thread. It is identified by its address on the call stack. The address is + referred to as the Canonical Frame Address (CFA). The call frame information + is used to determine the CFA for the call frames of the current thread's + call stack (see [6.4 Call Frame Information](#call-frame-information)). + + It is required for operations that specify target architecture registers to + support virtual unwinding of the call stack. + + For example, the `DW_OP_*reg*` operations. + + If specified, it must be an active call frame in the current thread. + Otherwise the result is undefined. + + If it is the currently executing call frame, then it is termed the top call + frame. + +4. A current program location + + The target architecture program location corresponding to the current call + frame of the current thread. + + The program location of the top call frame is the target architecture + program counter for the current thread. The call frame information is used + to obtain the value of the return address register to determine the program + location of the other call frames (see [6.4 Call Frame + Information](#call-frame-information)). + + It is required for the evaluation of location list expressions to select + amongst multiple program location ranges. It is required for operations that + specify target architecture registers to support virtual unwinding of the + call stack (see [6.4 Call Frame Information](#call-frame-information)). + + If specified: + + - If the current call frame is the top call frame, it must be the current + target architecture program location. + - If the current call frame F is not the top call frame, it must be the + program location associated with the call site in the current caller frame + F that invoked the callee frame. + - Otherwise the result is undefined. + +5. A current compilation unit + + The compilation unit debug information entry that contains the DWARF + expression being evaluated. + + It is required for operations that reference debug information associated + with the same compilation unit, including indicating if such references use + the 32-bit or 64-bit DWARF format. It can also provide the default address + space address size if no current target architecture is specified. + + For example, the `DW_OP_constx` and `DW_OP_addrx` operations. + + Note that this compilation unit may not be the same as the compilation + unit determined from the loaded code object corresponding to the current + program location. For example, the evaluation of the expression E associated + with a `DW_AT_location` attribute of the debug information entry operand of + the `DW_OP_call*` operations is evaluated with the compilation unit that + contains E and not the one that contains the `DW_OP_call*` operation + expression. + +6. A current target architecture + + The target architecture. + + It is required for operations that specify target architecture specific + entities. + + For example, target architecture specific entities include DWARF register + identifiers, DWARF address space identifiers, the default address space, and + the address space address sizes. + + If specified: + + - If the current thread is specified, then the current target architecture + must be the same as the target architecture of the current thread. + - If the current compilation unit is specified, then the current target + architecture default address space address size must be the same as the + `address_size` field in the header of the current compilation unit and any + associated entry in the `.debug_aranges` section. + - If the current program location is specified, then the current target + architecture must be the same as the target architecture of any line + number information entry (see [6.2 Line Number + Information](#line-number-information)) corresponding to the current + program location. + - If the current program location is specified, then the current target + architecture default address space address size must be the same as the + `address_size` field in the header of any entry corresponding to the + current program location in the `.debug_addr`, `.debug_line`, + `.debug_rnglists`, `.debug_rnglists.dwo`, `.debug_loclists`, and + `.debug_loclists.dwo` sections. + - Otherwise the result is undefined. + +7. A current object + + The location description of a program object. + + It is required for the `DW_OP_push_object_address` operation. + + For example, the `DW_AT_data_location` attribute on type debug + information entries specifies the program object corresponding to a runtime + descriptor as the current object when it evaluates its associated + expression. + + The result is undefined if the location descriptor is invalid (see [3.5.3 + DWARF Location Description](#dwarf-location-description)). + +8. An initial stack + + This is a list of values or location descriptions that will be pushed on the + operation expression evaluation stack in the order provided before + evaluation of an operation expression starts. + + Some debugger information entries have attributes that evaluate their DWARF + expression value with initial stack entries. In all other cases the initial + stack is empty. + + The result is undefined if any location descriptors are invalid (see [3.5.3 + DWARF Location Description](#dwarf-location-description)). + +If the evaluation requires a context element that is not specified, then the +result of the evaluation is an error. + +A DWARF expression for a location description may be able to be evaluated +without a thread, call frame, program location, or architecture context. For +example, the location of a global variable may be able to be evaluated without +such context. If the expression evaluates with an error then it may indicate the +variable has been optimized and so requires more context. + +The DWARF expression for call frame information (see [6.4 Call Frame +Information](#call-frame-information)) operations are restricted to those +that do not require the compilation unit context to be specified. + +The DWARF is ill-formed if all the `address_size` fields in the headers of all +the entries in the `.debug_info`, `.debug_addr`, `.debug_line`, +`.debug_rnglists`, `.debug_rnglists.dwo`, `.debug_loclists`, and +`.debug_loclists.dwo` sections corresponding to any given program location do +not match. + +#### A.2.5.2 DWARF Expression Value + +A value has a type and a literal value. It can represent a literal value of any +supported base type of the target architecture. The base type specifies the +size, encoding, and endianity of the literal value. + +> NOTE: It may be desirable to add an implicit pointer base type encoding. It +> would be used for the type of the value that is produced when the +> `DW_OP_deref*` operation retrieves the full contents of an implicit pointer +> location storage created by the `DW_OP_implicit_pointer` operation. The +> literal value would record the debugging information entry and byte +> displacement specified by the associated `DW_OP_implicit_pointer` operation. + +There is a distinguished base type termed the generic type, which is an integral +type that has the size of an address in the target architecture default address +space, a target architecture defined endianity, and unspecified signedness. + +The generic type is the same as the unspecified type used for stack +operations defined in DWARF Version 4 and before. + +An integral type is a base type that has an encoding of `DW_ATE_signed`, +`DW_ATE_signed_char`, `DW_ATE_unsigned`, `DW_ATE_unsigned_char`, +`DW_ATE_boolean`, or any target architecture defined integral encoding in the +inclusive range `DW_ATE_lo_user` to `DW_ATE_hi_user`. + +> NOTE: It is unclear if `DW_ATE_address` is an integral type. GDB does not seem +> to consider it as integral. + +#### A.2.5.3 DWARF Location Description + +Debugging information must provide consumers a way to find the location of +program variables, determine the bounds of dynamic arrays and strings, and +possibly to find the base address of a subprogram's call frame or the return +address of a subprogram. Furthermore, to meet the needs of recent computer +architectures and optimization techniques, debugging information must be able to +describe the location of an object whose location changes over the object's +lifetime, and may reside at multiple locations simultaneously during parts of an +object's lifetime. + +Information about the location of program objects is provided by location +descriptions. + +Location descriptions can consist of one or more single location descriptions. + +A single location description specifies the location storage that holds a +program object and a position within the location storage where the program +object starts. The position within the location storage is expressed as a bit +offset relative to the start of the location storage. + +A location storage is a linear stream of bits that can hold values. Each +location storage has a size in bits and can be accessed using a zero-based bit +offset. The ordering of bits within a location storage uses the bit numbering +and direction conventions that are appropriate to the current language on the +target architecture. + +There are five kinds of location storage: + +1. memory location storage + + Corresponds to the target architecture memory address spaces. + +2. register location storage + + Corresponds to the target architecture registers. + +3. implicit location storage + + Corresponds to fixed values that can only be read. + +4. undefined location storage + + Indicates no value is available and therefore cannot be read or written. + +5. composite location storage + + Allows a mixture of these where some bits come from one location storage and + some from another location storage, or from disjoint parts of the same + location storage. + +> NOTE: It may be better to add an implicit pointer location storage kind used +> by the `DW_OP_implicit_pointer` operation. It would specify the debugger +> information entry and byte offset provided by the operations. + +Location descriptions are a language independent representation of addressing +rules. + +- They can be the result of evaluating a debugger information entry attribute + that specifies an operation expression of arbitrary complexity. In this usage + they can describe the location of an object as long as its lifetime is either + static or the same as the lexical block (see [3.5 Lexical Block + Entries](#lexical-block-entries)) that owns it, and it does not move during + its lifetime. + +- They can be the result of evaluating a debugger information entry attribute + that specifies a location list expression. In this usage they can describe the + location of an object that has a limited lifetime, changes its location during + its lifetime, or has multiple locations over part or all of its lifetime. + +If a location description has more than one single location description, the +DWARF expression is ill-formed if the object value held in each single location +description's position within the associated location storage is not the same +value, except for the parts of the value that are uninitialized. + +A location description that has more than one single location description can +only be created by a location list expression that has overlapping program +location ranges, or certain expression operations that act on a location +description that has more than one single location description. There are no +operation expression operations that can directly create a location description +with more than one single location description. + +A location description with more than one single location description can be +used to describe objects that reside in more than one piece of storage at the +same time. An object may have more than one location as a result of +optimization. For example, a value that is only read may be promoted from memory +to a register for some region of code, but later code may revert to reading the +value from memory as the register may be used for other purposes. For the code +region where the value is in a register, any change to the object value must be +made in both the register and the memory so both regions of code will read the +updated value. + +A consumer of a location description with more than one single location +description can read the object's value from any of the single location +descriptions (since they all refer to location storage that has the same value), +but must write any changed value to all the single location descriptions. + +Updating a location description L by a bit offset B is defined as adding the +value of B to the bit offset of each single location description SL of L. It is +an evaluation error if the updated bit offset of any SL is less than 0 or +greater than or equal to the size of the location storage specified by SL. + +The evaluation of an expression may require context elements to create a +location description. If such a location description is accessed, the storage it +denotes is that associated with the context element values specified when the +location description was created, which may differ from the context at the time +it is accessed. + +For example, creating a register location description requires the thread +context: the location storage is for the specified register of that thread. +Creating a memory location description for an address space may required a +thread context: the location storage is the memory associated with that +thread. + +If any of the context elements required to create a location description change, +the location description becomes invalid and accessing it is undefined. + +Examples of context that can invalidate a location description are: + +- The thread context is required and execution causes the thread to + terminate. +- The call frame context is required and further execution causes the call + frame to return to the calling frame. +- The program location is required and further execution of the thread + occurs. That could change the location list entry or call frame information + entry that applies. +- An operation uses call frame information: + - Any of the frames used in the virtual call frame unwinding return. + - The top call frame is used, the program location is used to select the + call frame information entry, and further execution of the thread + occurs. + +A DWARF expression can be used to compute a location description for an +object. A subsequent DWARF expression evaluation can be given the object +location description as the object context or initial stack context to compute a +component of the object. The final result is undefined if the object location +description becomes invalid between the two expression evaluations. + +A change of a thread's program location may not make a location description +invalid, yet may still render it as no longer meaningful. Accessing such a +location description, or using it as the object context or initial stack context +of an expression evaluation, may produce an undefined result. + +For example, a location description may specify a register that no longer +holds the intended program object after a program location change. One way to +avoid such problems is to recompute location descriptions associated with +threads when their program locations change. + +#### A.2.5.4 DWARF Operation Expressions + +An operation expression is comprised of a stream of operations, each consisting +of an opcode followed by zero or more operands. The number of operands is +implied by the opcode. + +Operations represent a postfix operation on a simple stack machine. Each stack +entry can hold either a value or a location description. Operations can act on +entries on the stack, including adding entries and removing entries. If the kind +of a stack entry does not match the kind required by the operation and is not +implicitly convertible to the required kind (see [2.5.4.4.3 Memory Location +Description Operations](#memory-location-description-operations)), then +the DWARF operation expression is ill-formed. + +Evaluation of an operation expression starts with an empty stack on which the +entries from the initial stack provided by the context are pushed in the order +provided. Then the operations are evaluated, starting with the first operation +of the stream. Evaluation continues until either an operation has an evaluation +error, or until one past the last operation of the stream is reached. + +The result of the evaluation is: + +- If an operation has an evaluation error, or an operation evaluates an + expression that has an evaluation error, then the result is an evaluation + error. +- If the current result kind specifies a location description, then: + - If the stack is empty, the result is a location description with one + undefined location description. + + This rule is for backwards compatibility with DWARF Version 5 which uses + an empty operation expression for this purpose. + + - If the top stack entry is a location description, or can be converted to one + (see [2.5.4.4.3 Memory Location Description + Operations](#memory-location-description-operations)), then the result + is that, possibly converted, location description. Any other entries on the + stack are discarded. + - Otherwise the DWARF expression is ill-formed. + + > NOTE: Could define this case as returning an implicit location description + > as if the `DW_OP_implicit` operation is performed. + +- If the current result kind specifies a value, then: + - If the top stack entry is a value, or can be converted to one (see + [2.5.4.4.3 Memory Location Description + Operations](#memory-location-description-operations)), then the result is + that, possibly converted, value. Any other entries on the stack are + discarded. + - Otherwise the DWARF expression is ill-formed. +- If the current result kind is not specified, then: + - If the stack is empty, the result is a location description with one + undefined location description. + + This rule is for backwards compatibility with DWARF Version 5 which uses + an empty operation expression for this purpose. + + > NOTE: This rule is consistent with the rule above for when a location + > description is requested. However, GDB appears to report this as an error + > and no GDB tests appear to cause an empty stack for this case. + + - Otherwise, the top stack entry is returned. Any other entries on the stack + are discarded. + +An operation expression is encoded as a byte block with some form of prefix that +specifies the byte count. It can be used: + +- as the value of a debugging information entry attribute that is encoded using + class `exprloc` (see [7.5.5 Classes and Forms](#classes-and-forms)), +- as the operand to certain operation expression operations, +- as the operand to certain call frame information operations (see [6.4 Call + Frame Information](#call-frame-information)), +- and in location list entries (see [2.5.5 DWARF Location List + Expressions](#dwarf-location-list-expressions)). + +##### A.2.5.4.1 Stack Operations + +> NOTE: This section replaces DWARF Version 5 section 2.5.1.3. + +The following operations manipulate the DWARF stack. Operations that index the +stack assume that the top of the stack (most recently added entry) has index 0. +They allow the stack entries to be either a value or location description. + +If any stack entry accessed by a stack operation is an incomplete composite +location description (see [2.5.4.4.6 Composite Location Description +Operations](#composite-location-description-operations)), then the DWARF +expression is ill-formed. + +> NOTE: These operations now support stack entries that are values and location +> descriptions. + +> NOTE: If it is desired to also make them work with incomplete composite +> location descriptions, then would need to define that the composite location +> storage specified by the incomplete composite location description is also +> replicated when a copy is pushed. This ensures that each copy of the +> incomplete composite location description can update the composite location +> storage they specify independently. + +1. `DW_OP_dup` + + `DW_OP_dup` duplicates the stack entry at the top of the stack. + +2. `DW_OP_drop` + + `DW_OP_drop` pops the stack entry at the top of the stack and discards it. + +3. `DW_OP_pick` + + `DW_OP_pick` has a single unsigned 1-byte operand that represents an index + I. A copy of the stack entry with index I is pushed onto the stack. + +4. `DW_OP_over` + + `DW_OP_over` pushes a copy of the entry with index 1. + + This is equivalent to a `DW_OP_pick 1` operation. + +5. `DW_OP_swap` + + `DW_OP_swap` swaps the top two stack entries. The entry at the top of the + stack becomes the second stack entry, and the second stack entry becomes the + top of the stack. + +6. `DW_OP_rot` + + `DW_OP_rot` rotates the first three stack entries. The entry at the top of + the stack becomes the third stack entry, the second entry becomes the top of + the stack, and the third entry becomes the second entry. + +##### A.2.5.4.2 Control Flow Operations + +> NOTE: This section replaces DWARF Version 5 section 2.5.1.5. + +The following operations provide simple control of the flow of a DWARF operation +expression. + +1. `DW_OP_nop` + + `DW_OP_nop` is a place holder. It has no effect on the DWARF stack entries. + +2. `DW_OP_le`, `DW_OP_ge`, `DW_OP_eq`, `DW_OP_lt`, `DW_OP_gt`, + `DW_OP_ne` + + > NOTE: The same as in DWARF Version 5 section 2.5.1.5. + +3. `DW_OP_skip` + + `DW_OP_skip` is an unconditional branch. Its single operand is a 2-byte + signed integer constant. The 2-byte constant is the number of bytes of the + DWARF expression to skip forward or backward from the current operation, + beginning after the 2-byte constant. + + If the updated position is at one past the end of the last operation, then + the operation expression evaluation is complete. + + Otherwise, the DWARF expression is ill-formed if the updated operation + position is not in the range of the first to last operation inclusive, or + not at the start of an operation. + +4. `DW_OP_bra` + + `DW_OP_bra` is a conditional branch. Its single operand is a 2-byte signed + integer constant. This operation pops the top of stack. If the value popped + is not the constant 0, the 2-byte constant operand is the number of bytes of + the DWARF operation expression to skip forward or backward from the current + operation, beginning after the 2-byte constant. + + If the updated position is at one past the end of the last operation, then + the operation expression evaluation is complete. + + Otherwise, the DWARF expression is ill-formed if the updated operation + position is not in the range of the first to last operation inclusive, or + not at the start of an operation. + +5. `DW_OP_call2, DW_OP_call4, DW_OP_call_ref` + + `DW_OP_call2`, `DW_OP_call4`, and `DW_OP_call_ref` perform DWARF procedure + calls during evaluation of a DWARF expression. + + `DW_OP_call2` and `DW_OP_call4`, have one operand that is, respectively, a + 2-byte or 4-byte unsigned offset DR that represents the byte offset of a + debugging information entry D relative to the beginning of the current + compilation unit. + + `DW_OP_call_ref` has one operand that is a 4-byte unsigned value in the + 32-bit DWARF format, or an 8-byte unsigned value in the 64-bit DWARF format, + that represents the byte offset DR of a debugging information entry D + relative to the beginning of the `.debug_info` section that contains the + current compilation unit. D may not be in the current compilation unit. + + > NOTE: DWARF Version 5 states that DR can be an offset in a `.debug_info` + > section other than the one that contains the current compilation unit. It + > states that relocation of references from one executable or shared object + > file to another must be performed by the consumer. But given that DR is + > defined as an offset in a `.debug_info` section this seems impossible. If + > DR was defined as an implementation defined value, then the consumer could + > choose to interpret the value in an implementation defined manner to + > reference a debug information in another executable or shared object. + > + > In ELF the `.debug_info` section is in a non-`PT_LOAD` segment so standard + > dynamic relocations cannot be used. But even if they were loaded segments + > and dynamic relocations were used, DR would need to be the address of D, + > not an offset in a `.debug_info` section. That would also need DR to be + > the size of a global address. So it would not be possible to use the + > 32-bit DWARF format in a 64-bit global address space. In addition, the + > consumer would need to determine what executable or shared object the + > relocated address was in so it could determine the containing compilation + > unit. + > + > GDB only interprets DR as an offset in the `.debug_info` section that + > contains the current compilation unit. + > + > This comment also applies to `DW_OP_implicit_pointer`. + + Operand interpretation of `DW_OP_call2`, `DW_OP_call4`, and + `DW_OP_call_ref` is exactly like that for `DW_FORM_ref2`, `DW_FORM_ref4`, + and `DW_FORM_ref_addr`, respectively. + + The call operation is evaluated by: + + - If D has a `DW_AT_location` attribute that is encoded as a `exprloc` that + specifies an operation expression E, then execution of the current + operation expression continues from the first operation of E. Execution + continues until one past the last operation of E is reached, at which + point execution continues with the operation following the call operation. + The operations of E are evaluated with the same current context, except + current compilation unit is the one that contains D and the stack is the + same as that being used by the call operation. After the call operation + has been evaluated, the stack is therefore as it is left by the evaluation + of the operations of E. Since E is evaluated on the same stack as the call + operation, E can use, and/or remove entries already on the stack, and can + add new entries to the stack. + + Values on the stack at the time of the call may be used as parameters + by the called expression and values left on the stack by the called + expression may be used as return values by prior agreement between the + calling and called expressions. + + - If D has a `DW_AT_location` attribute that is encoded as a `loclist` or + `loclistsptr`, then the specified location list expression E is evaluated. + The evaluation of E uses the current context, except the result kind is a + location description, the compilation unit is the one that contains D, and + the initial stack is empty. The location description result is pushed on + the stack. + + > NOTE: This rule avoids having to define how to execute a matched + > location list entry operation expression on the same stack as the call + > when there are multiple matches. But it allows the call to obtain the + > location description for a variable or formal parameter which may use a + > location list expression. + > + > An alternative is to treat the case when D has a `DW_AT_location` + > attribute that is encoded as a `loclist` or `loclistsptr`, and the + > specified location list expression E' matches a single location list + > entry with operation expression E, the same as the `exprloc` case and + > evaluate on the same stack. + > + > But this is not attractive as if the attribute is for a variable that + > happens to end with a non-singleton stack, it will not simply put a + > location description on the stack. Presumably the intent of using + > `DW_OP_call*` on a variable or formal parameter debugger information + > entry is to push just one location description on the stack. That + > location description may have more than one single location description. + > + > The previous rule for `exprloc` also has the same problem, as normally a + > variable or formal parameter location expression may leave multiple + > entries on the stack and only return the top entry. + > + > GDB implements `DW_OP_call*` by always executing E on the same stack. If + > the location list has multiple matching entries, it simply picks the + > first one and ignores the rest. This seems fundamentally at odds with + > the desire to support multiple places for variables. + > + > So, it feels like `DW_OP_call*` should both support pushing a location + > description on the stack for a variable or formal parameter, and also + > support being able to execute an operation expression on the same stack. + > Being able to specify a different operation expression for different + > program locations seems a desirable feature to retain. + > + > A solution to that is to have a distinct `DW_AT_proc` attribute for the + > `DW_TAG_dwarf_procedure` debugging information entry. Then the + > `DW_AT_location` attribute expression is always executed separately and + > pushes a location description (that may have multiple single location + > descriptions), and the `DW_AT_proc` attribute expression is always + > executed on the same stack and can leave anything on the stack. + > + > The `DW_AT_proc` attribute could have the new classes `exprproc`, + > `loclistproc`, and `loclistsptrproc` to indicate that the expression is + > executed on the same stack. `exprproc` is the same encoding as + > `exprloc`. `loclistproc` and `loclistsptrproc` are the same encoding as + > their non-`proc` counterparts, except the DWARF is ill-formed if the + > location list does not match exactly one location list entry and a + > default entry is required. These forms indicate explicitly that the + > matched single operation expression must be executed on the same stack. + > This is better than ad hoc special rules for `loclistproc` and + > `loclistsptrproc` which are currently clearly defined to always return a + > location description. The producer then explicitly indicates the intent + > through the attribute classes. + > + > Such a change would be a breaking change for how GDB implements + > `DW_OP_call*`. However, are the breaking cases actually occurring in + > practice? GDB could implement the current approach for DWARF Version 5, + > and the new semantics for DWARF Version 6 which has been done for some + > other features. + > + > Another option is to limit the execution to be on the same stack only to + > the evaluation of an expression E that is the value of a + > `DW_AT_location` attribute of a `DW_TAG_dwarf_procedure` debugging + > information entry. The DWARF would be ill-formed if E is a location list + > expression that does not match exactly one location list entry. In all + > other cases the evaluation of an expression E that is the value of a + > `DW_AT_location` attribute would evaluate E with the current context, + > except the result kind is a location description, the compilation unit + > is the one that contains D, and the initial stack is empty. The location + > description result is pushed on the stack. + + - If D has a `DW_AT_const_value` attribute with a value V, then it is as if + a `DW_OP_implicit_value V` operation was executed. + + This allows a call operation to be used to compute the location + description for any variable or formal parameter regardless of whether the + producer has optimized it to a constant. This is consistent with the + `DW_OP_implicit_pointer` operation. + + > NOTE: Alternatively, could deprecate using `DW_AT_const_value` for + > `DW_TAG_variable` and `DW_TAG_formal_parameter` debugger information + > entries that are constants and instead use `DW_AT_location` with an + > operation expression that results in a location description with one + > implicit location description. Then this rule would not be required. + + - Otherwise, there is no effect and no changes are made to the stack. + + > NOTE: In DWARF Version 5, if D does not have a `DW_AT_location` then + > `DW_OP_call*` is defined to have no effect. It is unclear that this is + > the right definition as a producer should be able to rely on using + > `DW_OP_call*` to get a location description for any + > non-`DW_TAG_dwarf_procedure` debugging information entries. Also, the + > producer should not be creating DWARF with `DW_OP_call*` to a + > `DW_TAG_dwarf_procedure` that does not have a `DW_AT_location` + > attribute. So, should this case be defined as an ill-formed DWARF + > expression? + + The `DW_TAG_dwarf_procedure` debugging information entry can be used to + define DWARF procedures that can be called. + +##### A.2.5.4.3 Value Operations + +This section describes the operations that push values on the stack. + +Each value stack entry has a type and a literal value. It can represent a +literal value of any supported base type of the target architecture. The base +type specifies the size, encoding, and endianity of the literal value. + +The base type of value stack entries can be the distinguished generic type. + +###### A.2.5.4.3.1 Literal Operations + +> NOTE: This section replaces DWARF Version 5 section 2.5.1.1. + +The following operations all push a literal value onto the DWARF stack. + +Operations other than `DW_OP_const_type` push a value V with the generic type. +If V is larger than the generic type, then V is truncated to the generic type +size and the low-order bits used. + +1. `DW_OP_lit0`, `DW_OP_lit1`, ..., `DW_OP_lit31` + + `DW_OP_lit` operations encode an unsigned literal value N from 0 through + 31, inclusive. They push the value N with the generic type. + +2. `DW_OP_const1u`, `DW_OP_const2u`, `DW_OP_const4u`, `DW_OP_const8u` + + `DW_OP_constu` operations have a single operand that is a 1, 2, 4, or + 8-byte unsigned integer constant U, respectively. They push the value U with + the generic type. + +3. `DW_OP_const1s`, `DW_OP_const2s`, `DW_OP_const4s`, `DW_OP_const8s` + + `DW_OP_consts` operations have a single operand that is a 1, 2, 4, or + 8-byte signed integer constant S, respectively. They push the value S with + the generic type. + +4. `DW_OP_constu` + + `DW_OP_constu` has a single unsigned LEB128 integer operand N. It pushes the + value N with the generic type. + +5. `DW_OP_consts` + + `DW_OP_consts` has a single signed LEB128 integer operand N. It pushes the + value N with the generic type. + +6. `DW_OP_constx` + + `DW_OP_constx` has a single unsigned LEB128 integer operand that represents + a zero-based index into the `.debug_addr` section relative to the value of + the `DW_AT_addr_base` attribute of the associated compilation unit. The + value N in the `.debug_addr` section has the size of the generic type. It + pushes the value N with the generic type. + + The `DW_OP_constx` operation is provided for constants that require + link-time relocation but should not be interpreted by the consumer as a + relocatable address (for example, offsets to thread-local storage). + +7. `DW_OP_const_type` + + `DW_OP_const_type` has three operands. The first is an unsigned LEB128 + integer DR that represents the byte offset of a debugging information entry + D relative to the beginning of the current compilation unit, that provides + the type T of the constant value. The second is a 1-byte unsigned integral + constant S. The third is a block of bytes B, with a length equal to S. + + TS is the bit size of the type T. The least significant TS bits of B are + interpreted as a value V of the type D. It pushes the value V with the type + D. + + The DWARF is ill-formed if D is not a `DW_TAG_base_type` debugging + information entry in the current compilation unit, or if TS divided by 8 + (the byte size) and rounded up to a whole number is not equal to S. + + While the size of the byte block B can be inferred from the type D + definition, it is encoded explicitly into the operation so that the + operation can be parsed easily without reference to the `.debug_info` + section. + +###### A.2.5.4.3.2 Arithmetic and Logical Operations + +> NOTE: This section is the same as DWARF Version 5 section 2.5.1.4. + +###### A.2.5.4.3.3 Type Conversion Operations + +> NOTE: This section is the same as DWARF Version 5 section 2.5.1.6. + +###### A.2.5.4.3.4 Special Value Operations + +> NOTE: This section replaces parts of DWARF Version 5 sections 2.5.1.2, + 2.5.1.3, and 2.5.1.7. + +There are these special value operations currently defined: + +1. `DW_OP_regval_type` + + `DW_OP_regval_type` has two operands. The first is an unsigned LEB128 + integer that represents a register number R. The second is an unsigned + LEB128 integer DR that represents the byte offset of a debugging information + entry D relative to the beginning of the current compilation unit, that + provides the type T of the register value. + + The operation is equivalent to performing `DW_OP_regx R; DW_OP_deref_type + DR`. + + > NOTE: Should DWARF allow the type T to be a larger size than the size of + > the register R? Restricting a larger bit size avoids any issue of + > conversion as the, possibly truncated, bit contents of the register is + > simply interpreted as a value of T. If a conversion is wanted it can be + > done explicitly using a `DW_OP_convert` operation. + > + > GDB has a per register hook that allows a target specific conversion on a + > register by register basis. It defaults to truncation of bigger registers. + > Removing use of the target hook does not cause any test failures in common + > architectures. If the compiler for a target architecture did want some + > form of conversion, including a larger result type, it could always + > explicitly used the `DW_OP_convert` operation. + > + > If T is a larger type than the register size, then the default GDB + > register hook reads bytes from the next register (or reads out of bounds + > for the last register!). Removing use of the target hook does not cause + > any test failures in common architectures (except an illegal hand written + > assembly test). If a target architecture requires this behavior, these + > extensions allow a composite location description to be used to combine + > multiple registers. + +2. `DW_OP_deref` + + S is the bit size of the generic type divided by 8 (the byte size) and + rounded up to a whole number. DR is the offset of a hypothetical debug + information entry D in the current compilation unit for a base type of the + generic type. + + The operation is equivalent to performing `DW_OP_deref_type S, DR`. + +3. `DW_OP_deref_size` + + `DW_OP_deref_size` has a single 1-byte unsigned integral constant that + represents a byte result size S. + + TS is the smaller of the generic type bit size and S scaled by 8 (the byte + size). If TS is smaller than the generic type bit size then T is an unsigned + integral type of bit size TS, otherwise T is the generic type. DR is the + offset of a hypothetical debug information entry D in the current + compilation unit for a base type T. + + > NOTE: Truncating the value when S is larger than the generic type matches + > what GDB does. This allows the generic type size to not be an integral + > byte size. It does allow S to be arbitrarily large. Should S be restricted + > to the size of the generic type rounded up to a multiple of 8? + + The operation is equivalent to performing `DW_OP_deref_type S, DR`, except + if T is not the generic type, the value V pushed is zero-extended to the + generic type bit size and its type changed to the generic type. + +4. `DW_OP_deref_type` + + `DW_OP_deref_type` has two operands. The first is a 1-byte unsigned integral + constant S. The second is an unsigned LEB128 integer DR that represents the + byte offset of a debugging information entry D relative to the beginning of + the current compilation unit, that provides the type T of the result value. + + TS is the bit size of the type T. + + While the size of the pushed value V can be inferred from the type T, it + is encoded explicitly as the operand S so that the operation can be parsed + easily without reference to the `.debug_info` section. + + > NOTE: It is unclear why the operand S is needed. Unlike + > `DW_OP_const_type`, the size is not needed for parsing. Any evaluation + > needs to get the base type T to push with the value to know its encoding + > and bit size. + + It pops one stack entry that must be a location description L. + + A value V of TS bits is retrieved from the location storage LS specified by + one of the single location descriptions SL of L. + + If L, or the location description of any composite location description + part that is a subcomponent of L, has more than one single location + description, then any one of them can be selected as they are required to + all have the same value. For any single location description SL, bits are + retrieved from the associated storage location starting at the bit offset + specified by SL. For a composite location description, the retrieved bits + are the concatenation of the N bits from each composite location part PL, + where N is limited to the size of PL. + + V is pushed on the stack with the type T. + + > NOTE: This definition makes it an evaluation error if L is a register + > location description that has less than TS bits remaining in the register + > storage. Particularly since these extensions extend location descriptions + > to have a bit offset, it would be odd to define this as performing sign + > extension based on the type, or be target architecture dependent, as the + > number of remaining bits could be any number. This matches the GDB + > implementation for `DW_OP_deref_type`. + > + > These extensions define `DW_OP_*breg*` in terms of `DW_OP_regval_type`. + > `DW_OP_regval_type` is defined in terms of `DW_OP_regx`, which uses a 0 + > bit offset, and `DW_OP_deref_type`. Therefore, it requires the register + > size to be greater or equal to the address size of the address space. This + > matches the GDB implementation for `DW_OP_*breg*`. + + The DWARF is ill-formed if D is not in the current compilation unit, D is + not a `DW_TAG_base_type` debugging information entry, or if TS divided by 8 + (the byte size) and rounded up to a whole number is not equal to S. + + > NOTE: This definition allows the base type to be a bit size since there + > seems no reason to restrict it. + + It is an evaluation error if any bit of the value is retrieved from the + undefined location storage or the offset of any bit exceeds the size of the + location storage LS specified by any single location description SL of L. + + See [2.5.4.4.5 Implicit Location Description + Operations](#implicit-location-description-operations) for special + rules concerning implicit location descriptions created by the + `DW_OP_implicit_pointer` operation. + +5. `DW_OP_xderef` + + `DW_OP_xderef` pops two stack entries. The first must be an integral type + value that represents an address A. The second must be an integral type + value that represents a target architecture specific address space + identifier AS. + + The address size S is defined as the address bit size of the target + architecture specific address space that corresponds to AS. + + A is adjusted to S bits by zero extending if necessary, and then treating + the least significant S bits as an unsigned value A'. + + It creates a location description L with one memory location description SL. + SL specifies the memory location storage LS that corresponds to AS with a + bit offset equal to A' scaled by 8 (the byte size). + + If AS is an address space that is specific to context elements, then LS + corresponds to the location storage associated with the current context. + + For example, if AS is for per thread storage then LS is the location + storage for the current thread. Therefore, if L is accessed by an operation, + the location storage selected when the location description was created is + accessed, and not the location storage associated with the current context + of the access operation. + + The DWARF expression is ill-formed if AS is not one of the values defined by + the target architecture specific `DW_ASPACE_*` values. + + The operation is equivalent to popping A and AS, pushing L, and then + performing `DW_OP_deref`. The value V retrieved is left on the stack with + the generic type. + +6. `DW_OP_xderef_size` + + `DW_OP_xderef_size` has a single 1-byte unsigned integral constant that + represents a byte result size S. + + It pops two stack entries. The first must be an integral type value + that represents an address A. The second must be an integral type + value that represents a target architecture specific address space + identifier AS. + + It creates a location description L as described for `DW_OP_xderef`. + + The operation is equivalent to popping A and AS, pushing L, and then + performing `DW_OP_deref_size S` . The zero-extended value V retrieved is + left on the stack with the generic type. + +7. `DW_OP_xderef_type` + + `DW_OP_xderef_type` has two operands. The first is a 1-byte unsigned + integral constant S. The second operand is an unsigned LEB128 integer DR + that represents the byte offset of a debugging information entry D relative + to the beginning of the current compilation unit, that provides the type T + of the result value. + + It pops two stack entries. The first must be an integral type value that + represents an address A. The second must be an integral type value that + represents a target architecture specific address space identifier AS. + + It creates a location description L as described for `DW_OP_xderef`. + + The operation is equivalent to popping A and AS, pushing L, and then + performing `DW_OP_deref_type DR` . The value V retrieved is left on the + stack with the type T. + +8. `DW_OP_entry_value` Deprecated + + `DW_OP_entry_value` pushes the value of an expression that is evaluated in + the context of the calling frame. + + It may be used to determine the value of arguments on entry to the + current call frame provided they are not clobbered. + + It has two operands. The first is an unsigned LEB128 integer S. The second + is a block of bytes, with a length equal S, interpreted as a DWARF operation + expression E. + + E is evaluated with the current context, except the result kind is + unspecified, the call frame is the one that called the current frame, the + program location is the call site in the calling frame, the object is + unspecified, and the initial stack is empty. The calling frame information + is obtained by virtually unwinding the current call frame using the call + frame information (see [6.4 Call Frame + Information](#call-frame-information)). + + If the result of E is a location description L (see [2.5.4.4.4 Register + Location Description + Operations](#register-location-description-operations)), and the last + operation executed by E is a `DW_OP_reg*` for register R with a target + architecture specific base type of T, then the contents of the register are + retrieved as if a `DW_OP_deref_type DR` operation was performed where DR is + the offset of a hypothetical debug information entry in the current + compilation unit for T. The resulting value V s pushed on the stack. + + Using `DW_OP_reg*` provides a more compact form for the case where the + value was in a register on entry to the subprogram. + + > NOTE: It is unclear how this provides a more compact expression, as + > `DW_OP_regval_type` could be used which is marginally larger. + + If the result of E is a value V, then V is pushed on the stack. + + Otherwise, the DWARF expression is ill-formed. + + The `DW_OP_entry_value` operation is deprecated as its main usage is + provided by other means. DWARF Version 5 added the + `DW_TAG_call_site_parameter` debugger information entry for call sites that + has `DW_AT_call_value`, `DW_AT_call_data_location`, and + `DW_AT_call_data_value` attributes that provide DWARF expressions to compute + actual parameter values at the time of the call, and requires the producer + to ensure the expressions are valid to evaluate even when virtually + unwound. + + > NOTE: GDB only implements `DW_OP_entry_value` when E is exactly + > `DW_OP_reg*` or `DW_OP_breg*; DW_OP_deref*`. + +##### A.2.5.4.4 Location Description Operations + +This section describes the operations that push location descriptions on the +stack. + +###### A.2.5.4.4.1 General Location Description Operations + +> NOTE: This section replaces part of DWARF Version 5 section 2.5.1.3. + +1. `DW_OP_push_object_address` + + `DW_OP_push_object_address` pushes the location description L of the current + object. + + This object may correspond to an independent variable that is part of a + user presented expression that is being evaluated. The object location + description may be determined from the variable's own debugging information + entry or it may be a component of an array, structure, or class whose + address has been dynamically determined by an earlier step during user + expression evaluation. + + This operation provides explicit functionality (especially for arrays + involving descriptors) that is analogous to the implicit push of the base + location description of a structure prior to evaluation of a + `DW_AT_data_member_location` to access a data member of a structure. + + > NOTE: This operation could be removed and the object location description + > specified as the initial stack as for `DW_AT_data_member_location`. + > + > Or this operation could be used instead of needing to specify an initial + > stack. The latter approach is more composable as access to the object may + > be needed at any point of the expression, and passing it as the initial + > stack requires the entire expression to be aware where on the stack it is. + > If this were done, ``DW_AT_use_location`` would require a + > ``DW_OP_push_object2_address`` operation for the second object. + > + > Or a more general way to pass an arbitrary number of arguments in and an + > operation to get the Nth one such as ``DW_OP_arg N``. A vector of + > arguments would then be passed in the expression context rather than an + > initial stack. This could also resolve the issues with ``DW_OP_call*`` by + > allowing a specific number of arguments passed in and returned to be + > specified. The ``DW_OP_call*`` operation could then always execute on a + > separate stack: the number of arguments would be specified in a new call + > operation and taken from the callers stack, and similarly the number of + > return results specified and copied from the called stack back to the + > callee stack when the called expression was complete. + > + > The only attribute that specifies a current object is + > `DW_AT_data_location` so the non-normative text seems to overstate how + > this is being used. Or are there other attributes that need to state they + > pass an object? + +###### A.2.5.4.4.2 Undefined Location Description Operations + +> NOTE: This section replaces DWARF Version 5 section 2.6.1.1.1. + +The undefined location storage represents a piece or all of an object that is +present in the source but not in the object code (perhaps due to optimization). +Neither reading nor writing to the undefined location storage is meaningful. + +An undefined location description specifies the undefined location storage. +There is no concept of the size of the undefined location storage, nor of a bit +offset for an undefined location description. The `DW_OP_*piece` operations can +implicitly specify an undefined location description, allowing any size and +offset to be specified, and results in a part with all undefined bits. + +###### A.2.5.4.4.3 Memory Location Description Operations + +> NOTE: This section replaces parts of DWARF Version 5 section 2.5.1.1, 2.5.1.2, +> 2.5.1.3, and 2.6.1.1.2. + +Each of the target architecture specific address spaces has a corresponding +memory location storage that denotes the linear addressable memory of that +address space. The size of each memory location storage corresponds to the range +of the addresses in the corresponding address space. + +It is target architecture defined how address space location storage maps to +target architecture physical memory. For example, they may be independent +memory, or more than one location storage may alias the same physical memory +possibly at different offsets and with different interleaving. The mapping may +also be dictated by the source language address classes. + +A memory location description specifies a memory location storage. The bit +offset corresponds to a bit position within a byte of the memory. Bits accessed +using a memory location description, access the corresponding target +architecture memory starting at the bit position within the byte specified by +the bit offset. + +A memory location description that has a bit offset that is a multiple of 8 (the +byte size) is defined to be a byte address memory location description. It has a +memory byte address A that is equal to the bit offset divided by 8. + +A memory location description that does not have a bit offset that is a multiple +of 8 (the byte size) is defined to be a bit field memory location description. +It has a bit position B equal to the bit offset modulo 8, and a memory byte +address A equal to the bit offset minus B that is then divided by 8. + +The address space AS of a memory location description is defined to be the +address space that corresponds to the memory location storage associated with +the memory location description. + +A location description that is comprised of one byte address memory location +description SL is defined to be a memory byte address location description. It +has a byte address equal to A and an address space equal to AS of the +corresponding SL. + +`DW_ASPACE_none` is defined as the target architecture default address space. + +If a stack entry is required to be a location description, but it is a value V +with the generic type, then it is implicitly converted to a location description +L with one memory location description SL. SL specifies the memory location +storage that corresponds to the target architecture default address space with a +bit offset equal to V scaled by 8 (the byte size). + +> NOTE: If it is wanted to allow any integral type value to be implicitly +> converted to a memory location description in the target architecture default +> address space: +> +> > If a stack entry is required to be a location description, but is a value V +> > with an integral type, then it is implicitly converted to a location +> > description L with a one memory location description SL. If the type size of +> > V is less than the generic type size, then the value V is zero extended to +> > the size of the generic type. The least significant generic type size bits +> > are treated as an unsigned value to be used as an address A. SL specifies +> > memory location storage corresponding to the target architecture default +> > address space with a bit offset equal to A scaled by 8 (the byte size). +> +> The implicit conversion could also be defined as target architecture specific. +> For example, GDB checks if V is an integral type. If it is not it gives an +> error. Otherwise, GDB zero-extends V to 64 bits. If the GDB target defines a +> hook function, then it is called. The target specific hook function can modify +> the 64-bit value, possibly sign extending based on the original value type. +> Finally, GDB treats the 64-bit value V as a memory location address. + +If a stack entry is required to be a location description, but it is an implicit +pointer value IPV with the target architecture default address space, then it is +implicitly converted to a location description with one single location +description specified by IPV. See [2.5.4.4.5 Implicit Location Description +Operations](#implicit-location-description-operations). + +If a stack entry is required to be a value, but it is a location description L +with one memory location description SL in the target architecture default +address space with a bit offset B that is a multiple of 8, then it is implicitly +converted to a value equal to B divided by 8 (the byte size) with the generic +type. + +1. `DW_OP_addr` + + `DW_OP_addr` has a single byte constant value operand, which has the size of + the generic type, that represents an address A. + + It pushes a location description L with one memory location description SL + on the stack. SL specifies the memory location storage corresponding to the + target architecture default address space with a bit offset equal to A + scaled by 8 (the byte size). + + If the DWARF is part of a code object, then A may need to be relocated. + For example, in the ELF code object format, A must be adjusted by the + difference between the ELF segment virtual address and the virtual address + at which the segment is loaded. + +2. `DW_OP_addrx` + + `DW_OP_addrx` has a single unsigned LEB128 integer operand that represents a + zero-based index into the `.debug_addr` section relative to the value of the + `DW_AT_addr_base` attribute of the associated compilation unit. The address + value A in the `.debug_addr` section has the size of the generic type. + + It pushes a location description L with one memory location description SL + on the stack. SL specifies the memory location storage corresponding to the + target architecture default address space with a bit offset equal to A + scaled by 8 (the byte size). + + If the DWARF is part of a code object, then A may need to be relocated. + For example, in the ELF code object format, A must be adjusted by the + difference between the ELF segment virtual address and the virtual address + at which the segment is loaded. + +3. `DW_OP_form_tls_address` + + `DW_OP_form_tls_address` pops one stack entry that must be an integral type + value and treats it as a thread-local storage address TA. + + It pushes a location description L with one memory location description SL + on the stack. SL is the target architecture specific memory location + description that corresponds to the thread-local storage address TA. + + The meaning of the thread-local storage address TA is defined by the + run-time environment. If the run-time environment supports multiple + thread-local storage blocks for a single thread, then the block + corresponding to the executable or shared library containing this DWARF + expression is used. + + Some implementations of C, C++, Fortran, and other languages support a + thread-local storage class. Variables with this storage class have distinct + values and addresses in distinct threads, much as automatic variables have + distinct values and addresses in each subprogram invocation. Typically, + there is a single block of storage containing all thread-local variables + declared in the main executable, and a separate block for the variables + declared in each shared library. Each thread-local variable can then be + accessed in its block using an identifier. This identifier is typically a + byte offset into the block and pushed onto the DWARF stack by one of the + `DW_OP_const*` operations prior to the `DW_OP_form_tls_address` operation. + Computing the address of the appropriate block can be complex (in some + cases, the compiler emits a function call to do it), and difficult to + describe using ordinary DWARF location descriptions. Instead of forcing + complex thread-local storage calculations into the DWARF expressions, the + `DW_OP_form_tls_address` allows the consumer to perform the computation + based on the target architecture specific run-time environment. + +4. `DW_OP_call_frame_cfa` + + `DW_OP_call_frame_cfa` pushes the location description L of the Canonical + Frame Address (CFA) of the current subprogram, obtained from the call frame + information on the stack. See [6.4 Call Frame + Information](#call-frame-information). + + Although the value of the `DW_AT_frame_base` attribute of the debugger + information entry corresponding to the current subprogram can be computed + using a location list expression, in some cases this would require an + extensive location list because the values of the registers used in + computing the CFA change during a subprogram execution. If the call frame + information is present, then it already encodes such changes, and it is + space efficient to reference that using the `DW_OP_call_frame_cfa` + operation. + +5. `DW_OP_fbreg` + + `DW_OP_fbreg` has a single signed LEB128 integer operand that represents a + byte displacement B. + + The location description L for the frame base of the current + subprogram is obtained from the `DW_AT_frame_base` attribute of the debugger + information entry corresponding to the current subprogram as described in + [3.3.5 Low-Level Information](#low-level-information). + + The location description L is updated by bit offset B scaled by 8 (the byte + size) and pushed on the stack. + +6. `DW_OP_breg0`, `DW_OP_breg1`, ..., `DW_OP_breg31` + + The `DW_OP_breg` operations encode the numbers of up to 32 registers, + numbered from 0 through 31, inclusive. The register number R corresponds to + the N in the operation name. + + They have a single signed LEB128 integer operand that represents a byte + displacement B. + + The address space identifier AS is defined as the one corresponding to the + target architecture specific default address space. + + The address size S is defined as the address bit size of the target + architecture specific address space corresponding to AS. + + The contents of the register specified by R are retrieved as if a + `DW_OP_regval_type R, DR` operation was performed where DR is the offset of + a hypothetical debug information entry in the current compilation unit for + an unsigned integral base type of size S bits. B is added and the least + significant S bits are treated as an unsigned value to be used as an address + A. + + They push a location description L comprising one memory location + description LS on the stack. LS specifies the memory location storage that + corresponds to AS with a bit offset equal to A scaled by 8 (the byte size). + +7. `DW_OP_bregx` + + `DW_OP_bregx` has two operands. The first is an unsigned LEB128 integer that + represents a register number R. The second is a signed LEB128 integer that + represents a byte displacement B. + + The action is the same as for `DW_OP_breg`, except that R is used as the + register number and B is used as the byte displacement. + +###### A.2.5.4.4.4 Register Location Description Operations + +> NOTE: This section replaces DWARF Version 5 section 2.6.1.1.3. + +There is a register location storage that corresponds to each of the target +architecture registers. The size of each register location storage corresponds +to the size of the corresponding target architecture register. + +A register location description specifies a register location storage. The bit +offset corresponds to a bit position within the register. Bits accessed using a +register location description access the corresponding target architecture +register starting at the specified bit offset. + +1. `DW_OP_reg0`, `DW_OP_reg1`, ..., `DW_OP_reg31` + + `DW_OP_reg` operations encode the numbers of up to 32 registers, numbered + from 0 through 31, inclusive. The target architecture register number R + corresponds to the N in the operation name. + + The operation is equivalent to performing `DW_OP_regx R`. + +2. `DW_OP_regx` + + `DW_OP_regx` has a single unsigned LEB128 integer operand that represents a + target architecture register number R. + + If the current call frame is the top call frame, it pushes a location + description L that specifies one register location description SL on the + stack. SL specifies the register location storage that corresponds to R with + a bit offset of 0 for the current thread. + + If the current call frame is not the top call frame, call frame information + (see [6.4 Call Frame Information](#call-frame-information)) is used to + determine the location description that holds the register for the current + call frame and current program location of the current thread. The resulting + location description L is pushed. + + Note that if call frame information is used, the resulting location + description may be register, memory, or undefined. + + An implementation may evaluate the call frame information immediately, or + may defer evaluation until L is accessed by an operation. If evaluation is + deferred, R and the current context can be recorded in L. When accessed, the + recorded context is used to evaluate the call frame information, not the + current context of the access operation. + +These operations obtain a register location. To fetch the contents of a +register, it is necessary to use `DW_OP_regval_type`, use one of the +`DW_OP_breg*` register-based addressing operations, or use `DW_OP_deref*` on a +register location description. + +###### A.2.5.4.4.5 Implicit Location Description Operations + +> NOTE: This section replaces DWARF Version 5 section 2.6.1.1.4. + +Implicit location storage represents a piece or all of an object which has no +actual location in the program but whose contents are nonetheless known, either +as a constant or can be computed from other locations and values in the program. + +An implicit location description specifies an implicit location storage. The bit +offset corresponds to a bit position within the implicit location storage. Bits +accessed using an implicit location description, access the corresponding +implicit storage value starting at the bit offset. + +1. `DW_OP_implicit_value` + + `DW_OP_implicit_value` has two operands. The first is an unsigned LEB128 + integer that represents a byte size S. The second is a block of bytes with a + length equal to S treated as a literal value V. + + An implicit location storage LS is created with the literal value V and a + size of S. + + It pushes location description L with one implicit location description SL + on the stack. SL specifies LS with a bit offset of 0. + +2. `DW_OP_stack_value` + + `DW_OP_stack_value` pops one stack entry that must be a value V. + + An implicit location storage LS is created with the literal value V using + the size, encoding, and enianity specified by V's base type. + + It pushes a location description L with one implicit location description SL + on the stack. SL specifies LS with a bit offset of 0. + + The `DW_OP_stack_value` operation specifies that the object does not + exist in memory, but its value is nonetheless known. In this form, the + location description specifies the actual value of the object, rather than + specifying the memory or register storage that holds the value. + + See [2.5.4.4.5 Implicit Location Description + Operations](#implicit-location-description-operations) for special + rules concerning implicit pointer values produced by dereferencing implicit + location descriptions created by the `DW_OP_implicit_pointer` operation. + + > NOTE: Since location descriptions are allowed on the stack, the + > `DW_OP_stack_value` operation no longer terminates the DWARF operation + > expression execution as in DWARF Version 5. + +3. `DW_OP_implicit_pointer` + + An optimizing compiler may eliminate a pointer, while still retaining the + value that the pointer addressed. `DW_OP_implicit_pointer` allows a producer + to describe this value. + + `DW_OP_implicit_pointer` specifies an object is a pointer to the target + architecture default address space that cannot be represented as a real + pointer, even though the value it would point to can be described. In this + form, the location description specifies a debugging information entry that + represents the actual location description of the object to which the + pointer would point. Thus, a consumer of the debug information would be able + to access the dereferenced pointer, even when it cannot access the pointer + itself. + + `DW_OP_implicit_pointer` has two operands. The first operand is a 4-byte + unsigned value in the 32-bit DWARF format, or an 8-byte unsigned value in + the 64-bit DWARF format, that represents the byte offset DR of a debugging + information entry D relative to the beginning of the `.debug_info` section + that contains the current compilation unit. The second operand is a signed + LEB128 integer that represents a byte displacement B. + + Note that D may not be in the current compilation unit. + + The first operand interpretation is exactly like that for + `DW_FORM_ref_addr`. + + The address space identifier AS is defined as the one corresponding to the + target architecture specific default address space. + + The address size S is defined as the address bit size of the target + architecture specific address space corresponding to AS. + + An implicit location storage LS is created with the debugging information + entry D, address space AS, and size of S. + + It pushes a location description L that comprises one implicit location + description SL on the stack. SL specifies LS with a bit offset of 0. + + It is an evaluation error if a `DW_OP_deref*` operation pops a location + description L', and retrieves S bits, such that any retrieved bits come from + an implicit location storage that is the same as LS, unless both the + following conditions are met: + + 1. All retrieved bits come from an implicit location description that + refers to an implicit location storage that is the same as LS. + + Note that all bits do not have to come from the same implicit + location description, as L' may involve composite location + descriptors. + + 2. The bits come from consecutive ascending offsets within their respective + implicit location storage. + + These rules are equivalent to retrieving the complete contents of LS. + + If both the above conditions are met, then the value V pushed by the + `DW_OP_deref*` operation is an implicit pointer value IPV with a target + architecture specific address space of AS, a debugging information entry of + D, and a base type of T. If AS is the target architecture default address + space, then T is the generic type. Otherwise, T is a target architecture + specific integral type with a bit size equal to S. + + If IPV is either implicitly converted to a location description (only done + if AS is the target architecture default address space), then the resulting + location description RL is: + + - If D has a `DW_AT_location` attribute, the DWARF expression E from the + `DW_AT_location` attribute is evaluated with the current context, except + that the result kind is a location description, the compilation unit is + the one that contains D, the object is unspecified, and the initial stack + is empty. RL is the expression result. + + Note that E is evaluated with the context of the expression accessing + IPV, and not the context of the expression that contained the + `DW_OP_implicit_pointer` operation that created L. + + - If D has a `DW_AT_const_value` attribute, then an implicit location + storage RLS is created from the `DW_AT_const_value` attribute's value with + a size matching the size of the `DW_AT_const_value` attribute's value. RL + comprises one implicit location description SRL. SRL specifies RLS with a + bit offset of 0. + + > NOTE: If using `DW_AT_const_value` for variables and formal parameters + > is deprecated and instead `DW_AT_location` is used with an implicit + > location description, then this rule would not be required. + + - Otherwise, it is an evaluation error. + + The location description RL is updated by bit offset B scaled by 8 (the byte + size). + + If a `DW_OP_stack_value` operation pops a value that is the same as IPV, + then it pushes a location description that is the same as L. + + It is an evaluation error if LS or IPV is accessed in any other manner. + + The restrictions on how an implicit pointer location description created + by `DW_OP_implicit_pointer` can be used are to simplify the DWARF consumer. + Similarly, for an implicit pointer value created by `DW_OP_deref*` and + `DW_OP_stack_value`. + +Typically a `DW_OP_implicit_pointer` operation is used in a DWARF expression +E1 of a `DW_TAG_variable` or `DW_TAG_formal_parameter` debugging +information entry D1's `DW_AT_location` attribute. The debugging +information entry referenced by the `DW_OP_implicit_pointer` operation is +typically itself a `DW_TAG_variable` or `DW_TAG_formal_parameter` debugging +information entry D2 whose `DW_AT_location` attribute gives a second +DWARF expression E2. + +D1 and E1 are describing the location of a pointer type +object. D2 and E2 are describing the location of the +object pointed to by that pointer object. + +However, D2 may be any debugging information entry that contains a +`DW_AT_location` or `DW_AT_const_value` attribute (for example, +`DW_TAG_dwarf_procedure`). By using E2, a consumer can reconstruct +the value of the object when asked to dereference the pointer described by +E1 which contains the `DW_OP_implicit_pointer` operation. + +###### A.2.5.4.4.6 Composite Location Description Operations + +> NOTE: This section replaces DWARF Version 5 section 2.6.1.2. + +A composite location storage represents an object or value which may be +contained in part of another location storage or contained in parts of more than +one location storage. + +Each part has a part location description L and a part bit size S. L can have +one or more single location descriptions SL. If there are more than one SL then +that indicates that part is located in more than one place. The bits of each +place of the part comprise S contiguous bits from the location storage LS +specified by SL starting at the bit offset specified by SL. All the bits must be +within the size of LS or the DWARF expression is ill-formed. + +A composite location storage can have zero or more parts. The parts are +contiguous such that the zero-based location storage bit index will range over +each part with no gaps between them. Therefore, the size of a composite location +storage is the sum of the size of its parts. The DWARF expression is ill-formed +if the size of the contiguous location storage is larger than the size of the +memory location storage corresponding to the largest target architecture +specific address space. + +A composite location description specifies a composite location storage. The bit +offset corresponds to a bit position within the composite location storage. + +There are operations that create a composite location storage. + +There are other operations that allow a composite location storage to be +incrementally created. Each part is created by a separate operation. There may +be one or more operations to create the final composite location storage. A +series of such operations describes the parts of the composite location storage +that are in the order that the associated part operations are executed. + +To support incremental creation, a composite location storage can be in an +incomplete state. When an incremental operation operates on an incomplete +composite location storage, it adds a new part. + +A composite location description that specifies a composite location storage +that is incomplete is termed an incomplete composite location description. A +composite location description that specifies a composite location storage that +is complete is termed a complete composite location description. + +If the top stack entry is a location description that has one incomplete +composite location description SL after the execution of an operation expression +has completed, SL is converted to a complete composite location description. + +Note that this conversion does not happen after the completion of an +operation expression that is evaluated on the same stack by the `DW_OP_call*` +operations. Such executions are not a separate evaluation of an operation +expression, but rather the continued evaluation of the same operation expression +that contains the `DW_OP_call*` operation. + +If a stack entry is required to be a location description L, but L has an +incomplete composite location description, then the DWARF expression is +ill-formed. The exception is for the operations involved in incrementally +creating a composite location description as described below. + +Note that a DWARF operation expression may arbitrarily compose composite +location descriptions from any other location description, including those that +have multiple single location descriptions, and those that have composite +location descriptions. + +The incremental composite location description operations are defined to be +compatible with the definitions in DWARF Version 5. + +1. `DW_OP_piece` + + `DW_OP_piece` has a single unsigned LEB128 integer that represents a byte + size S. + + The action is based on the context: + + - If the stack is empty, then a location description L comprised of one + incomplete composite location description SL is pushed on the stack. + + An incomplete composite location storage LS is created with a single part + P. P specifies a location description PL and has a bit size of S scaled by + 8 (the byte size). PL is comprised of one undefined location description + PSL. + + SL specifies LS with a bit offset of 0. + + - Otherwise, if the top stack entry is a location description L comprised of + one incomplete composite location description SL, then the incomplete + composite location storage LS that SL specifies is updated to append a new + part P. P specifies a location description PL and has a bit size of S + scaled by 8 (the byte size). PL is comprised of one undefined location + description PSL. L is left on the stack. + - Otherwise, if the top stack entry is a location description or can be + converted to one, then it is popped and treated as a part location + description PL. Then: + + - If the top stack entry (after popping PL) is a location description L + comprised of one incomplete composite location description SL, then the + incomplete composite location storage LS that SL specifies is updated to + append a new part P. P specifies the location description PL and has a + bit size of S scaled by 8 (the byte size). L is left on the stack. + - Otherwise, a location description L comprised of one + incomplete composite location description SL is pushed on + the stack. + + An incomplete composite location storage LS is created with a single + part P. P specifies the location description PL and has a bit size of S + scaled by 8 (the byte size). + + SL specifies LS with a bit offset of 0. + + - Otherwise, the DWARF expression is ill-formed + + Many compilers store a single variable in sets of registers or store a + variable partially in memory and partially in registers. `DW_OP_piece` + provides a way of describing where a part of a variable is located. + + The evaluation rules for the `DW_OP_piece` operation allow it to be + compatible with the DWARF Version 5 definition. + + > NOTE: Since these extensions allow location descriptions to be entries on + > the stack, a simpler operation to create composite location descriptions + > could be defined. For example, just one operation that specifies how many + > parts, and pops pairs of stack entries for the part size and location + > description. Not only would this be a simpler operation and avoid the + > complexities of incomplete composite location descriptions, but it may + > also have a smaller encoding in practice. However, the desire for + > compatibility with DWARF Version 5 is likely a stronger consideration. + +2. `DW_OP_bit_piece` + + `DW_OP_bit_piece` has two operands. The first is an unsigned LEB128 integer + that represents the part bit size S. The second is an unsigned LEB128 + integer that represents a bit displacement B. + + The action is the same as for `DW_OP_piece`, except that any part created + has the bit size S, and the location description PL of any created part is + updated by a bit offset B. + + `DW_OP_bit_piece` is used instead of `DW_OP_piece` when the piece to be + assembled is not byte-sized or is not at the start of the part location + description. + +#### A.2.5.5 DWARF Location List Expressions + +> NOTE: This section replaces DWARF Version 5 section 2.6.2. + +To meet the needs of recent computer architectures and optimization +techniques, debugging information must be able to describe the location of an +object whose location changes over the object's lifetime, and may reside at +multiple locations during parts of an object's lifetime. Location list +expressions are used in place of operation expressions whenever the object whose +location is being described has these requirements. + +A location list expression consists of a series of location list entries. Each +location list entry is one of the following kinds: + +1. Bounded location description + + This kind of location list entry provides an operation expression that + evaluates to the location description of an object that is valid over a + lifetime bounded by a starting and ending address. The starting address is + the lowest address of the address range over which the location is valid. + The ending address is the address of the first location past the highest + address of the address range. + + The location list entry matches when the current program location is within + the given range. + + There are several kinds of bounded location description entries which differ + in the way that they specify the starting and ending addresses. + +2. Default location description + + This kind of location list entry provides an operation expression that + evaluates to the location description of an object that is valid when no + bounded location description entry applies. + + The location list entry matches when the current program location is not + within the range of any bounded location description entry. + +3. Base address + + This kind of location list entry provides an address to be used as the base + address for beginning and ending address offsets given in certain kinds of + bounded location description entries. The applicable base address of a + bounded location description entry is the address specified by the closest + preceding base address entry in the same location list. If there is no + preceding base address entry, then the applicable base address defaults to + the base address of the compilation unit (see DWARF Version 5 section + 3.1.1). + + In the case of a compilation unit where all of the machine code is contained + in a single contiguous section, no base address entry is needed. + +4. End-of-list + + This kind of location list entry marks the end of the location list + expression. + +The address ranges defined by the bounded location description entries of a +location list expression may overlap. When they do, they describe a situation in +which an object exists simultaneously in more than one place. + +If all of the address ranges in a given location list expression do not +collectively cover the entire range over which the object in question is +defined, and there is no following default location description entry, it is +assumed that the object is not available for the portion of the range that is +not covered. + +The result of the evaluation of a DWARF location list expression is: + +- If the current program location is not specified, then it is an evaluation + error. + + > NOTE: If the location list only has a single default entry, should that be + > considered a match if there is no program location? If there are non-default + > entries then it seems it has to be an evaluation error when there is no + > program location as that indicates the location depends on the program + > location which is not known. + +- If there are no matching location list entries, then the result is a location + description that comprises one undefined location description. +- Otherwise, the operation expression E of each matching location list entry is + evaluated with the current context, except that the result kind is a location + description, the object is unspecified, and the initial stack is empty. The + location list entry result is the location description returned by the + evaluation of E. + + The result is a location description that is comprised of the union of the + single location descriptions of the location description result of each + matching location list entry. + +A location list expression can only be used as the value of a debugger +information entry attribute that is encoded using class `loclist` or +`loclistsptr` (see [7.5.5 Classes and Forms](#classes-and-forms)). The value of +the attribute provides an index into a separate object file section called +`.debug_loclists` or `.debug_loclists.dwo` (for split DWARF object files) that +contains the location list entries. + +A `DW_OP_call*` and `DW_OP_implicit_pointer` operation can be used to specify a +debugger information entry attribute that has a location list expression. +Several debugger information entry attributes allow DWARF expressions that are +evaluated with an initial stack that includes a location description that may +originate from the evaluation of a location list expression. + +This location list representation, the `loclist` and `loclistsptr` class, and +the related `DW_AT_loclists_base` attribute are new in DWARF Version 5. Together +they eliminate most, or all of the code object relocations previously needed for +location list expressions. + +> NOTE: The rest of this section is the same as DWARF Version 5 section 2.6.2. + +## A.3 Program Scope Entries + +> NOTE: This section provides changes to existing debugger information entry +> attributes. These would be incorporated into the corresponding DWARF Version 5 +> chapter 3 sections. + +### A.3.3 Subroutine and Entry Point Entries + +#### A.3.3.5 Low-Level Information + +1. A `DW_TAG_subprogram`, `DW_TAG_inlined_subroutine`, or `DW_TAG_entry_point` + debugger information entry may have a `DW_AT_return_addr` attribute, whose + value is a DWARF expression E. + + The result of the attribute is obtained by evaluating E with a context that + has a result kind of a location description, an unspecified object, the + compilation unit that contains E, an empty initial stack, and other context + elements corresponding to the source language thread of execution upon which + the user is focused, if any. The result of the evaluation is the location + description L of the place where the return address for the current call + frame's subprogram or entry point is stored. + + The DWARF is ill-formed if L is not comprised of one memory location + description for one of the target architecture specific address spaces. + + > NOTE: It is unclear why `DW_TAG_inlined_subroutine` has a + > `DW_AT_return_addr` attribute but not a `DW_AT_frame_base` or + > `DW_AT_static_link` attribute. Seems it would either have all of them or + > none. Since inlined subprograms do not have a call frame it seems they + > would have none of these attributes. + +2. A `DW_TAG_subprogram` or `DW_TAG_entry_point` debugger information entry may + have a `DW_AT_frame_base` attribute, whose value is a DWARF expression E. + + The result of the attribute is obtained by evaluating E with a context that + has a result kind of a location description, an unspecified object, the + compilation unit that contains E, an empty initial stack, and other context + elements corresponding to the source language thread of execution upon which + the user is focused, if any. + + The DWARF is ill-formed if E contains an `DW_OP_fbreg` operation, or the + resulting location description L is not comprised of one single location + description SL. + + If SL is a register location description for register R, then L is replaced + with the result of evaluating a `DW_OP_bregx R, 0` operation. This computes + the frame base memory location description in the target architecture + default address space. + + This allows the more compact `DW_OP_reg*` to be used instead of + `DW_OP_breg* 0`. + + > NOTE: This rule could be removed and require the producer to create the + > required location description directly using `DW_OP_call_frame_cfa` or + > `DW_OP_breg*`. This would also then allow a target to implement the call + > frames within a large register. + + Otherwise, the DWARF is ill-formed if SL is not a memory location + description in any of the target architecture specific address spaces. + + The resulting L is the frame base for the subprogram or entry point. + + Typically, E will use the `DW_OP_call_frame_cfa` operation or be a stack + pointer register plus or minus some offset. + +3. If a `DW_TAG_subprogram` or `DW_TAG_entry_point` debugger information entry + is lexically nested, it may have a `DW_AT_static_link` attribute, whose + value is a DWARF expression E. + + The result of the attribute is obtained by evaluating E with a context that + has a result kind of a location description, an unspecified object, the + compilation unit that contains E, an empty initial stack, and other context + elements corresponding to the source language thread of execution upon which + the user is focused, if any. The result of the evaluation is the location + description L of the canonical frame address (see [6.4 Call Frame + Information](#call-frame-information)) of the relevant call frame of the + subprogram instance that immediately lexically encloses the current call + frame's subprogram or entry point. + + The DWARF is ill-formed if L is is not comprised of one memory location + description for one of the target architecture specific address spaces. + +### A.3.4 Call Site Entries and Parameters + +#### A.3.4.2 Call Site Parameters + +1. A `DW_TAG_call_site_parameter` debugger information entry may have a + `DW_AT_call_value` attribute, whose value is a DWARF operation expression + E1. + + The result of the `DW_AT_call_value` attribute is obtained by evaluating + E1 with a context that has a result kind of a value, an unspecified + object, the compilation unit that contains E, an empty initial stack, and other + context elements corresponding to the source language thread of execution upon + which the user is focused, if any. The resulting value V1 is the + value of the parameter at the time of the call made by the call site. + + For parameters passed by reference, where the code passes a pointer to a + location which contains the parameter, or for reference type parameters, the + `DW_TAG_call_site_parameter` debugger information entry may also have a + `DW_AT_call_data_location` attribute whose value is a DWARF operation expression + E2, and a `DW_AT_call_data_value` attribute whose value is a DWARF + operation expression E3. + + The value of the `DW_AT_call_data_location` attribute is obtained by evaluating + E2 with a context that has a result kind of a location description, + an unspecified object, the compilation unit that contains E, an empty initial + stack, and other context elements corresponding to the source language thread of + execution upon which the user is focused, if any. The resulting location + description L2 is the location where the referenced parameter lives + during the call made by the call site. If E2 would just be a + `DW_OP_push_object_address`, then the `DW_AT_call_data_location` attribute may + be omitted. + + > NOTE: The DWARF Version 5 implies that `DW_OP_push_object_address` may be + > used but does not state what object must be specified in the context. + > Either `DW_OP_push_object_address` cannot be used, or the object to be + > passed in the context must be defined. + + The value of the `DW_AT_call_data_value` attribute is obtained by evaluating + E3 with a context that has a result kind of a value, an unspecified + object, the compilation unit that contains E, an empty initial stack, and other + context elements corresponding to the source language thread of execution upon + which the user is focused, if any. The resulting value V3 is the + value in L2 at the time of the call made by the call site. + + The result of these attributes is undefined if the current call frame is not for + the subprogram containing the `DW_TAG_call_site_parameter` debugger information + entry or the current program location is not for the call site containing the + `DW_TAG_call_site_parameter` debugger information entry in the current call + frame. + + The consumer may have to virtually unwind to the call site (see [6.4 Call + Frame Information](#call-frame-information)) in order to evaluate these + attributes. This will ensure the source language thread of execution upon which + the user is focused corresponds to the call site needed to evaluate the + expression. + + If it is not possible to avoid the expressions of these attributes from + accessing registers or memory locations that might be clobbered by the + subprogram being called by the call site, then the associated attribute should + not be provided. + + The reason for the restriction is that the parameter may need to be accessed + during the execution of the callee. The consumer may virtually unwind from the + called subprogram back to the caller and then evaluate the attribute + expressions. The call frame information (see [6.4 Call Frame + Information](#call-frame-information)) will not be able to restore registers + that have been clobbered, and clobbered memory will no longer have the value at + the time of the call. + +### A.3.5 Lexical Block Entries + +> NOTE: This section is the same as DWARF Version 5 section 3.5. + +## A.4 Data Object and Object List Entries + +> NOTE: This section provides changes to existing debugger information entry +> attributes. These would be incorporated into the corresponding DWARF Version 5 +> chapter 4 sections. + +### A.4.1 Data Object Entries + +1. Any debugging information entry describing a data object (which includes + variables and parameters) or common blocks may have a `DW_AT_location` + attribute, whose value is a DWARF expression E. + + The result of the attribute is obtained by evaluating E with a context that + has a result kind of a location description, an unspecified object, the + compilation unit that contains E, an empty initial stack, and other context + elements corresponding to the source language thread of execution upon which + the user is focused, if any. The result of the evaluation is the location + description of the base of the data object. + + See [2.5.4.2 Control Flow Operations](#control-flow-operations) for special + evaluation rules used by the `DW_OP_call*` operations. + + > NOTE: Delete the description of how the `DW_OP_call*` operations evaluate + > a `DW_AT_location` attribute as that is now described in the operations. + + > NOTE: See the discussion about the `DW_AT_location` attribute in the + > `DW_OP_call*` operation. Having each attribute only have a single purpose + > and single execution semantics seems desirable. It makes it easier for the + > consumer that no longer have to track the context. It makes it easier for + > the producer as it can rely on a single semantics for each attribute. + > + > For that reason, limiting the `DW_AT_location` attribute to only + > supporting evaluating the location description of an object, and using a + > different attribute and encoding class for the evaluation of DWARF + > expression procedures on the same operation expression stack seems + > desirable. + +2. `DW_AT_const_value` + + > NOTE: Could deprecate using the `DW_AT_const_value` attribute for + > `DW_TAG_variable` or `DW_TAG_formal_parameter` debugger information + > entries that have been optimized to a constant. Instead, `DW_AT_location` + > could be used with a DWARF expression that produces an implicit location + > description now that any location description can be used within a DWARF + > expression. This allows the `DW_OP_call*` operations to be used to push + > the location description of any variable regardless of how it is + > optimized. + +## A.5 Type Entries + +> NOTE: This section provides changes to existing debugger information entry +> attributes. These would be incorporated into the corresponding DWARF Version 5 +> chapter 5 sections. + +### A.5.7 Structure, Union, Class and Interface Type Entries + +#### A.5.7.3 Derived or Extended Structures, Classes and Interfaces + +1. For a `DW_AT_data_member_location` attribute there are two cases: + + 1. If the attribute is an integer constant B, it provides the offset in + bytes from the beginning of the containing entity. + + The result of the attribute is obtained by updating the bit offset of + the location description of the beginning of the containing entity by B + scaled by 8 (the byte size). The result is the location description of + the base of the member entry. + + If the beginning of the containing entity is not byte aligned, then + the beginning of the member entry has the same bit displacement within a + byte. + + 2. Otherwise, the attribute must be a DWARF expression E which is evaluated + with a context that has a result kind of a location description, an + unspecified object, the compilation unit that contains E, an initial + stack comprising the location description of the beginning of the + containing entity, and other context elements corresponding to the + source language thread of execution upon which the user is focused, if + any. The result of the evaluation is the location description of the + base of the member entry. + + > NOTE: The beginning of the containing entity can now be any location + > description, including those with more than one single location + > description, and those with single location descriptions that are of any + > kind and have any bit offset. + +#### A.5.7.8 Member Function Entries + +1. An entry for a virtual function also has a `DW_AT_vtable_elem_location` + attribute whose value is a DWARF expression E. + + The result of the attribute is obtained by evaluating E with a context that + has a result kind of a location description, an unspecified object, the + compilation unit that contains E, an initial stack comprising the location + description of the object of the enclosing type, and other context elements + corresponding to the source language thread of execution upon which the user + is focused, if any. The result of the evaluation is the location description + of the slot for the function within the virtual function table for the + enclosing class. + +### A.5.14 Pointer to Member Type Entries + +1. The `DW_TAG_ptr_to_member_type` debugging information entry has a + `DW_AT_use_location` attribute whose value is a DWARF expression E. It is used + to compute the location description of the member of the class to which the + pointer to member entry points. + + The method used to find the location description of a given member of a + class, structure, or union is common to any instance of that class, structure, + or union and to any instance of the pointer to member type. The method is thus + associated with the pointer to member type, rather than with each object that + has a pointer to member type. + + The `DW_AT_use_location` DWARF expression is used in conjunction with the + location description for a particular object of the given pointer to member type + and for a particular structure or class instance. + + The result of the attribute is obtained by evaluating E with a context that has + a result kind of a location description, an unspecified object, the compilation + unit that contains E, an initial stack comprising two entries, and other context + elements corresponding to the source language thread of execution upon which the + user is focused, if any. The first stack entry is the value of the pointer to + member object itself. The second stack entry is the location description of the + base of the entire class, structure, or union instance containing the member + whose location is being calculated. The result of the evaluation is the location + description of the member of the class to which the pointer to member entry + points. + +### A.5.16 Dynamic Type Entries + +1. The `DW_AT_data_location` attribute may be used with any type that provides one + or more levels of hidden indirection and/or run-time parameters in its + representation. Its value is a DWARF operation expression E which computes the + location description of the data for an object. When this attribute is omitted, + the location description of the data is the same as the location description of + the object. + + The result of the attribute is obtained by evaluating E with a context that has + a result kind of a location description, an object that is the location + description of the data descriptor, the compilation unit that contains E, an + empty initial stack, and other context elements corresponding to the source + language thread of execution upon which the user is focused, if any. The result + of the evaluation is the location description of the base of the member entry. + + E will typically involve an operation expression that begins with a + `DW_OP_push_object_address` operation which loads the location description + of the object which can then serve as a descriptor in subsequent + calculation. + + > NOTE: Since `DW_AT_data_member_location`, `DW_AT_use_location`, and + > `DW_AT_vtable_elem_location` allow both operation expressions and location + > list expressions, why does `DW_AT_data_location` not allow both? In all cases + > they apply to data objects so less likely that optimization would cause + > different operation expressions for different program location ranges. But if + > supporting for some then should be for all. + > + > It seems odd this attribute is not the same as `DW_AT_data_member_location` in + > having an initial stack with the location description of the object since the + > expression has to need it. + +## A.6 Other Debugging Information + +> NOTE: This section provides changes to existing debugger information entry +> attributes. These would be incorporated into the corresponding DWARF Version 5 +> chapter 6 sections. + +### A.6.2 Line Number Information + +> NOTE: This section is the same as DWARF Version 5 section 6.2. + +### A.6.4 Call Frame Information + +> NOTE: This section provides changes to DWARF Version 5 section 6.4. Register +> unwind DWARF expressions are generalized to allow any location description, +> including those with composite and implicit location descriptions. + +#### A.6.4.1 Structure of Call Frame Information + +The register rules are: + +1. undefined + + A register that has this rule has no recoverable value in the previous + frame. The previous value of this register is the undefined location + description (see [2.5.4.4.2 Undefined Location Description + Operations](#undefined-location-description-operations)). + + By convention, the register is not preserved by a callee. + +2. same value + + This register has not been modified from the previous caller frame. + + If the current frame is the top frame, then the previous value of this + register is the location description L that specifies one register location + description SL. SL specifies the register location storage that corresponds + to the register with a bit offset of 0 for the current thread. + + If the current frame is not the top frame, then the previous value of this + register is the location description obtained using the call frame + information for the callee frame and callee program location invoked by the + current caller frame for the same register. + + By convention, the register is preserved by the callee, but the callee + has not modified it. + +3. offset(N) + + N is a signed byte offset. The previous value of this register is saved at + the location description L. Where L is the location description of the + current CFA (see [2.5.4 DWARF Operation + Expressions](#dwarf-operation-expressions)) updated with the bit offset N + scaled by 8 (the byte size). + +4. val_offset(N) + + N is a signed byte offset. The previous value of this register is the memory + byte address of the location description L. Where L is the location + description of the current CFA (see [2.5.4 DWARF Operation + Expressions](#dwarf-operation-expressions)) updated with the bit offset N + scaled by 8 (the byte size). + + The DWARF is ill-formed if the CFA location description is not a memory byte + address location description, or if the register size does not match the + size of an address in the target architecture default address space. + + Since the CFA location description is required to be a memory byte + address location description, the value of val_offset(N) will also be a + memory byte address location description since it is offsetting the CFA + location description by N bytes. Furthermore, the value of val_offset(N) + will be a memory byte address in the target architecture default address + space. + + > NOTE: Should DWARF allow the address size to be a different size to the + > size of the register? Requiring them to be the same bit size avoids any + > issue of conversion as the bit contents of the register is simply + > interpreted as a value of the address. + > + > GDB has a per register hook that allows a target specific conversion on a + > register by register basis. It defaults to truncation of bigger registers, + > and to actually reading bytes from the next register (or reads out of + > bounds for the last register) for smaller registers. There are no GDB + > tests that read a register out of bounds (except an illegal hand written + > assembly test). + +5. register(R) + + This register has been stored in another register numbered R. + + The previous value of this register is the location description obtained + using the call frame information for the current frame and current program + location for register R. + + The DWARF is ill-formed if the size of this register does not match the size + of register R or if there is a cyclic dependency in the call frame + information. + + > NOTE: Should this also allow R to be larger than this register? If so is + > the value stored in the low order bits and it is undefined what is stored + > in the extra upper bits? + +6. expression(E) + + The previous value of this register is located at the location description + produced by evaluating the DWARF operation expression E (see [2.5.4 DWARF + Operation Expressions](#dwarf-operation-expressions)). + + E is evaluated with the current context, except the result kind is a + location description, the compilation unit is unspecified, the object is + unspecified, and an initial stack comprising the location description of the + current CFA (see [2.5.4 DWARF Operation + Expressions](#dwarf-operation-expressions)). + +7. val_expression(E) + + The previous value of this register is the value produced by evaluating the + DWARF operation expression E (see [2.5.4 DWARF Operation + Expressions](#dwarf-operation-expressions)). + + E is evaluated with the current context, except the result kind is a value, + the compilation unit is unspecified, the object is unspecified, and an + initial stack comprising the location description of the current CFA (see + [2.5.4 DWARF Operation Expressions](#dwarf-operation-expressions)). + + The DWARF is ill-formed if the resulting value type size does not match the + register size. + + > NOTE: This has limited usefulness as the DWARF expression E can only + > produce values up to the size of the generic type. This is due to not + > allowing any operations that specify a type in a CFI operation expression. + > This makes it unusable for registers that are larger than the generic + > type. However, expression(E) can be used to create an implicit + > location description of any size. + +8. architectural + + The rule is defined externally to this specification by the augmenter. + +A Common Information Entry (CIE) holds information that is shared among many +Frame Description Entries (FDE). There is at least one CIE in every non-empty +`.debug_frame` section. A CIE contains the following fields, in order: + +1. `length` (initial length) + + A constant that gives the number of bytes of the CIE structure, not + including the length field itself. The size of the length field plus the + value of length must be an integral multiple of the address size specified + in the `address_size` field. + +2. `CIE_id` (4 or 8 bytes, see [7.4 32-Bit and 64-Bit DWARF + Formats](#32-bit-and-64-bit-dwarf-formats)) + + A constant that is used to distinguish CIEs from FDEs. + + In the 32-bit DWARF format, the value of the CIE id in the CIE header is + 0xffffffff; in the 64-bit DWARF format, the value is 0xffffffffffffffff. + +3. `version` (ubyte) + + A version number. This number is specific to the call frame information and + is independent of the DWARF version number. + + The value of the CIE version number is 4. + + > NOTE: Would this be increased to 5 to reflect the changes in these + > extensions? + +4. `augmentation` (sequence of UTF-8 characters) + + A null-terminated UTF-8 string that identifies the augmentation to this CIE + or to the FDEs that use it. If a reader encounters an augmentation string + that is unexpected, then only the following fields can be read: + + - CIE: length, CIE_id, version, augmentation + - FDE: length, CIE_pointer, initial_location, address_range + + If there is no augmentation, this value is a zero byte. + + The augmentation string allows users to indicate that there is additional + vendor and target architecture specific information in the CIE or FDE which + is needed to virtually unwind a stack frame. For example, this might be + information about dynamically allocated data which needs to be freed on exit + from the routine. + + Because the `.debug_frame` section is useful independently of any + `.debug_info` section, the augmentation string always uses UTF-8 + encoding. + +5. `address_size` (ubyte) + + The size of a target address in this CIE and any FDEs that use it, in bytes. + If a compilation unit exists for this frame, its address size must match the + address size here. + +6. `segment_selector_size` (ubyte) + + The size of a segment selector in this CIE and any FDEs that use it, in + bytes. + +7. `code_alignment_factor` (unsigned LEB128) + + A constant that is factored out of all advance location instructions (see + [6.4.2.1 Row Creation Instructions](#row-creation-instructions)). The + resulting value is `(operand * code_alignment_factor)`. + +8. `data_alignment_factor` (signed LEB128) + + A constant that is factored out of certain offset instructions (see [6.4.2.2 + CFA Definition Instructions](#cfa-definition-instructions) and [6.4.2.3 + Register Rule Instructions](#register-rule-instructions)). The + resulting value is `(operand * data_alignment_factor)`. + +9. `return_address_register` (unsigned LEB128) + + An unsigned LEB128 constant that indicates which column in the rule table + represents the return address of the subprogram. Note that this column might + not correspond to an actual machine register. + + The value of the return address register is used to determine the program + location of the caller frame. The program location of the top frame is the + target architecture program counter value of the current thread. + +10. `initial_instructions` (array of ubyte) + + A sequence of rules that are interpreted to create the initial setting of + each column in the table. + + The default rule for all columns before interpretation of the initial + instructions is the undefined rule. However, an ABI authoring body or a + compilation system authoring body may specify an alternate default value for + any or all columns. + +11. `padding` (array of ubyte) + + Enough `DW_CFA_nop` instructions to make the size of this entry match the + length value above. + +An FDE contains the following fields, in order: + +1. `length` (initial length) + + A constant that gives the number of bytes of the header and instruction + stream for this subprogram, not including the length field itself. The size + of the length field plus the value of length must be an integral multiple of + the address size. + +2. `CIE_pointer` (4 or 8 bytes, see [7.4 32-Bit and 64-Bit DWARF + Formats](#32-bit-and-64-bit-dwarf-formats)) + + A constant offset into the `.debug_frame` section that denotes the CIE that + is associated with this FDE. + +3. `initial_location` (segment selector and target address) + + The address of the first location associated with this table entry. If the + segment_selector_size field of this FDE's CIE is non-zero, the initial + location is preceded by a segment selector of the given length. + +4. `address_range` (target address) + + The number of bytes of program instructions described by this entry. + +5. `instructions` (array of ubyte) + + A sequence of table defining instructions that are described in [6.4.2 Call + Frame Instructions](#call-frame-instructions). + +6. `padding` (array of ubyte) + + Enough `DW_CFA_nop` instructions to make the size of this entry match the + length value above. + +#### A.6.4.2 Call Frame Instructions + +Some call frame instructions have operands that are encoded as DWARF operation +expressions E (see [2.5.4 DWARF Operation +Expressions](#dwarf-operation-expressions)). The DWARF operations that can be +used in E have the following restrictions: + +- `DW_OP_addrx`, `DW_OP_call2`, `DW_OP_call4`, `DW_OP_call_ref`, + `DW_OP_const_type`, `DW_OP_constx`, `DW_OP_convert`, `DW_OP_deref_type`, + `DW_OP_fbreg`, `DW_OP_implicit_pointer`, `DW_OP_regval_type`, + `DW_OP_reinterpret`, and `DW_OP_xderef_type` operations are not allowed + because the call frame information must not depend on other debug sections. +- `DW_OP_push_object_address` is not allowed because there is no object context + to provide a value to push. +- `DW_OP_call_frame_cfa` and `DW_OP_entry_value` are not allowed because their + use would be circular. + +Call frame instructions to which these restrictions apply include +`DW_CFA_def_cfa_expression`, `DW_CFA_expression`, and +`DW_CFA_val_expression`. + +##### A.6.4.2.1 Row Creation Instructions + +> NOTE: These instructions are the same as in DWARF Version 5 section 6.4.2.1. + +##### A.6.4.2.2 CFA Definition Instructions + +1. `DW_CFA_def_cfa` + + The `DW_CFA_def_cfa` instruction takes two unsigned LEB128 operands + representing a register number R and a (non-factored) byte displacement B. + The required action is to define the current CFA rule to be the result of + evaluating the DWARF operation expression `DW_OP_bregx R, B` as a location + description. + +2. `DW_CFA_def_cfa_sf` + + The `DW_CFA_def_cfa_sf` instruction takes two operands: an unsigned LEB128 + value representing a register number R and a signed LEB128 factored byte + displacement B. The required action is to define the current CFA rule to be + the result of evaluating the DWARF operation expression `DW_OP_bregx R, B * + data_alignment_factor` as a location description. + + The action is the same as `DW_CFA_def_cfa`, except that the second + operand is signed and factored. + +3. `DW_CFA_def_cfa_register` + + The `DW_CFA_def_cfa_register` instruction takes a single unsigned LEB128 + operand representing a register number R. The required action is to define + the current CFA rule to be the result of evaluating the DWARF operation + expression `DW_OP_bregx R, B` as a location description. B is the old CFA + byte displacement. + + If the subprogram has no current CFA rule, or the rule was defined by a + `DW_CFA_def_cfa_expression` instruction, then the DWARF is ill-formed. + +4. `DW_CFA_def_cfa_offset` + + The `DW_CFA_def_cfa_offset` instruction takes a single unsigned LEB128 + operand representing a (non-factored) byte displacement B. The required + action is to define the current CFA rule to be the result of evaluating the + DWARF operation expression `DW_OP_bregx R, B` as a location description. R + is the old CFA register number. + + If the subprogram has no current CFA rule, or the rule was defined by a + `DW_CFA_def_cfa_expression` instruction, then the DWARF is ill-formed. + +5. `DW_CFA_def_cfa_offset_sf` + + The `DW_CFA_def_cfa_offset_sf` instruction takes a signed LEB128 operand + representing a factored byte displacement B. The required action is to + define the current CFA rule to be the result of evaluating the DWARF + operation expression `DW_OP_bregx R, B * data_alignment_factor` as a + location description. R is the old CFA register number. + + If the subprogram has no current CFA rule, or the rule was defined by a + `DW_CFA_def_cfa_expression` instruction, then the DWARF is ill-formed. + + The action is the same as `DW_CFA_def_cfa_offset`, except that the + operand is signed and factored. + +6. `DW_CFA_def_cfa_expression` + + The `DW_CFA_def_cfa_expression` instruction takes a single operand encoded + as a `DW_FORM_exprloc` value representing a DWARF operation expression E. + The required action is to define the current CFA rule to be the result of + evaluating E with the current context, except the result kind is a location + description, the compilation unit is unspecified, the object is unspecified, + and an empty initial stack. + + See [6.4.2 Call Frame Instructions](#call-frame-instructions) regarding + restrictions on the DWARF expression operations that can be used in E. + + The DWARF is ill-formed if the result of evaluating E is not a memory byte + address location description. + +##### A.6.4.2.3 Register Rule Instructions + +1. `DW_CFA_undefined` + + The `DW_CFA_undefined` instruction takes a single unsigned LEB128 operand + that represents a register number R. The required action is to set the rule + for the register specified by R to `undefined`. + +2. `DW_CFA_same_value` + + The `DW_CFA_same_value` instruction takes a single unsigned LEB128 operand + that represents a register number R. The required action is to set the rule + for the register specified by R to `same value`. + +3. `DW_CFA_offset` + + The `DW_CFA_offset` instruction takes two operands: a register number R + (encoded with the opcode) and an unsigned LEB128 constant representing a + factored displacement B. The required action is to change the rule for the + register specified by R to be an offset(B * data_alignment_factor) + rule. + + > NOTE: Seems this should be named `DW_CFA_offset_uf` since the offset is + > unsigned factored. + +4. `DW_CFA_offset_extended` + + The `DW_CFA_offset_extended` instruction takes two unsigned LEB128 operands + representing a register number R and a factored displacement B. This + instruction is identical to `DW_CFA_offset`, except for the encoding and + size of the register operand. + + > NOTE: Seems this should be named `DW_CFA_offset_extended_uf` since the + > displacement is unsigned factored. + +5. `DW_CFA_offset_extended_sf` + + The `DW_CFA_offset_extended_sf` instruction takes two operands: an unsigned + LEB128 value representing a register number R and a signed LEB128 factored + displacement B. This instruction is identical to `DW_CFA_offset_extended`, + except that B is signed. + +6. `DW_CFA_val_offset` + + The `DW_CFA_val_offset` instruction takes two unsigned LEB128 operands + representing a register number R and a factored displacement B. The required + action is to change the rule for the register indicated by R to be a + val_offset(B * data_alignment_factor) rule. + + > NOTE: Seems this should be named `DW_CFA_val_offset_uf` since the + displacement is unsigned factored. + +7. `DW_CFA_val_offset_sf` + + The `DW_CFA_val_offset_sf` instruction takes two operands: an unsigned + LEB128 value representing a register number R and a signed LEB128 factored + displacement B. This instruction is identical to `DW_CFA_val_offset`, except + that B is signed. + +8. `DW_CFA_register` + + The `DW_CFA_register` instruction takes two unsigned LEB128 operands + representing register numbers R1 and R2 respectively. The required action is + to set the rule for the register specified by R1 to be a register(R2) + rule. + +9. `DW_CFA_expression` + + The `DW_CFA_expression` instruction takes two operands: an unsigned LEB128 + value representing a register number R, and a `DW_FORM_block` value + representing a DWARF operation expression E. The required action is to + change the rule for the register specified by R to be an + expression(E) rule. + + That is, E computes the location description where the register value can + be retrieved. + + See [6.4.2 Call Frame Instructions](#call-frame-instructions) regarding + restrictions on the DWARF expression operations that can be used in E. + +10. `DW_CFA_val_expression` + + The `DW_CFA_val_expression` instruction takes two operands: an unsigned + LEB128 value representing a register number R, and a `DW_FORM_block` value + representing a DWARF operation expression E. The required action is to + change the rule for the register specified by R to be a + val_expression(E) rule. + + That is, E computes the value of register R. + + See [6.4.2 Call Frame Instructions](#call-frame-instructions) regarding + restrictions on the DWARF expression operations that can be used in E. + + If the result of evaluating E is not a value with a base type size that + matches the register size, then the DWARF is ill-formed. + +11. `DW_CFA_restore` + + The `DW_CFA_restore` instruction takes a single operand (encoded with the + opcode) that represents a register number R. The required action is to + change the rule for the register specified by R to the rule assigned it by + the `initial_instructions` in the CIE. + +12. `DW_CFA_restore_extended` + + The `DW_CFA_restore_extended` instruction takes a single unsigned LEB128 + operand that represents a register number R. This instruction is identical + to `DW_CFA_restore`, except for the encoding and size of the register + operand. + +##### A.6.4.2.4 Row State Instructions + +> NOTE: These instructions are the same as in DWARF Version 5 section 6.4.2.4. + +##### A.6.4.2.5 Padding Instruction + +> NOTE: These instructions are the same as in DWARF Version 5 section 6.4.2.5. + +#### A.6.4.3 Call Frame Instruction Usage + +> NOTE: The same as in DWARF Version 5 section 6.4.3. + +#### A.6.4.4 Call Frame Calling Address + +> NOTE: The same as in DWARF Version 5 section 6.4.4. + +## A.7 Data Representation + +> NOTE: This section provides changes to existing debugger information entry +> attributes. These would be incorporated into the corresponding DWARF Version 5 +> chapter 7 sections. + +### A.7.4 32-Bit and 64-Bit DWARF Formats + +> NOTE: This augments DWARF Version 5 section 7.4 list item 3's table. + + Form Role + ------------------------ -------------------------------------- + DW_OP_implicit_pointer offset in `.debug_info` + +### A.7.5 Format of Debugging Information + +#### A.7.5.5 Classes and Forms + +> NOTE: The same as in DWARF Version 5 section 7.5.5. + +### A.7.7 DWARF Expressions + +> NOTE: Rename DWARF Version 5 section 7.7 to reflect the unification of +> location descriptions into DWARF expressions. + +#### A.7.7.1 Operation Expressions + +> NOTE: Rename DWARF Version 5 section 7.7.1 and delete section 7.7.2 to reflect +> the unification of location descriptions into DWARF expressions. + +#### A.7.7.3 Location List Expressions + +> NOTE: Rename DWARF Version 5 section 7.7.3 to reflect that location lists are +> a kind of DWARF expression. + +# B. Further Information The following references provide additional information on the extension. +A reference to the DWARF standard is provided. + +A formatted version of this extension is available on the LLVM site. It includes +many figures that help illustrate the textual description, especially of the +example DWARF expression evaluations. + Slides and a video of a presentation at the Linux Plumbers Conference 2021 related to this extension are available. -The LLVM compiler extension includes possible normative text changes for this -extension as well as the operations mentioned in the motivating examples. It -also covers other extensions needed for heterogeneous devices. +The LLVM compiler extension includes the operations mentioned in the motivating +examples. It also covers other extensions needed for heterogeneous devices. +- [DWARF Debugging Information Format](https://dwarfstd.org/) + - [DWARF Debugging Information Format Version 5](https://dwarfstd.org/Dwarf5Std.php) +- [Allow Location Descriptions on the DWARF Expression Stack](https://llvm.org/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.html) - DWARF extensions for optimized SIMT/SIMD (GPU) debugging - Linux Plumbers Conference 2021 - [Video](https://www.youtube.com/watch?v=QiR0ra0ymEY&t=10015s) - [Slides](https://linuxplumbersconf.org/event/11/contributions/1012/attachments/798/1505/DWARF_Extensions_for_Optimized_SIMT-SIMD_GPU_Debugging-LPC2021.pdf)