diff options
author | Eugene Tarassov | 2017-08-02 19:54:49 +0000 |
---|---|---|
committer | Eugene Tarassov | 2017-08-02 19:54:49 +0000 |
commit | db59380a4e891144b6e6c2f9cccf177537523aa3 (patch) | |
tree | 6eb4c774271e0d4cd0939f33c9778dd0259ed56a | |
parent | abcaf6bb99f17e9bea241b516f5264b31691eaad (diff) | |
download | org.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.h | 66 | ||||
-rw-r--r-- | agent/machine/arm/tcf/cpu-regs-gdb.h | 12 | ||||
-rw-r--r-- | agent/machine/i386/tcf/cpu-regs-gdb.h | 16 | ||||
-rw-r--r-- | agent/tcf/main/gdb-rsp.c | 105 |
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, ®num); - 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, ®num); - 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, ®num); - 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"); |