Bug 574668 - unexpected DWARF Register Number for fctrl and fstat in i386
diff --git a/agent/machine/i386/tcf/cpu-regs-gdb.h b/agent/machine/i386/tcf/cpu-regs-gdb.h
index d5fa9b8..02d4a37 100644
--- a/agent/machine/i386/tcf/cpu-regs-gdb.h
+++ b/agent/machine/i386/tcf/cpu-regs-gdb.h
@@ -45,8 +45,8 @@
" <reg name='st5' bitsize='80' type='i387_ext'/>\n"
" <reg name='st6' bitsize='80' type='i387_ext'/>\n"
" <reg name='st7' bitsize='80' type='i387_ext'/>\n"
-" <reg name='fctrl' bitsize='32' type='int' group='float' id='65'/>\n"
-" <reg name='fstat' bitsize='32' type='int' group='float' id='66'/>\n"
+" <reg name='fctrl' bitsize='32' type='int' group='float'/>\n"
+" <reg name='fstat' bitsize='32' type='int' group='float'/>\n"
" <reg name='ftag' bitsize='32' type='int' group='float'/>\n"
" <reg name='fiseg' bitsize='32' type='int' group='float'/>\n"
" <reg name='fioff' bitsize='32' type='int' group='float'/>\n"
diff --git a/agent/machine/x86_64/tcf/cpu-regs-gdb.h b/agent/machine/x86_64/tcf/cpu-regs-gdb.h
index c569008..6ef3ee8 100644
--- a/agent/machine/x86_64/tcf/cpu-regs-gdb.h
+++ b/agent/machine/x86_64/tcf/cpu-regs-gdb.h
@@ -76,9 +76,9 @@
" <reg name='fstat' bitsize='32' type='int' group='float' id='66'/>\n"
" <reg name='ftag' bitsize='32' type='int' group='float'/>\n"
" <reg name='fiseg' bitsize='32' type='int' group='float'/>\n"
-" <reg name='fioff' bitsize='32' type='int' group='float'/>\n"
+" <reg name='fioff' bitsize='64' type='int' group='float'/>\n"
" <reg name='foseg' bitsize='32' type='int' group='float'/>\n"
-" <reg name='fooff' bitsize='32' type='int' group='float'/>\n"
+" <reg name='fooff' bitsize='64' type='int' group='float'/>\n"
" <reg name='fop' bitsize='32' type='int' group='float'/>\n"
"</feature>\n"
"<feature name='org.gnu.gdb.i386.sse'>\n"
diff --git a/agent/machine/x86_64/tcf/cpudefs-mdep.c b/agent/machine/x86_64/tcf/cpudefs-mdep.c
index 5583828..abed12d 100644
--- a/agent/machine/x86_64/tcf/cpudefs-mdep.c
+++ b/agent/machine/x86_64/tcf/cpudefs-mdep.c
@@ -81,8 +81,8 @@
{ "st6", REG_OFFSET(FloatSave.RegisterArea) + 60, 10, 39, 39, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
{ "st7", REG_OFFSET(FloatSave.RegisterArea) + 70, 10, 40, 40, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
- { "control", REG_OFFSET(FloatSave.ControlWord), 2, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
- { "status", REG_OFFSET(FloatSave.StatusWord), 2, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
+ { "control", REG_OFFSET(FloatSave.ControlWord), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
+ { "status", REG_OFFSET(FloatSave.StatusWord), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
{ "tag", REG_OFFSET(FloatSave.TagWord), 1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 24 },
{ "xmm", 0, 0, -1, -1, 0, 0, 1, 1 }, /* 36 */
@@ -455,39 +455,41 @@
{ "swd", REG_OFFSET(fp.swd), 2, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
{ "ftw", REG_OFFSET(fp.ftw), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
{ "fop", REG_OFFSET(fp.fop), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
- { "rip", REG_OFFSET(fp.rip), 8, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
- { "rdp", REG_OFFSET(fp.rdp), 8, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
+ { "fip", REG_OFFSET(fp.rip), 8, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
+ { "fcs", REG_OFFSET(user.regs.cs), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
+ { "foo", REG_OFFSET(fp.rdp), 8, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
+ { "fos", REG_OFFSET(user.regs.ds), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
{ "mxcsr", REG_OFFSET(fp.mxcsr), 4, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
{ "mxcr_mask", REG_OFFSET(fp.mxcr_mask), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 26 },
{ "xmm", 0, 0, -1, -1, 0, 0, 1, 1 },
- { "xmm0", REG_OFFSET(fp.xmm_space) + 0, 16, 17, 17, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm1", REG_OFFSET(fp.xmm_space) + 16, 16, 18, 18, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm2", REG_OFFSET(fp.xmm_space) + 32, 16, 19, 19, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm3", REG_OFFSET(fp.xmm_space) + 48, 16, 20, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm4", REG_OFFSET(fp.xmm_space) + 64, 16, 21, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm5", REG_OFFSET(fp.xmm_space) + 80, 16, 22, 22, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm6", REG_OFFSET(fp.xmm_space) + 96, 16, 23, 23, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm7", REG_OFFSET(fp.xmm_space) + 112, 16, 24, 24, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm8", REG_OFFSET(fp.xmm_space) + 128, 16, 25, 25, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm9", REG_OFFSET(fp.xmm_space) + 144, 16, 26, 26, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm10", REG_OFFSET(fp.xmm_space) + 160, 16, 27, 27, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm11", REG_OFFSET(fp.xmm_space) + 176, 16, 28, 28, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm12", REG_OFFSET(fp.xmm_space) + 192, 16, 29, 29, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm13", REG_OFFSET(fp.xmm_space) + 208, 16, 30, 30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm14", REG_OFFSET(fp.xmm_space) + 224, 16, 31, 31, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
- { "xmm15", REG_OFFSET(fp.xmm_space) + 240, 16, 32, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 43 },
+ { "xmm0", REG_OFFSET(fp.xmm_space) + 0, 16, 17, 17, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm1", REG_OFFSET(fp.xmm_space) + 16, 16, 18, 18, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm2", REG_OFFSET(fp.xmm_space) + 32, 16, 19, 19, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm3", REG_OFFSET(fp.xmm_space) + 48, 16, 20, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm4", REG_OFFSET(fp.xmm_space) + 64, 16, 21, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm5", REG_OFFSET(fp.xmm_space) + 80, 16, 22, 22, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm6", REG_OFFSET(fp.xmm_space) + 96, 16, 23, 23, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm7", REG_OFFSET(fp.xmm_space) + 112, 16, 24, 24, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm8", REG_OFFSET(fp.xmm_space) + 128, 16, 25, 25, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm9", REG_OFFSET(fp.xmm_space) + 144, 16, 26, 26, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm10", REG_OFFSET(fp.xmm_space) + 160, 16, 27, 27, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm11", REG_OFFSET(fp.xmm_space) + 176, 16, 28, 28, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm12", REG_OFFSET(fp.xmm_space) + 192, 16, 29, 29, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm13", REG_OFFSET(fp.xmm_space) + 208, 16, 30, 30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm14", REG_OFFSET(fp.xmm_space) + 224, 16, 31, 31, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
+ { "xmm15", REG_OFFSET(fp.xmm_space) + 240, 16, 32, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 45 },
- { "debug", 0, 0, -1, -1, 0, 0, 1, 1 }, /* 60 */
+ { "debug", 0, 0, -1, -1, 0, 0, 1, 1 }, /* 62 */
- { "dr0", REG_OFFSET(user.u_debugreg[0]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
- { "dr1", REG_OFFSET(user.u_debugreg[1]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
- { "dr2", REG_OFFSET(user.u_debugreg[2]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
- { "dr3", REG_OFFSET(user.u_debugreg[3]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
- { "dr6", REG_OFFSET(user.u_debugreg[6]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
- { "dr7", REG_OFFSET(user.u_debugreg[7]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 60 },
+ { "dr0", REG_OFFSET(user.u_debugreg[0]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
+ { "dr1", REG_OFFSET(user.u_debugreg[1]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
+ { "dr2", REG_OFFSET(user.u_debugreg[2]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
+ { "dr3", REG_OFFSET(user.u_debugreg[3]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
+ { "dr6", REG_OFFSET(user.u_debugreg[6]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
+ { "dr7", REG_OFFSET(user.u_debugreg[7]), 8, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, regs_def + 62 },
{ "fs_base32", REG_OFFSET(other.fs.base), 4, 158, 158, 0, 0, 0, 1 },
{ "gs_base32", REG_OFFSET(other.gs.base), 4, 159, 159, 0, 0, 0, 1 },
@@ -540,8 +542,8 @@
{ "st6", REG_OFFSET(other.fpx.st_space) + 96, 10, 39, 39, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
{ "st7", REG_OFFSET(other.fpx.st_space) + 112, 10, 40, 40, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
- { "cwd", REG_OFFSET(other.fpx.cwd), 2, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
- { "swd", REG_OFFSET(other.fpx.swd), 2, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
+ { "cwd", REG_OFFSET(other.fpx.cwd), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
+ { "swd", REG_OFFSET(other.fpx.swd), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
{ "twd", REG_OFFSET(other.fpx.twd), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
{ "fop", REG_OFFSET(other.fpx.fop), 2, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
{ "fip", REG_OFFSET(other.fpx.fip), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 28 },
diff --git a/agent/tcf/main/gdb-rsp.c b/agent/tcf/main/gdb-rsp.c
index c4e2dbc..6a2c8ed 100644
--- a/agent/tcf/main/gdb-rsp.c
+++ b/agent/tcf/main/gdb-rsp.c
@@ -321,9 +321,18 @@
return h;
}
-static RegisterDefinition * find_register(GdbThread * t, GdbRegister * r) {
+static RegisterDefinition * find_register_by_name(GdbThread * t, const char * name) {
RegisterDefinition ** map = t->regs_nm_map;
- unsigned n = 0;
+ unsigned n = reg_name_hash(name) & t->regs_nm_map_index_mask;
+ while (map[n] != NULL) {
+ if (strcmp(map[n]->name, name) == 0) return map[n];
+ n = (n + 1) & t->regs_nm_map_index_mask;
+ }
+ return NULL;
+}
+
+static RegisterDefinition * find_register(GdbThread * t, GdbRegister * r) {
+ RegisterDefinition * res = NULL;
if (r->id >= 0) {
RegisterDefinition * def = get_reg_definitions(t->ctx);
@@ -334,9 +343,10 @@
}
return NULL;
}
- if (map == NULL) {
+ if (t->regs_nm_map == NULL) {
unsigned map_len = 0;
unsigned map_len_p2 = 1;
+ RegisterDefinition ** map = NULL;
RegisterDefinition * def = get_reg_definitions(t->ctx);
if (def == NULL) return NULL;
while (def->name != NULL) {
@@ -356,12 +366,31 @@
}
t->regs_nm_map = map;
}
- n = reg_name_hash(r->name) & t->regs_nm_map_index_mask;
- while (map[n] != NULL) {
- if (strcmp(map[n]->name, r->name) == 0) return map[n];
- n = (n + 1) & t->regs_nm_map_index_mask;
+ res = find_register_by_name(t, r->name);
+ if (res == NULL) {
+ const char * regs = get_regs(t->process->client);
+ /* Try alternative register names */
+ if (regs == cpu_regs_gdb_i386 || regs == cpu_regs_gdb_x86_64) {
+ static const char * alt_names[] = {
+ "fctrl", "control", "fpcr", "cwd", NULL,
+ "fstat", "status", "fpsr", "swd", NULL,
+ "ftag", "tag", "fptag", "twd", NULL,
+ "fiseg", "fcs", NULL,
+ "fioff", "fip", NULL,
+ "foseg", "fos", NULL,
+ "fooff", "foo", NULL,
+ NULL
+ };
+ unsigned i = 0;
+ for (; alt_names[i] != NULL && res == NULL; i++) {
+ int b = strcmp(alt_names[i++], r->name) == 0;
+ for (; alt_names[i] != NULL && res == NULL; i++) {
+ if (b) res = find_register_by_name(t, alt_names[i]);
+ }
+ }
+ }
}
- return NULL;
+ return res;
}
static int open_server(const char * port) {