]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - gnu/usr.bin/gdb/kgdb/trgt_mips.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / gnu / usr.bin / gdb / kgdb / trgt_mips.c
1 /*
2  * Copyright (c) 2007 Juniper Networks, Inc.
3  * Copyright (c) 2004 Marcel Moolenaar
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * from: src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c,v 1.2.2.1 2005/09/15 05:32:10 marcel
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/types.h>
34 #include <machine/asm.h>
35 #include <machine/pcb.h>
36 #include <machine/frame.h>
37 #include <err.h>
38 #include <kvm.h>
39 #include <string.h>
40
41 #include <defs.h>
42 #include <target.h>
43 #include <gdbthread.h>
44 #include <inferior.h>
45 #include <regcache.h>
46 #include <frame-unwind.h>
47 #include <mips-tdep.h>
48
49 #ifndef CROSS_DEBUGGER
50 #include <machine/pcb.h>
51 #endif
52
53 #include "kgdb.h"
54
55 CORE_ADDR
56 kgdb_trgt_core_pcb(u_int cpuid)
57 {
58         return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
59 }
60
61 void
62 kgdb_trgt_fetch_registers(int regno __unused)
63 {
64 #ifndef CROSS_DEBUGGER
65         struct kthr *kt;
66         struct pcb pcb;
67
68         kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid));
69         if (kt == NULL)
70                 return;
71         if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
72                 warnx("kvm_read: %s", kvm_geterr(kvm));
73                 memset(&pcb, 0, sizeof(pcb));
74         }
75
76         supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]);
77         supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]);
78         supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]);
79         supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]);
80         supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]);
81         supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]);
82         supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]);
83         supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]);
84         supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]);
85         supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]);
86         supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]);
87         supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]);
88 #endif
89 }
90
91 void
92 kgdb_trgt_store_registers(int regno __unused)
93 {
94
95         fprintf_unfiltered(gdb_stderr, "Unimplemented function: %s\n", __func__);
96 }
97
98 void
99 kgdb_trgt_new_objfile(struct objfile *objfile)
100 {
101 }
102
103 #ifndef CROSS_DEBUGGER
104 struct kgdb_frame_cache {
105         CORE_ADDR       pc;
106         CORE_ADDR       sp;
107 };
108
109 static int kgdb_trgt_frame_offset[] = {
110         offsetof(struct trapframe, zero),
111         offsetof(struct trapframe, ast),
112         offsetof(struct trapframe, v0),
113         offsetof(struct trapframe, v1),
114         offsetof(struct trapframe, a0),
115         offsetof(struct trapframe, a1),
116         offsetof(struct trapframe, a2),
117         offsetof(struct trapframe, a3),
118 #if defined(__mips_n32) || defined(__mips_n64)
119         offsetof(struct trapframe, a4),
120         offsetof(struct trapframe, a5),
121         offsetof(struct trapframe, a6),
122         offsetof(struct trapframe, a7),
123         offsetof(struct trapframe, t0),
124         offsetof(struct trapframe, t1),
125         offsetof(struct trapframe, t2),
126         offsetof(struct trapframe, t3),
127 #else
128         offsetof(struct trapframe, t0),
129         offsetof(struct trapframe, t1),
130         offsetof(struct trapframe, t2),
131         offsetof(struct trapframe, t3),
132         offsetof(struct trapframe, t4),
133         offsetof(struct trapframe, t5),
134         offsetof(struct trapframe, t6),
135         offsetof(struct trapframe, t7),
136 #endif
137         offsetof(struct trapframe, s0),
138         offsetof(struct trapframe, s1),
139         offsetof(struct trapframe, s2),
140         offsetof(struct trapframe, s3),
141         offsetof(struct trapframe, s4),
142         offsetof(struct trapframe, s5),
143         offsetof(struct trapframe, s6),
144         offsetof(struct trapframe, s7),
145         offsetof(struct trapframe, t8),
146         offsetof(struct trapframe, t9),
147         offsetof(struct trapframe, k0),
148         offsetof(struct trapframe, k1),
149         offsetof(struct trapframe, gp),
150         offsetof(struct trapframe, sp),
151         offsetof(struct trapframe, s8),
152         offsetof(struct trapframe, ra),
153 };
154
155 static struct kgdb_frame_cache *
156 kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache)
157 {
158         char buf[MAX_REGISTER_SIZE];
159         struct kgdb_frame_cache *cache;
160
161         cache = *this_cache;
162         if (cache == NULL) {
163                 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache);
164                 *this_cache = cache;
165                 cache->pc = frame_func_unwind(next_frame);
166                 frame_unwind_register(next_frame, SP_REGNUM, buf);
167                 cache->sp = extract_unsigned_integer(buf,
168                     register_size(current_gdbarch, SP_REGNUM));
169         }
170         return (cache);
171 }
172
173 static void
174 kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache,
175     struct frame_id *this_id)
176 {
177         struct kgdb_frame_cache *cache;
178
179         cache = kgdb_trgt_frame_cache(next_frame, this_cache);
180         *this_id = frame_id_build(cache->sp, cache->pc);
181 }
182
183 static void
184 kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused,
185     void **this_cache __unused, int regnum __unused, int *optimizedp __unused,
186     enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused,
187     int *realnump __unused, void *valuep __unused)
188 {
189         char dummy_valuep[MAX_REGISTER_SIZE];
190         struct kgdb_frame_cache *cache;
191         int ofs, regsz;
192
193         regsz = register_size(current_gdbarch, regnum);
194
195         if (valuep == NULL)
196                 valuep = dummy_valuep;
197         memset(valuep, 0, regsz);
198         *optimizedp = 0;
199         *addrp = 0;
200         *lvalp = not_lval;
201         *realnump = -1;
202
203         ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ?
204             kgdb_trgt_frame_offset[regnum] : -1;
205         if (ofs == -1)
206                 return;
207
208         cache = kgdb_trgt_frame_cache(next_frame, this_cache);
209         *addrp = cache->sp + ofs * 8;
210         *lvalp = lval_memory;
211         target_read_memory(*addrp, valuep, regsz);
212 }
213
214 static const struct frame_unwind kgdb_trgt_trapframe_unwind = {
215         UNKNOWN_FRAME,
216         &kgdb_trgt_trapframe_this_id,
217         &kgdb_trgt_trapframe_prev_register
218 };
219 #endif
220
221 const struct frame_unwind *
222 kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame)
223 {
224 #ifndef CROSS_DEBUGGER
225         char *pname;
226         CORE_ADDR pc;
227
228         pc = frame_pc_unwind(next_frame);
229         pname = NULL;
230         find_pc_partial_function(pc, &pname, NULL, NULL);
231         if (pname == NULL)
232                 return (NULL);
233         if ((strcmp(pname, "MipsKernIntr") == 0) ||
234             (strcmp(pname, "MipsKernGenException") == 0) ||
235             (strcmp(pname, "MipsUserIntr") == 0) ||
236             (strcmp(pname, "MipsUserGenException") == 0))
237                 return (&kgdb_trgt_trapframe_unwind);
238 #endif
239         return (NULL);
240 }