FreeBSD/gnu/usr.bin/gdb/kgdb/trgt_i386.c
/*
 * 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.
 */
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.
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
kgdb_trgt_fetch_tss(void)
{
	struct kthr *kt;
	struct segment_descriptor sd;
	uintptr_t addr, cpu0prvpage, tss;
	kt = kgdb_thr_lookup_tid(ptid_get_pid(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 (kvm_read(kvm, addr, &sd, sizeof(sd)) != sizeof(sd)) {
		warnx("kvm_read: %s", kvm_geterr(kvm));
		return (0);
	}
	if (sd.sd_type != SDT_SYS386BSY) {
		warnx("descriptor is not a busy TSS");
		return (0);
	}
	tss = sd.sd_hibase << 24 | sd.sd_lobase;
	if (trunc_page(tss) == 0xffc00000) {
		addr = kgdb_lookup("cpu0prvpage");
		if (addr == 0)
			return (0);
		if (kvm_read(kvm, addr, &cpu0prvpage, sizeof(cpu0prvpage)) !=
		    sizeof(cpu0prvpage)) {
			warnx("kvm_read: %s", kvm_geterr(kvm));
			return (0);
		}
		tss = cpu0prvpage + (tss & PAGE_MASK);
	}
	return ((CORE_ADDR)tss);
}
static CORE_ADDR kgdb_trgt_fetch_tss ( void ) { struct kthr * kt ; struct segment_descriptor sd ; uintptr_t addr , cpu0prvpage , tss ; kt = kgdb_thr_lookup_tid ( ptid_get_pid ( inferior_ptid ) ) ; if ( kt == NULL || kt -> cpu == NOCPU || kt -> cpu < 0 ) return ( 0 ) ; addr = kgdb_lookup ( " " ) ; if ( addr == 0 ) return ( 0 ) ; addr += ( kt -> cpu * NGDT + GPROC0_SEL ) * sizeof ( sd ) ; if ( kvm_read ( kvm , addr , & sd , sizeof ( sd ) ) != sizeof ( sd ) ) { warnx ( " " , kvm_geterr ( kvm ) ) ; return ( 0 ) ; } if ( sd . sd_type != SDT_SYS386BSY ) { warnx ( " " ) ; return ( 0 ) ; } tss = sd . sd_hibase << 24 | sd . sd_lobase ; if ( trunc_page ( tss ) == 0xffc00000 ) { addr = kgdb_lookup ( " " ) ; if ( addr == 0 ) return ( 0 ) ; if ( kvm_read ( kvm , addr , & cpu0prvpage , sizeof ( cpu0prvpage ) ) != sizeof ( cpu0prvpage ) ) { warnx ( " " , kvm_geterr ( kvm ) ) ; return ( 0 ) ; } tss = cpu0prvpage + ( tss & PAGE_MASK ) ; } return ( ( CORE_ADDR ) tss ) ; }
If the current thread is executing on a CPU, fetch the common_tss
 for that CPU.
If the current thread is executing on a CPU fetch the common_tss for that CPU .
/*
	 * 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.
	 */