add dbginfo support for 64 bit entries (LDT,GDT) long mode (#33)

This commit is contained in:
Dreg 2022-08-21 10:06:03 +02:00 committed by GitHub
parent fac15a7d03
commit 1eb1a8d641
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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*/