From: markus.t.metzger@intel.com
To: kettenis@gnu.org
Cc: gdb-patches@sourceware.org, markus.t.metzger@gmail.com,
Markus Metzger <markus.t.metzger@intel.com>
Subject: [PATCH 15/16] gdbserver, btrace: add generic btrace support
Date: Wed, 23 May 2012 11:25:00 -0000 [thread overview]
Message-ID: <1337772151-20265-16-git-send-email-markus.t.metzger@intel.com> (raw)
In-Reply-To: <1337772151-20265-1-git-send-email-markus.t.metzger@intel.com>
From: Markus Metzger <markus.t.metzger@intel.com>
Add support to gdbserver to understand branch trace related packages.
2012-05-23 Markus Metzger <markus.t.metzger@intel.com>
gdb/gdbserver/
* target.h (struct target_ops): Add btrace ops
(target_supports_btrace): New macro
(target_btrace_has_changed): New macro
(target_enable_btrace): New macro
(target_disable_btrace): New macro
(target_read_btrace): New macro
* gdbthread.h (struct thread_info): Add btrace field
* server.c (handle_btrace_general_set): New function
(handle_general_set): Call handle_btrace_general_set
(handle_qxfer_btrace): New function
(struct qxfer qxfer_packets[]): Add btrace entry
(handle_btrace_query): New function
(handle_query): Add btrace to supported query, call handle_btrace_query
* inferiors.c (remove_thread): Disable btrace
---
gdb/gdbserver/gdbthread.h | 5 ++
gdb/gdbserver/inferiors.c | 3 +
gdb/gdbserver/server.c | 171 +++++++++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/target.h | 38 ++++++++++
4 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index d863ec0..b2b6f62 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -22,6 +22,8 @@
#include "server.h"
+struct btrace_target_info;
+
struct thread_info
{
struct inferior_list_entry entry;
@@ -58,6 +60,9 @@ struct thread_info
Each item in the list holds the current step of the while-stepping
action. */
struct wstep_state *while_stepping;
+
+ /* Branch trace target information for this thread. */
+ struct btrace_target_info *btrace;
};
extern struct inferior_list all_threads;
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 76abaf5..76f5731 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -161,6 +161,9 @@ free_one_thread (struct inferior_list_entry *inf)
void
remove_thread (struct thread_info *thread)
{
+ if (thread->btrace)
+ target_disable_btrace (thread->btrace);
+
remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
free_one_thread (&thread->entry);
}
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index b3d1b41..87613b9 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -446,6 +446,85 @@ write_qxfer_response (char *buf, const void *data, int len, int is_more)
/* Handle all of the extended 'Q' packets. */
+static int
+handle_btrace_general_set (char *own_buf)
+{
+ char *operation = own_buf + strlen ("Qbtrace:");
+
+ if (strncmp ("Qbtrace:", own_buf, strlen ("Qbtrace:")) != 0)
+ return 0;
+
+ if (strncmp ("on:", operation, strlen ("on:")) == 0)
+ {
+ char* ptid_str = operation + strlen ("on:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (thread->btrace)
+ {
+ fprintf (stderr, "Btrace already enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ {
+ thread->btrace = target_enable_btrace (thread->entry.id);
+ if (!thread->btrace)
+ {
+ fprintf (stderr, "Could not enable btrace for %s: %s\n",
+ ptid_str, strerror (errno));
+ write_enn (own_buf);
+ }
+ else
+ write_ok (own_buf);
+ }
+ }
+ else if (strncmp ("off:", operation, strlen ("off:")) == 0)
+ {
+ char* ptid_str = operation + strlen ("off:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ {
+ int errcode = target_disable_btrace (thread->btrace);
+ if (errcode)
+ {
+ fprintf (stderr, "Could not disable btrace for %s: %s\n",
+ ptid_str, strerror (errcode));
+ write_enn (own_buf);
+ }
+ else
+ {
+ thread->btrace = NULL;
+ write_ok (own_buf);
+ }
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Unknown btrace operation: %s. Use on or off.\n",
+ own_buf);
+ write_enn (own_buf);
+ }
+
+ return 1;
+}
+
static void
handle_general_set (char *own_buf)
{
@@ -600,6 +679,9 @@ handle_general_set (char *own_buf)
return;
}
+ if (handle_btrace_general_set (own_buf))
+ return;
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
@@ -1298,6 +1380,57 @@ handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
return (*the_target->read_loadmap) (annex, offset, readbuf, len);
}
+static int
+handle_qxfer_btrace (const char *annex,
+ gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST offset, LONGEST len)
+{
+ static struct buffer cache;
+ struct thread_info *thread;
+ ptid_t ptid;
+ int error;
+
+ if (!the_target->read_btrace || writebuf)
+ return -2;
+
+ if (!target_running () || !annex)
+ return -1;
+
+ ptid = read_ptid ((char *) annex, NULL);
+ thread = find_thread_ptid (ptid);
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", annex);
+ return -1;
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", annex);
+ return -1;
+ }
+
+ if (!offset)
+ {
+ buffer_free (&cache);
+
+ error = target_read_btrace (thread->btrace, &cache);
+ if (error)
+ return -error;
+ }
+ else if (offset >= cache.used_size)
+ {
+ buffer_free (&cache);
+ return 0;
+ }
+
+ if (len > (cache.used_size - offset))
+ len = cache.used_size - offset;
+
+ memcpy (readbuf, cache.buffer + offset, len);
+
+ return len;
+}
+
static const struct qxfer qxfer_packets[] =
{
{ "auxv", handle_qxfer_auxv },
@@ -1311,6 +1444,7 @@ static const struct qxfer qxfer_packets[] =
{ "statictrace", handle_qxfer_statictrace },
{ "threads", handle_qxfer_threads },
{ "traceframe-info", handle_qxfer_traceframe_info },
+ { "btrace", handle_qxfer_btrace },
};
static int
@@ -1467,6 +1601,33 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
/* Handle all of the extended 'q' packets. */
+static int
+handle_btrace_query (char *own_buf)
+{
+ if (strncmp ("qbtrace:", own_buf, strlen ("qbtrace:")) == 0)
+ {
+ char *ptid_str = own_buf + strlen ("qbtrace:");
+ ptid_t ptid = read_ptid (ptid_str, NULL);
+ struct thread_info *thread = find_thread_ptid (ptid);
+
+ if (!thread)
+ {
+ fprintf (stderr, "No such thread: %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else if (!thread->btrace)
+ {
+ fprintf (stderr, "Btrace not enabled for %s\n", ptid_str);
+ write_enn (own_buf);
+ }
+ else
+ strcpy (own_buf,
+ (target_btrace_has_changed (thread->btrace) ? "yes" : "no"));
+ return 1;
+ }
+ return 0;
+}
+
void
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
@@ -1693,6 +1854,13 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_agent ())
strcat (own_buf, ";QAgent+");
+ if (target_supports_btrace ())
+ {
+ strcat (own_buf, ";qbtrace+");
+ strcat (own_buf, ";Qbtrace+");
+ strcat (own_buf, ";qXfer:btrace:read+");
+ }
+
return;
}
@@ -1883,6 +2051,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (target_supports_tracepoints () && handle_tracepoint_query (own_buf))
return;
+ if (handle_btrace_query (own_buf))
+ return;
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index dcf0230..f89b106 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -22,6 +22,8 @@
#define TARGET_H
struct emit_ops;
+struct btrace_target_info;
+struct buffer;
/* Ways to "resume" a thread. */
@@ -397,6 +399,23 @@ struct target_ops
/* Return true if target supports debugging agent. */
int (*supports_agent) (void);
+
+ /* Check whether the target supports branch tracing. */
+ int (*supports_btrace) (void);
+
+ /* Enable branch tracing for @ptid and allocate a branch trace target
+ information struct for reading and for disabling branch trace. */
+ struct btrace_target_info *(*enable_btrace) (ptid_t ptid);
+
+ /* Disable branch tracing. */
+ int (*disable_btrace) (struct btrace_target_info *tinfo);
+
+ /* Check whether branch trace changed on the target. */
+ int (*btrace_has_changed) (struct btrace_target_info *);
+
+ /* Read branch trace data into buffer.
+ Returns 0 on success, an error code, otherwise. */
+ int (*read_btrace) (struct btrace_target_info *, struct buffer *);
};
extern struct target_ops *the_target;
@@ -521,6 +540,25 @@ void set_target_ops (struct target_ops *);
(the_target->supports_agent ? \
(*the_target->supports_agent) () : 0)
+#define target_supports_btrace() \
+ (the_target->supports_btrace ? (*the_target->supports_btrace) () : 0)
+
+#define target_enable_btrace(ptid) \
+ (the_target->enable_btrace ? \
+ (*the_target->enable_btrace) (ptid) : (errno = ENOSYS, NULL))
+
+#define target_disable_btrace(tinfo) \
+ (the_target->disable_btrace ? \
+ (*the_target->disable_btrace) (tinfo) : (errno = ENOSYS))
+
+#define target_btrace_has_changed(tinfo) \
+ (the_target->btrace_has_changed ? \
+ (*the_target->btrace_has_changed) (tinfo) : (errno = ENOSYS, 0))
+
+#define target_read_btrace(tinfo, buffer) \
+ (the_target->read_btrace ? \
+ (*the_target->read_btrace) (tinfo, buffer) : (errno = ENOSYS))
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);
--
1.7.1
next prev parent reply other threads:[~2012-05-23 11:25 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-23 11:23 [PATCH 00/16] branch tracing support (resend) markus.t.metzger
2012-05-23 11:24 ` [PATCH 10/16] btrace, config: enable btrace for 32bit and 64bit linux native markus.t.metzger
2012-05-23 11:24 ` [PATCH 06/16] configure: add check for perf_event header markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
2012-06-22 20:40 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
2012-05-23 11:24 ` [PATCH 02/16] source: add flags to print_source_lines () markus.t.metzger
2012-05-30 20:41 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
2012-06-22 20:08 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
2012-05-23 11:25 ` markus.t.metzger [this message]
2012-05-23 11:25 ` [PATCH 13/16] xml, btrace: define btrace xml document style markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 8:39 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 16/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
2012-05-23 11:25 ` [PATCH 14/16] remote, btrace: add branch trace remote ops markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 8:49 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 01/16] disas: add precise instructions flag markus.t.metzger
2012-05-23 11:25 ` [PATCH 03/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
2012-05-30 20:41 ` Jan Kratochvil
2012-05-23 11:25 ` [PATCH 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 04/16] thread, btrace: add generic branch trace support markus.t.metzger
2012-05-30 20:42 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 05/16] cli, btrace: add btrace cli markus.t.metzger
2012-05-30 20:42 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
2012-06-01 18:42 ` Jan Kratochvil
2012-06-05 9:56 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 11/16] test, btrace: add branch trace tests markus.t.metzger
2012-05-30 20:44 ` Jan Kratochvil
2012-06-01 11:37 ` Metzger, Markus T
2012-05-23 11:25 ` [PATCH 09/16] btrace, linux: add linux native btrace target ops markus.t.metzger
2012-05-30 20:43 ` Jan Kratochvil
2012-05-31 15:34 ` Metzger, Markus T
2012-05-23 11:26 ` [PATCH 12/16] test, btrace: more branch tracing tests markus.t.metzger
2012-05-23 11:26 ` [PATCH 07/16] configure: autoreconf markus.t.metzger
2012-06-22 20:44 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
2012-05-25 19:18 ` [PATCH 00/16] branch tracing support (resend) Pedro Alves
2012-05-29 14:31 ` Metzger, Markus T
2012-05-30 14:49 ` Pedro Alves
2012-05-30 15:51 ` Metzger, Markus T
2012-05-30 17:56 ` Pedro Alves
2012-05-31 17:11 ` Metzger, Markus T
2012-06-04 6:46 ` Metzger, Markus T
2012-06-12 11:32 ` Metzger, Markus T
2012-06-12 12:09 ` Jan Kratochvil
2012-06-12 12:23 ` Pedro Alves
2012-06-12 12:25 ` Jan Kratochvil
2012-06-12 13:38 ` Metzger, Markus T
2012-05-30 20:41 ` Jan Kratochvil
2012-05-31 15:33 ` Metzger, Markus T
2012-06-22 20:31 ` Tom Tromey
2012-06-25 8:50 ` Metzger, Markus T
2012-07-02 8:29 ` Metzger, Markus T
-- strict thread matches above, loose matches on Subject: below --
2012-05-10 15:15 [PATCH 00/16] branch tracing support markus.t.metzger
2012-05-10 15:18 ` [PATCH 15/16] gdbserver, btrace: add generic btrace support markus.t.metzger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1337772151-20265-16-git-send-email-markus.t.metzger@intel.com \
--to=markus.t.metzger@intel.com \
--cc=gdb-patches@sourceware.org \
--cc=kettenis@gnu.org \
--cc=markus.t.metzger@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox