blob: f7378bed393199804494a05002e1afe63b731023 [file] [log] [blame]
hp.com!davidm76166fb2002-04-05 23:37:55 +00001/* libunwind - a platform-independent unwind library
2 Copyright (C) 2001-2002 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of libunwind.
6
7libunwind is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12libunwind is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17As a special exception, if you link this library with other files to
18produce an executable, this library does not by itself cause the
19resulting executable to be covered by the GNU General Public License.
20This exception does not however invalidate any other reasons why the
21executable file might be covered by the GNU General Public
22License. */
23
24#define UNW_PASTE2(x,y) x##y
25#define UNW_PASTE(x,y) UNW_PASTE2(x,y)
26#define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn)
27
28#ifdef UNW_LOCAL_ONLY
29# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_)
30#else /* !UNW_LOCAL_ONLY */
31# define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_)
32#endif /* !UNW_LOCAL_ONLY */
33
34typedef unw_tdep_word_t unw_word_t;
35
36/* This needs to be big enough to accommodate the unwind state of any
37 architecture, while leaving some slack for future expansion.
38 Changing this value will require recompiling all users of this
39 library. */
40#define UNW_STATE_LEN 127
41
42/* Error codes. The unwind routines return the *negated* values of
43 these error codes on error and a non-negative value on success. */
44typedef enum
45 {
46 UNW_ESUCCESS = 0, /* no error */
47 UNW_EUNSPEC, /* unspecified (general) error */
48 UNW_ENOMEM, /* out of memory */
49 UNW_EBADREG, /* bad register number */
50 UNW_EREADONLYREG, /* attempt to write read-only register */
51 UNW_ESTOPUNWIND, /* stop unwinding */
52 UNW_EINVALIDIP, /* invalid IP */
53 UNW_EBADFRAME, /* bad frame */
54 UNW_EINVAL, /* unsupported operation */
55 UNW_EBADVERSION, /* unwind info has unsupported version */
56 UNW_ENOINFO /* no unwind info found */
57 }
58unw_error_t;
59
60/* The following enum defines the indices for a couple of
61 (pseudo-)registers which have the same meaning across all
62 platforms. (RO) means read-only. (RW) means read-write. General
63 registers (aka "integer registers") are expected to start with
64 index 0. The number of such registers is architecture-dependent.
65 The remaining indices can be used as an architecture sees fit. The
66 last valid register index is given by UNW_REG_LAST. */
67typedef enum
68 {
69 UNW_REG_IP = UNW_TDEP_IP, /* (rw) instruction pointer (pc) */
70 UNW_REG_SP = UNW_TDEP_SP, /* (ro) stack pointer */
71 UNW_REG_PROC_START = UNW_TDEP_PROC_START, /* (ro) proc startaddr */
72 UNW_REG_HANDLER = UNW_TDEP_HANDLER, /* (ro) addr. of personality routine */
73 UNW_REG_LSDA = UNW_TDEP_LSDA, /* (ro) addr. of lang.-specific data */
74 UNW_REG_LAST = UNW_TDEP_LAST_REG
75 }
76unw_frame_regnum_t;
77
78typedef int unw_regnum_t;
79
80/* The unwind cursor starts at the youngest (most deeply nested) frame
81 and is used to track the frame state as the unwinder steps from
82 frame to frame. It is safe to make (shallow) copies of variables
83 of this type. */
84typedef struct unw_cursor
85 {
86 unw_word_t opaque[UNW_STATE_LEN];
87 }
88unw_cursor_t;
89
90/* This type encapsulates the entire (preserved) machine-state. */
91typedef unw_tdep_context_t unw_context_t;
92
93/* unw_getcontext() fills the unw_context_t pointed to by UC with the
94 machine state as it exists at the call-site. For implementation
95 reasons, this needs to be a target-dependent macro. It's easiest
96 to think of unw_getcontext() as being identical to getcontext(). */
97#define unw_getcontext(uc) unw_tdep_getcontext(uc)
98
99/* We will assume that "long double" is sufficiently large and aligned
100 to hold the contents of a floating-point register. Note that the
101 fp register format is not usually the same format as a "long
102 double". Instead, the content of unw_fpreg_t should be manipulated
103 only through the "raw.bits" member. */
104typedef union
105 {
106 struct { unw_word_t bits[1]; } raw;
107 long double dummy; /* dummy to force 16-byte alignment */
108 }
109unw_fpreg_t;
110
111/* These are backend callback routines that provide access to the
112 state of a "remote" process. This can be used, for example, to
113 unwind another process through the ptrace() interface. */
114typedef struct unw_accessors
115 {
116 /* Lock for unwind info for address IP. The architecture specific
117 UNWIND_INFO is updated as necessary. */
118 int (*acquire_unwind_info) (unw_word_t ip, void *unwind_info, void *arg);
119 int (*release_unwind_info) (void *unwind_info, void *arg);
120
121 /* Access aligned word at address ADDR. */
122 int (*access_mem) (unw_word_t addr, unw_word_t *val, int write, void *arg);
123
124 /* Access register number REG at address ADDR. */
125 int (*access_reg) (unw_regnum_t reg, unw_word_t *val, int write,
126 void *arg);
127
128 /* Access register number REG at address ADDR. */
129 int (*access_fpreg) (unw_regnum_t reg, unw_fpreg_t *val, int write,
130 void *arg);
131
132 int (*resume) (unw_cursor_t *c, void *arg);
133
134 void *arg; /* application-specific data */
135 }
136unw_accessors_t;
137
138typedef enum unw_save_loc_type
139 {
140 UNW_SLT_NONE, /* register is not saved ("not an l-value") */
141 UNW_SLT_MEMORY, /* register has been saved in memory */
142 UNW_SLT_REG /* register has been saved in (another) register */
143 }
144unw_save_loc_type_t;
145
146typedef struct unw_save_loc
147 {
148 unw_save_loc_type_t type;
149 union
150 {
151 unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */
152 unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */
153 }
154 u;
155 unw_tdep_save_loc_t extra; /* target-dependent additional information */
156 }
157unw_save_loc_t;
158
159/* These routines work both for local and remote unwinding. */
160
161extern int UNW_OBJ(init_local) (unw_cursor_t *c, ucontext_t *u);
162extern int UNW_OBJ(init_remote) (unw_cursor_t *c, unw_accessors_t *a);
163extern int UNW_OBJ(step) (unw_cursor_t *c);
164extern int UNW_OBJ(resume) (unw_cursor_t *c);
165extern int UNW_OBJ(get_reg) (unw_cursor_t *c, int regnum, unw_word_t *valp);
166extern int UNW_OBJ(set_reg) (unw_cursor_t *c, int regnum, unw_word_t val);
167extern int UNW_OBJ(get_fpreg) (unw_cursor_t *c, int regnum, unw_fpreg_t *val);
168extern int UNW_OBJ(set_fpreg) (unw_cursor_t *c, int regnum, unw_fpreg_t val);
169extern int UNW_OBJ(get_save_loc) (unw_cursor_t *c, int regnum,
170 unw_save_loc_t *loc);
171extern int UNW_OBJ(is_signal_frame) (unw_cursor_t *c);
172
173/* Initialize cursor C such that unwinding starts at the point
174 represented by the context U. Returns zero on success, negative
175 value on failure. */
176#define unw_init_local(c,u) UNW_OBJ(init_local)(c, u)
177
178/* Initialize cursor C such that it accesses the unwind target through
179 accessors A. */
180#define unw_init_remote(c,a) UNW_OBJ(init_remote)(c, a)
181
182/* Move cursor up by one step (up meaning toward earlier, less deeply
183 nested frames). Returns positive number if there are more frames
184 to unwind, 0 if last frame has been reached, negative number in
185 case of an error. */
186#define unw_step(c) UNW_OBJ(step)(c)
187
188/* Resume execution at the point identified by the cursor. */
189#define unw_resume(c) UNW_OBJ(resume)(c)
190
191/* Register accessor routines. Return zero on success, negative value
192 on failure. */
193#define unw_get_reg(c,r,v) UNW_OBJ(get_reg)(c,r,v)
194#define unw_set_reg(c,r,v) UNW_OBJ(set_reg)(c,r,v)
195
196/* Floating-point accessor routines. Return zero on success, negative
197 value on failure. */
198#define unw_get_fpreg(c,r,v) UNW_OBJ(get_fpreg)(c,r,v)
199#define unw_set_fpreg(c,r,v) UNW_OBJ(set_fpreg)(c,r,v)
200
201#define unw_get_save_loc(c,r,l) UNW_OBJ(get_save_loc)(c,r,l)
202
203/* Return 1 if register number R is a floating-point register, zero
204 otherwise. */
205#define unw_is_fpreg(r) unw_tdep_is_fpreg(r)
206
207/* Returns non-zero value if the cursor points to a signal frame. */
208#define unw_is_signal_frame(c) UNW_OBJ(is_signal_frame)(c)