Deleted Added
full compact
trgt_i386.c (167143) trgt_i386.c (173681)
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 *

--- 11 unchanged lines hidden (view full) ---

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>
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 *

--- 11 unchanged lines hidden (view full) ---

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: head/gnu/usr.bin/gdb/kgdb/trgt_i386.c 167143 2007-03-01 13:56:08Z kib $");
28__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/trgt_i386.c 173681 2007-11-16 22:17:37Z jhb $");
29
29
30#include <sys/types.h>
30#include <sys/param.h>
31#include <sys/proc.h>
31#include <machine/pcb.h>
32#include <machine/frame.h>
32#include <machine/pcb.h>
33#include <machine/frame.h>
34#include <machine/segments.h>
35#include <machine/tss.h>
33#include <err.h>
34#include <kvm.h>
35#include <string.h>
36
37#include <defs.h>
38#include <target.h>
39#include <gdbthread.h>
40#include <inferior.h>

--- 25 unchanged lines hidden (view full) ---

66}
67
68void
69kgdb_trgt_store_registers(int regno __unused)
70{
71 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
72}
73
36#include <err.h>
37#include <kvm.h>
38#include <string.h>
39
40#include <defs.h>
41#include <target.h>
42#include <gdbthread.h>
43#include <inferior.h>

--- 25 unchanged lines hidden (view full) ---

