/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Public interface for AMD64 Unwind context */ #ifndef _UNWIND_CONTEXT_H #define _UNWIND_CONTEXT_H #pragma ident "%Z%%M% %I% %E% SMI" /* * implementation of context structure * * Register arrays are indexed as specified in reg_num.h */ struct _Unwind_Context { uint64_t entry_regs[16]; uint64_t current_regs[16]; uint64_t cfa; uint64_t pc; uint64_t ra; void *fde; _Unwind_Personality_Fn pfn; uint64_t func; void *lsda; uint64_t range; }; enum register_rule { undefined_rule, same_value_rule, /* target_reg = target_reg */ offset_rule, /* target_reg = *(offset + CFA) */ is_offset_rule, /* target_reg = offset + CFA */ register_rule, /* target_reg = offset + source_reg */ constant_rule, /* target_reg = offset */ indirect_rule /* target_reg = *(offset + source_reg) */ }; struct register_state { uint64_t offset; enum register_rule rule; unsigned char source_reg; }; struct eh_frame_fields { void *cie_ops; void *cie_ops_end; ptrdiff_t cie_reloc; int code_align; int data_align; int code_enc; void *fde_ops; void *fde_ops_end; ptrdiff_t fde_reloc; }; _Unwind_Reason_Code _Unw_very_boring_personality(int version, int actions, uint64_t exclass, struct _Unwind_Exception *exception_object, struct _Unwind_Context *ctx); /* * Starting withe an initialized context (from a ucontext) * the following routines are sufficient to implement a non-destructive * stack walk if modified to access the target processes memory. These * routines refer to the local address of an item using names containing * `data' names containing `reloc' give the correction to get target * process location. */ /* ================== find function ====================== */ /* * Computes the func and fde fields using pc as the lookup key. * Return is 0 or address of fde * * This is the only function that look into .eh_frame_hdr */ void *_Unw_EhfhLookup(struct _Unwind_Context *ctx); /* =================== analyze function ================== */ /* * Fills in personality_fn and lsda fields of the context based * the fde entry which must be valid and also partially unpacks * fde and cie into *f * * This is one of two functions that look inside fde's */ struct eh_frame_fields *_Unw_Decode_FDE(struct eh_frame_fields *f, struct _Unwind_Context *ctx); /* * Computes register values at entry to function based on current * register values, pc and fde values in a context * * This is the other function which looks inside fde's and * the only one to look at CFA operations * * If 'f' is NULL (because no fde was found), a default calculation * assuming an FP is done. */ uint64_t _Unw_Rollback_Registers(struct eh_frame_fields *f, struct _Unwind_Context *ctx); /* ================= register propagation =============== */ /* * Fills in the current register context for the caller * based on computed at-entry state of callee */ void _Unw_Propagate_Registers(struct _Unwind_Context *old_ctx, struct _Unwind_Context *new_ctx); /* ================================================= */ enum operand_desc { NO_OPR, ULEB128_FAC, ULEB128, ULEB128_SREG, SLEB128, SLEB128_FAC, ADDR, SIZE, ZTSTRING, UNUM6, UNUM6_CFAC, UNUM8, UNUM8_CFAC, UNUM16, UNUM16_CFAC, UNUM32, UNUM32_CFAC, UNUM64, SNUM8, SNUM16, SNUM32, SNUM64, BLOCK }; uint64_t _Unw_get_val(void **datap, ptrdiff_t reloc, enum operand_desc opr, int daf, int caf, int enc); #endif /* _UNWIND_CONTEXT_H */