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