Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/unwind/include/mach-o/compact_unwind_encoding.h
12346 views
1
//===------------------ mach-o/compact_unwind_encoding.h ------------------===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// This file is dual licensed under the MIT and the University of Illinois Open
6
// Source Licenses. See LICENSE.TXT for details.
7
//
8
//
9
// Darwin's alternative to DWARF based unwind encodings.
10
//
11
//===----------------------------------------------------------------------===//
12
13
14
#ifndef __COMPACT_UNWIND_ENCODING__
15
#define __COMPACT_UNWIND_ENCODING__
16
17
#include <stdint.h>
18
19
//
20
// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section
21
// of object files. Or compilers can emit compact unwind information in
22
// the __LD,__compact_unwind section.
23
//
24
// When the linker creates a final linked image, it will create a
25
// __TEXT,__unwind_info section. This section is a small and fast way for the
26
// runtime to access unwind info for any given function. If the compiler
27
// emitted compact unwind info for the function, that compact unwind info will
28
// be encoded in the __TEXT,__unwind_info section. If the compiler emitted
29
// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset
30
// of the FDE in the __TEXT,__eh_frame section in the final linked image.
31
//
32
// Note: Previously, the linker would transform some DWARF unwind infos into
33
// compact unwind info. But that is fragile and no longer done.
34
35
36
//
37
// The compact unwind endoding is a 32-bit value which encoded in an
38
// architecture specific way, which registers to restore from where, and how
39
// to unwind out of the function.
40
//
41
typedef uint32_t compact_unwind_encoding_t;
42
43
44
// architecture independent bits
45
enum {
46
UNWIND_IS_NOT_FUNCTION_START = 0x80000000,
47
UNWIND_HAS_LSDA = 0x40000000,
48
UNWIND_PERSONALITY_MASK = 0x30000000,
49
};
50
51
52
53
54
//
55
// x86
56
//
57
// 1-bit: start
58
// 1-bit: has lsda
59
// 2-bit: personality index
60
//
61
// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF
62
// ebp based:
63
// 15-bits (5*3-bits per reg) register permutation
64
// 8-bits for stack offset
65
// frameless:
66
// 8-bits stack size
67
// 3-bits stack adjust
68
// 3-bits register count
69
// 10-bits register permutation
70
//
71
enum {
72
UNWIND_X86_MODE_MASK = 0x0F000000,
73
UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
74
UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
75
UNWIND_X86_MODE_STACK_IND = 0x03000000,
76
UNWIND_X86_MODE_DWARF = 0x04000000,
77
78
UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
79
UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
80
81
UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
82
UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
83
UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
84
UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
85
86
UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
87
};
88
89
enum {
90
UNWIND_X86_REG_NONE = 0,
91
UNWIND_X86_REG_EBX = 1,
92
UNWIND_X86_REG_ECX = 2,
93
UNWIND_X86_REG_EDX = 3,
94
UNWIND_X86_REG_EDI = 4,
95
UNWIND_X86_REG_ESI = 5,
96
UNWIND_X86_REG_EBP = 6,
97
};
98
99
//
100
// For x86 there are four modes for the compact unwind encoding:
101
// UNWIND_X86_MODE_EBP_FRAME:
102
// EBP based frame where EBP is push on stack immediately after return address,
103
// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current
104
// EPB value, then EBP is restored by popping off the stack, and the return
105
// is done by popping the stack once more into the pc.
106
// All non-volatile registers that need to be restored must have been saved
107
// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4
108
// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved
109
// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries.
110
// Each entry contains which register to restore.
111
// UNWIND_X86_MODE_STACK_IMMD:
112
// A "frameless" (EBP not used as frame pointer) function with a small
113
// constant stack size. To return, a constant (encoded in the compact
114
// unwind encoding) is added to the ESP. Then the return is done by
115
// popping the stack into the pc.
116
// All non-volatile registers that need to be restored must have been saved
117
// on the stack immediately after the return address. The stack_size/4 is
118
// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).
119
// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.
120
// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
121
// saved and their order.
122
// UNWIND_X86_MODE_STACK_IND:
123
// A "frameless" (EBP not used as frame pointer) function large constant
124
// stack size. This case is like the previous, except the stack size is too
125
// large to encode in the compact unwind encoding. Instead it requires that
126
// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact
127
// encoding contains the offset to the nnnnnnnn value in the function in
128
// UNWIND_X86_FRAMELESS_STACK_SIZE.
129
// UNWIND_X86_MODE_DWARF:
130
// No compact unwind encoding is available. Instead the low 24-bits of the
131
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
132
// This mode is never used in object files. It is only generated by the
133
// linker in final linked images which have only DWARF unwind info for a
134
// function.
135
//
136
// The permutation encoding is a Lehmer code sequence encoded into a
137
// single variable-base number so we can encode the ordering of up to
138
// six registers in a 10-bit space.
139
//
140
// The following is the algorithm used to create the permutation encoding used
141
// with frameless stacks. It is passed the number of registers to be saved and
142
// an array of the register numbers saved.
143
//
144
//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6])
145
//{
146
// uint32_t renumregs[6];
147
// for (int i=6-registerCount; i < 6; ++i) {
148
// int countless = 0;
149
// for (int j=6-registerCount; j < i; ++j) {
150
// if ( registers[j] < registers[i] )
151
// ++countless;
152
// }
153
// renumregs[i] = registers[i] - countless -1;
154
// }
155
// uint32_t permutationEncoding = 0;
156
// switch ( registerCount ) {
157
// case 6:
158
// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1]
159
// + 6*renumregs[2] + 2*renumregs[3]
160
// + renumregs[4]);
161
// break;
162
// case 5:
163
// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2]
164
// + 6*renumregs[3] + 2*renumregs[4]
165
// + renumregs[5]);
166
// break;
167
// case 4:
168
// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3]
169
// + 3*renumregs[4] + renumregs[5]);
170
// break;
171
// case 3:
172
// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4]
173
// + renumregs[5]);
174
// break;
175
// case 2:
176
// permutationEncoding |= (5*renumregs[4] + renumregs[5]);
177
// break;
178
// case 1:
179
// permutationEncoding |= (renumregs[5]);
180
// break;
181
// }
182
// return permutationEncoding;
183
//}
184
//
185
186
187
188
189
//
190
// x86_64
191
//
192
// 1-bit: start
193
// 1-bit: has lsda
194
// 2-bit: personality index
195
//
196
// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF
197
// rbp based:
198
// 15-bits (5*3-bits per reg) register permutation
199
// 8-bits for stack offset
200
// frameless:
201
// 8-bits stack size
202
// 3-bits stack adjust
203
// 3-bits register count
204
// 10-bits register permutation
205
//
206
enum {
207
UNWIND_X86_64_MODE_MASK = 0x0F000000,
208
UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
209
UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
210
UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
211
UNWIND_X86_64_MODE_DWARF = 0x04000000,
212
213
UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
214
UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
215
216
UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
217
UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
218
UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
219
UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
220
221
UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
222
};
223
224
enum {
225
UNWIND_X86_64_REG_NONE = 0,
226
UNWIND_X86_64_REG_RBX = 1,
227
UNWIND_X86_64_REG_R12 = 2,
228
UNWIND_X86_64_REG_R13 = 3,
229
UNWIND_X86_64_REG_R14 = 4,
230
UNWIND_X86_64_REG_R15 = 5,
231
UNWIND_X86_64_REG_RBP = 6,
232
};
233
//
234
// For x86_64 there are four modes for the compact unwind encoding:
235
// UNWIND_X86_64_MODE_RBP_FRAME:
236
// RBP based frame where RBP is push on stack immediately after return address,
237
// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current
238
// EPB value, then RBP is restored by popping off the stack, and the return
239
// is done by popping the stack once more into the pc.
240
// All non-volatile registers that need to be restored must have been saved
241
// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8
242
// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved
243
// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.
244
// Each entry contains which register to restore.
245
// UNWIND_X86_64_MODE_STACK_IMMD:
246
// A "frameless" (RBP not used as frame pointer) function with a small
247
// constant stack size. To return, a constant (encoded in the compact
248
// unwind encoding) is added to the RSP. Then the return is done by
249
// popping the stack into the pc.
250
// All non-volatile registers that need to be restored must have been saved
251
// on the stack immediately after the return address. The stack_size/8 is
252
// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).
253
// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.
254
// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were
255
// saved and their order.
256
// UNWIND_X86_64_MODE_STACK_IND:
257
// A "frameless" (RBP not used as frame pointer) function large constant
258
// stack size. This case is like the previous, except the stack size is too
259
// large to encode in the compact unwind encoding. Instead it requires that
260
// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact
261
// encoding contains the offset to the nnnnnnnn value in the function in
262
// UNWIND_X86_64_FRAMELESS_STACK_SIZE.
263
// UNWIND_X86_64_MODE_DWARF:
264
// No compact unwind encoding is available. Instead the low 24-bits of the
265
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
266
// This mode is never used in object files. It is only generated by the
267
// linker in final linked images which have only DWARF unwind info for a
268
// function.
269
//
270
271
272
// ARM64
273
//
274
// 1-bit: start
275
// 1-bit: has lsda
276
// 2-bit: personality index
277
//
278
// 4-bits: 4=frame-based, 3=DWARF, 2=frameless
279
// frameless:
280
// 12-bits of stack size
281
// frame-based:
282
// 4-bits D reg pairs saved
283
// 5-bits X reg pairs saved
284
// DWARF:
285
// 24-bits offset of DWARF FDE in __eh_frame section
286
//
287
enum {
288
UNWIND_ARM64_MODE_MASK = 0x0F000000,
289
UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
290
UNWIND_ARM64_MODE_DWARF = 0x03000000,
291
UNWIND_ARM64_MODE_FRAME = 0x04000000,
292
293
UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
294
UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
295
UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
296
UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
297
UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
298
UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
299
UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
300
UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
301
UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
302
303
UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
304
UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
305
};
306
// For arm64 there are three modes for the compact unwind encoding:
307
// UNWIND_ARM64_MODE_FRAME:
308
// This is a standard arm64 prolog where FP/LR are immediately pushed on the
309
// stack, then SP is copied to FP. If there are any non-volatile registers
310
// saved, then are copied into the stack frame in pairs in a contiguous
311
// range right below the saved FP/LR pair. Any subset of the five X pairs
312
// and four D pairs can be saved, but the memory layout must be in register
313
// number order.
314
// UNWIND_ARM64_MODE_FRAMELESS:
315
// A "frameless" leaf function, where FP/LR are not saved. The return address
316
// remains in LR throughout the function. If any non-volatile registers
317
// are saved, they must be pushed onto the stack before any stack space is
318
// allocated for local variables. The stack sized (including any saved
319
// non-volatile registers) divided by 16 is encoded in the bits
320
// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.
321
// UNWIND_ARM64_MODE_DWARF:
322
// No compact unwind encoding is available. Instead the low 24-bits of the
323
// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
324
// This mode is never used in object files. It is only generated by the
325
// linker in final linked images which have only DWARF unwind info for a
326
// function.
327
//
328
329
330
331
332
333
////////////////////////////////////////////////////////////////////////////////
334
//
335
// Relocatable Object Files: __LD,__compact_unwind
336
//
337
////////////////////////////////////////////////////////////////////////////////
338
339
//
340
// A compiler can generated compact unwind information for a function by adding
341
// a "row" to the __LD,__compact_unwind section. This section has the
342
// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.
343
// It is removed by the new linker, so never ends up in final executables.
344
// This section is a table, initially with one row per function (that needs
345
// unwind info). The table columns and some conceptual entries are:
346
//
347
// range-start pointer to start of function/range
348
// range-length
349
// compact-unwind-encoding 32-bit encoding
350
// personality-function or zero if no personality function
351
// lsda or zero if no LSDA data
352
//
353
// The length and encoding fields are 32-bits. The other are all pointer sized.
354
//
355
// In x86_64 assembly, these entry would look like:
356
//
357
// .section __LD,__compact_unwind,regular,debug
358
//
359
// #compact unwind for _foo
360
// .quad _foo
361
// .set L1,LfooEnd-_foo
362
// .long L1
363
// .long 0x01010001
364
// .quad 0
365
// .quad 0
366
//
367
// #compact unwind for _bar
368
// .quad _bar
369
// .set L2,LbarEnd-_bar
370
// .long L2
371
// .long 0x01020011
372
// .quad __gxx_personality
373
// .quad except_tab1
374
//
375
//
376
// Notes: There is no need for any labels in the the __compact_unwind section.
377
// The use of the .set directive is to force the evaluation of the
378
// range-length at assembly time, instead of generating relocations.
379
//
380
// To support future compiler optimizations where which non-volatile registers
381
// are saved changes within a function (e.g. delay saving non-volatiles until
382
// necessary), there can by multiple lines in the __compact_unwind table for one
383
// function, each with a different (non-overlapping) range and each with
384
// different compact unwind encodings that correspond to the non-volatiles
385
// saved at that range of the function.
386
//
387
// If a particular function is so wacky that there is no compact unwind way
388
// to encode it, then the compiler can emit traditional DWARF unwind info.
389
// The runtime will use which ever is available.
390
//
391
// Runtime support for compact unwind encodings are only available on 10.6
392
// and later. So, the compiler should not generate it when targeting pre-10.6.
393
394
395
396
397
////////////////////////////////////////////////////////////////////////////////
398
//
399
// Final Linked Images: __TEXT,__unwind_info
400
//
401
////////////////////////////////////////////////////////////////////////////////
402
403
//
404
// The __TEXT,__unwind_info section is laid out for an efficient two level lookup.
405
// The header of the section contains a coarse index that maps function address
406
// to the page (4096 byte block) containing the unwind info for that function.
407
//
408
409
#define UNWIND_SECTION_VERSION 1
410
struct unwind_info_section_header
411
{
412
uint32_t version; // UNWIND_SECTION_VERSION
413
uint32_t commonEncodingsArraySectionOffset;
414
uint32_t commonEncodingsArrayCount;
415
uint32_t personalityArraySectionOffset;
416
uint32_t personalityArrayCount;
417
uint32_t indexSectionOffset;
418
uint32_t indexCount;
419
// compact_unwind_encoding_t[]
420
// uint32_t personalities[]
421
// unwind_info_section_header_index_entry[]
422
// unwind_info_section_header_lsda_index_entry[]
423
};
424
425
struct unwind_info_section_header_index_entry
426
{
427
uint32_t functionOffset;
428
uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page
429
uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range
430
};
431
432
struct unwind_info_section_header_lsda_index_entry
433
{
434
uint32_t functionOffset;
435
uint32_t lsdaOffset;
436
};
437
438
//
439
// There are two kinds of second level index pages: regular and compressed.
440
// A compressed page can hold up to 1021 entries, but it cannot be used
441
// if too many different encoding types are used. The regular page holds
442
// 511 entries.
443
//
444
445
struct unwind_info_regular_second_level_entry
446
{
447
uint32_t functionOffset;
448
compact_unwind_encoding_t encoding;
449
};
450
451
#define UNWIND_SECOND_LEVEL_REGULAR 2
452
struct unwind_info_regular_second_level_page_header
453
{
454
uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR
455
uint16_t entryPageOffset;
456
uint16_t entryCount;
457
// entry array
458
};
459
460
#define UNWIND_SECOND_LEVEL_COMPRESSED 3
461
struct unwind_info_compressed_second_level_page_header
462
{
463
uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
464
uint16_t entryPageOffset;
465
uint16_t entryCount;
466
uint16_t encodingsPageOffset;
467
uint16_t encodingsCount;
468
// 32-bit entry array
469
// encodings array
470
};
471
472
#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
473
#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF)
474
475
476
477
#endif
478
479