]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - gnu/usr.bin/gdb/kgdb/trgt_ia64.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / gnu / usr.bin / gdb / kgdb / trgt_ia64.c
1 /*
2  * Copyright (c) 2004 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
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.
14  *
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.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/types.h>
31 #ifdef CROSS_DEBUGGER
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>
36 #else
37 #include <machine/frame.h>
38 #include <machine/md_var.h>
39 #include <machine/pcb.h>
40 #endif
41 #include <err.h>
42 #include <kvm.h>
43 #include <string.h>
44
45 #include <defs.h>
46 #include <target.h>
47 #include <gdbthread.h>
48 #include <inferior.h>
49 #include <regcache.h>
50 #include <frame-unwind.h>
51 #include <ia64-tdep.h>
52
53 #include "kgdb.h"
54
55 CORE_ADDR
56 kgdb_trgt_core_pcb(u_int cpuid)
57 {
58         CORE_ADDR addr;
59         char *expr;
60
61         asprintf(&expr, "&cpuid_to_pcpu[%d]->pc_md.pcb", cpuid);
62         addr = kgdb_parse(expr);
63         free(expr);
64         return (addr);
65 }
66
67 void
68 kgdb_trgt_fetch_registers(int regno __unused)
69 {
70         struct kthr *kt;
71         struct pcb pcb;
72         uint64_t r;
73
74         kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid));
75         if (kt == NULL)
76                 return;
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));
80         }
81
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);
90
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);
112
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);
121
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);
128         } else {
129                 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp);
130                 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs);
131         }
132
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;
138         else
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);
149 }
150
151 void
152 kgdb_trgt_store_registers(int regno __unused)
153 {
154         fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
155 }
156
157 void
158 kgdb_trgt_new_objfile(struct objfile *objfile)
159 {
160 }
161
162 struct kgdb_frame_cache {
163         CORE_ADDR       bsp;
164         CORE_ADDR       ip;
165         CORE_ADDR       sp;
166         CORE_ADDR       saved_bsp;
167 };
168
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)
175
176 static int kgdb_trgt_frame_ofs_gr[32] = {
177         -1,                                     /* gr0 */
178         SPECIAL(gp),
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)
188 };
189
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)
197 };
198
199 static int kgdb_trgt_frame_ofs_br[8] = {
200         SPECIAL(rp),
201         -1, -1, -1, -1, -1,                     /* br1-br5 */
202         SCRATCH(br6), SCRATCH(br7)
203 };
204
205 static int kgdb_trgt_frame_ofs_ar[49] = {
206         /* ar0-ar15 */
207         SPECIAL(rsc),
208         -1,                                     /* ar.bsp */
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 */
213         SCRATCH(ccv),
214         -1, -1, -1,                             /* ar33-ar35 */
215         SPECIAL(unat),
216         -1, -1, -1,                             /* ar37-ar39 */
217         SPECIAL(fpsr),
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 */
221         SPECIAL(pfs)
222 };
223
224 static struct kgdb_frame_cache *
225 kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
226 {
227         char buf[MAX_REGISTER_SIZE];
228         struct kgdb_frame_cache *cache;
229
230         cache = *this_cache;
231         if (cache == NULL) {
232                 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
233                 *this_cache = 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));
241         }
242         return (cache);
243 }
244
245 static void
246 kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
247     struct frame_id *this_id)
248 {
249         struct kgdb_frame_cache *cache;
250
251         cache = kgdb_trgt_frame_cache(next_frame, this_cache);
252         *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp);
253 }
254
255 static void
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)
259 {
260         char buf[MAX_REGISTER_SIZE];
261         char dummy_valuep[MAX_REGISTER_SIZE];
262         struct kgdb_frame_cache *cache;
263         CORE_ADDR bsp;
264         int ofs, regsz;
265
266         regsz = register_size(current_gdbarch, regnum);
267
268         if (valuep == NULL)
269                 valuep = dummy_valuep;
270         memset(valuep, 0, regsz);
271         *optimizedp = 0;
272         *addrp = 0;
273         *lvalp = not_lval;
274         *realnump = -1;
275
276         cache = kgdb_trgt_frame_cache(next_frame, this_cache);
277
278         if (regnum == IA64_BSP_REGNUM) {
279                 if (cache->saved_bsp == 0) {
280                         target_read_memory(cache->sp + 16 + SPECIAL(bspstore),
281                             buf, regsz);
282                         bsp = extract_unsigned_integer(buf, regsz);
283                         target_read_memory(cache->sp + 16 + SPECIAL(ndirty),
284                             buf, regsz);
285                         bsp += extract_unsigned_integer(buf, regsz);
286                         cache->saved_bsp = bsp;
287                 }
288                 store_unsigned_integer(valuep, regsz, cache->saved_bsp);
289                 return;
290         }
291         if (regnum == IA64_PR_REGNUM)
292                 ofs = SPECIAL(pr);
293         else if (regnum == IA64_IP_REGNUM)
294                 ofs = SPECIAL(iip);
295         else if (regnum == IA64_PSR_REGNUM)
296                 ofs = SPECIAL(psr);
297         else if (regnum == IA64_CFM_REGNUM)
298                 ofs = SPECIAL(cfm);
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];
307         else
308                 ofs = -1;
309         if (ofs == -1)
310                 return;
311
312         *addrp = cache->sp + 16 + ofs;
313         *lvalp = lval_memory;
314         target_read_memory(*addrp, valuep, regsz);
315 }
316
317 static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
318         UNKNOWN_FRAME,
319         &kgdb_trgt_trapframe_this_id,
320         &kgdb_trgt_trapframe_prev_register
321 };
322
323 const struct frame_unwind *
324 kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
325 {
326         char *pname;
327         CORE_ADDR ip;
328
329         ip = frame_func_unwind(next_frame);
330         pname = NULL;
331         find_pc_partial_function(ip, &pname, NULL, NULL);
332         if (pname == NULL)
333                 return (NULL);
334         if (strncmp(pname, "ivt_", 4) == 0)
335                 return (&kgdb_trgt_trapframe_unwind);
336         /* printf("%s: %lx =%s\n", __func__, ip, pname); */
337         return (NULL);
338 }