Beispiel #1
0
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);
}
Beispiel #2
0
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
Beispiel #3
0
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);
}
Beispiel #4
0
/*
 * 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);
	}
Beispiel #5
0
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);
}