Home | History | Annotate | Download | only in mach-o
      1 /* Mach-O compact unwind encoding.
      2    Copyright (C) 2014 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #ifndef _MACH_O_UNWIND_H
     22 #define _MACH_O_UNWIND_H
     23 
     24 /* Encodings bits for all cpus.  */
     25 #define MACH_O_UNWIND_IS_NOT_FUNCTION_START 0x80000000
     26 #define MACH_O_UNWIND_HAS_LSDA              0x40000000
     27 #define MACH_O_UNWIND_PERSONALITY_MASK      0x30000000
     28 #define MACH_O_UNWIND_PERSONALITY_SHIFT     28
     29 
     30 /* Encodings for x86-64.  */
     31 
     32 /* Kind of encoding (4 bits).  */
     33 #define MACH_O_UNWIND_X86_64_MODE_MASK       0x0f000000
     34 
     35 /* Frame is RBP based, using the standard sequence: push %rbp; mov %rsp, %rbp.
     36    Non-volatile registers must be saved in the stack starting at %rbp-8 to
     37    %rbp-2040 (offset is encoded in offset bits * 8).  Registers saved are
     38    encoded in registers bits, 3 bits per register.  */
     39 #define MACH_O_UNWIND_X86_64_MODE_RBP_FRAME  0x01000000
     40 #define  MACH_O_UNWIND_X86_64_RBP_FRAME_REGSITERS 0x00007FFF
     41 #define  MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET    0x00FF0000
     42 
     43 /* Frameless function, with a small stack size.  */
     44 #define MACH_O_UNWIND_X86_64_MODE_STACK_IMMD 0x02000000
     45 #define  MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE      0x00FF0000
     46 #define  MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT       0x00001C00
     47 #define  MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION 0x000003FF
     48 
     49 /* Frameless function, with a larger stack size. The stack size is the sum
     50    of the X in subq $X,%rsp (address of X is at function + stack size bits)
     51    and stack adjust.  */
     52 #define MACH_O_UNWIND_X86_64_MODE_STACK_IND          0x03000000
     53 #define  MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST 0x0000E000
     54 
     55 /* Use dwarf.  */
     56 #define MACH_O_UNWIND_X86_64_MODE_DWARF      0x04000000
     57 #define  MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET 0x00ffffff
     58 
     59 /* Registers.  */
     60 #define MACH_O_UNWIND_X86_64_REG_NONE 0
     61 #define MACH_O_UNWIND_X86_64_REG_RBX 1
     62 #define MACH_O_UNWIND_X86_64_REG_R12 2
     63 #define MACH_O_UNWIND_X86_64_REG_R13 3
     64 #define MACH_O_UNWIND_X86_64_REG_R14 4
     65 #define MACH_O_UNWIND_X86_64_REG_R15 5
     66 #define MACH_O_UNWIND_X86_64_REG_RBP 6
     67 
     68 /* Encodings for x86 (almot the same as x86-64).  */
     69 
     70 /* Kind of encoding (4 bits).  */
     71 #define MACH_O_UNWIND_X86_MODE_MASK       0x0f000000
     72 
     73 /* Frame is EBP based, using the standard sequence: push %ebp; mov %esp, %ebp.
     74    Non-volatile registers must be saved in the stack starting at %ebp-4 to
     75    %ebp-240 (offset is encoded in offset bits * 4).  Registers saved are
     76    encoded in registers bits, 3 bits per register.  */
     77 #define MACH_O_UNWIND_X86_MODE_EBP_FRAME  0x01000000
     78 #define  MACH_O_UNWIND_X86_EBP_FRAME_REGSITERS 0x00007FFF
     79 #define  MACH_O_UNWIND_X86_EBP_FRAME_OFFSET    0x00FF0000
     80 
     81 /* Frameless function, with a small stack size.  */
     82 #define MACH_O_UNWIND_X86_MODE_STACK_IMMD 0x02000000
     83 #define  MACH_O_UNWIND_X86_FRAMELESS_STACK_SIZE      0x00FF0000
     84 #define  MACH_O_UNWIND_X86_FRAMELESS_REG_COUNT       0x00001C00
     85 #define  MACH_O_UNWIND_X86_FRAMELESS_REG_PERMUTATION 0x000003FF
     86 
     87 /* Frameless function, with a larger stack size. The stack size is the sum
     88    of the X in subq $X,%esp (address of X is at function + stack size bits)
     89    and stack adjust.  */
     90 #define MACH_O_UNWIND_X86_MODE_STACK_IND          0x03000000
     91 #define  MACH_O_UNWIND_X86_FRAMELESS_STACK_ADJUST 0x0000E000
     92 
     93 /* Use dwarf.  */
     94 #define MACH_O_UNWIND_X86_MODE_DWARF      0x04000000
     95 #define  MACH_O_UNWIND_X86_DWARF_SECTION_OFFSET 0x00ffffff
     96 
     97 /* Registers.  */
     98 #define MACH_O_UNWIND_X86_REG_NONE 0
     99 #define MACH_O_UNWIND_X86_REG_EBX 1
    100 #define MACH_O_UNWIND_X86_REG_ECX 2
    101 #define MACH_O_UNWIND_X86_REG_EDX 3
    102 #define MACH_O_UNWIND_X86_REG_EDI 4
    103 #define MACH_O_UNWIND_X86_REG_ESI 5
    104 #define MACH_O_UNWIND_X86_REG_EBP 6
    105 
    106 /* Entry in object file (in __LD,__compact_unwind section).  */
    107 
    108 struct mach_o_compact_unwind_32
    109 {
    110   unsigned char start[4];
    111   unsigned char length[4];
    112   unsigned char encoding[4];
    113   unsigned char personality[4];
    114   unsigned char lsda[4];
    115 };
    116 
    117 struct mach_o_compact_unwind_64
    118 {
    119   unsigned char start[8];
    120   unsigned char length[4];
    121   unsigned char encoding[4];
    122   unsigned char personality[8];
    123   unsigned char lsda[8];
    124 };
    125 
    126 /* Header in images (in __TEXT,__unwind_info).  */
    127 
    128 #define MACH_O_UNWIND_SECTION_VERSION 1 /* Current verion in header.  */
    129 struct mach_o_unwind_info_header
    130 {
    131   unsigned char version[4];	/* Currently MACH_O_UNWIND_SECTION_VERSION. */
    132   unsigned char encodings_array_offset[4];
    133   unsigned char encodings_array_count[4];
    134   unsigned char personality_array_offset[4];
    135   unsigned char personality_array_count[4];
    136   unsigned char index_offset[4];
    137   unsigned char index_count[4];
    138   /* Followed by:
    139      - encodings array
    140        These are the encodings shared, for index < encoding_array_count
    141      - personality array
    142        count given by personality_array_count
    143      - index entries
    144        count given by index_count
    145      - lsda index entries
    146        last offset given by lsda offset of last index_entry.
    147   */
    148 };
    149 
    150 struct mach_o_unwind_index_entry
    151 {
    152   unsigned char function_offset[4];
    153   unsigned char second_level_offset[4];
    154   unsigned char lsda_index_offset[4];
    155 };
    156 
    157 struct mach_o_unwind_lsda_index_entry
    158 {
    159   unsigned char function_offset[4];
    160   unsigned char lsda_offset[4];
    161 };
    162 
    163 /* Second level index pages.  */
    164 
    165 #define MACH_O_UNWIND_SECOND_LEVEL_REGULAR 2
    166 struct mach_o_unwind_regular_second_level_page_header
    167 {
    168   unsigned char kind[4];
    169   unsigned char entry_page_offset[2];
    170   unsigned char entry_count[2];
    171   /* Array of entries.  */
    172 };
    173 
    174 struct mach_o_unwind_regular_second_level_entry
    175 {
    176   unsigned char function_offset[4];
    177   unsigned char encoding[4];
    178 };
    179 
    180 #define MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED 3
    181 struct mach_o_unwind_compressed_second_level_page_header
    182 {
    183   unsigned char kind[4];
    184   unsigned char entry_page_offset[2];
    185   unsigned char entry_count[2];
    186   unsigned char encodings_offset[2];
    187   unsigned char encodings_count[2];
    188   /* Followed by entries array (one word, see below).  */
    189   /* Followed by (non-common) encodings array.  */
    190 };
    191 
    192 /* Compressed entries are one word, containing function offset and encoding
    193    index.  */
    194 #define MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(en) \
    195    ((en) & 0x00FFFFFF)
    196 #define MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(en) \
    197    (((en) >> 24) & 0xFF)
    198 
    199 #endif /* _MACH_O_UNWIND_H */
    200