69}
70
71void
72kgdb_trgt_store_registers(int regno __unused)
73{
74 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
75}
76
77struct kgdb_tss_cache {
78 CORE_ADDR pc;
79 CORE_ADDR sp;
80 CORE_ADDR tss;
81};
82
83static int kgdb_trgt_tss_offset[15] = {
84 offsetof(struct i386tss, tss_eax),
85 offsetof(struct i386tss, tss_ecx),
86 offsetof(struct i386tss, tss_edx),
87 offsetof(struct i386tss, tss_ebx),
88 offsetof(struct i386tss, tss_esp),
89 offsetof(struct i386tss, tss_ebp),
90 offsetof(struct i386tss, tss_esi),
91 offsetof(struct i386tss, tss_edi),
92 offsetof(struct i386tss, tss_eip),
93 offsetof(struct i386tss, tss_eflags),
94 offsetof(struct i386tss, tss_cs),
95 offsetof(struct i386tss, tss_ss),
96 offsetof(struct i386tss, tss_ds),
97 offsetof(struct i386tss, tss_es),
98 offsetof(struct i386tss, tss_fs)
99};
100
101/*
102 * If the current thread is executing on a CPU, fetch the common_tss
103 * for that CPU.
104 *
105 * This is painful because 'struct pcpu' is variant sized, so we can't
106 * use it. Instead, we lookup the GDT selector for this CPU and
107 * extract the base of the TSS from there.
108 */
109static CORE_ADDR
110kgdb_trgt_fetch_tss(void)
111{
112 struct kthr *kt;
113 struct segment_descriptor sd;
114 uintptr_t addr, cpu0prvpage, tss;
115
116 kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
117 if (kt == NULL || kt->cpu == NOCPU)
118 return (0);
119
120 addr = kgdb_lookup("_gdt");
121 if (addr == 0)
122 return (0);
123 addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd);
124 if (kvm_read(kvm, addr, &sd, sizeof(sd)) != sizeof(sd)) {
125 warnx("kvm_read: %s", kvm_geterr(kvm));
126 return (0);
127 }
128 if (sd.sd_type != SDT_SYS386BSY) {
129 warnx("descriptor is not a busy TSS");
130 return (0);
131 }
132 tss = sd.sd_hibase << 24 | sd.sd_lobase;
133
134 /*
135 * In SMP kernels, the TSS is stored as part of the per-CPU
136 * data. On older kernels, the CPU0's private page
137 * is stored at an address that isn't mapped in minidumps.
138 * However, the data is mapped at the alternate cpu0prvpage
139 * address. Thus, if the TSS is at the invalid address,
140 * change it to be relative to cpu0prvpage instead.
141 */
142 if (trunc_page(tss) == 0xffc00000) {
143 addr = kgdb_lookup("_cpu0prvpage");
144 if (addr == 0)
145 return (0);
146 if (kvm_read(kvm, addr, &cpu0prvpage, sizeof(cpu0prvpage)) !=
147 sizeof(cpu0prvpage)) {
148 warnx("kvm_read: %s", kvm_geterr(kvm));
149 return (0);
150 }
151 tss = cpu0prvpage + (tss & PAGE_MASK);
152 }
153 return ((CORE_ADDR)tss);
154}
155
156static struct kgdb_tss_cache *
157kgdb_trgt_tss_cache(struct frame_info *next_frame, void **this_cache)
158{
159 char buf[MAX_REGISTER_SIZE];
160 struct kgdb_tss_cache *cache;
161
162 cache = *this_cache;
163 if (cache == NULL) {
164 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_tss_cache);
165 *this_cache = cache;
166 cache->pc = frame_func_unwind(next_frame);
167 frame_unwind_register(next_frame, SP_REGNUM, buf);
168 cache->sp = extract_unsigned_integer(buf,
169 register_size(current_gdbarch, SP_REGNUM));
170 cache->tss = kgdb_trgt_fetch_tss();
171 }
172 return (cache);
173}
174
175static void
176kgdb_trgt_dblfault_this_id(struct frame_info *next_frame, void **this_cache,
177 struct frame_id *this_id)
178{
179 struct kgdb_tss_cache *cache;
180
181 cache = kgdb_trgt_tss_cache(next_frame, this_cache);
182 *this_id = frame_id_build(cache->sp, cache->pc);
183}
184
185static void
186kgdb_trgt_dblfault_prev_register(struct frame_info *next_frame,
187 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp,
188 CORE_ADDR *addrp, int *realnump, void *valuep)
189{
190 char dummy_valuep[MAX_REGISTER_SIZE];
191 struct kgdb_tss_cache *cache;
192 int ofs, regsz;
193
194 regsz = register_size(current_gdbarch, regnum);
195
196 if (valuep == NULL)
197 valuep = dummy_valuep;
198 memset(valuep, 0, regsz);
199 *optimizedp = 0;
200 *addrp = 0;
201 *lvalp = not_lval;
202 *realnump = -1;
203
204 ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM)
205 ? kgdb_trgt_tss_offset[regnum] : -1;
206 if (ofs == -1)
207 return;
208
209 cache = kgdb_trgt_tss_cache(next_frame, this_cache);
210 if (cache->tss == 0)
211 return;
212 *addrp = cache->tss + ofs;
213 *lvalp = lval_memory;
214 target_read_memory(*addrp, valuep, regsz);
215}
216
217static const struct frame_unwind kgdb_trgt_dblfault_unwind = {
218 UNKNOWN_FRAME,
219 &kgdb_trgt_dblfault_this_id,
220 &kgdb_trgt_dblfault_prev_register
221};
222
74struct kgdb_frame_cache {
75 int intrframe;
76 CORE_ADDR pc;
77 CORE_ADDR sp;
78};
79
80static int kgdb_trgt_frame_offset[15] = {
81 offsetof(struct trapframe, tf_eax),

--- 107 unchanged lines hidden (view full) ---

189 char *pname;
190 CORE_ADDR pc;
191
192 pc = frame_pc_unwind(next_frame);
193 pname = NULL;
194 find_pc_partial_function(pc, &pname, NULL, NULL);
195 if (pname == NULL)
196 return (NULL);
223struct kgdb_frame_cache {
224 int intrframe;
225 CORE_ADDR pc;
226 CORE_ADDR sp;
227};
228
229static int kgdb_trgt_frame_offset[15] = {
230 offsetof(struct trapframe, tf_eax),

--- 107 unchanged lines hidden (view full) ---

338 char *pname;
339 CORE_ADDR pc;
340
341 pc = frame_pc_unwind(next_frame);
342 pname = NULL;
343 find_pc_partial_function(pc, &pname, NULL, NULL);
344 if (pname == NULL)
345 return (NULL);
346 if (strcmp(pname, "dblfault_handler") == 0)
347 return (&kgdb_trgt_dblfault_unwind);
197 if (strcmp(pname, "calltrap") == 0 ||
198 (pname[0] == 'X' && pname[1] != '_'))
199 return (&kgdb_trgt_trapframe_unwind);
200 /* printf("%s: %llx =%s\n", __func__, pc, pname); */
201 return (NULL);
202}
348 if (strcmp(pname, "calltrap") == 0 ||
349 (pname[0] == 'X' && pname[1] != '_'))
350 return (&kgdb_trgt_trapframe_unwind);
351 /* printf("%s: %llx =%s\n", __func__, pc, pname); */
352 return (NULL);
353}