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