forked from ccoutant/dwarf-locations
-
Notifications
You must be signed in to change notification settings - Fork 0
/
010-generalize-offsetting.txt
436 lines (358 loc) · 21.2 KB
/
010-generalize-offsetting.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
Part 7: Generalize Offsetting of Location Descriptions
PROBLEM DESCRIPTION
After [Allow location description on the DWARF evaluation stack] proposal, the
DW_OP_plus and DW_OP_minus operations can be defined to operate on a memory
location description in the default target architecture specific address space
and a generic type value to produce an updated memory location description. This
allows them to continue to be used to offset an address.
To generalize offsetting to any location description, including location
descriptions that describe when bytes are in registers, are implicit, or a
composite of these, the DW_OP_offset, DW_OP_offset_uconst, and DW_OP_bit_offset
offset operations are added.
It could be possible to define DW_OP_plus, DW_OP_plus_uconst, and DW_OP_minus to
operate on any location description to avoid needing DW_OP_offset and
DW_OP_offset_uconst. However, this is not proposed since currently the
arithmetic operations are defined to require values of the same base type and
produces a result with the same base type. Allowing these operations to act on
location descriptions would permit the first operand to be a location
description and the second operand to be an integral value type, or vice versa,
and return a location description. This complicates the rules for implicit
conversions between default address space memory location descriptions and
generic base type values. Currently the rules would convert such a location
description to the memory address value and then perform two's compliment wrap
around arithmetic. If the result was used as a location description, it would be
implicitly converted back to a default address space memory location
description. This is different to the overflow rules on location descriptions.
To allow control, an operation that converts a memory location description to an
address integral type value would be required. Keeping a separation of location
description operations and arithmetic operations avoids this semantic
complexity.
The offset operators are designed to address four specific problems.
The offset operations can operate on location storage of any size. For example,
register, composite, and implicit location storage could be any number of bits
in size. It is simpler to define offsets that exceed the size of the location
storage as being an evaluation error, than having to force an implementation to
support potentially infinite precision offsets to allow it to correctly track a
series of positive and negative offsets that may transiently overflow or
underflow, but end up in range. This is simple for the arithmetic operations as
they are defined in terms of two's compliment arithmetic on a base type of a
fixed size. Therefore, the offset operation defines that integer overflow is
ill-formed. This is in contrast to the DW_OP_plus, DW_OP_plus_uconst, and
DW_OP_minus arithmetic operations which define that it causes wrap-around.
Having the offset operations allows DW_OP_push_object_address to push a
location description that may be in a register, or be an implicit value. The
DWARF expression of DW_TAG_ptr_to_member_type can use the offset operations
without regard to what kind of location description was pushed.
Since [Allow location description on the DWARF evaluation stack] has
generalized location storage to be bit indexable, DW_OP_bit_offset generalizes
DWARF to work with bit fields. This is generally not possible in DWARF Version
5.
The DW_OP_*piece operations only allow literal indices. A way to use a computed
offset of an arbitrary location description (such as a vector register) is
required. The offset operations provide this ability since they can be used to
compute a location description on the stack.
PROPOSED SOLUTION
This proposal depends on proposal [Allow location description on the DWARF
evaluation stack].
In Section 2.5.3 "DWARF Location Description", delete the following paragraph:
----------------------------------------------------------------------------
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.
----------------------------------------------------------------------------
Add the following to Section 2.5.4.4.1 "General Location Description
Operations":
----------------------------------------------------------------------------
1. DW_OP_offset
DW_OP_offset pops two stack entries. The first must be an integral type
value that represents a byte displacement B. The second must be a
location description L.
It adds the value of B scaled by 8 (the byte size) to the bit offset of
each single location description SL of L, and pushes the updated 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.
2. DW_OP_offset_uconst
DW_OP_offset_uconst has a single unsigned LEB128 integer operand that
represents a byte displacement B.
The operation is equivalent to performing DW_OP_constu B;
DW_OP_offset.
[non-normative] This operation is supplied specifically to be able to
encode more field displacements in two bytes than can be done with
DW_OP_lit*; DW_OP_offset.
3. DW_OP_bit_offset
DW_OP_bit_offset pops two stack entries. The first must be an integral
type value that represents a bit displacement B. The second must be a
location description L.
It adds the value of B to the bit offset of each single location
description SL of L, and pushes the updated 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.
4. DW_OP_push_object_address
...[same]
----------------------------------------------------------------------------
> [For further discussion...]
> Should DW_OP_offset_uconst be named DW_OP_offset_uconst to match
> DW_OP_plus_uconst, or DW_OP_offset_constu to match DW_OP_constu?
In Section 2.5.4.4.3 "Memory Location Description Operations" in the description
of DW_OP_fbreg, replace the paragraph:
----------------------------------------------------------------------------
The location description L is updated by bit offset B scaled by 8 (the byte
size) and pushed on the stack.
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
The location description L is updated as if the DW_OP_offset_uconst B
operation was applied. The updated L is pushed on the stack.
----------------------------------------------------------------------------
In Section 2.5.4.4.5 "Implicit Location Description Operations" in the
description of DW_OP_implicit_pointer, replace the paragraph:
----------------------------------------------------------------------------
The location description RL is updated by bit offset B scaled by 8 (the byte
size).
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
The bit offset of RL is updated as if the DW_OP_offset_uconst B operation
was applied.
----------------------------------------------------------------------------
In Section 2.5.4.4.6 "Composite Location Description Operations" in the
description of DW_OP_piece, after the paragraph:
----------------------------------------------------------------------------
[non-normative] Many compilers store a single variable in sets of
registers...
----------------------------------------------------------------------------
... add the following paragraph:
----------------------------------------------------------------------------
[non-normative] If a non-0 byte displacement is required, the DW_OP_offset
operation can be used to update the location description before using it as
the part location description of a DW_OP_piece operation.
----------------------------------------------------------------------------
In Section 2.5.4.4.6 "Composite Location Description Operations" in the
description of DW_OP_bit_piece, replace the paragraph:
----------------------------------------------------------------------------
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.
----------------------------------------------------------------------------
... with the following paragraph:
----------------------------------------------------------------------------
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 as if the DW_OP_constu B; DW_OP_bit_offset operations were applied.
----------------------------------------------------------------------------
In Section 2.5.4.4.6 "Composite Location Description Operations" in the
description of DW_OP_bit_piece, after the paragraph:
----------------------------------------------------------------------------
[non-normative] DW_OP_bit_piece is used instead of DW_OP_piece when the
piece...
----------------------------------------------------------------------------
... add the following paragraph:
----------------------------------------------------------------------------
[non-normative] If a computed bit displacement is required, the
DW_OP_bit_offset operation can be used to update the location description
before using it as the part location description of a DW_OP_bit_piece
operation.
----------------------------------------------------------------------------
In Section 5.7.3 "Derived or Extended Structures, Classes and Interfaces" in the
description of DW_AT_data_member_location, replace the following paragraph:
----------------------------------------------------------------------------
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.
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
The result of the attribute is obtained by evaluating a DW_OP_offset B
operation with an initial stack comprising the location description of the
beginning of the containing entity. The result of the evaluation is the
location description of the base of the member entry.
----------------------------------------------------------------------------
In Section 6.4.1 Structure of Call Frame Information, replace the following
paragraph:
----------------------------------------------------------------------------
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]) updated with
the bit offset N scaled by 8 (the byte size).
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
offset(N)
N is a signed byte offset. The previous value of this register is saved
at the location description computed as if the DWARF operation
expression DW_OP_offset N 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).
----------------------------------------------------------------------------
And the following paragraph:
----------------------------------------------------------------------------
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]) updated with the bit offset
N scaled by 8 (the byte size).
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
val_offset(N)
N is a signed byte offset. The previous value of this register is the
memory byte address of the location description computed as if the DWARF
operation expression DW_OP_offset N 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).
----------------------------------------------------------------------------
Add the following rows to table 7.9 in section "7.7.1 Operation Expressions":
----------------------------------------------------------------------------
------------------- ----- --------- ---------------------------
No. of
Operation Code Operands Notes
------------------- ----- --------- ---------------------------
...
DW_OP_offset TBA 0
DW_OP_offset_uconst TBA 1 ULEB128 byte displacement
DW_OP_bit_offset TBA 0
------------------- ----- --------- ---------------------------
----------------------------------------------------------------------------
In Appendix D.1.3 "DWARF Location Description Examples", replace the example:
----------------------------------------------------------------------------
DW_OP_plus_uconst 4
A structure member is four bytes from the start of the structure
instance. The base address is assumed to be already on the stack.
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
DW_OP_offset_uconst 4
A structure member is four bytes from the start of the structure
instance. The location description of the base of the structure instance
is assumed to be already on the stack.
----------------------------------------------------------------------------
In Appendix D.1.3 "DWARF Location Description Examples", replace the example:
----------------------------------------------------------------------------
DW_OP_entry_value 1 DW_OP_reg5 DW_OP_plus_uconst 16
The address of the memory location is calculated by adding 16 to the
value contained in register 5 upon entering the current subprogram.
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
DW_OP_entry_value 1 DW_OP_reg5 DW_OP_offset_uconst 16
The address of the memory location is calculated by adding 16 to the
value contained in register 5 upon entering the current subprogram.
----------------------------------------------------------------------------
In Appendix D.2.1 "Fortran Simple Array Example", replace each occurrence of
DW_OP_plus with DW_OP_offset in Figure D.4 "Fortran array example: DWARF
description".
In Appendix D.2.3 "Fortran 2008 Assumed-rank Array Example", replace Figure D.13
"Sample DWARF for the array descriptor in Figure D.12":
----------------------------------------------------------------------------
10$: DW_TAG_array_type
DW_AT_type(reference to real)
DW_AT_rank(expression=
DW_OP_push_object_address
DW_OP_lit<n>
DW_OP_plus
DW_OP_deref)
DW_AT_data_location(expression=
DW_OP_push_object_address
DW_OP_lit<n>
DW_OP_plus
DW_OP_deref)
11$: DW_TAG_generic_subrange
DW_AT_type(reference to integer)
! offset of rank in descriptor
! offset of data in descriptor
DW_AT_lower_bound(expression=
! Looks up the lower bound of dimension i.
! Operation ! Stack effect
! (implicit) ! i
DW_OP_lit<n> ! i sizeof(dim)
DW_OP_mul ! dim[i]
DW_OP_lit<n> ! dim[i] offsetof(dim)
DW_OP_plus ! dim[i]+offset
DW_OP_push_object_address ! dim[i]+offsetof(dim) objptr
DW_OP_plus ! objptr.dim[i]
DW_OP_lit<n> ! objptr.dim[i] offsetof(lb)
DW_OP_plus ! objptr.dim[i].lowerbound
DW_OP_deref) ! *objptr.dim[i].lowerbound
DW_AT_upper_bound(expression=
! Looks up the upper bound of dimension i.
DW_OP_lit<n> ! sizeof(dim)
DW_OP_mul
DW_OP_lit<n> ! offsetof(dim)
DW_OP_plus
DW_OP_push_object_address
DW_OP_plus
DW_OP_lit<n> ! offset of upperbound in dim
DW_OP_plus
DW_OP_deref)
DW_AT_byte_stride(expression=
! Looks up the byte stride of dimension i.
...
! (analogous to DW_AT_upper_bound)
)
----------------------------------------------------------------------------
... with the following:
----------------------------------------------------------------------------
10$: DW_TAG_array_type
DW_AT_type(reference to real)
DW_AT_rank(expression=
DW_OP_push_object_address
DW_OP_lit<n>
| DW_OP_offset
DW_OP_deref)
DW_AT_data_location(expression=
DW_OP_push_object_address
DW_OP_lit<n>
| DW_OP_offset
DW_OP_deref)
11$: DW_TAG_generic_subrange
DW_AT_type(reference to integer)
! offset of rank in descriptor
! offset of data in descriptor
DW_AT_lower_bound(expression=
! Looks up the lower bound of dimension i.
! Operation ! Stack effect
! (implicit) ! i
DW_OP_lit<n> ! i sizeof(dim)
DW_OP_mul ! dim[i]
DW_OP_lit<n> ! dim[i] offsetof(dim)
DW_OP_plus ! dim[i]+offset
DW_OP_push_object_address ! dim[i]+offsetof(dim) objptr
| DW_OP_swap ! objptr dim[i]+offsetof(dim)
| DW_OP_offset ! objptr.dim[i]
DW_OP_lit<n> ! objptr.dim[i] offsetof(lb)
| DW_OP_offset ! objptr.dim[i].lowerbound
DW_OP_deref) ! *objptr.dim[i].lowerbound
DW_AT_upper_bound(expression=
! Looks up the upper bound of dimension i.
DW_OP_lit<n> ! sizeof(dim)
DW_OP_mul
DW_OP_lit<n> ! offsetof(dim)
DW_OP_plus
DW_OP_push_object_address
| DW_OP_swap
| DW_OP_offset
DW_OP_lit<n> ! offset of upperbound in dim
| DW_OP_offset
DW_OP_deref)
DW_AT_byte_stride(expression=
! Looks up the byte stride of dimension i.
...
! (analogous to DW_AT_upper_bound)
)
----------------------------------------------------------------------------
> [For further discussion...]
> This example suggests that DW_AT_lower_bound and DW_AT_upper_bound evaluate an
> exprloc with an initial stack containing the rank value. The attribute
> definition should be updated to state this.
In Appendix D.2.6 "Ada Example", replace DW_OP_plus with DW_OP_offset in Figure
D.20 "Ada example: DWARF description".