TCF Agent: more of GDB Remote Serial Protocol - hide processes with unsupported ISA
diff --git a/agent/tcf/main/gdb-rsp.c b/agent/tcf/main/gdb-rsp.c
index 95d2090..0d0b5ef 100644
--- a/agent/tcf/main/gdb-rsp.c
+++ b/agent/tcf/main/gdb-rsp.c
@@ -278,6 +278,29 @@
return NULL;
}
+static int check_process_isa(GdbClient * c, Context * prs) {
+ ContextISA isa;
+ const char * regs = get_regs(c);
+ if (regs != NULL) {
+ memset(&isa, 0, sizeof(isa));
+ context_get_isa(prs, 0, &isa);
+ printf("%s %s\n", prs->name, isa.def ? isa.def : "???");
+ if (isa.def != NULL) {
+ if (strcmp(isa.def, "386") == 0) return regs == cpu_regs_gdb_i386;
+ if (strcmp(isa.def, "X86_64") == 0) return regs == cpu_regs_gdb_x86_64;
+ if (strcmp(isa.def, "ARM") == 0) return regs == cpu_regs_gdb_arm;
+ if (strcmp(isa.def, "Thumb") == 0) return regs == cpu_regs_gdb_arm;
+ if (strcmp(isa.def, "ThumbEE") == 0) return regs == cpu_regs_gdb_arm;
+ if (strcmp(isa.def, "Jazelle") == 0) return regs == cpu_regs_gdb_arm;
+ if (strcmp(isa.def, "A64") == 0) return regs == cpu_regs_gdb_a64;
+ if (strcmp(isa.def, "PPC") == 0) return regs == cpu_regs_gdb_powerpc;
+ if (strcmp(isa.def, "PPC64") == 0) return regs == cpu_regs_gdb_ppc64;
+ if (strcmp(isa.def, "MicroBlaze") == 0) return regs == cpu_regs_gdb_microblaze;
+ }
+ }
+ return 0;
+}
+
static unsigned reg_name_hash(const char * name) {
unsigned h = 5381;
while (*name) h = ((h << 5) + h) + *name++;
@@ -437,38 +460,58 @@
p->attached = 0;
}
-static void start_client(void * args) {
- LINK * l;
- unsigned has_state_cnt = 0;
- GdbClient * c = (GdbClient *)args;
-
- for (l = context_root.next; l != &context_root; l = l->next) {
- Context * ctx = ctxl2ctxp(l);
- if (!ctx->exited && context_has_state(ctx)) {
- has_state_cnt++;
+static int is_all_intercepted(GdbClient * c) {
+ LINK * l, * m;
+ for (l = c->link_c2p.next; l != &c->link_c2p; l = l->next) {
+ GdbProcess * p = link_c2p(l);
+ for (m = p->link_p2t.next; m != &p->link_p2t; m = m->next) {
+ GdbThread * t = link_p2t(m);
+ assert(p->attached);
+ assert(!t->ctx->exited);
+ assert(context_has_state(t->ctx));
+ if (!is_intercepted(t->ctx)) return 0;
}
}
+ return 1;
+}
- if (c->start_timer > 10 || has_state_cnt > 0) {
+static void start_client(void * args) {
+ GdbClient * c = (GdbClient *)args;
+ if (c->start_timer > 10 || (c->stopped && is_all_intercepted(c))) {
+ if (c->stopped && !is_all_intercepted(c)) {
+ LINK * l;
+ c->cur_g_pid = 0;
+ c->cur_g_tid = 0;
+ for (l = c->link_c2p.next; l != &c->link_c2p; l = l->next) {
+ GdbProcess * p = link_c2p(l);
+ detach_process(p);
+ }
+ }
+ c->req.u.sio.rval = 0;
+ async_req_post(&c->req);
+ return;
+ }
+
+ if (!c->stopped) {
+ LINK * l;
/* Select initial debug target */
for (l = context_root.next; l != &context_root; l = l->next) {
Context * ctx = ctxl2ctxp(l);
- Context * prs = context_get_group(ctx, CONTEXT_GROUP_PROCESS);
if (!ctx->exited && context_has_state(ctx)) {
- attach_process(find_process_ctx(c, prs));
- lock_threads(c);
- break;
+ Context * prs = context_get_group(ctx, CONTEXT_GROUP_PROCESS);
+ GdbProcess * p = find_process_ctx(c, prs);
+ if (p != NULL) {
+ attach_process(p);
+ lock_threads(c);
+ break;
+ }
}
}
+ }
- c->req.u.sio.rval = 0;
- async_req_post(&c->req);
- }
- else {
- post_event_with_delay(start_client, args, 500000);
- c->start_timer++;
- }
+ post_event_with_delay(start_client, args, 500000);
+ c->start_timer++;
}
static void close_client(GdbClient * c) {
@@ -821,21 +864,6 @@
return r->name[0] && r->bits > 0;
}
-static int is_all_intercepted(GdbClient * c) {
- LINK * l, * m;
- for (l = c->link_c2p.next; l != &c->link_c2p; l = l->next) {
- GdbProcess * p = link_c2p(l);
- for (m = p->link_p2t.next; m != &p->link_p2t; m = m->next) {
- GdbThread * t = link_p2t(m);
- assert(p->attached);
- assert(!t->ctx->exited);
- assert(context_has_state(t->ctx));
- if (!is_intercepted(t->ctx)) return 0;
- }
- }
- return 1;
-}
-
static void breakpoint_cb(Context * ctx, void * args) {
GdbBreakpoint * b = (GdbBreakpoint *)args;
GdbProcess * p = b->process;
@@ -860,7 +888,13 @@
char s[256];
char * m = s;
GdbProcess * p = link_c2p(l);
- snprintf(s, sizeof(s), "%u: %s\n", (unsigned)p->pid, p->ctx->name ? p->ctx->name : p->ctx->id);
+ if (context_has_state(p->ctx)) {
+ const char * state = get_context_state_name(p->ctx);
+ snprintf(s, sizeof(s), "%u: %s (%s)\n", (unsigned)p->pid, p->ctx->name ? p->ctx->name : p->ctx->id, state);
+ }
+ else {
+ snprintf(s, sizeof(s), "%u: %s\n", (unsigned)p->pid, p->ctx->name ? p->ctx->name : p->ctx->id);
+ }
while (*m) add_res_hex8(c, *m++);
cnt++;
}
@@ -1667,8 +1701,10 @@
Context * ctx = ctxl2ctxp(l);
if (!ctx->exited && context_has_state(ctx)) {
Context * prs = context_get_group(ctx, CONTEXT_GROUP_PROCESS);
- GdbProcess * p = find_process_ctx(c, prs);
- if (p == NULL) p = add_process(c, prs);
+ if (check_process_isa(c, prs)) {
+ GdbProcess * p = find_process_ctx(c, prs);
+ if (p == NULL) p = add_process(c, prs);
+ }
}
}
@@ -1692,9 +1728,11 @@
GdbServer * s = link_a2s(l);
for (n = s->link_s2c.next; n != &s->link_s2c; n = n->next) {
GdbClient * c = link_s2c(n);
- GdbProcess * p = find_process_ctx(c, prs);
- if (p == NULL) p = add_process(c, prs);
- else if (p->attached) add_thread(c, ctx);
+ if (check_process_isa(c, prs)) {
+ GdbProcess * p = find_process_ctx(c, prs);
+ if (p == NULL) p = add_process(c, prs);
+ else if (p->attached) add_thread(c, ctx);
+ }
}
}
}