blob: 0aedff23559b3ad08d18630505474055fadba1ad [file] [log] [blame]
mostang.com!davidm51095502003-03-11 01:11:18 +00001/* libunwind - a platform-independent unwind library
hp.com!davidm25b87952004-01-22 08:36:15 +00002 Copyright (C) 2002-2004 Hewlett-Packard Co
mostang.com!davidm51095502003-03-11 01:11:18 +00003 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
26#ifndef TDEP_X86_H
27#define TDEP_X86_H
28
29/* Target-dependent definitions that are internal to libunwind but need
30 to be shared with target-independent code. */
31
32#include <stdlib.h>
33#include <libunwind.h>
34
hp.com!davidm497018e2003-11-27 06:52:54 +000035#include "elf32.h"
hp.com!davidm468aacc2003-12-20 11:50:00 +000036#include "dwarf.h"
mostang.com!davidm51095502003-03-11 01:11:18 +000037
38struct unw_addr_space
39 {
40 struct unw_accessors acc;
41 unw_caching_policy_t caching_policy;
42 uint32_t cache_generation;
43 unw_word_t dyn_generation; /* see dyn-common.h */
44 unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */
45 };
46
47struct cursor
48 {
hp.com!davidm468aacc2003-12-20 11:50:00 +000049 struct dwarf_cursor dwarf; /* must be first */
hp.com!davidm78cec362004-01-30 00:01:24 +000050
51 /* Format of sigcontext structure and address at which it is
52 stored: */
53 enum
54 {
55 X86_SCF_NONE, /* no signal frame encountered */
56 X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
57 X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
58 }
59 sigcontext_format;
60 unw_word_t sigcontext_addr;
mostang.com!davidm51095502003-03-11 01:11:18 +000061 };
62
hp.com!davidm468aacc2003-12-20 11:50:00 +000063#define DWARF_GET_LOC(l) ((l).val)
64
65#ifdef UNW_LOCAL_ONLY
66# define DWARF_NULL_LOC DWARF_LOC (0, 0)
67# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
68# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
69# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
70 tdep_uc_addr((c)->as_arg, (r)), 0))
71# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
72# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
73 tdep_uc_addr((c)->as_arg, (r)), 0))
74
75static inline int
76dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
77{
78 if (!DWARF_GET_LOC (loc))
79 return -1;
80 *val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
81 return 0;
82}
83
84static inline int
hp.com!davidm78cec362004-01-30 00:01:24 +000085dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
hp.com!davidm468aacc2003-12-20 11:50:00 +000086{
87 if (!DWARF_GET_LOC (loc))
88 return -1;
hp.com!davidm78cec362004-01-30 00:01:24 +000089 *(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
hp.com!davidm468aacc2003-12-20 11:50:00 +000090 return 0;
91}
92
93static inline int
94dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
95{
96 if (!DWARF_GET_LOC (loc))
97 return -1;
98 *val = *(unw_word_t *) DWARF_GET_LOC (loc);
99 return 0;
100}
101
102static inline int
103dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
104{
105 if (!DWARF_GET_LOC (loc))
106 return -1;
107 *(unw_word_t *) DWARF_GET_LOC (loc) = val;
108 return 0;
109}
110
111#else /* !UNW_LOCAL_ONLY */
112# define DWARF_LOC_TYPE_FP (1 << 0)
113# define DWARF_LOC_TYPE_REG (1 << 1)
114# define DWARF_NULL_LOC DWARF_LOC (0, 0)
115# define DWARF_IS_NULL_LOC(l) \
116 ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
117# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) })
118# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0)
119# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0)
120# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG)
121# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
122# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \
123 | DWARF_LOC_TYPE_FP))
124
125static inline int
126dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
127{
hp.com!davidm78cec362004-01-30 00:01:24 +0000128 if (DWARF_IS_NULL_LOC (loc))
129 return -UNW_EBADREG;
130
131# warning fix me
hp.com!davidm468aacc2003-12-20 11:50:00 +0000132 abort ();
133}
134
135static inline int
136dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
137{
hp.com!davidm78cec362004-01-30 00:01:24 +0000138 if (DWARF_IS_NULL_LOC (loc))
139 return -UNW_EBADREG;
140
141# warning fix me
hp.com!davidm468aacc2003-12-20 11:50:00 +0000142 abort ();
143}
144
145static inline int
146dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
147{
hp.com!davidm78cec362004-01-30 00:01:24 +0000148 if (DWARF_IS_NULL_LOC (loc))
149 return -UNW_EBADREG;
150
hp.com!davidm468aacc2003-12-20 11:50:00 +0000151 if (DWARF_IS_FP_LOC (loc))
hp.com!davidm78cec362004-01-30 00:01:24 +0000152# warning fix me
hp.com!davidm468aacc2003-12-20 11:50:00 +0000153 abort ();
154
155 if (DWARF_IS_REG_LOC (loc))
156 return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
157 0, c->as_arg);
158 else
159 return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
160 0, c->as_arg);
161}
162
163static inline int
164dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
165{
hp.com!davidm78cec362004-01-30 00:01:24 +0000166 if (DWARF_IS_NULL_LOC (loc))
167 return -UNW_EBADREG;
168
hp.com!davidm468aacc2003-12-20 11:50:00 +0000169 if (DWARF_IS_FP_LOC (loc))
hp.com!davidm78cec362004-01-30 00:01:24 +0000170# warning fix me
hp.com!davidm468aacc2003-12-20 11:50:00 +0000171 abort ();
172
173 if (DWARF_IS_REG_LOC (loc))
174 return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
175 1, c->as_arg);
176 else
177 return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
178 1, c->as_arg);
179}
180
181#endif /* !UNW_LOCAL_ONLY */
182
hp.com!davidm78cec362004-01-30 00:01:24 +0000183#define tdep_needs_initialization UNW_OBJ(needs_initialization)
184#define tdep_init UNW_OBJ(init)
mostang.com!davidm51095502003-03-11 01:11:18 +0000185/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
186 tdep_search_unwind_table. */
hp.com!davidm468aacc2003-12-20 11:50:00 +0000187#define tdep_search_unwind_table dwarf_search_unwind_table
hp.com!davidm78cec362004-01-30 00:01:24 +0000188#define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
189#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
190#define tdep_access_reg UNW_OBJ(access_reg)
191#define tdep_access_fpreg UNW_OBJ(access_fpreg)
192
mostang.com!davidm582cfb12004-05-05 01:54:53 +0000193#ifdef UNW_LOCAL_ONLY
194# define tdep_find_proc_info(c,ip,n) \
195 dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
196 (c)->as_arg)
197# define tdep_put_unwind_info(c,pi) \
198 dwarf_put_unwind_info((c)->as, (pi), (c)->as_arg)
199#else
200# define tdep_find_proc_info(c,ip,n) \
201 (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \
202 (c)->as_arg)
203# define tdep_put_unwind_info(c,pi) \
204 (*(c)->as->acc.put_unwind_info)((c)->as, (pi), (c)->as_arg)
205#endif
206
hp.com!davidm78cec362004-01-30 00:01:24 +0000207#define tdep_get_as(c) ((c)->dwarf.as)
208#define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
209#define tdep_get_ip(c) ((c)->dwarf.ip)
210#define tdep_big_endian(as) 0
211
212extern int tdep_needs_initialization;
213
214extern void tdep_init (void);
mostang.com!davidm51095502003-03-11 01:11:18 +0000215extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
216 unw_dyn_info_t *di, unw_proc_info_t *pi,
217 int need_unwind_info, void *arg);
mostang.com!davidm51095502003-03-11 01:11:18 +0000218extern void *tdep_uc_addr (ucontext_t *uc, int reg);
hp.com!davidmf9cc1e42003-03-29 07:32:50 +0000219extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
220 unsigned long *segbase, unsigned long *mapoff);
hp.com!davidm78cec362004-01-30 00:01:24 +0000221extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
222 unw_word_t *valp, int write);
223extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
224 unw_fpreg_t *valp, int write);
mostang.com!davidm51095502003-03-11 01:11:18 +0000225
226#endif /* TDEP_X86_H */