2 * Copyright (c) 2004 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/types.h>
32 #include <sys/ia64/include/_regset.h>
33 #include <sys/ia64/include/frame.h>
34 #include <sys/ia64/include/md_var.h>
35 #include <sys/ia64/include/pcb.h>
37 #include <machine/frame.h>
38 #include <machine/md_var.h>
39 #include <machine/pcb.h>
47 #include <gdbthread.h>
50 #include <frame-unwind.h>
51 #include <ia64-tdep.h>
56 kgdb_trgt_fetch_registers(int regno __unused)
62 kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid));
65 if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
66 warnx("kvm_read: %s", kvm_geterr(kvm));
67 memset(&pcb, 0, sizeof(pcb));
70 /* Registers 0-127: general registers. */
71 supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp);
72 supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4);
73 supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5);
74 supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6);
75 supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7);
76 supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp);
77 supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp);
79 /* Registers 128-255: floating-point registers. */
80 supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2);
81 supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3);
82 supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4);
83 supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5);
84 supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16);
85 supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17);
86 supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18);
87 supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19);
88 supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20);
89 supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21);
90 supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22);
91 supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23);
92 supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24);
93 supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25);
94 supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26);
95 supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27);
96 supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28);
97 supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29);
98 supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30);
99 supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31);
101 /* Registers 320-327: branch registers. */
102 if (pcb.pcb_special.__spare == ~0UL)
103 supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp);
104 supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1);
105 supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2);
106 supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3);
107 supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4);
108 supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5);
110 /* Registers 328-333: misc. other registers. */
111 supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr);
112 if (pcb.pcb_special.__spare == ~0UL) {
113 r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3);
114 supply_register(IA64_IP_REGNUM, (char *)&r);
115 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm);
117 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp);
118 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs);
121 /* Registers 334-461: application registers. */
122 supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc);
123 r = pcb.pcb_special.bspstore;
124 if (pcb.pcb_special.__spare == ~0UL)
125 r += pcb.pcb_special.ndirty;
127 r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) -
128 IA64_CFM_SOL(pcb.pcb_special.pfs));
129 supply_register(IA64_BSP_REGNUM, (char *)&r);
130 supply_register(IA64_BSPSTORE_REGNUM, (char *)&r);
131 supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat);
132 supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat);
133 supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr);
134 if (pcb.pcb_special.__spare == ~0UL)
135 supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs);
136 supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc);
140 kgdb_trgt_store_registers(int regno __unused)
142 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
146 kgdb_trgt_new_objfile(struct objfile *objfile)
150 struct kgdb_frame_cache {
157 #define SPECIAL(x) offsetof(struct trapframe, tf_special) \
158 + offsetof(struct _special, x)
159 #define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \
160 + offsetof(struct _caller_saved, x)
161 #define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \
162 + offsetof(struct _caller_saved_fp, x)
164 static int kgdb_trgt_frame_ofs_gr[32] = {
167 SCRATCH(gr2), SCRATCH(gr3),
168 -1, -1, -1, -1, /* gr4-gr7 */
169 SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11),
170 SPECIAL(sp), SPECIAL(tp),
171 SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17),
172 SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21),
173 SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25),
174 SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29),
175 SCRATCH(gr30), SCRATCH(gr31)
178 static int kgdb_trgt_frame_ofs_fr[32] = {
179 -1, /* fr0: constant 0.0 */
180 -1, /* fr1: constant 1.0 */
181 -1, -1, -1, -1, /* fr2-fr5 */
182 SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9),
183 SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13),
184 SCRATCH_FP(fr14), SCRATCH_FP(fr15)
187 static int kgdb_trgt_frame_ofs_br[8] = {
189 -1, -1, -1, -1, -1, /* br1-br5 */
190 SCRATCH(br6), SCRATCH(br7)
193 static int kgdb_trgt_frame_ofs_ar[49] = {
197 SPECIAL(bspstore), SPECIAL(rnat),
198 -1, -1, -1, -1, -1, /* ar20-ar24 */
199 SCRATCH(csd), SCRATCH(ssd),
200 -1, -1, -1, -1, -1, /* ar27-ar31 */
202 -1, -1, -1, /* ar33-ar35 */
204 -1, -1, -1, /* ar37-ar39 */
206 -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */
207 -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */
208 -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */
212 static struct kgdb_frame_cache *
213 kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
215 char buf[MAX_REGISTER_SIZE];
216 struct kgdb_frame_cache *cache;
220 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
222 frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf);
223 cache->bsp = extract_unsigned_integer(buf,
224 register_size(current_gdbarch, IA64_BSP_REGNUM));
225 cache->ip = frame_func_unwind(next_frame);
226 frame_unwind_register(next_frame, SP_REGNUM, buf);
227 cache->sp = extract_unsigned_integer(buf,
228 register_size(current_gdbarch, SP_REGNUM));
234 kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
235 struct frame_id *this_id)
237 struct kgdb_frame_cache *cache;
239 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
240 *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp);
244 kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
245 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp,
246 CORE_ADDR *addrp, int *realnump, void *valuep)
248 char buf[MAX_REGISTER_SIZE];
249 char dummy_valuep[MAX_REGISTER_SIZE];
250 struct kgdb_frame_cache *cache;
254 regsz = register_size(current_gdbarch, regnum);
257 valuep = dummy_valuep;
258 memset(valuep, 0, regsz);
264 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
266 if (regnum == IA64_BSP_REGNUM) {
267 if (cache->saved_bsp == 0) {
268 target_read_memory(cache->sp + 16 + SPECIAL(bspstore),
270 bsp = extract_unsigned_integer(buf, regsz);
271 target_read_memory(cache->sp + 16 + SPECIAL(ndirty),
273 bsp += extract_unsigned_integer(buf, regsz);
274 cache->saved_bsp = bsp;
276 store_unsigned_integer(valuep, regsz, cache->saved_bsp);
279 if (regnum == IA64_PR_REGNUM)
281 else if (regnum == IA64_IP_REGNUM)
283 else if (regnum == IA64_PSR_REGNUM)
285 else if (regnum == IA64_CFM_REGNUM)
287 else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM)
288 ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM];
289 else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM)
290 ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM];
291 else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM)
292 ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM];
293 else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM)
294 ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM];
300 *addrp = cache->sp + 16 + ofs;
301 *lvalp = lval_memory;
302 target_read_memory(*addrp, valuep, regsz);
305 static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
307 &kgdb_trgt_trapframe_this_id,
308 &kgdb_trgt_trapframe_prev_register
311 const struct frame_unwind *
312 kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
317 ip = frame_func_unwind(next_frame);
319 find_pc_partial_function(ip, &pname, NULL, NULL);
322 if (strncmp(pname, "ivt_", 4) == 0)
323 return (&kgdb_trgt_trapframe_unwind);
324 /* printf("%s: %lx =%s\n", __func__, ip, pname); */