zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

compact_unwind_encoding.h (21531B) - Raw


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