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 #pragma ident "%Z%%M% %I% %E% SMI" 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate /* 37*7c478bd9Sstevel@tonic-gate * implementation of context structure 38*7c478bd9Sstevel@tonic-gate * 39*7c478bd9Sstevel@tonic-gate * Register arrays are indexed as specified in reg_num.h 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate struct _Unwind_Context { 42*7c478bd9Sstevel@tonic-gate uint64_t entry_regs[16]; 43*7c478bd9Sstevel@tonic-gate uint64_t current_regs[16]; 44*7c478bd9Sstevel@tonic-gate uint64_t cfa; 45*7c478bd9Sstevel@tonic-gate uint64_t pc; 46*7c478bd9Sstevel@tonic-gate uint64_t ra; 47*7c478bd9Sstevel@tonic-gate void *fde; 48*7c478bd9Sstevel@tonic-gate _Unwind_Personality_Fn pfn; 49*7c478bd9Sstevel@tonic-gate uint64_t func; 50*7c478bd9Sstevel@tonic-gate void *lsda; 51*7c478bd9Sstevel@tonic-gate uint64_t range; 52*7c478bd9Sstevel@tonic-gate }; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate enum register_rule { 55*7c478bd9Sstevel@tonic-gate undefined_rule, 56*7c478bd9Sstevel@tonic-gate same_value_rule, /* target_reg = target_reg */ 57*7c478bd9Sstevel@tonic-gate offset_rule, /* target_reg = *(offset + CFA) */ 58*7c478bd9Sstevel@tonic-gate is_offset_rule, /* target_reg = offset + CFA */ 59*7c478bd9Sstevel@tonic-gate register_rule, /* target_reg = offset + source_reg */ 60*7c478bd9Sstevel@tonic-gate constant_rule, /* target_reg = offset */ 61*7c478bd9Sstevel@tonic-gate indirect_rule /* target_reg = *(offset + source_reg) */ 62*7c478bd9Sstevel@tonic-gate }; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate struct register_state { 65*7c478bd9Sstevel@tonic-gate uint64_t offset; 66*7c478bd9Sstevel@tonic-gate enum register_rule rule; 67*7c478bd9Sstevel@tonic-gate unsigned char source_reg; 68*7c478bd9Sstevel@tonic-gate }; 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate struct eh_frame_fields { 71*7c478bd9Sstevel@tonic-gate void *cie_ops; 72*7c478bd9Sstevel@tonic-gate void *cie_ops_end; 73*7c478bd9Sstevel@tonic-gate ptrdiff_t cie_reloc; 74*7c478bd9Sstevel@tonic-gate int code_align; 75*7c478bd9Sstevel@tonic-gate int data_align; 76*7c478bd9Sstevel@tonic-gate int code_enc; 77*7c478bd9Sstevel@tonic-gate void *fde_ops; 78*7c478bd9Sstevel@tonic-gate void *fde_ops_end; 79*7c478bd9Sstevel@tonic-gate ptrdiff_t fde_reloc; 80*7c478bd9Sstevel@tonic-gate }; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate _Unwind_Reason_Code 83*7c478bd9Sstevel@tonic-gate _Unw_very_boring_personality(int version, int actions, uint64_t exclass, 84*7c478bd9Sstevel@tonic-gate struct _Unwind_Exception *exception_object, 85*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * Starting withe an initialized context (from a ucontext) 88*7c478bd9Sstevel@tonic-gate * the following routines are sufficient to implement a non-destructive 89*7c478bd9Sstevel@tonic-gate * stack walk if modified to access the target processes memory. These 90*7c478bd9Sstevel@tonic-gate * routines refer to the local address of an item using names containing 91*7c478bd9Sstevel@tonic-gate * `data' names containing `reloc' give the correction to get target 92*7c478bd9Sstevel@tonic-gate * process location. 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* ================== find function ====================== */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate * Computes the func and fde fields using pc as the lookup key. 99*7c478bd9Sstevel@tonic-gate * Return is 0 or address of fde 100*7c478bd9Sstevel@tonic-gate * 101*7c478bd9Sstevel@tonic-gate * This is the only function that look into .eh_frame_hdr 102*7c478bd9Sstevel@tonic-gate */ 103*7c478bd9Sstevel@tonic-gate void *_Unw_EhfhLookup(struct _Unwind_Context *ctx); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* =================== analyze function ================== */ 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* 108*7c478bd9Sstevel@tonic-gate * Fills in personality_fn and lsda fields of the context based 109*7c478bd9Sstevel@tonic-gate * the fde entry which must be valid and also partially unpacks 110*7c478bd9Sstevel@tonic-gate * fde and cie into *f 111*7c478bd9Sstevel@tonic-gate * 112*7c478bd9Sstevel@tonic-gate * This is one of two functions that look inside fde's 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate struct eh_frame_fields *_Unw_Decode_FDE(struct eh_frame_fields *f, 115*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * Computes register values at entry to function based on current 119*7c478bd9Sstevel@tonic-gate * register values, pc and fde values in a context 120*7c478bd9Sstevel@tonic-gate * 121*7c478bd9Sstevel@tonic-gate * This is the other function which looks inside fde's and 122*7c478bd9Sstevel@tonic-gate * the only one to look at CFA operations 123*7c478bd9Sstevel@tonic-gate * 124*7c478bd9Sstevel@tonic-gate * If 'f' is NULL (because no fde was found), a default calculation 125*7c478bd9Sstevel@tonic-gate * assuming an FP is done. 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate uint64_t _Unw_Rollback_Registers(struct eh_frame_fields *f, 128*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *ctx); 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* ================= register propagation =============== */ 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate /* 133*7c478bd9Sstevel@tonic-gate * Fills in the current register context for the caller 134*7c478bd9Sstevel@tonic-gate * based on computed at-entry state of callee 135*7c478bd9Sstevel@tonic-gate */ 136*7c478bd9Sstevel@tonic-gate void 137*7c478bd9Sstevel@tonic-gate _Unw_Propagate_Registers(struct _Unwind_Context *old_ctx, 138*7c478bd9Sstevel@tonic-gate struct _Unwind_Context *new_ctx); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* ================================================= */ 141*7c478bd9Sstevel@tonic-gate enum operand_desc { 142*7c478bd9Sstevel@tonic-gate NO_OPR, 143*7c478bd9Sstevel@tonic-gate ULEB128_FAC, 144*7c478bd9Sstevel@tonic-gate ULEB128, 145*7c478bd9Sstevel@tonic-gate ULEB128_SREG, 146*7c478bd9Sstevel@tonic-gate SLEB128, 147*7c478bd9Sstevel@tonic-gate SLEB128_FAC, 148*7c478bd9Sstevel@tonic-gate ADDR, 149*7c478bd9Sstevel@tonic-gate SIZE, 150*7c478bd9Sstevel@tonic-gate ZTSTRING, 151*7c478bd9Sstevel@tonic-gate UNUM6, 152*7c478bd9Sstevel@tonic-gate UNUM6_CFAC, 153*7c478bd9Sstevel@tonic-gate UNUM8, 154*7c478bd9Sstevel@tonic-gate UNUM8_CFAC, 155*7c478bd9Sstevel@tonic-gate UNUM16, 156*7c478bd9Sstevel@tonic-gate UNUM16_CFAC, 157*7c478bd9Sstevel@tonic-gate UNUM32, 158*7c478bd9Sstevel@tonic-gate UNUM32_CFAC, 159*7c478bd9Sstevel@tonic-gate UNUM64, 160*7c478bd9Sstevel@tonic-gate SNUM8, 161*7c478bd9Sstevel@tonic-gate SNUM16, 162*7c478bd9Sstevel@tonic-gate SNUM32, 163*7c478bd9Sstevel@tonic-gate SNUM64, 164*7c478bd9Sstevel@tonic-gate BLOCK 165*7c478bd9Sstevel@tonic-gate }; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate uint64_t _Unw_get_val(void **datap, ptrdiff_t reloc, 168*7c478bd9Sstevel@tonic-gate enum operand_desc opr, 169*7c478bd9Sstevel@tonic-gate int daf, int caf, int enc); 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate #endif /* _UNWIND_CONTEXT_H */ 172