15ba6b03cSchristos /* Mach-O compact unwind encoding. 2*f22f0ef4Schristos Copyright (C) 2014-2022 Free Software Foundation, Inc. 35ba6b03cSchristos 45ba6b03cSchristos This file is part of BFD, the Binary File Descriptor library. 55ba6b03cSchristos 65ba6b03cSchristos This program is free software; you can redistribute it and/or modify 75ba6b03cSchristos it under the terms of the GNU General Public License as published by 85ba6b03cSchristos the Free Software Foundation; either version 3 of the License, or 95ba6b03cSchristos (at your option) any later version. 105ba6b03cSchristos 115ba6b03cSchristos This program is distributed in the hope that it will be useful, 125ba6b03cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 135ba6b03cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 145ba6b03cSchristos GNU General Public License for more details. 155ba6b03cSchristos 165ba6b03cSchristos You should have received a copy of the GNU General Public License 175ba6b03cSchristos along with this program; if not, write to the Free Software 185ba6b03cSchristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 195ba6b03cSchristos MA 02110-1301, USA. */ 205ba6b03cSchristos 215ba6b03cSchristos #ifndef _MACH_O_UNWIND_H 225ba6b03cSchristos #define _MACH_O_UNWIND_H 235ba6b03cSchristos 245ba6b03cSchristos /* Encodings bits for all cpus. */ 255ba6b03cSchristos #define MACH_O_UNWIND_IS_NOT_FUNCTION_START 0x80000000 265ba6b03cSchristos #define MACH_O_UNWIND_HAS_LSDA 0x40000000 275ba6b03cSchristos #define MACH_O_UNWIND_PERSONALITY_MASK 0x30000000 285ba6b03cSchristos #define MACH_O_UNWIND_PERSONALITY_SHIFT 28 295ba6b03cSchristos 305ba6b03cSchristos /* Encodings for x86-64. */ 315ba6b03cSchristos 325ba6b03cSchristos /* Kind of encoding (4 bits). */ 335ba6b03cSchristos #define MACH_O_UNWIND_X86_64_MODE_MASK 0x0f000000 345ba6b03cSchristos 355ba6b03cSchristos /* Frame is RBP based, using the standard sequence: push %rbp; mov %rsp, %rbp. 365ba6b03cSchristos Non-volatile registers must be saved in the stack starting at %rbp-8 to 375ba6b03cSchristos %rbp-2040 (offset is encoded in offset bits * 8). Registers saved are 385ba6b03cSchristos encoded in registers bits, 3 bits per register. */ 395ba6b03cSchristos #define MACH_O_UNWIND_X86_64_MODE_RBP_FRAME 0x01000000 40fa2c2dd3Schristos #define MACH_O_UNWIND_X86_64_RBP_FRAME_REGISTERS 0x00007FFF 415ba6b03cSchristos #define MACH_O_UNWIND_X86_64_RBP_FRAME_OFFSET 0x00FF0000 425ba6b03cSchristos 435ba6b03cSchristos /* Frameless function, with a small stack size. */ 445ba6b03cSchristos #define MACH_O_UNWIND_X86_64_MODE_STACK_IMMD 0x02000000 455ba6b03cSchristos #define MACH_O_UNWIND_X86_64_FRAMELESS_STACK_SIZE 0x00FF0000 465ba6b03cSchristos #define MACH_O_UNWIND_X86_64_FRAMELESS_REG_COUNT 0x00001C00 475ba6b03cSchristos #define MACH_O_UNWIND_X86_64_FRAMELESS_REG_PERMUTATION 0x000003FF 485ba6b03cSchristos 495ba6b03cSchristos /* Frameless function, with a larger stack size. The stack size is the sum 505ba6b03cSchristos of the X in subq $X,%rsp (address of X is at function + stack size bits) 515ba6b03cSchristos and stack adjust. */ 525ba6b03cSchristos #define MACH_O_UNWIND_X86_64_MODE_STACK_IND 0x03000000 535ba6b03cSchristos #define MACH_O_UNWIND_X86_64_FRAMELESS_STACK_ADJUST 0x0000E000 545ba6b03cSchristos 555ba6b03cSchristos /* Use dwarf. */ 565ba6b03cSchristos #define MACH_O_UNWIND_X86_64_MODE_DWARF 0x04000000 575ba6b03cSchristos #define MACH_O_UNWIND_X86_64_DWARF_SECTION_OFFSET 0x00ffffff 585ba6b03cSchristos 595ba6b03cSchristos /* Registers. */ 605ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_NONE 0 615ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_RBX 1 625ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_R12 2 635ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_R13 3 645ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_R14 4 655ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_R15 5 665ba6b03cSchristos #define MACH_O_UNWIND_X86_64_REG_RBP 6 675ba6b03cSchristos 685ba6b03cSchristos /* Encodings for x86 (almot the same as x86-64). */ 695ba6b03cSchristos 705ba6b03cSchristos /* Kind of encoding (4 bits). */ 715ba6b03cSchristos #define MACH_O_UNWIND_X86_MODE_MASK 0x0f000000 725ba6b03cSchristos 735ba6b03cSchristos /* Frame is EBP based, using the standard sequence: push %ebp; mov %esp, %ebp. 745ba6b03cSchristos Non-volatile registers must be saved in the stack starting at %ebp-4 to 755ba6b03cSchristos %ebp-240 (offset is encoded in offset bits * 4). Registers saved are 765ba6b03cSchristos encoded in registers bits, 3 bits per register. */ 775ba6b03cSchristos #define MACH_O_UNWIND_X86_MODE_EBP_FRAME 0x01000000 78fa2c2dd3Schristos #define MACH_O_UNWIND_X86_EBP_FRAME_REGISTERS 0x00007FFF 795ba6b03cSchristos #define MACH_O_UNWIND_X86_EBP_FRAME_OFFSET 0x00FF0000 805ba6b03cSchristos 815ba6b03cSchristos /* Frameless function, with a small stack size. */ 825ba6b03cSchristos #define MACH_O_UNWIND_X86_MODE_STACK_IMMD 0x02000000 835ba6b03cSchristos #define MACH_O_UNWIND_X86_FRAMELESS_STACK_SIZE 0x00FF0000 845ba6b03cSchristos #define MACH_O_UNWIND_X86_FRAMELESS_REG_COUNT 0x00001C00 855ba6b03cSchristos #define MACH_O_UNWIND_X86_FRAMELESS_REG_PERMUTATION 0x000003FF 865ba6b03cSchristos 875ba6b03cSchristos /* Frameless function, with a larger stack size. The stack size is the sum 885ba6b03cSchristos of the X in subq $X,%esp (address of X is at function + stack size bits) 895ba6b03cSchristos and stack adjust. */ 905ba6b03cSchristos #define MACH_O_UNWIND_X86_MODE_STACK_IND 0x03000000 915ba6b03cSchristos #define MACH_O_UNWIND_X86_FRAMELESS_STACK_ADJUST 0x0000E000 925ba6b03cSchristos 935ba6b03cSchristos /* Use dwarf. */ 945ba6b03cSchristos #define MACH_O_UNWIND_X86_MODE_DWARF 0x04000000 955ba6b03cSchristos #define MACH_O_UNWIND_X86_DWARF_SECTION_OFFSET 0x00ffffff 965ba6b03cSchristos 975ba6b03cSchristos /* Registers. */ 985ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_NONE 0 995ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_EBX 1 1005ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_ECX 2 1015ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_EDX 3 1025ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_EDI 4 1035ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_ESI 5 1045ba6b03cSchristos #define MACH_O_UNWIND_X86_REG_EBP 6 1055ba6b03cSchristos 10675f9f1baSchristos /* Encodings for arm64. */ 10775f9f1baSchristos 10875f9f1baSchristos #define MACH_O_UNWIND_ARM64_MODE_MASK 0x0f000000 10975f9f1baSchristos 11075f9f1baSchristos /* Leaf function: FP/LR are *not* saved, none or some non-volatile registers 11175f9f1baSchristos are saved, stack is allocated. The size of the frame (register saved and 11275f9f1baSchristos memory) is encoded in STACK_SIZE in 16 byte units. */ 11375f9f1baSchristos #define MACH_O_UNWIND_ARM64_MODE_FRAMELESS 0x02000000 11475f9f1baSchristos 11575f9f1baSchristos #define MACH_O_UNWIND_ARM64_MODE_DWARF 0x03000000 11675f9f1baSchristos 11775f9f1baSchristos /* Standard frame: FP/LR are pushed, SP is copied to FP, then non-volatile 11875f9f1baSchristos registers are saved. */ 11975f9f1baSchristos #define MACH_O_UNWIND_ARM64_MODE_FRAME 0x04000000 12075f9f1baSchristos 12175f9f1baSchristos /* Registers (for FRAME). */ 12275f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_X19_X20_PAIR 0x00000001 12375f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_X21_X22_PAIR 0x00000002 12475f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_X23_X24_PAIR 0x00000004 12575f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_X25_X26_PAIR 0x00000008 12675f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_X27_X28_PAIR 0x00000010 12775f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_D8_D9_PAIR 0x00000100 12875f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_D10_D11_PAIR 0x00000200 12975f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_D12_D13_PAIR 0x00000400 13075f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAME_D14_D15_PAIR 0x00000800 13175f9f1baSchristos 13275f9f1baSchristos #define MACH_O_UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK 0x00fff000 13375f9f1baSchristos #define MACH_O_UNWIND_ARM64_DWARF_SECTION_OFFSET 0x00ffffff 13475f9f1baSchristos 1355ba6b03cSchristos /* Entry in object file (in __LD,__compact_unwind section). */ 1365ba6b03cSchristos 1375ba6b03cSchristos struct mach_o_compact_unwind_32 1385ba6b03cSchristos { 1395ba6b03cSchristos unsigned char start[4]; 1405ba6b03cSchristos unsigned char length[4]; 1415ba6b03cSchristos unsigned char encoding[4]; 1425ba6b03cSchristos unsigned char personality[4]; 1435ba6b03cSchristos unsigned char lsda[4]; 1445ba6b03cSchristos }; 1455ba6b03cSchristos 1465ba6b03cSchristos struct mach_o_compact_unwind_64 1475ba6b03cSchristos { 1485ba6b03cSchristos unsigned char start[8]; 1495ba6b03cSchristos unsigned char length[4]; 1505ba6b03cSchristos unsigned char encoding[4]; 1515ba6b03cSchristos unsigned char personality[8]; 1525ba6b03cSchristos unsigned char lsda[8]; 1535ba6b03cSchristos }; 1545ba6b03cSchristos 1555ba6b03cSchristos /* Header in images (in __TEXT,__unwind_info). */ 1565ba6b03cSchristos 1575ba6b03cSchristos #define MACH_O_UNWIND_SECTION_VERSION 1 /* Current verion in header. */ 1585ba6b03cSchristos struct mach_o_unwind_info_header 1595ba6b03cSchristos { 1605ba6b03cSchristos unsigned char version[4]; /* Currently MACH_O_UNWIND_SECTION_VERSION. */ 1615ba6b03cSchristos unsigned char encodings_array_offset[4]; 1625ba6b03cSchristos unsigned char encodings_array_count[4]; 1635ba6b03cSchristos unsigned char personality_array_offset[4]; 1645ba6b03cSchristos unsigned char personality_array_count[4]; 1655ba6b03cSchristos unsigned char index_offset[4]; 1665ba6b03cSchristos unsigned char index_count[4]; 1675ba6b03cSchristos /* Followed by: 1685ba6b03cSchristos - encodings array 1695ba6b03cSchristos These are the encodings shared, for index < encoding_array_count 1705ba6b03cSchristos - personality array 1715ba6b03cSchristos count given by personality_array_count 1725ba6b03cSchristos - index entries 1735ba6b03cSchristos count given by index_count 1745ba6b03cSchristos - lsda index entries 1755ba6b03cSchristos last offset given by lsda offset of last index_entry. 1765ba6b03cSchristos */ 1775ba6b03cSchristos }; 1785ba6b03cSchristos 1795ba6b03cSchristos struct mach_o_unwind_index_entry 1805ba6b03cSchristos { 1815ba6b03cSchristos unsigned char function_offset[4]; 1825ba6b03cSchristos unsigned char second_level_offset[4]; 1835ba6b03cSchristos unsigned char lsda_index_offset[4]; 1845ba6b03cSchristos }; 1855ba6b03cSchristos 1865ba6b03cSchristos struct mach_o_unwind_lsda_index_entry 1875ba6b03cSchristos { 1885ba6b03cSchristos unsigned char function_offset[4]; 1895ba6b03cSchristos unsigned char lsda_offset[4]; 1905ba6b03cSchristos }; 1915ba6b03cSchristos 1925ba6b03cSchristos /* Second level index pages. */ 1935ba6b03cSchristos 1945ba6b03cSchristos #define MACH_O_UNWIND_SECOND_LEVEL_REGULAR 2 1955ba6b03cSchristos struct mach_o_unwind_regular_second_level_page_header 1965ba6b03cSchristos { 1975ba6b03cSchristos unsigned char kind[4]; 1985ba6b03cSchristos unsigned char entry_page_offset[2]; 1995ba6b03cSchristos unsigned char entry_count[2]; 2005ba6b03cSchristos /* Array of entries. */ 2015ba6b03cSchristos }; 2025ba6b03cSchristos 2035ba6b03cSchristos struct mach_o_unwind_regular_second_level_entry 2045ba6b03cSchristos { 2055ba6b03cSchristos unsigned char function_offset[4]; 2065ba6b03cSchristos unsigned char encoding[4]; 2075ba6b03cSchristos }; 2085ba6b03cSchristos 2095ba6b03cSchristos #define MACH_O_UNWIND_SECOND_LEVEL_COMPRESSED 3 2105ba6b03cSchristos struct mach_o_unwind_compressed_second_level_page_header 2115ba6b03cSchristos { 2125ba6b03cSchristos unsigned char kind[4]; 2135ba6b03cSchristos unsigned char entry_page_offset[2]; 2145ba6b03cSchristos unsigned char entry_count[2]; 2155ba6b03cSchristos unsigned char encodings_offset[2]; 2165ba6b03cSchristos unsigned char encodings_count[2]; 2175ba6b03cSchristos /* Followed by entries array (one word, see below). */ 2185ba6b03cSchristos /* Followed by (non-common) encodings array. */ 2195ba6b03cSchristos }; 2205ba6b03cSchristos 2215ba6b03cSchristos /* Compressed entries are one word, containing function offset and encoding 2225ba6b03cSchristos index. */ 2235ba6b03cSchristos #define MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(en) \ 2245ba6b03cSchristos ((en) & 0x00FFFFFF) 2255ba6b03cSchristos #define MACH_O_UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(en) \ 2265ba6b03cSchristos (((en) >> 24) & 0xFF) 2275ba6b03cSchristos 2285ba6b03cSchristos #endif /* _MACH_O_UNWIND_H */ 229