Path: blob/main/contrib/llvm-project/libunwind/include/mach-o/compact_unwind_encoding.h
35235 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//7// Darwin's alternative to DWARF based unwind encodings.8//9//===----------------------------------------------------------------------===//101112#ifndef __COMPACT_UNWIND_ENCODING__13#define __COMPACT_UNWIND_ENCODING__1415#include <stdint.h>1617//18// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section19// of object files. Or compilers can emit compact unwind information in20// the __LD,__compact_unwind section.21//22// When the linker creates a final linked image, it will create a23// __TEXT,__unwind_info section. This section is a small and fast way for the24// runtime to access unwind info for any given function. If the compiler25// emitted compact unwind info for the function, that compact unwind info will26// be encoded in the __TEXT,__unwind_info section. If the compiler emitted27// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset28// of the FDE in the __TEXT,__eh_frame section in the final linked image.29//30// Note: Previously, the linker would transform some DWARF unwind infos into31// compact unwind info. But that is fragile and no longer done.323334//35// The compact unwind encoding is a 32-bit value which encoded in an36// architecture specific way, which registers to restore from where, and how37// to unwind out of the function.38//39typedef uint32_t compact_unwind_encoding_t;404142// architecture independent bits43enum {44UNWIND_IS_NOT_FUNCTION_START = 0x80000000,45UNWIND_HAS_LSDA = 0x40000000,46UNWIND_PERSONALITY_MASK = 0x30000000,47};4849505152//53// x8654//55// 1-bit: start56// 1-bit: has lsda57// 2-bit: personality index58//59// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF60// ebp based:61// 15-bits (5*3-bits per reg) register permutation62// 8-bits for stack offset63// frameless:64// 8-bits stack size65// 3-bits stack adjust66// 3-bits register count67// 10-bits register permutation68//69enum {70UNWIND_X86_MODE_MASK = 0x0F000000,71UNWIND_X86_MODE_EBP_FRAME = 0x01000000,72UNWIND_X86_MODE_STACK_IMMD = 0x02000000,73UNWIND_X86_MODE_STACK_IND = 0x03000000,74UNWIND_X86_MODE_DWARF = 0x04000000,7576UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,77UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,7879UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,80UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,81UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,82UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,8384UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,85};8687enum {88UNWIND_X86_REG_NONE = 0,89UNWIND_X86_REG_EBX = 1,90UNWIND_X86_REG_ECX = 2,91UNWIND_X86_REG_EDX = 3,92UNWIND_X86_REG_EDI = 4,93UNWIND_X86_REG_ESI = 5,94UNWIND_X86_REG_EBP = 6,95};9697//98// For x86 there are four modes for the compact unwind encoding:99// UNWIND_X86_MODE_EBP_FRAME:100// EBP based frame where EBP is push on stack immediately after return address,101// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current102// EPB value, then EBP is restored by popping off the stack, and the return103// is done by popping the stack once more into the pc.104// All non-volatile registers that need to be restored must have been saved105// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4106// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved107// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries.108// Each entry contains which register to restore.109// UNWIND_X86_MODE_STACK_IMMD:110// A "frameless" (EBP not used as frame pointer) function with a small111// constant stack size. To return, a constant (encoded in the compact112// unwind encoding) is added to the ESP. Then the return is done by113// popping the stack into the pc.114// All non-volatile registers that need to be restored must have been saved115// on the stack immediately after the return address. The stack_size/4 is116// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024).117// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT.118// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION contains which registers were119// saved and their order.120// UNWIND_X86_MODE_STACK_IND:121// A "frameless" (EBP not used as frame pointer) function large constant122// stack size. This case is like the previous, except the stack size is too123// large to encode in the compact unwind encoding. Instead it requires that124// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact125// encoding contains the offset to the nnnnnnnn value in the function in126// UNWIND_X86_FRAMELESS_STACK_SIZE.127// UNWIND_X86_MODE_DWARF:128// No compact unwind encoding is available. Instead the low 24-bits of the129// compact encoding is the offset of the DWARF FDE in the __eh_frame section.130// This mode is never used in object files. It is only generated by the131// linker in final linked images which have only DWARF unwind info for a132// function.133//134// The permutation encoding is a Lehmer code sequence encoded into a135// single variable-base number so we can encode the ordering of up to136// six registers in a 10-bit space.137//138// The following is the algorithm used to create the permutation encoding used139// with frameless stacks. It is passed the number of registers to be saved and140// an array of the register numbers saved.141//142//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6])143//{144// uint32_t renumregs[6];145// for (int i=6-registerCount; i < 6; ++i) {146// int countless = 0;147// for (int j=6-registerCount; j < i; ++j) {148// if ( registers[j] < registers[i] )149// ++countless;150// }151// renumregs[i] = registers[i] - countless -1;152// }153// uint32_t permutationEncoding = 0;154// switch ( registerCount ) {155// case 6:156// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1]157// + 6*renumregs[2] + 2*renumregs[3]158// + renumregs[4]);159// break;160// case 5:161// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2]162// + 6*renumregs[3] + 2*renumregs[4]163// + renumregs[5]);164// break;165// case 4:166// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3]167// + 3*renumregs[4] + renumregs[5]);168// break;169// case 3:170// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4]171// + renumregs[5]);172// break;173// case 2:174// permutationEncoding |= (5*renumregs[4] + renumregs[5]);175// break;176// case 1:177// permutationEncoding |= (renumregs[5]);178// break;179// }180// return permutationEncoding;181//}182//183184185186187//188// x86_64189//190// 1-bit: start191// 1-bit: has lsda192// 2-bit: personality index193//194// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF195// rbp based:196// 15-bits (5*3-bits per reg) register permutation197// 8-bits for stack offset198// frameless:199// 8-bits stack size200// 3-bits stack adjust201// 3-bits register count202// 10-bits register permutation203//204enum {205UNWIND_X86_64_MODE_MASK = 0x0F000000,206UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,207UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,208UNWIND_X86_64_MODE_STACK_IND = 0x03000000,209UNWIND_X86_64_MODE_DWARF = 0x04000000,210211UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,212UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,213214UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,215UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,216UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,217UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,218219UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,220};221222enum {223UNWIND_X86_64_REG_NONE = 0,224UNWIND_X86_64_REG_RBX = 1,225UNWIND_X86_64_REG_R12 = 2,226UNWIND_X86_64_REG_R13 = 3,227UNWIND_X86_64_REG_R14 = 4,228UNWIND_X86_64_REG_R15 = 5,229UNWIND_X86_64_REG_RBP = 6,230};231//232// For x86_64 there are four modes for the compact unwind encoding:233// UNWIND_X86_64_MODE_RBP_FRAME:234// RBP based frame where RBP is push on stack immediately after return address,235// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current236// EPB value, then RBP is restored by popping off the stack, and the return237// is done by popping the stack once more into the pc.238// All non-volatile registers that need to be restored must have been saved239// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8240// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved241// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries.242// Each entry contains which register to restore.243// UNWIND_X86_64_MODE_STACK_IMMD:244// A "frameless" (RBP not used as frame pointer) function with a small245// constant stack size. To return, a constant (encoded in the compact246// unwind encoding) is added to the RSP. Then the return is done by247// popping the stack into the pc.248// All non-volatile registers that need to be restored must have been saved249// on the stack immediately after the return address. The stack_size/8 is250// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048).251// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT.252// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION contains which registers were253// saved and their order.254// UNWIND_X86_64_MODE_STACK_IND:255// A "frameless" (RBP not used as frame pointer) function large constant256// stack size. This case is like the previous, except the stack size is too257// large to encode in the compact unwind encoding. Instead it requires that258// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact259// encoding contains the offset to the nnnnnnnn value in the function in260// UNWIND_X86_64_FRAMELESS_STACK_SIZE.261// UNWIND_X86_64_MODE_DWARF:262// No compact unwind encoding is available. Instead the low 24-bits of the263// compact encoding is the offset of the DWARF FDE in the __eh_frame section.264// This mode is never used in object files. It is only generated by the265// linker in final linked images which have only DWARF unwind info for a266// function.267//268269270// ARM64271//272// 1-bit: start273// 1-bit: has lsda274// 2-bit: personality index275//276// 4-bits: 4=frame-based, 3=DWARF, 2=frameless277// frameless:278// 12-bits of stack size279// frame-based:280// 4-bits D reg pairs saved281// 5-bits X reg pairs saved282// DWARF:283// 24-bits offset of DWARF FDE in __eh_frame section284//285enum {286UNWIND_ARM64_MODE_MASK = 0x0F000000,287UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,288UNWIND_ARM64_MODE_DWARF = 0x03000000,289UNWIND_ARM64_MODE_FRAME = 0x04000000,290291UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,292UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,293UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,294UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,295UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,296UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,297UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,298UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,299UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,300301UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,302UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,303};304// For arm64 there are three modes for the compact unwind encoding:305// UNWIND_ARM64_MODE_FRAME:306// This is a standard arm64 prolog where FP/LR are immediately pushed on the307// stack, then SP is copied to FP. If there are any non-volatile registers308// saved, then are copied into the stack frame in pairs in a contiguous309// range right below the saved FP/LR pair. Any subset of the five X pairs310// and four D pairs can be saved, but the memory layout must be in register311// number order.312// UNWIND_ARM64_MODE_FRAMELESS:313// A "frameless" leaf function, where FP/LR are not saved. The return address314// remains in LR throughout the function. If any non-volatile registers315// are saved, they must be pushed onto the stack before any stack space is316// allocated for local variables. The stack sized (including any saved317// non-volatile registers) divided by 16 is encoded in the bits318// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.319// UNWIND_ARM64_MODE_DWARF:320// No compact unwind encoding is available. Instead the low 24-bits of the321// compact encoding is the offset of the DWARF FDE in the __eh_frame section.322// This mode is never used in object files. It is only generated by the323// linker in final linked images which have only DWARF unwind info for a324// function.325//326327328329330331////////////////////////////////////////////////////////////////////////////////332//333// Relocatable Object Files: __LD,__compact_unwind334//335////////////////////////////////////////////////////////////////////////////////336337//338// A compiler can generated compact unwind information for a function by adding339// a "row" to the __LD,__compact_unwind section. This section has the340// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers.341// It is removed by the new linker, so never ends up in final executables.342// This section is a table, initially with one row per function (that needs343// unwind info). The table columns and some conceptual entries are:344//345// range-start pointer to start of function/range346// range-length347// compact-unwind-encoding 32-bit encoding348// personality-function or zero if no personality function349// lsda or zero if no LSDA data350//351// The length and encoding fields are 32-bits. The other are all pointer sized.352//353// In x86_64 assembly, these entry would look like:354//355// .section __LD,__compact_unwind,regular,debug356//357// #compact unwind for _foo358// .quad _foo359// .set L1,LfooEnd-_foo360// .long L1361// .long 0x01010001362// .quad 0363// .quad 0364//365// #compact unwind for _bar366// .quad _bar367// .set L2,LbarEnd-_bar368// .long L2369// .long 0x01020011370// .quad __gxx_personality371// .quad except_tab1372//373//374// Notes: There is no need for any labels in the __compact_unwind section.375// The use of the .set directive is to force the evaluation of the376// range-length at assembly time, instead of generating relocations.377//378// To support future compiler optimizations where which non-volatile registers379// are saved changes within a function (e.g. delay saving non-volatiles until380// necessary), there can by multiple lines in the __compact_unwind table for one381// function, each with a different (non-overlapping) range and each with382// different compact unwind encodings that correspond to the non-volatiles383// saved at that range of the function.384//385// If a particular function is so wacky that there is no compact unwind way386// to encode it, then the compiler can emit traditional DWARF unwind info.387// The runtime will use which ever is available.388//389// Runtime support for compact unwind encodings are only available on 10.6390// and later. So, the compiler should not generate it when targeting pre-10.6.391392393394395////////////////////////////////////////////////////////////////////////////////396//397// Final Linked Images: __TEXT,__unwind_info398//399////////////////////////////////////////////////////////////////////////////////400401//402// The __TEXT,__unwind_info section is laid out for an efficient two level lookup.403// The header of the section contains a coarse index that maps function address404// to the page (4096 byte block) containing the unwind info for that function.405//406407#define UNWIND_SECTION_VERSION 1408struct unwind_info_section_header409{410uint32_t version; // UNWIND_SECTION_VERSION411uint32_t commonEncodingsArraySectionOffset;412uint32_t commonEncodingsArrayCount;413uint32_t personalityArraySectionOffset;414uint32_t personalityArrayCount;415uint32_t indexSectionOffset;416uint32_t indexCount;417// compact_unwind_encoding_t[]418// uint32_t personalities[]419// unwind_info_section_header_index_entry[]420// unwind_info_section_header_lsda_index_entry[]421};422423struct unwind_info_section_header_index_entry424{425uint32_t functionOffset;426uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page427uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range428};429430struct unwind_info_section_header_lsda_index_entry431{432uint32_t functionOffset;433uint32_t lsdaOffset;434};435436//437// There are two kinds of second level index pages: regular and compressed.438// A compressed page can hold up to 1021 entries, but it cannot be used439// if too many different encoding types are used. The regular page holds440// 511 entries.441//442443struct unwind_info_regular_second_level_entry444{445uint32_t functionOffset;446compact_unwind_encoding_t encoding;447};448449#define UNWIND_SECOND_LEVEL_REGULAR 2450struct unwind_info_regular_second_level_page_header451{452uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR453uint16_t entryPageOffset;454uint16_t entryCount;455// entry array456};457458#define UNWIND_SECOND_LEVEL_COMPRESSED 3459struct unwind_info_compressed_second_level_page_header460{461uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED462uint16_t entryPageOffset;463uint16_t entryCount;464uint16_t encodingsPageOffset;465uint16_t encodingsCount;466// 32-bit entry array467// encodings array468};469470#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)471#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF)472473474475#endif476477478479