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>
31 #include <machine/frame.h>
32 #include <machine/md_var.h>
33 #include <machine/pcb.h>
40 #include <gdbthread.h>
43 #include <frame-unwind.h>
44 #include <ia64-tdep.h>
49 kgdb_trgt_fetch_registers(int regno __unused)
55 kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid));
58 if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
59 warnx("kvm_read: %s", kvm_geterr(kvm));
60 memset(&pcb, 0, sizeof(pcb));
63 /* Registers 0-127: general registers. */
64 supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp);
65 supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4);
66 supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5);
67 supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6);
68 supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7);
69 supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp);
70 supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp);
72 /* Registers 128-255: floating-point registers. */
73 supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2);
74 supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3);
75 supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4);
76 supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5);
77 supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16);
78 supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17);
79 supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18);
80 supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19);
81 supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20);
82 supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21);
83 supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22);
84 supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23);
85 supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24);
86 supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25);
87 supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26);
88 supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27);
89 supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28);
90 supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29);
91 supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30);
92 supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31);
94 /* Registers 320-327: branch registers. */
95 if (pcb.pcb_special.__spare == ~0UL)
96 supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp);
97 supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1);
98 supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2);
99 supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3);
100 supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4);
101 supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5);
103 /* Registers 328-333: misc. other registers. */
104 supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr);
105 if (pcb.pcb_special.__spare == ~0UL) {
106 r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3);
107 supply_register(IA64_IP_REGNUM, (char *)&r);
108 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm);
110 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp);
111 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs);
114 /* Registers 334-461: application registers. */
115 supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc);
116 r = pcb.pcb_special.bspstore;
117 if (pcb.pcb_special.__spare == ~0UL)
118 r += pcb.pcb_special.ndirty;
120 r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) -
121 IA64_CFM_SOL(pcb.pcb_special.pfs));
122 supply_register(IA64_BSP_REGNUM, (char *)&r);
123 supply_register(IA64_BSPSTORE_REGNUM, (char *)&r);
124 supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat);
125 supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat);
126 supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr);
127 if (pcb.pcb_special.__spare == ~0UL)
128 supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs);
129 supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc);
133 kgdb_trgt_store_registers(int regno __unused)
135 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
139 kgdb_trgt_new_objfile(struct objfile *objfile)
143 struct kgdb_frame_cache {
150 #define SPECIAL(x) offsetof(struct trapframe, tf_special) \
151 + offsetof(struct _special, x)
152 #define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \
153 + offsetof(struct _caller_saved, x)
154 #define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \
155 + offsetof(struct _caller_saved_fp, x)
157 static int kgdb_trgt_frame_ofs_gr[32] = {
160 SCRATCH(gr2), SCRATCH(gr3),
161 -1, -1, -1, -1, /* gr4-gr7 */
162 SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11),
163 SPECIAL(sp), SPECIAL(tp),
164 SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17),
165 SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21),
166 SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25),
167 SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29),
168 SCRATCH(gr30), SCRATCH(gr31)
171 static int kgdb_trgt_frame_ofs_fr[32] = {
172 -1, /* fr0: constant 0.0 */
173 -1, /* fr1: constant 1.0 */
174 -1, -1, -1, -1, /* fr2-fr5 */
175 SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9),
176 SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13),
177 SCRATCH_FP(fr14), SCRATCH_FP(fr15)
180 static int kgdb_trgt_frame_ofs_br[8] = {
182 -1, -1, -1, -1, -1, /* br1-br5 */
183 SCRATCH(br6), SCRATCH(br7)
186 static int kgdb_trgt_frame_ofs_ar[49] = {
190 SPECIAL(bspstore), SPECIAL(rnat),
191 -1, -1, -1, -1, -1, /* ar20-ar24 */
192 SCRATCH(csd), SCRATCH(ssd),
193 -1, -1, -1, -1, -1, /* ar27-ar31 */
195 -1, -1, -1, /* ar33-ar35 */
197 -1, -1, -1, /* ar37-ar39 */
199 -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */
200 -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */
201 -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */
205 static struct kgdb_frame_cache *
206 kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
208 char buf[MAX_REGISTER_SIZE];
209 struct kgdb_frame_cache *cache;
213 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
215 frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf);
216 cache->bsp = extract_unsigned_integer(buf,
217 register_size(current_gdbarch, IA64_BSP_REGNUM));
218 cache->ip = frame_func_unwind(next_frame);
219 frame_unwind_register(next_frame, SP_REGNUM, buf);
220 cache->sp = extract_unsigned_integer(buf,
221 register_size(current_gdbarch, SP_REGNUM));
227 kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
228 struct frame_id *this_id)
230 struct kgdb_frame_cache *cache;
232 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
233 *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp);
237 kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
238 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp,
239 CORE_ADDR *addrp, int *realnump, void *valuep)
241 char buf[MAX_REGISTER_SIZE];
242 char dummy_valuep[MAX_REGISTER_SIZE];
243 struct kgdb_frame_cache *cache;
247 regsz = register_size(current_gdbarch, regnum);
250 valuep = dummy_valuep;
251 memset(valuep, 0, regsz);
257 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
259 if (regnum == IA64_BSP_REGNUM) {
260 if (cache->saved_bsp == 0) {
261 target_read_memory(cache->sp + 16 + SPECIAL(bspstore),
263 bsp = extract_unsigned_integer(buf, regsz);
264 target_read_memory(cache->sp + 16 + SPECIAL(ndirty),
266 bsp += extract_unsigned_integer(buf, regsz);
267 cache->saved_bsp = bsp;
269 store_unsigned_integer(valuep, regsz, cache->saved_bsp);
272 if (regnum == IA64_PR_REGNUM)
274 else if (regnum == IA64_IP_REGNUM)
276 else if (regnum == IA64_PSR_REGNUM)
278 else if (regnum == IA64_CFM_REGNUM)
280 else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM)
281 ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM];
282 else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM)
283 ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM];
284 else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM)
285 ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM];
286 else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM)
287 ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM];
293 *addrp = cache->sp + 16 + ofs;
294 *lvalp = lval_memory;
295 target_read_memory(*addrp, valuep, regsz);
298 static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
300 &kgdb_trgt_trapframe_this_id,
301 &kgdb_trgt_trapframe_prev_register
304 const struct frame_unwind *
305 kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
310 ip = frame_func_unwind(next_frame);
312 find_pc_partial_function(ip, &pname, NULL, NULL);
315 if (strncmp(pname, "ivt_", 4) == 0)
316 return (&kgdb_trgt_trapframe_unwind);
317 /* printf("%s: %lx =%s\n", __func__, ip, pname); */