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); 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); }
struct kthr * kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int)) { struct gdbarch *gdbarch = target_gdbarch (); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct kthr *kt; CORE_ADDR addr, paddr; while (first != NULL) { kt = first; first = kt->next; free(kt); } addr = kgdb_lookup("allproc"); if (addr == 0) return (NULL); TRY { paddr = read_memory_typed_address (addr, ptr_type); } CATCH(e, RETURN_MASK_ERROR) { return (NULL); } END_CATCH dumppcb = kgdb_lookup("dumppcb"); if (dumppcb == 0) return (NULL); #if 1 TRY { dumptid = parse_and_eval_long("dumptid"); } CATCH(e, RETURN_MASK_ERROR) { dumptid = -1; } END_CATCH #else addr = kgdb_lookup("dumptid"); if (addr != 0) { TRY { dumptid = read_memory_integer (addr, 4, byte_order); } CATCH(e, RETURN_MASK_ERROR) { dumptid = -1; } END_CATCH } else
CORE_ADDR kgdb_trgt_stop_pcb(u_int cpuid, u_int pcbsz) { static int once = 0; if (stoppcbs == 0 && !once) { once = 1; stoppcbs = kgdb_lookup("stoppcbs"); } if (stoppcbs == 0) return 0; return (stoppcbs + pcbsz * cpuid); }
/* * 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); }
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); }