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

Generated by cgit