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_core_pcb(u_int cpuid)
61 asprintf(&expr, "&cpuid_to_pcpu[%d]->pc_md.pcb", cpuid);
62 addr = kgdb_parse(expr);
68 kgdb_trgt_fetch_registers(int regno __unused)
74 kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid));
77 if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
78 warnx("kvm_read: %s", kvm_geterr(kvm));
79 memset(&pcb, 0, sizeof(pcb));
82 /* Registers 0-127: general registers. */
83 supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp);
84 supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4);
85 supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5);
86 supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6);
87 supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7);
88 supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp);
89 supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp);
91 /* Registers 128-255: floating-point registers. */
92 supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2);
93 supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3);
94 supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4);
95 supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5);
96 supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16);
97 supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17);
98 supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18);
99 supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19);
100 supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20);
101 supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21);
102 supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22);
103 supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23);
104 supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24);
105 supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25);
106 supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26);
107 supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27);
108 supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28);
109 supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29);
110 supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30);
111 supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31);
113 /* Registers 320-327: branch registers. */
114 if (pcb.pcb_special.__spare == ~0UL)
115 supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp);
116 supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1);
117 supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2);
118 supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3);
119 supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4);
120 supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5);
122 /* Registers 328-333: misc. other registers. */
123 supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr);
124 if (pcb.pcb_special.__spare == ~0UL) {
125 r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3);
126 supply_register(IA64_IP_REGNUM, (char *)&r);
127 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm);
129 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp);
130 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs);
133 /* Registers 334-461: application registers. */
134 supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc);
135 r = pcb.pcb_special.bspstore;
136 if (pcb.pcb_special.__spare == ~0UL)
137 r += pcb.pcb_special.ndirty;
139 r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) -
140 IA64_CFM_SOL(pcb.pcb_special.pfs));
141 supply_register(IA64_BSP_REGNUM, (char *)&r);
142 supply_register(IA64_BSPSTORE_REGNUM, (char *)&r);
143 supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat);
144 supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat);
145 supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr);
146 if (pcb.pcb_special.__spare == ~0UL)
147 supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs);
148 supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc);
152 kgdb_trgt_store_registers(int regno __unused)
154 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
158 kgdb_trgt_new_objfile(struct objfile *objfile)
162 struct kgdb_frame_cache {
169 #define SPECIAL(x) offsetof(struct trapframe, tf_special) \
170 + offsetof(struct _special, x)
171 #define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \
172 + offsetof(struct _caller_saved, x)
173 #define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \
174 + offsetof(struct _caller_saved_fp, x)
176 static int kgdb_trgt_frame_ofs_gr[32] = {
179 SCRATCH(gr2), SCRATCH(gr3),
180 -1, -1, -1, -1, /* gr4-gr7 */
181 SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11),
182 SPECIAL(sp), SPECIAL(tp),
183 SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17),
184 SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21),
185 SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25),
186 SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29),
187 SCRATCH(gr30), SCRATCH(gr31)
190 static int kgdb_trgt_frame_ofs_fr[32] = {
191 -1, /* fr0: constant 0.0 */
192 -1, /* fr1: constant 1.0 */
193 -1, -1, -1, -1, /* fr2-fr5 */
194 SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9),
195 SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13),
196 SCRATCH_FP(fr14), SCRATCH_FP(fr15)
199 static int kgdb_trgt_frame_ofs_br[8] = {
201 -1, -1, -1, -1, -1, /* br1-br5 */
202 SCRATCH(br6), SCRATCH(br7)
205 static int kgdb_trgt_frame_ofs_ar[49] = {
209 SPECIAL(bspstore), SPECIAL(rnat),
210 -1, -1, -1, -1, -1, /* ar20-ar24 */
211 SCRATCH(csd), SCRATCH(ssd),
212 -1, -1, -1, -1, -1, /* ar27-ar31 */
214 -1, -1, -1, /* ar33-ar35 */
216 -1, -1, -1, /* ar37-ar39 */
218 -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */
219 -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */
220 -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */
224 static struct kgdb_frame_cache *
225 kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
227 char buf[MAX_REGISTER_SIZE];
228 struct kgdb_frame_cache *cache;
232 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
234 frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf);
235 cache->bsp = extract_unsigned_integer(buf,
236 register_size(current_gdbarch, IA64_BSP_REGNUM));
237 cache->ip = frame_func_unwind(next_frame);
238 frame_unwind_register(next_frame, SP_REGNUM, buf);
239 cache->sp = extract_unsigned_integer(buf,
240 register_size(current_gdbarch, SP_REGNUM));
246 kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
247 struct frame_id *this_id)
249 struct kgdb_frame_cache *cache;
251 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
252 *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp);
256 kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
257 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp,
258 CORE_ADDR *addrp, int *realnump, void *valuep)
260 char buf[MAX_REGISTER_SIZE];
261 char dummy_valuep[MAX_REGISTER_SIZE];
262 struct kgdb_frame_cache *cache;
266 regsz = register_size(current_gdbarch, regnum);
269 valuep = dummy_valuep;
270 memset(valuep, 0, regsz);
276 cache = kgdb_trgt_frame_cache(next_frame, this_cache);
278 if (regnum == IA64_BSP_REGNUM) {
279 if (cache->saved_bsp == 0) {
280 target_read_memory(cache->sp + 16 + SPECIAL(bspstore),
282 bsp = extract_unsigned_integer(buf, regsz);
283 target_read_memory(cache->sp + 16 + SPECIAL(ndirty),
285 bsp += extract_unsigned_integer(buf, regsz);
286 cache->saved_bsp = bsp;
288 store_unsigned_integer(valuep, regsz, cache->saved_bsp);
291 if (regnum == IA64_PR_REGNUM)
293 else if (regnum == IA64_IP_REGNUM)
295 else if (regnum == IA64_PSR_REGNUM)
297 else if (regnum == IA64_CFM_REGNUM)
299 else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM)
300 ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM];
301 else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM)
302 ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM];
303 else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM)
304 ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM];
305 else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM)
306 ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM];
312 *addrp = cache->sp + 16 + ofs;
313 *lvalp = lval_memory;
314 target_read_memory(*addrp, valuep, regsz);
317 static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
319 &kgdb_trgt_trapframe_this_id,
320 &kgdb_trgt_trapframe_prev_register
323 const struct frame_unwind *
324 kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
329 ip = frame_func_unwind(next_frame);
331 find_pc_partial_function(ip, &pname, NULL, NULL);
334 if (strncmp(pname, "ivt_", 4) == 0)
335 return (&kgdb_trgt_trapframe_unwind);
336 /* printf("%s: %lx =%s\n", __func__, ip, pname); */