add dbginfo support for 64 bit entries (LDT,GDT) long mode (#33)
This commit is contained in:
parent
fac15a7d03
commit
1eb1a8d641
@ -3110,18 +3110,30 @@ void bx_dbg_info_idt_command(unsigned from, unsigned to)
|
||||
dbg_printf("You can list individual entries with 'info idt [NUM]' or groups with 'info idt [NUM] [NUM]'\n");
|
||||
}
|
||||
|
||||
void bx_dbg_info_gdt_command(unsigned from, unsigned to)
|
||||
void bx_dbg_info_lgdt_command(unsigned from, unsigned to, bool gdt)
|
||||
{
|
||||
bx_dbg_global_sreg_t gdtr;
|
||||
BX_CPU(dbg_cpu)->dbg_get_gdtr(&gdtr);
|
||||
bool all = 0;
|
||||
const char *name = gdt ? "gdt" : "ldt";
|
||||
bx_address base = 0;
|
||||
Bit32u limit = 0;
|
||||
|
||||
if (gdt) {
|
||||
bx_dbg_global_sreg_t gdtr;
|
||||
BX_CPU(dbg_cpu)->dbg_get_gdtr(&gdtr);
|
||||
base = gdtr.base;
|
||||
limit = gdtr.limit;
|
||||
}
|
||||
else { // LDT
|
||||
base = SIM->get_param_num("LDTR.base", dbg_cpu_list)->get64();
|
||||
limit = SIM->get_param_num("LDTR.limit_scaled", dbg_cpu_list)->get();
|
||||
}
|
||||
|
||||
if (to == (unsigned) EMPTY_ARG) {
|
||||
to = from;
|
||||
if(from == (unsigned) EMPTY_ARG) { from = 0; to = 0xffff; all = 1; }
|
||||
}
|
||||
if (from > 0xffff || to > 0xffff) {
|
||||
dbg_printf("GDT entry should be [0-65535], 'info gdt' command malformed\n");
|
||||
dbg_printf("%s entry should be [0-65535], 'info %s' command malformed\n", name, name);
|
||||
return;
|
||||
}
|
||||
if (from > to) {
|
||||
@ -3130,67 +3142,72 @@ void bx_dbg_info_gdt_command(unsigned from, unsigned to)
|
||||
to = temp;
|
||||
}
|
||||
|
||||
dbg_printf("Global Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", gdtr.base, gdtr.limit);
|
||||
dbg_printf("%s (base=0x" FMT_ADDRX ", limit=%d):\n", name, base, limit);
|
||||
for (unsigned n = from; n<=to; n++) {
|
||||
Bit8u entry[8];
|
||||
if (8*n + 7 > gdtr.limit) break;
|
||||
if (bx_dbg_read_linear(dbg_cpu, gdtr.base + 8*n, 8, entry)) {
|
||||
dbg_printf("GDT[0x%04x]=", n << 3);
|
||||
Bit8u entry[16];
|
||||
if (8*n + 7 > limit) break;
|
||||
if (bx_dbg_read_linear(dbg_cpu, base + 8*n, 8, entry)) {
|
||||
if (gdt) {
|
||||
dbg_printf("%s[0x%04x]=", name, n << 3);
|
||||
}
|
||||
else { // LDT
|
||||
dbg_printf("%s[0x%02x]=", name, n);
|
||||
}
|
||||
|
||||
Bit32u lo = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]);
|
||||
Bit32u hi = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]);
|
||||
|
||||
bx_dbg_print_descriptor(lo, hi);
|
||||
if (0 == lo && 0 == hi) {
|
||||
dbg_printf("<null entry>\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU(dbg_cpu)->long_mode()) {
|
||||
const Bit32u sys_descriptor = (1 << 12);
|
||||
if ((hi & sys_descriptor) == 0) {
|
||||
n++;
|
||||
if (8*n + 7 > limit) break;
|
||||
if (bx_dbg_read_linear(dbg_cpu, base + 8*n, 8, entry + 8)) {
|
||||
Bit32u lo2 = (entry[11] << 24) | (entry[10] << 16) | (entry[9] << 8) | (entry[8]);
|
||||
Bit32u hi2 = (entry[15] << 24) | (entry[14] << 16) | (entry[13] << 8) | (entry[12]);
|
||||
|
||||
bx_dbg_print_descriptor64(lo, hi, lo2, hi2);
|
||||
}
|
||||
else {
|
||||
dbg_printf("error: %sr+8*%d points to incomplete (size must be 16) descriptor, linear address 0x" FMT_ADDRX "\n", name, n, base);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
bx_dbg_print_descriptor(lo, hi);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
bx_dbg_print_descriptor(lo, hi);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dbg_printf("error: GDTR+8*%d points to invalid linear address 0x" FMT_ADDRX "\n",
|
||||
n, gdtr.base);
|
||||
dbg_printf("error: %sr+8*%d points to invalid linear address 0x" FMT_ADDRX "\n", name, n, base);
|
||||
}
|
||||
}
|
||||
|
||||
if (all)
|
||||
dbg_printf("You can list individual entries with 'info gdt [NUM]' or groups with 'info gdt [NUM] [NUM]'\n");
|
||||
dbg_printf("You can list individual entries with 'info %s [NUM]' or groups with 'info %s [NUM] [NUM]'\n", name, name);
|
||||
}
|
||||
|
||||
void bx_dbg_info_gdt_command(unsigned from, unsigned to)
|
||||
{
|
||||
bx_dbg_info_lgdt_command(from, to, true);
|
||||
}
|
||||
|
||||
void bx_dbg_info_ldt_command(unsigned from, unsigned to)
|
||||
{
|
||||
bx_address ldtr_base = SIM->get_param_num("LDTR.base", dbg_cpu_list)->get64();
|
||||
Bit32u ldtr_limit = SIM->get_param_num("LDTR.limit_scaled", dbg_cpu_list)->get();
|
||||
|
||||
bool all = 0;
|
||||
|
||||
if (to == (unsigned) EMPTY_ARG) {
|
||||
to = from;
|
||||
if(from == (unsigned) EMPTY_ARG) { from = 0; to = 0xffff; all = 1; }
|
||||
}
|
||||
if (from > 0xffff || to > 0xffff) {
|
||||
dbg_printf("LDT entry should be [0-65535], 'info ldt' command malformed\n");
|
||||
return;
|
||||
}
|
||||
if (from > to) {
|
||||
unsigned temp = from;
|
||||
from = to;
|
||||
to = temp;
|
||||
}
|
||||
|
||||
dbg_printf("Local Descriptor Table (base=0x" FMT_ADDRX ", limit=%d):\n", ldtr_base, ldtr_limit);
|
||||
for (unsigned n = from; n<=to; n++) {
|
||||
Bit8u entry[8];
|
||||
if (8*n + 7 > ldtr_limit) break;
|
||||
if (bx_dbg_read_linear(dbg_cpu, ldtr_base + 8*n, 8, entry)) {
|
||||
dbg_printf("LDT[0x%02x]=", n);
|
||||
|
||||
Bit32u lo = (entry[3] << 24) | (entry[2] << 16) | (entry[1] << 8) | (entry[0]);
|
||||
Bit32u hi = (entry[7] << 24) | (entry[6] << 16) | (entry[5] << 8) | (entry[4]);
|
||||
|
||||
bx_dbg_print_descriptor(lo, hi);
|
||||
}
|
||||
else {
|
||||
dbg_printf("error: LDTR+8*%d points to invalid linear address 0x" FMT_ADDRX "\n",
|
||||
n, ldtr_base);
|
||||
}
|
||||
}
|
||||
if (all)
|
||||
dbg_printf("You can list individual entries with 'info ldt [NUM]' or groups with 'info ldt [NUM] [NUM]'\n");
|
||||
bx_dbg_info_lgdt_command(from, to, false);
|
||||
}
|
||||
|
||||
/*form RB list*/
|
||||
|
Loading…
Reference in New Issue
Block a user