mostang.com!davidm | be72029 | 2002-02-23 20:27:03 +0000 | [diff] [blame] | 1 | The central data structure of the unwind API is the unwind cursor. |
mostang.com!davidm | 8da6258 | 2002-11-09 03:59:27 +0000 | [diff] [blame] | 2 | This structure tracks the register contents. The unwind API defines a |
| 3 | handful of well-known frame "registers": |
mostang.com!davidm | be72029 | 2002-02-23 20:27:03 +0000 | [diff] [blame] | 4 | |
| 5 | - ip: the instruction pointer (pc) |
| 6 | - rp: the return pointer (rp, aka "return address" or "return link") |
| 7 | - sp: the stack pointer (memory stack pointer, in the case of ia64) |
| 8 | - fp: the frame pointer |
| 9 | - first_ip: the starting address of the current "procedure" |
| 10 | - handler: a pointer to an architecture & language-specific |
| 11 | "personality" routine |
| 12 | - lsda: a pointer to an architecture & language-specific |
| 13 | data-area |
| 14 | |
| 15 | The API defines no well-known preserved registers. Each architecture |
| 16 | can define additional registers as needed. Of course, a portable |
| 17 | application may only rely on well-known registers. The names for |
| 18 | preserved registers are defined in the architecture-specific header |
| 19 | file <unwind-ARCH.h>. For example, to get the IA-64-specific register |
| 20 | names, an application would do: |
| 21 | |
| 22 | #include <unwind-ia64.h> |
| 23 | |
| 24 | The API is designed to handle two primary cases: unwinding within the |
| 25 | current (local) process and unwinding of another ("remote") process |
| 26 | (e.g., through ptrace()). In the local case, the initial machine |
| 27 | state is captured by an unwind context (currently the same as |
| 28 | ucontext_t). In the remote case, the initial machine state is |
| 29 | captured by an unwind accessor structure, which provides callback |
| 30 | routines for reading/writing memory and registers and for obtaining |
| 31 | unwind information. |
| 32 | |
| 33 | Once a cursor has been initialized, you can step through the call |
| 34 | chain with the unw_step() routine. The frame registers and the |
| 35 | preserved state can then be accessed with unw_get_reg() or modified |
| 36 | with unw_set_reg(). For floating-point registers, there are separate |
| 37 | unw_get_fpreg() and unw_set_fpreg() routines (on some arches, e.g., |
| 38 | Alpha, these could be just aliases for unw_{g,s}et_reg()). The |
| 39 | unw_resume() routine can be used to resume execution at an arbitrary |
| 40 | point in the call-chain (as identified by an unwind cursor). This is |
| 41 | intended for exception handling and, at least for now, the intention |
| 42 | is to support this routine only for the local case. Kevin, if you |
| 43 | feel gdb could benefit from such a routine, I'd be interested to hear |
| 44 | about it. |
| 45 | |
| 46 | Note that it is perfectly legal to make copies of the unwind cursor. |
| 47 | This makes it possible, e.g., to obtain an unwind context, modify the |
| 48 | state in an earlier call frame, and then resume execution at the point |
| 49 | at which the unwind context was captured. |
| 50 | |
| 51 | Here is a quick example of how to use the unwind API to do a simple |
| 52 | stack trace: |
| 53 | |
| 54 | unw_cursor_t cursor; |
| 55 | unw_word_t ip, sp; |
mostang.com!davidm | 7776832 | 2003-01-14 07:11:56 +0000 | [diff] [blame] | 56 | unw_context_t uc; |
mostang.com!davidm | be72029 | 2002-02-23 20:27:03 +0000 | [diff] [blame] | 57 | |
mostang.com!davidm | 7776832 | 2003-01-14 07:11:56 +0000 | [diff] [blame] | 58 | unw_getcontext(&uc); |
mostang.com!davidm | be72029 | 2002-02-23 20:27:03 +0000 | [diff] [blame] | 59 | unw_init_local(&cursor, &uc); |
| 60 | do |
| 61 | { |
| 62 | unw_get_reg(&cursor, UNW_REG_IP, &ip); |
| 63 | unw_get_reg(&cursor, UNW_REG_SP, &sp); |
| 64 | printf ("ip=%016lx sp=%016lx\n", ip, sp); |
| 65 | } |
| 66 | while (unw_step (&cursor) > 0); |
| 67 | |
| 68 | Note that this particular example should work on pretty much any |
| 69 | architecture, as it doesn't rely on any arch-specific registers. |
hp.com!davidm | 4b00b1f | 2002-04-05 23:37:55 +0000 | [diff] [blame] | 70 | |
| 71 | * Multiarchitecture support |
| 72 | |
| 73 | If libunwind is configured for a target other than the local (native) |
| 74 | host, the library is installed as libunwind-$ARCH, where $ARCH is |
| 75 | the target architecture name (e.g., ia32, ia64, or alpha). Similarly, |
| 76 | the header file is installed as libunwind-$ARCH. |
| 77 | |
| 78 | With this setup, an application should: |
| 79 | |
| 80 | - include <libunwind.h>, and |
| 81 | - link against -lunwind |
| 82 | |
| 83 | if the application needs to use the unwinder of the host. An |
| 84 | application wanting to use the unwinder for a different target (e.g., |
| 85 | a cross-debugger) should: |
| 86 | |
| 87 | - include <libunwind-$ARCH.h>, and |
| 88 | - link against -lunwind-$ARCH |
| 89 | |
| 90 | The global symbols exported by -lunwind-$ARCH are unique such that the |
| 91 | same application can be linked against the separate unwind libraries |
| 92 | of multiple targets. However, a single compilation unit can include |
| 93 | the header file for only one target. For example, foo.c might include |
| 94 | <libunwind-ia64.h> and bar.c might include <libunwind.h> and the |
| 95 | entire application would have to be linked against both -lunwind and |
| 96 | -lunwind-ia64. |
| 97 | |
| 98 | Note: the unwind header files of all targets have a common dependency |
| 99 | on libunwind-common.h. To avoid version conflicts, it is necessary to |
| 100 | ensure that the unwind libraries for all targets were derived from the |
| 101 | same release of libunwind. That is, if the unwind library for one |
| 102 | target is upgraded to a newer version, the libraries for all other |
| 103 | targets also need to be upgraded. |
| 104 | |
| 105 | Note 2: The assumption is that a cross-unwinder can handle all |
| 106 | interesting flavors of a target. For example, the unwinder for the |
| 107 | ia64 target is expected to be able to handle both Linux and HP-UX. |
mostang.com!davidm | 8da6258 | 2002-11-09 03:59:27 +0000 | [diff] [blame] | 108 | |
| 109 | * IA-64 Specific Information |
| 110 | |
| 111 | Apart from the normal frame-registers, the IA-64 implementation of |
| 112 | libunwind provides the means to access the current value of the |
| 113 | register backing store pointer (bsp). One quirk with this |
| 114 | frame-register is that it corresponds to the address that would be in |
| 115 | register ar.bsp after flushing the current register stack to the |
| 116 | backing store (i.e., as if a "flushrs" instruction had been executed). |
| 117 | Of course, given this value and the contents of the current frame |
| 118 | marker (CFM), it's easy to calculate the original value of ar.bsp: |
| 119 | |
| 120 | unw_word_t cfm, bsp, bsp_after_flushrs, sof; |
| 121 | |
| 122 | unw_get_reg (&cursor, UNW_IA64_BSP, &bsp_after_flushrs); |
| 123 | unw_get_reg (&cursor, UNW_IA64_CFM, &cfm); |
| 124 | bsp = ia64_rse_skip_regs (bsp_after_flushrs, -(cfm & 0x7f)); |
mostang.com!davidm | 1b7547e | 2002-12-03 08:19:58 +0000 | [diff] [blame] | 125 | |
| 126 | ** Dynamic Unwind Info |
| 127 | |