void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; struct gdbarch_tdep *tdep; int i; tdep = gdbarch_tdep (current_gdbarch); kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } /* * r14-r31 are saved in the pcb */ for (i = 14; i <= 31; i++) { supply_register(tdep->ppc_gp0_regnum + i, (char *)&pcb.pcb_context[i]); } /* r1 is saved in the sp field */ supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); }
void kgdb_trgt_fetch_registers(int regno __unused) { #ifndef CROSS_DEBUGGER struct kthr *kt; struct pcb pcb; int i, reg; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) { supply_register(i, (char *)&pcb.un_32.pcb32_r8 + (i - (ARM_A1_REGNUM + 8 )) * 4); } if (pcb.un_32.pcb32_sp != 0) { for (i = 0; i < 4; i++) { if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4, ®, 4) != 4) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } supply_register(ARM_A1_REGNUM + 4 + i, (char *)®); } if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); } #endif }
void kgdb_trgt_fetch_registers(int regno __unused) { #ifndef CROSS_DEBUGGER struct kthr *kt; struct pcb pcb; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]); supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]); supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]); supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]); supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]); supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]); supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]); supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]); supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]); supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]); supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]); supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]); #endif }
char * kgdb_thr_extra_thread_info(int tid) { char comm[MAXCOMLEN + 1]; char td_name[MAXCOMLEN + 1]; struct kthr *kt; struct proc *p; struct thread *t; static char buf[64]; kt = kgdb_thr_lookup_tid(tid); if (kt == NULL) return (NULL); snprintf(buf, sizeof(buf), "PID=%d", kt->pid); p = (struct proc *)kt->paddr; if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) != sizeof(comm)) return (buf); strlcat(buf, ": ", sizeof(buf)); strlcat(buf, comm, sizeof(buf)); t = (struct thread *)kt->kaddr; if (kvm_read(kvm, (uintptr_t)&t->td_name[0], &td_name, sizeof(td_name)) == sizeof(td_name) && strcmp(comm, td_name) != 0) { strlcat(buf, "/", sizeof(buf)); strlcat(buf, td_name, sizeof(buf)); } return (buf); }
struct kthr * kgdb_thr_init(void) { long cpusetsize; struct kthr *kt; CORE_ADDR addr; uintptr_t paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("allproc"); if (addr == 0) return (NULL); kvm_read(kvm, addr, &paddr, sizeof(paddr)); dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); addr = kgdb_lookup("dumptid"); if (addr != 0) kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); else dumptid = -1; addr = kgdb_lookup("stopped_cpus"); CPU_ZERO(&stopped_cpus); cpusetsize = sysconf(_SC_CPUSET_SIZE); if (cpusetsize != -1 && (u_long)cpusetsize <= sizeof(cpuset_t) && addr != 0) kvm_read(kvm, addr, &stopped_cpus, cpusetsize); stoppcbs = kgdb_lookup("stoppcbs"); kgdb_thr_add_procs(paddr); addr = kgdb_lookup("zombproc"); if (addr != 0) { kvm_read(kvm, addr, &paddr, sizeof(paddr)); kgdb_thr_add_procs(paddr); } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); }
void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); sparc_supply_rwindow(current_regcache, pcb.pcb_sp, -1); supply_register(SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); pcb.pcb_pc += 4; supply_register(SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); }
void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(I386_EBX_REGNUM, (char *)&pcb.pcb_ebx); supply_register(I386_ESP_REGNUM, (char *)&pcb.pcb_esp); supply_register(I386_EBP_REGNUM, (char *)&pcb.pcb_ebp); supply_register(I386_ESI_REGNUM, (char *)&pcb.pcb_esi); supply_register(I386_EDI_REGNUM, (char *)&pcb.pcb_edi); supply_register(I386_EIP_REGNUM, (char *)&pcb.pcb_eip); }
/* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR i386fbsd_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; CORE_ADDR addr, cpu0prvpage, tss; kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0) return (0); addr = kgdb_lookup("gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (target_read_memory(addr, (void *)&sd, sizeof(sd)) != 0) return (0); if (sd.sd_type != SDT_SYS386BSY) { warning ("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { TRY { cpu0prvpage = parse_and_eval_address("cpu0prvpage"); } CATCH(e, RETURN_MASK_ERROR) { return (0); } END_CATCH tss = cpu0prvpage + (tss & PAGE_MASK); }
void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); amd64_supply_fxsave(current_regcache, -1, (struct fpusave *)(&pcb + 1)); }
static int kgdb_trgt_thread_alive(ptid_t ptid) { return (kgdb_thr_lookup_tid(ptid_get_pid(ptid)) != NULL); }
struct kthr * kgdb_thr_init(void) { struct proc p; struct thread td; long cpusetsize; struct kthr *kt; CORE_ADDR addr; uintptr_t paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("allproc"); if (addr == 0) return (NULL); kvm_read(kvm, addr, &paddr, sizeof(paddr)); dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); addr = kgdb_lookup("dumptid"); if (addr != 0) kvm_read(kvm, addr, &dumptid, sizeof(dumptid)); else dumptid = -1; addr = kgdb_lookup("stopped_cpus"); CPU_ZERO(&stopped_cpus); cpusetsize = sysconf(_SC_CPUSET_SIZE); if (cpusetsize != -1 && (u_long)cpusetsize <= sizeof(cpuset_t) && addr != 0) kvm_read(kvm, addr, &stopped_cpus, cpusetsize); stoppcbs = kgdb_lookup("stoppcbs"); while (paddr != 0) { if (kvm_read(kvm, paddr, &p, sizeof(p)) != sizeof(p)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } addr = (uintptr_t)TAILQ_FIRST(&p.p_threads); while (addr != 0) { if (kvm_read(kvm, addr, &td, sizeof(td)) != sizeof(td)) { warnx("kvm_read: %s", kvm_geterr(kvm)); break; } kt = malloc(sizeof(*kt)); kt->next = first; kt->kaddr = addr; if (td.td_tid == dumptid) kt->pcb = dumppcb; else if (td.td_state == TDS_RUNNING && stoppcbs != 0 && CPU_ISSET(td.td_oncpu, &stopped_cpus)) kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu; else kt->pcb = (uintptr_t)td.td_pcb; kt->kstack = td.td_kstack; kt->tid = td.td_tid; kt->pid = p.p_pid; kt->paddr = paddr; kt->cpu = td.td_oncpu; first = kt; addr = (uintptr_t)TAILQ_NEXT(&td, td_plist); } paddr = (uintptr_t)LIST_NEXT(&p, p_list); } curkthr = kgdb_thr_lookup_tid(dumptid); if (curkthr == NULL) curkthr = first; return (first); }
void kgdb_trgt_fetch_registers(int regno __unused) { struct kthr *kt; struct pcb pcb; uint64_t r; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); if (kt == NULL) return; if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } /* Registers 0-127: general registers. */ supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); /* Registers 128-255: floating-point registers. */ supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); /* Registers 320-327: branch registers. */ if (pcb.pcb_special.__spare == ~0UL) supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); /* Registers 328-333: misc. other registers. */ supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); if (pcb.pcb_special.__spare == ~0UL) { r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); supply_register(IA64_IP_REGNUM, (char *)&r); supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); } else {