[PATCH 5/9] agent capability

Yao Qi
2012-02-17T02:57:15Z

Different agents may have different capabilities, so this piece of work is to present
what agent can do, and can not do. This version still keeps the implementation of last
version, instead of qSupported-like implementation, because,

- It is independent of "command buffer" and sync socket, so GDB or GDBserver can read
it from agent at any time.
- It is reliable to get capability in this way,

2012-02-13 Yao Qi <yao@codesourcery.com>

* common/agent.c (struct ipa_sym_addresses) <addr_capability>: New.
(agent_capability_check, agent_capability_invalidate): New.
(symbol_list): New array element.
* common/agent.h (enum agent_capa): New.
* target.c (target_pre_inferior): Call agent_capability_invalidate.
---
gdb/common/agent.c | 40 ++++++++++++++++++++++++++++++++++++++++
gdb/common/agent.h | 17 +++++++++++++++++
gdb/target.c | 3 +++
3 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 5a9ac16..074efea 100644
--- a/gdb/common/agent.c
+++ b/gdb/common/agent.c
@@ -51,6 +51,7 @@ struct ipa_sym_addresses
{
CORE_ADDR addr_helper_thread_id;
CORE_ADDR addr_cmd_buf;
+ CORE_ADDR addr_capability;
};

/* Cache of the helper thread id. FIXME: this global should be made
@@ -65,6 +66,7 @@ static struct
} symbol_list[] = {
IPA_SYM(helper_thread_id),
IPA_SYM(cmd_buf),
+ IPA_SYM(capability),
};

static struct ipa_sym_addresses ipa_sym_addrs;
@@ -298,3 +300,41 @@ agent_run_command (int pid, const char *cmd)

return 0;
}
+
+/* Each bit of it stands for a capability of agent. */
+static unsigned int agent_capability = 0;
+
+/* Return true if agent has capability AGENT_CAP, otherwise return false. */
+
+int
+agent_capability_check (enum agent_capa agent_capa)
+{
+ if (agent_capability == 0)
+ {
+#ifdef GDBSERVER
+ if (read_inferior_memory (ipa_sym_addrs.addr_capability,
+ (unsigned char *) &agent_capability,
+ sizeof agent_capability))
+#else
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte buf[4];
+
+ if (target_read_memory (ipa_sym_addrs.addr_capability,
+ buf, sizeof buf) == 0)
+ agent_capability = extract_unsigned_integer (buf, sizeof buf,
+ byte_order);
+ else
+#endif
+ warning ("Error reading capability of agent");
+ }
+ return agent_capability & agent_capa;
+}
+
+/* Invalidate the cache of agent capability, so we'll read it from inferior
+ again. Call it when launches a new program or reconnect to remote stub. */
+
+void
+agent_capability_invalidate (void)
+{
+ agent_capability = 0;
+}
diff --git a/gdb/common/agent.h b/gdb/common/agent.h
index 2965215..a1ac9b2 100644
--- a/gdb/common/agent.h
+++ b/gdb/common/agent.h
@@ -36,3 +36,20 @@ int agent_look_up_symbols (void);
extern int debug_agent;

extern int use_agent;
+
+/* Capability of agent. Different agents may have different capabilities,
+ such as installing fast tracepoint or evaluating breakpoint conditions.
+ Capabilities are represented by bit-maps, and each capability occupies one
+ bit. */
+
+enum agent_capa
+{
+ /* Capability to install fast tracepoint. */
+ AGENT_CAPA_FAST_TRACE = 0x1,
+ /* Capability to install static tracepoint. */
+ AGENT_CAPA_STATIC_TRACE = (0x1 << 1),
+};
+
+int agent_capability_check (enum agent_capa);
+
+void agent_capability_invalidate (void);
diff --git a/gdb/target.c b/gdb/target.c
index a7c11c3..776be23 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -43,6 +43,7 @@
#include "inline-frame.h"
#include "tracepoint.h"
#include "gdb/fileio.h"
+#include "agent.h"

static void target_info (char *, int);

@@ -2496,6 +2497,8 @@ target_pre_inferior (int from_tty)

target_clear_description ();
}
+
+ agent_capability_invalidate ();
}

/* Callback for iterate_over_inferiors. Gets rid of the given
--
1.7.0.4