1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* 28*7c478bd9Sstevel@tonic-gate * Public interface for AMD64 Unwind context 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #ifndef _UNWIND_CONTEXT_H 32*7c478bd9Sstevel@tonic-gate #define _UNWIND_CONTEXT_H 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * implementation of context structure 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * Register arrays are indexed as specified in reg_num.h 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate struct _Unwind_Context { 40*7c478bd9Sstevel@tonic-gate uint64_t entry_regs[16]; 41*7c478bd9Sstevel@tonic-gate uint64_t current_regs[16]; 42*7c478bd9Sstevel@tonic-gate uint64_t cfa; 43*7c478bd9Sstevel@tonic-gate uint64_t pc; 44*7c478bd9Sstevel@tonic-gate uint64_t ra; 45*7c478bd9Sstevel@tonic-gate void *fde; 46*7c478bd9Sstevel@tonic-gate _Unwind_Personality_Fn pfn; 47*7c478bd9Sstevel@tonic-gate uint64_t func; 48*7c478bd9Sstevel@tonic-gate void *lsda; 49*7c478bd9Sstevel@tonic-gate uint64_t range; 50*7c478bd9Sstevel@tonic-gate }; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate enum register_rule { 53*7c478bd9Sstevel@tonic-gate undefined_rule, 54*7c478bd9Sstevel@tonic-gate same_value_rule, /* target_reg = target_reg */ 55*7c478bd9Sstevel@tonic-gate offset_rule, /* target_reg = *(offset + CFA) */ 56*7c478bd9Sstevel@tonic-gate is_offset_rule, /* target_reg = offset + CFA */ 57*7c478bd9Sstevel@tonic-gate register_rule, /* target_reg = offset + source_reg */ 58*7c478bd9Sstevel@tonic-gate constant_rule, /* target_reg = offset */ 59*7c478bd9Sstevel@tonic-gate indirect_rule /* target_reg = *(offset + source_reg) */ 60*7c478bd9Sstevel@tonic-gate }; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate struct register_state { 63*7c478bd9Sstevel@tonic-gate uint64_t offset; 64*7c478bd9Sstevel@tonic-gate enum register_rule rule; 65*7c478bd9Sstevel@tonic-gate unsigned char source_reg; 66*7c478bd9Sstevel@tonic-gate }; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate struct eh_frame_fields { 69*7c478bd9Sstevel@tonic-gate void *cie_ops; 70*7c478bd9Sstevel@tonic-gate void *cie_ops_end; 71*7c478bd9Sstevel@tonic-gate ptrdiff_t cie_reloc; 72*7c478bd9Sstevel@tonic-gate int code_align; 73*7c478bd9Sstevel@tonic-gate int data_align; 74*7c478bd9Sstevel@tonic-gate int code_enc; 75*7c478bd9Sstevel@tonic-gate void *fde_ops; 76*7c478bd9Sstevel@tonic-gate void *fde_ops_end; 77*7c478bd9Sstevel@tonic-gate ptrdiff_t fde_reloc; 78*7c478bd9Sstevel@tonic-gate }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate _Unwind_Reason_Code 81*7c478bd9Sstevel@tonic-gate _Unw_very_boring_personality(int version, int actions, uint64_t exclass, 82*7c478bd9Sstevel@tonic-gate struct _Unwind_Exception *exception_object, 83*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 84*7c478bd9Sstevel@tonic-gate /* 85*7c478bd9Sstevel@tonic-gate * Starting withe an initialized context (from a ucontext) 86*7c478bd9Sstevel@tonic-gate * the following routines are sufficient to implement a non-destructive 87*7c478bd9Sstevel@tonic-gate * stack walk if modified to access the target processes memory. These 88*7c478bd9Sstevel@tonic-gate * routines refer to the local address of an item using names containing 89*7c478bd9Sstevel@tonic-gate * `data' names containing `reloc' give the correction to get target 90*7c478bd9Sstevel@tonic-gate * process location. 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* ================== find function ====================== */ 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * Computes the func and fde fields using pc as the lookup key. 97*7c478bd9Sstevel@tonic-gate * Return is 0 or address of fde 98*7c478bd9Sstevel@tonic-gate * 99*7c478bd9Sstevel@tonic-gate * This is the only function that look into .eh_frame_hdr 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate void *_Unw_EhfhLookup(struct _Unwind_Context *ctx); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* =================== analyze function ================== */ 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* 106*7c478bd9Sstevel@tonic-gate * Fills in personality_fn and lsda fields of the context based 107*7c478bd9Sstevel@tonic-gate * the fde entry which must be valid and also partially unpacks 108*7c478bd9Sstevel@tonic-gate * fde and cie into *f 109*7c478bd9Sstevel@tonic-gate * 110*7c478bd9Sstevel@tonic-gate * This is one of two functions that look inside fde's 111*7c478bd9Sstevel@tonic-gate */ 112*7c478bd9Sstevel@tonic-gate struct eh_frame_fields *_Unw_Decode_FDE(struct eh_frame_fields *f, 113*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate /* 116*7c478bd9Sstevel@tonic-gate * Computes register values at entry to function based on current 117*7c478bd9Sstevel@tonic-gate * register values, pc and fde values in a context 118*7c478bd9Sstevel@tonic-gate * 119*7c478bd9Sstevel@tonic-gate * This is the other function which looks inside fde's and 120*7c478bd9Sstevel@tonic-gate * the only one to look at CFA operations 121*7c478bd9Sstevel@tonic-gate * 122*7c478bd9Sstevel@tonic-gate * If 'f' is NULL (because no fde was found), a default calculation 123*7c478bd9Sstevel@tonic-gate * assuming an FP is done. 124*7c478bd9Sstevel@tonic-gate */ 125*7c478bd9Sstevel@tonic-gate uint64_t _Unw_Rollback_Registers(struct eh_frame_fields *f, 126*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* ================= register propagation =============== */ 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * Fills in the current register context for the caller 132*7c478bd9Sstevel@tonic-gate * based on computed at-entry state of callee 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate void 135*7c478bd9Sstevel@tonic-gate _Unw_Propagate_Registers(struct _Unwind_Context *old_ctx, 136*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *new_ctx); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* ================================================= */ 139*7c478bd9Sstevel@tonic-gate enum operand_desc { 140*7c478bd9Sstevel@tonic-gate NO_OPR, 141*7c478bd9Sstevel@tonic-gate ULEB128_FAC, 142*7c478bd9Sstevel@tonic-gate ULEB128, 143*7c478bd9Sstevel@tonic-gate ULEB128_SREG, 144*7c478bd9Sstevel@tonic-gate SLEB128, 145*7c478bd9Sstevel@tonic-gate SLEB128_FAC, 146*7c478bd9Sstevel@tonic-gate ADDR, 147*7c478bd9Sstevel@tonic-gate SIZE, 148*7c478bd9Sstevel@tonic-gate ZTSTRING, 149*7c478bd9Sstevel@tonic-gate UNUM6, 150*7c478bd9Sstevel@tonic-gate UNUM6_CFAC, 151*7c478bd9Sstevel@tonic-gate UNUM8, 152*7c478bd9Sstevel@tonic-gate UNUM8_CFAC, 153*7c478bd9Sstevel@tonic-gate UNUM16, 154*7c478bd9Sstevel@tonic-gate UNUM16_CFAC, 155*7c478bd9Sstevel@tonic-gate UNUM32, 156*7c478bd9Sstevel@tonic-gate UNUM32_CFAC, 157*7c478bd9Sstevel@tonic-gate UNUM64, 158*7c478bd9Sstevel@tonic-gate SNUM8, 159*7c478bd9Sstevel@tonic-gate SNUM16, 160*7c478bd9Sstevel@tonic-gate SNUM32, 161*7c478bd9Sstevel@tonic-gate SNUM64, 162*7c478bd9Sstevel@tonic-gate BLOCK 163*7c478bd9Sstevel@tonic-gate }; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate uint64_t _Unw_get_val(void **datap, ptrdiff_t reloc, 166*7c478bd9Sstevel@tonic-gate enum operand_desc opr, 167*7c478bd9Sstevel@tonic-gate int daf, int caf, int enc); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate #endif /* _UNWIND_CONTEXT_H */ 170