Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2017-08-02 19:54:49 +0000
committerEugene Tarassov2017-08-02 19:54:49 +0000
commitdb59380a4e891144b6e6c2f9cccf177537523aa3 (patch)
tree6eb4c774271e0d4cd0939f33c9778dd0259ed56a
parentabcaf6bb99f17e9bea241b516f5264b31691eaad (diff)
downloadorg.eclipse.tcf.agent-db59380a4e891144b6e6c2f9cccf177537523aa3.tar.gz
org.eclipse.tcf.agent-db59380a4e891144b6e6c2f9cccf177537523aa3.tar.xz
org.eclipse.tcf.agent-db59380a4e891144b6e6c2f9cccf177537523aa3.zip
TCF Agent: more of GDB Remote Serial Protocol
-rw-r--r--agent/machine/a64/tcf/cpu-regs-gdb.h66
-rw-r--r--agent/machine/arm/tcf/cpu-regs-gdb.h12
-rw-r--r--agent/machine/i386/tcf/cpu-regs-gdb.h16
-rw-r--r--agent/tcf/main/gdb-rsp.c105
4 files changed, 107 insertions, 92 deletions
diff --git a/agent/machine/a64/tcf/cpu-regs-gdb.h b/agent/machine/a64/tcf/cpu-regs-gdb.h
index 0375e6c8..ca9d28f6 100644
--- a/agent/machine/a64/tcf/cpu-regs-gdb.h
+++ b/agent/machine/a64/tcf/cpu-regs-gdb.h
@@ -21,39 +21,39 @@
static const char * cpu_regs_gdb_a64 =
"<architecture>aarch64</architecture>\n"
"<feature name='org.gnu.gdb.aarch64.core'>\n"
-" <reg name='x0' bitsize='64' />\n"
-" <reg name='x1' bitsize='64' />\n"
-" <reg name='x2' bitsize='64' />\n"
-" <reg name='x3' bitsize='64' />\n"
-" <reg name='x4' bitsize='64' />\n"
-" <reg name='x5' bitsize='64' />\n"
-" <reg name='x6' bitsize='64' />\n"
-" <reg name='x7' bitsize='64' />\n"
-" <reg name='x8' bitsize='64' />\n"
-" <reg name='x9' bitsize='64' />\n"
-" <reg name='x10' bitsize='64' />\n"
-" <reg name='x11' bitsize='64' />\n"
-" <reg name='x12' bitsize='64' />\n"
-" <reg name='x13' bitsize='64' />\n"
-" <reg name='x14' bitsize='64' />\n"
-" <reg name='x15' bitsize='64' />\n"
-" <reg name='x16' bitsize='64' />\n"
-" <reg name='x17' bitsize='64' />\n"
-" <reg name='x18' bitsize='64' />\n"
-" <reg name='x19' bitsize='64' />\n"
-" <reg name='x20' bitsize='64' />\n"
-" <reg name='x21' bitsize='64' />\n"
-" <reg name='x22' bitsize='64' />\n"
-" <reg name='x23' bitsize='64' />\n"
-" <reg name='x24' bitsize='64' />\n"
-" <reg name='x25' bitsize='64' />\n"
-" <reg name='x26' bitsize='64' />\n"
-" <reg name='x27' bitsize='64' />\n"
-" <reg name='x28' bitsize='64' />\n"
-" <reg name='x29' bitsize='64' />\n"
-" <reg name='x30' bitsize='64' />\n"
-" <reg name='sp' bitsize='64' type='data_ptr' />\n"
-" <reg name='pc' bitsize='64' type='code_ptr' />\n"
+" <reg name='x0' bitsize='64' id='0' />\n"
+" <reg name='x1' bitsize='64' id='1' />\n"
+" <reg name='x2' bitsize='64' id='2' />\n"
+" <reg name='x3' bitsize='64' id='3' />\n"
+" <reg name='x4' bitsize='64' id='4' />\n"
+" <reg name='x5' bitsize='64' id='5' />\n"
+" <reg name='x6' bitsize='64' id='6' />\n"
+" <reg name='x7' bitsize='64' id='7' />\n"
+" <reg name='x8' bitsize='64' id='8' />\n"
+" <reg name='x9' bitsize='64' id='9' />\n"
+" <reg name='x10' bitsize='64' id='10' />\n"
+" <reg name='x11' bitsize='64' id='11' />\n"
+" <reg name='x12' bitsize='64' id='12' />\n"
+" <reg name='x13' bitsize='64' id='13' />\n"
+" <reg name='x14' bitsize='64' id='14' />\n"
+" <reg name='x15' bitsize='64' id='15' />\n"
+" <reg name='x16' bitsize='64' id='16' />\n"
+" <reg name='x17' bitsize='64' id='17' />\n"
+" <reg name='x18' bitsize='64' id='18' />\n"
+" <reg name='x19' bitsize='64' id='19' />\n"
+" <reg name='x20' bitsize='64' id='20' />\n"
+" <reg name='x21' bitsize='64' id='21' />\n"
+" <reg name='x22' bitsize='64' id='22' />\n"
+" <reg name='x23' bitsize='64' id='23' />\n"
+" <reg name='x24' bitsize='64' id='24' />\n"
+" <reg name='x25' bitsize='64' id='25' />\n"
+" <reg name='x26' bitsize='64' id='26' />\n"
+" <reg name='x27' bitsize='64' id='27' />\n"
+" <reg name='x28' bitsize='64' id='28' />\n"
+" <reg name='x29' bitsize='64' id='29' />\n"
+" <reg name='x30' bitsize='64' id='30' />\n"
+" <reg name='sp' bitsize='64' type='data_ptr' id='31' />\n"
+" <reg name='pc' bitsize='64' type='code_ptr' id='33' />\n"
" <flags id='cpsr_flags' size='4'>\n"
" <field name='SP' start='0' end='0' />\n"
" <field name='' start='1' end='1' />\n"
diff --git a/agent/machine/arm/tcf/cpu-regs-gdb.h b/agent/machine/arm/tcf/cpu-regs-gdb.h
index edda753a..675c7dd9 100644
--- a/agent/machine/arm/tcf/cpu-regs-gdb.h
+++ b/agent/machine/arm/tcf/cpu-regs-gdb.h
@@ -32,12 +32,12 @@ static const char * cpu_regs_gdb_arm =
" <reg name='r8' bitsize='32' type='uint32'/>\n"
" <reg name='r9' bitsize='32' type='uint32'/>\n"
" <reg name='r10' bitsize='32' type='uint32'/>\n"
-" <reg name='r11' bitsize='32' type='uint32'/>\n"
-" <reg name='r12' bitsize='32' type='uint32'/>\n"
-" <reg name='sp' bitsize='32' type='data_ptr'/>\n"
-" <reg name='lr' bitsize='32'/>\n"
-" <reg name='pc' bitsize='32' type='code_ptr'/>\n"
-" <reg name='cpsr' bitsize='32' regnum='25'/>\n"
+" <reg name='r11' bitsize='32' type='uint32' id='11'/>\n"
+" <reg name='r12' bitsize='32' type='uint32' id='12'/>\n"
+" <reg name='sp' bitsize='32' type='data_ptr' id='13'/>\n"
+" <reg name='lr' bitsize='32' id='14'/>\n"
+" <reg name='pc' bitsize='32' type='code_ptr' id='15'/>\n"
+" <reg name='cpsr' bitsize='32' regnum='25' id='128'/>\n"
"</feature>\n"
"<feature name='org.gnu.gdb.arm.vfp'>\n"
" <reg name='d0' bitsize='64' type='ieee_double'/>\n"
diff --git a/agent/machine/i386/tcf/cpu-regs-gdb.h b/agent/machine/i386/tcf/cpu-regs-gdb.h
index 141528dd..d5fa9b87 100644
--- a/agent/machine/i386/tcf/cpu-regs-gdb.h
+++ b/agent/machine/i386/tcf/cpu-regs-gdb.h
@@ -31,12 +31,12 @@ static const char * cpu_regs_gdb_i386 =
" <reg name='edi' bitsize='32' type='int32'/>\n"
" <reg name='eip' bitsize='32' type='code_ptr'/>\n"
" <reg name='eflags' bitsize='32' type='int32'/>\n"
-" <reg name='cs' bitsize='16' type='int32'/>\n"
-" <reg name='ss' bitsize='16' type='int32'/>\n"
-" <reg name='ds' bitsize='16' type='int32'/>\n"
-" <reg name='es' bitsize='16' type='int32'/>\n"
-" <reg name='fs' bitsize='16' type='int32'/>\n"
-" <reg name='gs' bitsize='16' type='int32'/>\n"
+" <reg name='cs' bitsize='32' type='int32'/>\n"
+" <reg name='ss' bitsize='32' type='int32'/>\n"
+" <reg name='ds' bitsize='32' type='int32'/>\n"
+" <reg name='es' bitsize='32' type='int32'/>\n"
+" <reg name='fs' bitsize='32' type='int32'/>\n"
+" <reg name='gs' bitsize='32' type='int32'/>\n"
" <reg name='st0' bitsize='80' type='i387_ext'/>\n"
" <reg name='st1' bitsize='80' type='i387_ext'/>\n"
" <reg name='st2' bitsize='80' type='i387_ext'/>\n"
@@ -45,8 +45,8 @@ static const char * cpu_regs_gdb_i386 =
" <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'/>\n"
-" <reg name='fstat' bitsize='32' type='int' group='float'/>\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='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/tcf/main/gdb-rsp.c b/agent/tcf/main/gdb-rsp.c
index 2542ba14..73b7252f 100644
--- a/agent/tcf/main/gdb-rsp.c
+++ b/agent/tcf/main/gdb-rsp.c
@@ -132,6 +132,13 @@ typedef struct GdbBreakpoint {
BreakpointInfo * bp;
} GdbBreakpoint;
+typedef struct GdbRegister {
+ unsigned regnum;
+ char name[256];
+ unsigned bits;
+ int id;
+} GdbRegister;
+
typedef struct MonitorCommand {
const char * name;
void (*func)(GdbClient *, const char *);
@@ -239,6 +246,8 @@ static void free_process(GdbProcess * p) {
static const char * get_regs(GdbClient * c) {
if (strcmp(c->server->isa, "i386") == 0) return cpu_regs_gdb_i386;
+ if (strcmp(c->server->isa, "i486") == 0) return cpu_regs_gdb_i386;
+ if (strcmp(c->server->isa, "i586") == 0) return cpu_regs_gdb_i386;
if (strcmp(c->server->isa, "i686") == 0) return cpu_regs_gdb_i386;
if (strcmp(c->server->isa, "x86") == 0) return cpu_regs_gdb_i386;
if (strcmp(c->server->isa, "ia32") == 0) return cpu_regs_gdb_i386;
@@ -247,6 +256,7 @@ static const char * get_regs(GdbClient * c) {
if (strcmp(c->server->isa, "x64") == 0) return cpu_regs_gdb_x86_64;
if (strcmp(c->server->isa, "arm") == 0) return cpu_regs_gdb_arm;
if (strcmp(c->server->isa, "a32") == 0) return cpu_regs_gdb_arm;
+ if (strcmp(c->server->isa, "arm64") == 0) return cpu_regs_gdb_a64;
if (strcmp(c->server->isa, "aarch64") == 0) return cpu_regs_gdb_a64;
if (strcmp(c->server->isa, "a64") == 0) return cpu_regs_gdb_a64;
if (strcmp(c->server->isa, "ppc") == 0) return cpu_regs_gdb_powerpc;
@@ -267,10 +277,18 @@ static unsigned reg_name_hash(const char * name) {
return h;
}
-static RegisterDefinition * find_register(GdbThread * t, const char * name) {
+static RegisterDefinition * find_register(GdbThread * t, GdbRegister * r) {
RegisterDefinition ** map = t->regs_nm_map;
unsigned n = 0;
+ if (r->id >= 0) {
+ RegisterDefinition * def = get_reg_definitions(t->ctx);
+ while (def->name != NULL) {
+ if (def->dwarf_id == r->id) return def;
+ def++;
+ }
+ return NULL;
+ }
if (map == NULL) {
unsigned map_len = 0;
unsigned map_len_p2 = 1;
@@ -293,9 +311,9 @@ static RegisterDefinition * find_register(GdbThread * t, const char * name) {
}
t->regs_nm_map = map;
}
- n = reg_name_hash(name) & t->regs_nm_map_index_mask;
+ n = reg_name_hash(r->name) & t->regs_nm_map_index_mask;
while (map[n] != NULL) {
- if (strcmp(map[n]->name, name) == 0) return map[n];
+ if (strcmp(map[n]->name, r->name) == 0) return map[n];
n = (n + 1) & t->regs_nm_map_index_mask;
}
return NULL;
@@ -567,12 +585,12 @@ static int add_res_exec_file(GdbClient * c, unsigned pid) {
return 0;
}
-static void add_res_reg_value(GdbClient * c, GdbThread * t, const char * name, unsigned bits) {
+static void add_res_reg_value(GdbClient * c, GdbThread * t, GdbRegister * r) {
RegisterDefinition * def = NULL;
- unsigned size = (bits + 7) / 8;
+ unsigned size = (r->bits + 7) / 8;
void * buf = tmp_alloc_zero(size);
unsigned i = 0;
- if (t != NULL) def = find_register(t, name);
+ if (t != NULL) def = find_register(t, r);
if (def != NULL && context_read_reg(t->ctx, def, 0, def->size < size ? def->size : size, buf) < 0) def = NULL;
while (i < size) {
if (def == NULL) {
@@ -718,12 +736,13 @@ static void get_xfer_range(GdbClient * c, char ** p) {
c->xfer_range_size = get_cmd_uint(c, p);
}
-static void read_reg_attributes(const char * p, char ** name, unsigned * bits, unsigned * regnum) {
+static int read_reg_attributes(const char * p, unsigned n, GdbRegister * r) {
const char * p0 = p;
- *name = NULL;
- *bits = 0;
+ memset(r, 0, sizeof(GdbRegister));
+ r->regnum = n;
+ r->id = -1;
while (*p == ' ') p++;
- if (strncmp(p, "<reg ", 5) != 0) return;
+ if (strncmp(p, "<reg ", 5) != 0) return 0;
p += 5;
while (*p) {
if (*p == '\n') break;
@@ -736,21 +755,25 @@ static void read_reg_attributes(const char * p, char ** name, unsigned * bits, u
while (*v1 != 0 && *v1 != q) v1++;
while (n0 > p0 && *(n0 - 1) != ' ') n0--;
if (n1 - n0 == 4 && strncmp(n0, "name", 4) == 0) {
- size_t l = v1 - v0;
- *name = (char *)tmp_alloc_zero(l + 1);
- memcpy(*name, v0, l);
+ size_t l = v1 - v0 + 1;
+ if (l > sizeof(r->name)) l = sizeof(r->name);
+ strlcpy(r->name, v0, l);
}
if (n1 - n0 == 7 && strncmp(n0, "bitsize", 7) == 0) {
- *bits = (unsigned)atoi(v0);
+ r->bits = (unsigned)atoi(v0);
}
if (n1 - n0 == 6 && strncmp(n0, "regnum", 6) == 0) {
- *regnum = (unsigned)atoi(v0);
+ r->regnum = (unsigned)atoi(v0);
+ }
+ if (n1 - n0 == 2 && strncmp(n0, "id", 2) == 0) {
+ r->id = atoi(v0);
}
if (*v1 != q) break;
p = v1;
}
p++;
}
+ return r->name != NULL && r->bits > 0;
}
static void breakpoint_cb(Context * ctx, void * args) {
@@ -784,19 +807,17 @@ static int handle_g_command(GdbClient * c) {
GdbThread * t = find_thread(c, c->cur_g_pid, c->cur_g_tid);
const char * regs = get_regs(c);
const char * p = regs;
- const char * s = regs;
+ const char * q = regs;
unsigned regnum = 0;
if (p == NULL) return -1;
while (*p) {
if (*p++ == '\n') {
- char * name = NULL;
- unsigned bits = 0;
- read_reg_attributes(s, &name, &bits, &regnum);
- if (name != NULL && bits != 0) {
- add_res_reg_value(c, t, name, bits);
- regnum++;
+ GdbRegister r;
+ if (read_reg_attributes(q, regnum, &r)) {
+ add_res_reg_value(c, t, &r);
+ regnum = r.regnum + 1;
}
- s = p;
+ q = p;
}
}
return 0;
@@ -860,22 +881,20 @@ static int handle_p_command(GdbClient * c) {
unsigned reg = get_cmd_uint(c, &s);
const char * regs = get_regs(c);
const char * p = regs;
- const char * r = regs;
+ const char * q = regs;
unsigned regnum = 0;
if (p == NULL) return -1;
while (*p) {
if (*p++ == '\n') {
- char * name = NULL;
- unsigned bits = 0;
- read_reg_attributes(r, &name, &bits, &regnum);
- if (name != NULL && bits != 0) {
- if (regnum == reg) {
- add_res_reg_value(c, t, name, bits);
+ GdbRegister r;
+ if (read_reg_attributes(q, regnum, &r)) {
+ if (r.regnum == reg) {
+ add_res_reg_value(c, t, &r);
return 0;
}
- regnum++;
+ regnum = r.regnum + 1;
}
- r = p;
+ q = p;
}
}
add_res_str(c, "E01");
@@ -889,35 +908,31 @@ static int handle_P_command(GdbClient * c) {
unsigned reg = get_cmd_uint(c, &s);
const char * regs = get_regs(c);
const char * p = regs;
- const char * r = regs;
+ const char * q = regs;
unsigned regnum = 0;
if (p == NULL) return -1;
while (*p) {
if (*p++ == '\n') {
- char * name = NULL;
- unsigned bits = 0;
- read_reg_attributes(r, &name, &bits, &regnum);
- if (name != NULL && bits != 0) {
- if (regnum == reg) {
+ GdbRegister r;
+ if (read_reg_attributes(q, regnum, &r)) {
+ if (r.regnum == reg) {
RegisterDefinition * def = NULL;
- unsigned size = (bits + 7) / 8;
+ unsigned size = (r.bits + 7) / 8;
void * buf = tmp_alloc_zero(size);
if (*s++ == '=') {
unsigned i = 0;
- while (i < size) {
- ((uint8_t *)buf)[i++] = get_cmd_uint8(c, &s);
- }
+ while (i < size) ((uint8_t *)buf)[i++] = get_cmd_uint8(c, &s);
}
- if (t != NULL) def = find_register(t, name);
+ if (t != NULL) def = find_register(t, &r);
if (def != NULL && context_write_reg(t->ctx, def, 0, def->size < size ? def->size : size, buf) == 0) {
add_res_str(c, "OK");
return 0;
}
break;
}
- regnum++;
+ regnum = r.regnum + 1;
}
- r = p;
+ q = p;
}
}
add_res_str(c, "E01");

Back to the top