hp.com!davidm | d7e9f75 | 2002-11-23 02:12:30 +0000 | [diff] [blame] | 1 | /* libunwind - a platform-independent unwind library |
| 2 | Copyright (C) 2002 Hewlett-Packard Co |
| 3 | Contributed by David Mosberger-Tang <davidm@hpl.hp.com> |
| 4 | |
| 5 | This file is part of libunwind. |
| 6 | |
| 7 | Permission is hereby granted, free of charge, to any person obtaining |
| 8 | a copy of this software and associated documentation files (the |
| 9 | "Software"), to deal in the Software without restriction, including |
| 10 | without limitation the rights to use, copy, modify, merge, publish, |
| 11 | distribute, sublicense, and/or sell copies of the Software, and to |
| 12 | permit persons to whom the Software is furnished to do so, subject to |
| 13 | the following conditions: |
| 14 | |
| 15 | The above copyright notice and this permission notice shall be |
| 16 | included in all copies or substantial portions of the Software. |
| 17 | |
| 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| 22 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 24 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
| 25 | |
| 26 | #ifndef LIBUNWIND_DYNAMIC_H |
| 27 | #define LIBUNWIND_DYNAMIC_H |
| 28 | |
| 29 | /* This file defines the runtime-support routines for dynamically |
| 30 | generated code. Even though it is implemented as part of |
| 31 | libunwind, it is logically separate from the interface to perform |
| 32 | the actual unwinding. In particular, this interface is always used |
| 33 | in the context of the unwind target, whereas the rest of the unwind |
| 34 | API is used in context of the process that is doing the unwind |
| 35 | (which may be a debugger running on another machine, for |
| 36 | example). */ |
| 37 | |
| 38 | typedef enum |
| 39 | { |
| 40 | UNW_OP_SAVE_REG, /* save register to another register */ |
| 41 | UNW_OP_SPILL_FP_REL, /* frame-pointer-relative register spill */ |
| 42 | UNW_OP_SPILL_SP_REL, /* stack-pointer-relative register spill */ |
| 43 | UNW_OP_ADD, /* add constant value to a register */ |
| 44 | UNW_OP_POP_STACK, /* drop one or more stack frames */ |
| 45 | UNW_OP_LABEL_STATE, /* name the current state */ |
| 46 | UNW_OP_COPY_STATE, /* set the region's entry-state */ |
| 47 | UNW_OP_ALIAS, /* get unwind info from an alias */ |
| 48 | UNW_OP_STOP /* end-of-unwind-info marker */ |
| 49 | } |
| 50 | unw_operator_t; |
| 51 | |
| 52 | typedef struct unw_proc_info |
| 53 | { |
| 54 | unsigned long private[4]; /* reserved for use by libunwind */ |
| 55 | void *proc_start; /* first text-address of procedure */ |
| 56 | void *proc_end; /* first text-address beyond the procedure */ |
| 57 | unsigned long flags; |
| 58 | const char *proc_name; /* unique & human-readable procedure name */ |
| 59 | void *creator_hook; /* hook for whoever created this procedure */ |
| 60 | unsigned long reserved[7]; /* reserved for future extensions */ |
| 61 | } |
| 62 | unw_proc_info_t; |
| 63 | |
| 64 | typedef struct unw_region_info |
| 65 | { |
| 66 | struct unw_region_info *next; /* NULL-terminated list of regions */ |
| 67 | void *creator_hook; |
| 68 | unsigned int insn_count; /* region length (# of instructions) */ |
| 69 | unsigned int op_count; /* length of op-array */ |
| 70 | unsigned long reserved[5]; |
| 71 | struct unw_op_t |
| 72 | { |
| 73 | unsigned int tag : 16; /* what operation? */ |
| 74 | unsigned int reg : 16; /* what register */ |
| 75 | unsigned int when : 32; /* when does it take effect? */ |
| 76 | unsigned long val; /* auxiliary value */ |
| 77 | } |
| 78 | op[1]; |
| 79 | } |
| 80 | unw_region_info_t; |
| 81 | |
| 82 | /* Return the size (in bytes) of an unw_region_info_t structure that can |
| 83 | hold OP_COUNT ops. */ |
| 84 | #define unw_region_info_size(op_count) \ |
| 85 | (sizeof (unw_region_info_t) \ |
| 86 | + (op_count > 0) ? ((op_count) - 1) * sizeof (struct unw_op) : 0) |
| 87 | |
| 88 | /* Register the unwind info for a single procedure. |
| 89 | This routine is NOT signal-safe. */ |
| 90 | extern int unw_register_proc (unw_proc_info_t *proc); |
| 91 | |
| 92 | /* Cancel the unwind info for a single procedure. |
| 93 | This routine is NOT signal-safe. */ |
| 94 | extern int unw_cancel_proc (unw_proc_info_t *proc); |
| 95 | |
| 96 | |
| 97 | /* Convenience routines. */ |
| 98 | |
| 99 | #define unw_op(tag, when, reg, val) \ |
| 100 | (struct unw_op_t) { \ |
| 101 | .tag = (tag), \ |
| 102 | .when = (when), \ |
| 103 | .reg = (reg), \ |
| 104 | .val = (val) \ |
| 105 | } |
| 106 | |
| 107 | #define unw_op_save_reg(op, when, reg, dst) \ |
| 108 | unw_op(UNW_OP_SAVE_REG, (when), (reg), (dst)) |
| 109 | |
| 110 | #define unw_op_spill_fp_rel(when, reg, offset) \ |
| 111 | unw_op(UNW_OP_SPILL_FP_REL, (when), (reg), (offset)) |
| 112 | |
| 113 | #define unw_op_spill_sp_rel(when, reg, offset) \ |
| 114 | unw_op(UNW_OP_SPILL_SP_REL, (when), (reg), (offset)) |
| 115 | |
| 116 | #define unw_op_add(when, reg, value) \ |
| 117 | unw_op(UNW_OP_ADD, (when), (reg), (value)) |
| 118 | |
| 119 | #define unw_op_pop_stack(op, num_frames) \ |
| 120 | unw_op(UNW_OP_POP_STACK, (when), 0, (num_frames)) |
| 121 | |
| 122 | #define unw_op_label_state(op, when, label) \ |
| 123 | unw_op(UNW_OP_LABEL_STATE, (when), 0, (label)) |
| 124 | |
| 125 | #define unw_op_copy_state(op, when, label) \ |
| 126 | unw_op(UNW_OP_COPY_STATE, (when), 0, (label)) |
| 127 | |
| 128 | #define unw_op_alias(op, when, delta) \ |
| 129 | unw_op(UNW_OP_ALIAS, (when), 0, (label)) |
| 130 | |
| 131 | #endif /* LIBUNWIND_DYNAMIC_H */ |