public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [patch v3 02/16] disas: add precise instructions flag
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
  2012-08-14 13:00 ` [patch v3 01/16] gdbserver, build: add -DGDBSERVER markus.t.metzger
@ 2012-08-14 13:00 ` markus.t.metzger
  2012-08-14 13:00 ` [patch v3 10/16] xml, btrace: define btrace xml document style markus.t.metzger
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:00 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

When disassembling an address range with interleaved sources, the addresses that
are being disassembled may not exactly match the specified range.

Addresses may be:
  - added after the specified range
  - omitted at the beginning of the specified range

Add a new disassembly flag that fixes the above two cases.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* disasm.h: Add new flag DISASSEMBLY_PRECISE_INSN.
	* disasm.c (do_mixed_source_and_assembly): Adjust mle boundaries.


---
 gdb/disasm.c |   26 ++++++++++++++++++++++----
 gdb/disasm.h |    7 ++++---
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/gdb/disasm.c b/gdb/disasm.c
index e3d3349..c5c35ea 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -217,13 +217,22 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 
   /* First, skip all the preceding functions.  */
 
-  for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+  /* If we want precise instructions, we only skip the line entries for which
+     the pc range between this and the next entry precedes the requested
+     instruction range.  */
+  if (flags & DISASSEMBLY_PRECISE_INSN)
+    for (i = 0; i < nlines - 2 && le[i + 1].pc <= low; i++);
+  else
+    for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
 
   /* Now, copy all entries before the end of this function.  */
 
   for (; i < nlines - 1 && le[i].pc < high; i++)
     {
-      if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+      CORE_ADDR start = le[i].pc;
+      CORE_ADDR end = le[i + 1].pc;
+
+      if (le[i].line == le[i + 1].line && start == end)
 	continue;		/* Ignore duplicates.  */
 
       /* Skip any end-of-function markers.  */
@@ -233,8 +242,17 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
       mle[newlines].line = le[i].line;
       if (le[i].line > le[i + 1].line)
 	out_of_order = 1;
-      mle[newlines].start_pc = le[i].pc;
-      mle[newlines].end_pc = le[i + 1].pc;
+
+      /* If we want precise instructions, adjust the line ranges to only contain
+         instructions in the requested range.  */
+      if (flags & DISASSEMBLY_PRECISE_INSN)
+        {
+          end = min (end, high);
+          start = max (start, low);
+        }
+
+      mle[newlines].start_pc = start;
+      mle[newlines].end_pc = end;
       newlines++;
     }
 
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 646ee8e..5b459f4 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -19,9 +19,10 @@
 #ifndef DISASM_H
 #define DISASM_H
 
-#define DISASSEMBLY_SOURCE	(0x1 << 0)
-#define DISASSEMBLY_RAW_INSN	(0x1 << 1)
-#define DISASSEMBLY_OMIT_FNAME	(0x1 << 2)
+#define DISASSEMBLY_SOURCE		(0x1 << 0)
+#define DISASSEMBLY_RAW_INSN		(0x1 << 1)
+#define DISASSEMBLY_OMIT_FNAME		(0x1 << 2)
+#define DISASSEMBLY_PRECISE_INSN	(0x1 << 3)
 
 struct ui_out;
 struct ui_file;
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 01/16] gdbserver, build: add -DGDBSERVER
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
@ 2012-08-14 13:00 ` markus.t.metzger
  2012-08-15  0:41   ` Doug Evans
  2012-08-14 13:00 ` [patch v3 02/16] disas: add precise instructions flag markus.t.metzger
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:00 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

A use of common/vec.h in gdbserver may result in compile errors if GDBSERVER is
not defined.

Add -DGDBSERVER to all gdbserver cflags.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

gdbserver/
	* Makefile.in: (INTERNAL_CFLAGS): Add -DGDBSERVER
	(various make rules): Remove -DGDBSERVER


---
 gdb/gdbserver/Makefile.in |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index f62799e..ae5a60e 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -113,6 +113,9 @@ INTERNAL_CFLAGS_BASE =  ${CFLAGS} ${GLOBAL_CFLAGS} \
 INTERNAL_WARN_CFLAGS =  ${INTERNAL_CFLAGS_BASE} $(WARN_CFLAGS)
 INTERNAL_CFLAGS =  ${INTERNAL_WARN_CFLAGS} $(WERROR_CFLAGS)
 
+# Let all files know we're compiling for gdbserver.
+INTERNAL_CFLAGS += -DGDBSERVER
+
 # LDFLAGS is specifically reserved for setting from the command line
 # when running make.
 LDFLAGS = @LDFLAGS@
@@ -447,7 +450,7 @@ UST_CFLAGS = $(ustinc) -DCONFIG_UST_GDB_INTEGRATION
 # Note, we only build the IPA if -fvisibility=hidden is supported in
 # the first place.
 IPAGENT_CFLAGS = $(CPPFLAGS) $(INTERNAL_CFLAGS) $(UST_CFLAGS) \
-	-fPIC -DGDBSERVER -DIN_PROCESS_AGENT \
+	-fPIC -DIN_PROCESS_AGENT \
 	-fvisibility=hidden
 
 # In-process agent object rules
@@ -494,40 +497,40 @@ gdbreplay.o: gdbreplay.c config.h
 dll.o: dll.c $(server_h)
 
 signals.o: ../common/signals.c $(server_h) $(signals_def)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 linux-procfs.o: ../common/linux-procfs.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 linux-ptrace.o: ../common/linux-ptrace.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 common-utils.o: ../common/common-utils.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 vec.o: ../common/vec.c $(vec_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 gdb_vecs.o: ../common/gdb_vecs.c $(vec_h) $(gdb_vecs_h) $(host_defs_h)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
 
 xml-utils.o: ../common/xml-utils.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 linux-osdata.o: ../common/linux-osdata.c $(server_h) $(linux_osdata_h) ../common/gdb_dirent.h
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 ptid.o: ../common/ptid.c $(ptid_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 buffer.o: ../common/buffer.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 format.o: ../common/format.c $(server_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 agent.o: ../common/agent.c $(server_h) $(agent_h)
-	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
 # We build vasprintf with -DHAVE_CONFIG_H because we want that unit to
 # include our config.h file.  Otherwise, some system headers do not get
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 10/16] xml, btrace: define btrace xml document style
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
  2012-08-14 13:00 ` [patch v3 01/16] gdbserver, build: add -DGDBSERVER markus.t.metzger
  2012-08-14 13:00 ` [patch v3 02/16] disas: add precise instructions flag markus.t.metzger
@ 2012-08-14 13:00 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:00 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Define the xml document style for transferring branch trace data.

Add a function to parse a btrace xml document into a vector of branch trace
blocks.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* features/btrace.dtd: New file.
	* Makefile.in (XMLFILES): Add btrace.dtd.
	* btrace.h (parse_xml_btrace): New declaration.
	* btrace.c (parse_xml_btrace): New function.
	(parse_xml_btrace_block): New function.
	(block_attributes): New struct.
	(btrace_attributes): New struct.
	(btrace_children): New struct.
	(btrace_elements): New struct.


---
 gdb/Makefile.in         |    3 +-
 gdb/btrace.c            |   89 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/btrace.h            |    3 ++
 gdb/features/btrace.dtd |   12 ++++++
 4 files changed, 106 insertions(+), 1 deletions(-)
 create mode 100644 gdb/features/btrace.dtd

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f6df0e0..7dd9bf1 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -489,7 +489,8 @@ RUNTESTFLAGS=
 XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
 	$(srcdir)/features/library-list.dtd \
 	$(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
-	$(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd
+	$(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
+	$(srcdir)/features/btrace.dtd
 
 # This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
 # interface to the serial port.  Hopefully if get ported to OS/2, VMS,
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 0953be6..cba3367 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -32,6 +32,7 @@
 #include "arch-utils.h"
 #include "disasm.h"
 #include "gdbarch.h"
+#include "xml-support.h"
 
 #include <ctype.h>
 #include <string.h>
@@ -716,6 +717,94 @@ cmd_btrace (char *args, int from_tty)
     do_btrace_range (tp, flags, args);
 }
 
+#if defined(HAVE_LIBEXPAT)
+
+/* Check the btrace document version.  */
+static void
+check_xml_btrace_version (struct gdb_xml_parser *parser,
+			  const struct gdb_xml_element *element,
+			  void *user_data, VEC (gdb_xml_value_s) *attributes)
+{
+  const char *version = xml_find_attribute (attributes, "version")->value;
+
+  if (strcmp (version, "1.0") != 0)
+    gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version);
+}
+
+/* Parse a btrace "block" xml record.  */
+static void
+parse_xml_btrace_block (struct gdb_xml_parser *parser,
+			const struct gdb_xml_element *element,
+			void *user_data, VEC (gdb_xml_value_s) *attributes)
+{
+  VEC (btrace_block_s) **btrace = user_data;
+  struct btrace_block *block = VEC_safe_push (btrace_block_s, *btrace, NULL);
+  ULONGEST *begin, *end;
+
+  begin = xml_find_attribute (attributes, "begin")->value;
+  end = xml_find_attribute (attributes, "end")->value;
+
+  block->begin = *begin;
+  block->end = *end;
+}
+
+static const struct gdb_xml_attribute block_attributes[] = {
+  { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute btrace_attributes[] = {
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_children[] = {
+  { "block", block_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element btrace_elements[] = {
+  { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE,
+    check_xml_btrace_version, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+#endif /* defined(HAVE_LIBEXPAT) */
+
+/* See btrace.h.  */
+VEC (btrace_block_s) *
+parse_xml_btrace (const char *buffer)
+{
+  VEC (btrace_block_s) *btrace = NULL;
+  struct cleanup *cleanup;
+  int errcode;
+
+#if defined(HAVE_LIBEXPAT)
+
+  cleanup = make_cleanup (VEC_cleanup (btrace_block_s), &btrace);
+  errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements,
+				 buffer, &btrace);
+  if (errcode)
+    {
+      do_cleanups (cleanup);
+      errno = errcode;
+      return NULL;
+    }
+
+  /* Keep parse results.  */
+  discard_cleanups (cleanup);
+
+#else  /* !defined(HAVE_LIBEXPAT) */
+
+  error (_("Cannot process branch tracing result. XML parsing not supported."));
+
+#endif  /* !defined(HAVE_LIBEXPAT) */
+
+  return btrace;
+}
+
 void _initialize_btrace (void);
 
 /* Initialize btrace commands.  */
diff --git a/gdb/btrace.h b/gdb/btrace.h
index e70a46e..855162f 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -71,4 +71,7 @@ extern struct btrace_block *read_btrace (struct thread_info *, int);
 extern struct btrace_block *prev_btrace (struct thread_info *);
 extern struct btrace_block *next_btrace (struct thread_info *);
 
+/* Parse a branch trace xml document into a block vector.  */
+extern VEC (btrace_block_s) *parse_xml_btrace (const char*);
+
 #endif /* BTRACE_H */
diff --git a/gdb/features/btrace.dtd b/gdb/features/btrace.dtd
new file mode 100644
index 0000000..7e6bfd0
--- /dev/null
+++ b/gdb/features/btrace.dtd
@@ -0,0 +1,12 @@
+<!-- Copyright (C) 2012 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!ELEMENT btrace  (block)* >
+<!ATTLIST btrace  version CDATA   #REQUIRED>
+
+<!ELEMENT block        EMPTY>
+<!ATTLIST block        begin  CDATA   #REQUIRED
+                       end    CDATA   #REQUIRED>
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 05/16] thread, btrace: add generic branch trace support
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (5 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 07/16] configure: add check for perf_event header markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 09/16] linux, i386, amd64: enable btrace for 32bit and 64bit linux native markus.t.metzger
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add branch trace information to struct thread_info to hold the branch trace
information for that thread.

Add functions to enable/disable, and get a thread's branch trace, as well as
for iterating over it.

Iteration uses a per-thread iterator stored in the thread_info's branch trace
information.

Iterators are reset implicitly when a thread's branch trace changes.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* target.h: Add include.
	(struct target_ops): Add btrace ops.
	* target.c (update_current_target): Initialize btrace ops.
	(target_supports_btrace): New function.
	(target_enable_btrace): New function.
	(target_disable_btrace): New function.
	(target_read_btrace): New function.
	(target_btrace_has_changed): New function.
	* btrace.h: New file.
	* btrace.c: New file.
	* Makefile.in: Add btrace.c.
	* gdbthread.h: Add include.
	(struct thread_info): Add btrace field.
	* thread.c: Add include.
	(free_thread): Call disable_btrace.
	* infcmd.c: Add include.
	(detach_command): Call disconnect_btrace.
	* common/btrace-common.h: New file.


---
 gdb/Makefile.in            |    4 +-
 gdb/btrace.c               |  175 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/btrace.h               |   74 +++++++++++++++++++
 gdb/common/btrace-common.h |   56 ++++++++++++++
 gdb/gdbthread.h            |    4 +
 gdb/infcmd.c               |    2 +
 gdb/target.c               |   89 ++++++++++++++++++++++
 gdb/target.h               |   35 +++++++++
 gdb/thread.c               |    4 +
 9 files changed, 441 insertions(+), 2 deletions(-)
 create mode 100644 gdb/btrace.c
 create mode 100644 gdb/btrace.h
 create mode 100644 gdb/common/btrace-common.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 06f93ce..7601d5b 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -746,7 +746,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	regset.c sol-thread.c windows-termcap.c \
 	common/gdb_vecs.c common/common-utils.c common/xml-utils.c \
 	common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c \
-	common/format.c
+	common/format.c btrace.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -919,7 +919,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	inferior.o osdata.o gdb_usleep.o record.o gcore.o \
 	gdb_vecs.o jit.o progspace.o skip.o probe.o \
 	common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
-	format.o
+	format.o btrace.o
 
 TSOBS = inflow.o
 
diff --git a/gdb/btrace.c b/gdb/btrace.c
new file mode 100644
index 0000000..05fc627
--- /dev/null
+++ b/gdb/btrace.c
@@ -0,0 +1,175 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "btrace.h"
+#include "gdbthread.h"
+#include "frame.h"
+#include "exceptions.h"
+#include "inferior.h"
+#include "target.h"
+
+/* See btrace.h.  */
+void
+enable_btrace (struct thread_info *tp)
+{
+  if (!target_supports_btrace ())
+    error (_("Target does not support branch tracing."));
+
+  if (tp->btrace.target)
+    error (_("Branch tracing already enabled for %s."),
+	   target_pid_to_str (tp->ptid));
+
+  tp->btrace.target = target_enable_btrace (tp->ptid);
+}
+
+/* See btrace.h.  */
+void
+disable_btrace (struct thread_info *tp)
+{
+  struct btrace_thread_info *btp = &tp->btrace;
+  int errcode = 0;
+
+  if (!btp->target)
+    error (_("Branch tracing not enabled for %s."),
+	   target_pid_to_str (tp->ptid));
+
+  /* When killing the inferior, we may have lost our target before we disable
+     branch tracing.  */
+  if (target_supports_btrace ())
+    target_disable_btrace (btp->target);
+
+  btp->target = NULL;
+  VEC_free (btrace_block_s, btp->btrace);
+}
+
+/* Disable branch tracing for @tp. Ignore errors.  */
+static int
+do_disconnect_btrace (struct thread_info *tp, void *ignored)
+{
+  if (tp->btrace.target)
+    {
+      volatile struct gdb_exception error;
+
+      TRY_CATCH (error, RETURN_MASK_ERROR)
+	disable_btrace (tp);
+    }
+
+  return 0;
+}
+
+/* See btrace.h.  */
+void
+disconnect_btrace (void)
+{
+  iterate_over_threads (do_disconnect_btrace, NULL);
+}
+
+/* Update @btp's trace data in case of new trace.  */
+static void
+update_btrace (struct btrace_thread_info *btp)
+{
+  if (btp->target && target_btrace_has_changed (btp->target))
+    {
+      btp->btrace = target_read_btrace (btp->target);
+      btp->iterator = -1;
+
+      /* The first block ends at the current pc.  */
+      if (!VEC_empty (btrace_block_s, btp->btrace))
+	{
+	  struct frame_info *frame = get_current_frame ();
+
+	  if (frame)
+	    {
+	      struct btrace_block *head =
+		VEC_index (btrace_block_s, btp->btrace, 0);
+
+	      if (head && !head->end)
+		head->end = get_frame_pc (frame);
+	    }
+	}
+    }
+}
+
+/* See btrace.h.  */
+VEC (btrace_block_s) *
+get_btrace (struct thread_info *tp)
+{
+  update_btrace (&tp->btrace);
+
+  return tp->btrace.btrace;
+}
+
+/* See btrace.h.  */
+struct btrace_block *
+read_btrace (struct thread_info *tp, int index)
+{
+  struct btrace_thread_info *btp = &tp->btrace;
+
+  if (index < 0)
+    error (_("Invalid index: %d."), index);
+
+  update_btrace (btp);
+  btp->iterator = index;
+
+  if (btp->iterator >= VEC_length (btrace_block_s, btp->btrace))
+    {
+      btp->iterator = VEC_length (btrace_block_s, btp->btrace);
+      return NULL;
+    }
+
+  return VEC_index (btrace_block_s, btp->btrace, btp->iterator);
+}
+
+/* See btrace.h.  */
+struct btrace_block *
+prev_btrace (struct thread_info *tp)
+{
+  struct btrace_thread_info *btp = &tp->btrace;
+
+  update_btrace (btp);
+  btp->iterator += 1;
+
+  if (btp->iterator >= VEC_length (btrace_block_s, btp->btrace))
+    {
+      btp->iterator = VEC_length (btrace_block_s, btp->btrace);
+      return NULL;
+    }
+
+  return VEC_index (btrace_block_s, btp->btrace, btp->iterator);
+}
+
+/* See btrace.h.  */
+struct btrace_block *
+next_btrace (struct thread_info *tp)
+{
+  struct btrace_thread_info *btp = &tp->btrace;
+
+  update_btrace (btp);
+  btp->iterator -= 1;
+
+  if (btp->iterator <= -1)
+    {
+      btp->iterator = -1;
+      return NULL;
+    }
+
+  return VEC_index (btrace_block_s, btp->btrace, btp->iterator);
+}
diff --git a/gdb/btrace.h b/gdb/btrace.h
new file mode 100644
index 0000000..e70a46e
--- /dev/null
+++ b/gdb/btrace.h
@@ -0,0 +1,74 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef BTRACE_H
+#define BTRACE_H
+
+#include "btrace-common.h"
+
+struct thread_info;
+
+/* Branch trace information per thread.  */
+struct btrace_thread_info
+{
+  /* The target branch trace information for this thread.  */
+  struct btrace_target_info *target;
+
+  /* The current branch trace for this thread.  */
+  VEC (btrace_block_s) *btrace;
+
+  /* The current iterator position in the above trace vector.
+     In additon to valid vector indices, the iterator can be:
+
+       -1            one before the head
+       VEC_length()  one after the tail
+
+     Prev and next will remain at those extreme positions.  */
+  int iterator;
+};
+
+/* Enable branch tracing for a thread.
+   Allocates the branch trace target information and stores it in @tp.  */
+extern void enable_btrace (struct thread_info *tp);
+
+/* Disable branch tracing for a thread.
+   Deallocates the branch trace target information as well as the current branch
+   trace data.  */
+extern void disable_btrace (struct thread_info *);
+
+/* Disconnect branch tracing on detach.  */
+extern void disconnect_btrace (void);
+
+/* Return the current branch trace vector for a thread, or NULL if ther is no
+   trace.  */
+extern VEC (btrace_block_s) *get_btrace (struct thread_info *);
+
+/* Functions to iterate over a thread's branch trace.
+   There is one global iterator per thread.  The iterator is reset implicitly
+   when branch trace for this thread changes.
+   On success, read_btrace sets the iterator to the returned trace entry.
+   Returns the selected block or NULL if there is no trace or the iteratoris
+   out of bounds.  */
+extern struct btrace_block *read_btrace (struct thread_info *, int);
+extern struct btrace_block *prev_btrace (struct thread_info *);
+extern struct btrace_block *next_btrace (struct thread_info *);
+
+#endif /* BTRACE_H */
diff --git a/gdb/common/btrace-common.h b/gdb/common/btrace-common.h
new file mode 100644
index 0000000..4e1cd66
--- /dev/null
+++ b/gdb/common/btrace-common.h
@@ -0,0 +1,56 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef BTRACE_COMMON_H
+#define BTRACE_COMMON_H
+
+#include "vec.h"
+
+/* For CORE_ADDR.  */
+#ifdef GDBSERVER
+#  include "server.h"
+#else
+#  include "defs.h"
+#endif
+
+/* A branch trace block.
+
+   Beware that a block is not a branch.  Rather, blocks are connected through
+   branches.  */
+struct btrace_block
+{
+  /* The address of the first instruction in the block.  */
+  CORE_ADDR begin;
+  /* The address of the last instruction in the block.  */
+  CORE_ADDR end;
+};
+
+/* Branch trace is represented as a vector of branch trace blocks starting with
+   the most recent block.  */
+typedef struct btrace_block btrace_block_s;
+
+/* Define functions operating on a vector of branch trace blocks.  */
+DEF_VEC_O (btrace_block_s);
+
+/* Target specific branch trace information.  */
+struct btrace_target_info;
+
+#endif /* BTRACE_COMMON_H */
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 0250555..69320f3 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -28,6 +28,7 @@ struct symtab;
 #include "frame.h"
 #include "ui-out.h"
 #include "inferior.h"
+#include "btrace.h"
 
 /* Frontend view of the thread state.  Possible extensions: stepping,
    finishing, until(ling),...  */
@@ -227,6 +228,9 @@ struct thread_info
   /* Function that is called to free PRIVATE.  If this is NULL, then
      xfree will be called on PRIVATE.  */
   void (*private_dtor) (struct private_thread_info *);
+
+  /* Branch trace information for this thread.  */
+  struct btrace_thread_info btrace;
 };
 
 /* Create an empty thread list, or empty the existing one.  */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index d56503c..17efd15 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -56,6 +56,7 @@
 #include "inf-loop.h"
 #include "continuations.h"
 #include "linespec.h"
+#include "btrace.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -2705,6 +2706,7 @@ detach_command (char *args, int from_tty)
     error (_("The program is not being run."));
 
   disconnect_tracing (from_tty);
+  disconnect_btrace ();
 
   target_detach (args, from_tty);
 
diff --git a/gdb/target.c b/gdb/target.c
index 1fc8802..ac94574 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -701,6 +701,11 @@ update_current_target (void)
       INHERIT (to_traceframe_info, t);
       INHERIT (to_use_agent, t);
       INHERIT (to_can_use_agent, t);
+      INHERIT (to_supports_btrace, t);
+      INHERIT (to_enable_btrace, t);
+      INHERIT (to_disable_btrace, t);
+      INHERIT (to_btrace_has_changed, t);
+      INHERIT (to_read_btrace, t);
       INHERIT (to_magic, t);
       INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
       INHERIT (to_can_run_breakpoint_commands, t);
@@ -943,6 +948,21 @@ update_current_target (void)
 	    (int (*) (void))
 	    return_zero);
   de_fault (to_execution_direction, default_execution_direction);
+  de_fault (to_supports_btrace,
+	    (int (*) (void))
+	    return_zero);
+  de_fault (to_enable_btrace,
+	    (struct btrace_target_info * (*) (ptid_t))
+	    tcomplain);
+  de_fault (to_disable_btrace,
+      (void (*) (struct btrace_target_info *))
+	    tcomplain);
+  de_fault (to_btrace_has_changed,
+      (int (*) (struct btrace_target_info *))
+	    tcomplain);
+  de_fault (to_read_btrace,
+      (VEC (btrace_block_s) * (*) (struct btrace_target_info *))
+	    tcomplain);
 
 #undef de_fault
 
@@ -4145,6 +4165,75 @@ target_ranged_break_num_registers (void)
   return -1;
 }
 
+/* See target.h.  */
+int
+target_supports_btrace (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_supports_btrace != NULL)
+      return t->to_supports_btrace ();
+
+  return 0;
+}
+
+/* See target.h.  */
+struct btrace_target_info *
+target_enable_btrace (ptid_t ptid)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_enable_btrace != NULL)
+      return t->to_enable_btrace (ptid);
+
+  tcomplain ();
+  return NULL;
+}
+
+/* See target.h.  */
+void
+target_disable_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_disable_btrace != NULL)
+      return t->to_disable_btrace (btinfo);
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+int
+target_btrace_has_changed (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_btrace_has_changed != NULL)
+      return t->to_btrace_has_changed (btinfo);
+
+  tcomplain ();
+  return 0;
+}
+
+/* See target.h.  */
+VEC (btrace_block_s) *
+target_read_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_read_btrace != NULL)
+      return t->to_read_btrace (btinfo);
+
+  tcomplain ();
+  return NULL;
+}
+
+
 static void
 debug_to_prepare_to_store (struct regcache *regcache)
 {
diff --git a/gdb/target.h b/gdb/target.h
index 95cfbe2..12cb411 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -62,6 +62,7 @@ struct expression;
 #include "memattr.h"
 #include "vec.h"
 #include "gdb_signals.h"
+#include "btrace.h"
 
 enum strata
   {
@@ -857,6 +858,22 @@ struct target_ops
     /* Is the target able to use agent in current state?  */
     int (*to_can_use_agent) (void);
 
+    /* Check whether the target supports branch tracing.  */
+    int (*to_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 *(*to_enable_btrace) (ptid_t ptid);
+
+    /* Disable branch tracing and deallocate @tinfo.  */
+    void (*to_disable_btrace) (struct btrace_target_info *tinfo);
+
+    /* Check whether branch trace changed on the target.  */
+    int (*to_btrace_has_changed) (struct btrace_target_info *);
+
+    /* Read branch trace data.  */
+    VEC (btrace_block_s) *(*to_read_btrace) (struct btrace_target_info *);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1898,4 +1915,22 @@ extern void update_target_permissions (void);
 /* Blank target vector entries are initialized to target_ignore.  */
 void target_ignore (void);
 
+/* Check whether the target supports branch tracing.  */
+extern int target_supports_btrace (void);
+
+/* Enable branch tracing for @ptid.
+   Returns a branch tracing target info object.  */
+extern struct btrace_target_info *target_enable_btrace (ptid_t ptid);
+
+/* Disable branch tracing. Deallocates @btinfo.  */
+extern void target_disable_btrace (struct btrace_target_info *btinfo);
+
+/* Check whether there is no branch tracing data available.  */
+extern int target_btrace_has_changed (struct btrace_target_info *btinfo);
+
+/* Read branch tracing data.
+   Returns a vector of branch trace blocks with the latest entry at index 0.  */
+extern VEC (btrace_block_s) *target_read_btrace (struct btrace_target_info *);
+
+
 #endif /* !defined (TARGET_H) */
diff --git a/gdb/thread.c b/gdb/thread.c
index 7e8eec5..e6b8c6a 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -34,6 +34,7 @@
 #include "regcache.h"
 #include "gdb.h"
 #include "gdb_string.h"
+#include "btrace.h"
 
 #include <ctype.h>
 #include <sys/types.h>
@@ -132,6 +133,9 @@ free_thread (struct thread_info *tp)
 	xfree (tp->private);
     }
 
+  if (tp->btrace.target)
+    disable_btrace (tp);
+
   xfree (tp->name);
   xfree (tp);
 }
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 16/16] btrace, x86: restrict to Atom
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (7 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 09/16] linux, i386, amd64: enable btrace for 32bit and 64bit linux native markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:27   ` Mark Kettenis
  2012-08-14 13:01 ` [patch v3 11/16] remote, btrace: add branch trace remote ops markus.t.metzger
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Restrict branch tracing support to Atom processors.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* amd64-linux-nat.c (_initialize_amd64_linux_nat): Change supports_btrace method.
	* i386-linux-nat.c (_initialize_i386_linux_nat): Change supports_btrace method.
	* i386-linux-tdep.h (i386_linux_supports_btrace): New function.
	* i386-linux-tdep.c: Add linux-btrace.h include.
	(i386_linux_supports_btrace): New function.

gdbserver/
	* linux-low.h (linux_target_ops): Add supports_btrace method.
	* linux-low.c (linux_low_supports_btrace): New function.
	(linux_target_ops): Change supports_btrace method.
	* linux-x86-low.c (x86_supports_btrace): New function.
	(the_low_target): Add supports_btrace method.


---
 gdb/amd64-linux-nat.c         |    2 +-
 gdb/gdbserver/linux-low.c     |   15 ++++++++++++++-
 gdb/gdbserver/linux-low.h     |    2 ++
 gdb/gdbserver/linux-x86-low.c |   31 +++++++++++++++++++++++++++++++
 gdb/i386-linux-nat.c          |    2 +-
 gdb/i386-linux-tdep.c         |   34 ++++++++++++++++++++++++++++++++++
 gdb/i386-linux-tdep.h         |    3 +++
 7 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 3cfa45c..b411beb 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -1162,7 +1162,7 @@ _initialize_amd64_linux_nat (void)
   t->to_read_description = amd64_linux_read_description;
 
   /* Add btrace methods.  */
-  t->to_supports_btrace = linux_supports_btrace;
+  t->to_supports_btrace = i386_linux_supports_btrace;
   t->to_enable_btrace = amd64_linux_enable_btrace;
   t->to_disable_btrace = amd64_linux_disable_btrace;
   t->to_btrace_has_changed = linux_btrace_has_changed;
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 20b1ca5..77ecbe0 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -5793,6 +5793,19 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
   return len;
 }
 
+/* See linux-low.h.  */
+static int
+linux_low_supports_btrace (void)
+{
+  if (!linux_supports_btrace ())
+    return 0;
+
+  if (*the_low_target.supports_btrace == NULL)
+    return 0;
+
+  return (*the_low_target.supports_btrace) ();
+}
+
 /* Read branch trace data for @tinfo as btrace xml document into @buffer.  */
 static void
 linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer)
@@ -5882,7 +5895,7 @@ static struct target_ops linux_target_ops = {
   linux_get_min_fast_tracepoint_insn_len,
   linux_qxfer_libraries_svr4,
   linux_supports_agent,
-  linux_supports_btrace,
+  linux_low_supports_btrace,
   linux_enable_btrace,
   linux_disable_btrace,
   linux_btrace_has_changed,
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 99d882a..5768a77 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -169,6 +169,8 @@ struct linux_target_ops
      for use as a fast tracepoint.  */
   int (*get_min_fast_tracepoint_insn_len) (void);
 
+  /* Returns true if the low target supports btrace.  */
+  int (*supports_btrace) (void);
 };
 
 extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 1215bae..e12fccb 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -1859,6 +1859,36 @@ x86_get_min_fast_tracepoint_insn_len (void)
     }
 }
 
+/* See linux-low.h.  */
+static int
+x86_supports_btrace (void)
+{
+  unsigned int cpuid, model, family;
+
+  __asm__ __volatile__ ("movl   $1, %%eax;"
+			"cpuid;"
+			: "=a" (cpuid)
+			:: "%ebx", "%ecx", "%edx");
+
+  family = (cpuid >> 8) & 0xf;
+  model = (cpuid >> 4) & 0xf;
+
+  switch (family)
+    {
+    case 6:
+      model += (cpuid >> 12) & 0xf0;
+
+      switch (model)
+        {
+	case 28: /* Atom.  */
+	case 38:
+	  return 1;
+	}
+    }
+
+  return 0;
+}
+
 static void
 add_insns (unsigned char *start, int len)
 {
@@ -3214,4 +3244,5 @@ struct linux_target_ops the_low_target =
   x86_install_fast_tracepoint_jump_pad,
   x86_emit_ops,
   x86_get_min_fast_tracepoint_insn_len,
+  x86_supports_btrace,
 };
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 0248fd7..35bc477 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -1086,7 +1086,7 @@ _initialize_i386_linux_nat (void)
   t->to_read_description = i386_linux_read_description;
 
   /* Add btrace methods.  */
-  t->to_supports_btrace = linux_supports_btrace;
+  t->to_supports_btrace = i386_linux_supports_btrace;
   t->to_enable_btrace = i386_linux_enable_btrace;
   t->to_disable_btrace = i386_linux_disable_btrace;
   t->to_btrace_has_changed = linux_btrace_has_changed;
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 8475d7a..b0f7b43 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -37,6 +37,7 @@
 #include "symtab.h"
 #include "arch-utils.h"
 #include "xml-syscall.h"
+#include "linux-btrace.h"
 
 #include "i387-tdep.h"
 #include "i386-xstate.h"
@@ -704,6 +705,39 @@ i386_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
   return closure;
 }
 
+/* See i386-linux-tdep.h.  */
+int
+i386_linux_supports_btrace (void)
+{
+  unsigned int cpuid, model, family;
+
+  if (!linux_supports_btrace ())
+    return 0;
+
+  __asm__ __volatile__ ("movl   $1, %%eax;"
+			"cpuid;"
+			: "=a" (cpuid)
+			:: "%ebx", "%ecx", "%edx");
+
+  family = (cpuid >> 8) & 0xf;
+  model = (cpuid >> 4) & 0xf;
+
+  switch (family)
+    {
+    case 6:
+      model += (cpuid >> 12) & 0xf0;
+
+      switch (model)
+        {
+	case 28: /* Atom.  */
+	case 38:
+	  return 1;
+	}
+    }
+
+  return 0;
+}
+
 static void
 i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index c3a316f..45bdece 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -66,4 +66,7 @@ extern struct target_desc *tdesc_i386_avx_linux;
 
 extern int i386_linux_gregset_reg_offset[];
 
+/* Return 1 if target supports btrace.  */
+extern int i386_linux_supports_btrace (void);
+
 #endif /* i386-linux-tdep.h */
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 04/16] source, disasm: optionally prefix source lines with filename
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (11 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 03/16] source: add flags to print_source_lines () markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-09-11 20:21   ` Tom Tromey
  2012-08-14 13:03 ` [patch v3 15/16] test, btrace: more branch tracing tests markus.t.metzger
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add respective flags to print_source_lines () and gdb_disassembly () to prefix
the source line with its file name.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* disasm.h (DISASSEMBLY_FILENAME): New macro.
	* disasm.c (do_mixed_source_and_assembly): Pass filename flag on to
	print_source_lines ().
	* symtab.h (PRINT_SOURCE_LINES_FILENAME): New print source lines flag.
	* source.c (print_source_lines_base): Prefix source line with filename if
	PRINT_SOURCE_LINES_FILENAME flag is set.


---
 gdb/disasm.c |   12 ++++++++----
 gdb/disasm.h |    1 +
 gdb/source.c |    5 +++++
 gdb/symtab.h |    5 ++++-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/gdb/disasm.c b/gdb/disasm.c
index c5c35ea..2120add 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -204,10 +204,14 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
   int out_of_order = 0;
   int next_line = 0;
   int num_displayed = 0;
+  enum print_source_lines_flags psl_flags = 0;
   struct cleanup *ui_out_chain;
   struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
   struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
 
+  if (flags & DISASSEMBLY_FILENAME)
+    psl_flags |= PRINT_SOURCE_LINES_FILENAME;
+
   mle = (struct dis_line_entry *) alloca (nlines
 					  * sizeof (struct dis_line_entry));
 
@@ -293,7 +297,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 		  ui_out_tuple_chain
 		    = make_cleanup_ui_out_tuple_begin_end (uiout,
 							   "src_and_asm_line");
-		  print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
 		}
 	      else
 		{
@@ -307,7 +311,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 			= make_cleanup_ui_out_tuple_begin_end (uiout,
 							       "src_and_asm_line");
 		      print_source_lines (symtab, next_line, next_line + 1,
-					  0);
+					  psl_flags);
 		      ui_out_list_chain_line
 			= make_cleanup_ui_out_list_begin_end (uiout,
 							      "line_asm_insn");
@@ -319,7 +323,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 		  ui_out_tuple_chain
 		    = make_cleanup_ui_out_tuple_begin_end (uiout,
 							   "src_and_asm_line");
-		  print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
 		}
 	    }
 	  else
@@ -327,7 +331,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 	      ui_out_tuple_chain
 		= make_cleanup_ui_out_tuple_begin_end (uiout,
 						       "src_and_asm_line");
-	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
 	    }
 
 	  next_line = mle[i].line + 1;
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 5b459f4..5ae71c9 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -23,6 +23,7 @@
 #define DISASSEMBLY_RAW_INSN		(0x1 << 1)
 #define DISASSEMBLY_OMIT_FNAME		(0x1 << 2)
 #define DISASSEMBLY_PRECISE_INSN	(0x1 << 3)
+#define DISASSEMBLY_FILENAME		(0x1 << 4)
 
 struct ui_out;
 struct ui_file;
diff --git a/gdb/source.c b/gdb/source.c
index d4616be..daf720d 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1336,6 +1336,11 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
       if (c == EOF)
 	break;
       last_line_listed = current_source_line;
+      if (flags & PRINT_SOURCE_LINES_FILENAME)
+        {
+          ui_out_text (uiout, s->filename);
+          ui_out_text (uiout, ":");
+        }
       sprintf (buf, "%d\t", current_source_line++);
       ui_out_text (uiout, buf);
       do
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 750da2a..8642618 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1146,7 +1146,10 @@ extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
 enum print_source_lines_flags
   {
     /* Do not print an error message.  */
-    PRINT_SOURCE_LINES_NOERROR = (1 << 0)
+    PRINT_SOURCE_LINES_NOERROR = (1 << 0),
+
+    /* Print the filename in front of the source lines.  */
+    PRINT_SOURCE_LINES_FILENAME = (1 << 1)
   };
 
 extern void print_source_lines (struct symtab *, int, int,
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 08/16] linux, btrace: perf_event based branch tracing
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (2 preceding siblings ...)
  2012-08-14 13:00 ` [patch v3 10/16] xml, btrace: define btrace xml document style markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 13/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Implement branch tracing on Linux based on perf_event such taht it can be shared
between gdb and gdbserver.

The actual btrace target ops will be implemented on top.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* common/linux_btrace.h: New file.
	* common/linux_btrace.c: New file.
	* Makefile.in: Add linux-btrace rules.

gdbserver/
	* Makefile.in: Add linux-btrace rules.


---
 gdb/Makefile.in           |    6 +-
 gdb/common/linux-btrace.c |  382 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/common/linux-btrace.h |   76 +++++++++
 gdb/gdbserver/Makefile.in |    6 +-
 4 files changed, 468 insertions(+), 2 deletions(-)
 create mode 100644 gdb/common/linux-btrace.c
 create mode 100644 gdb/common/linux-btrace.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 7601d5b..f6df0e0 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -828,7 +828,7 @@ gnulib/import/extra/snippet/arg-nonnull.h gnulib/import/extra/snippet/c++defs.h
 gnulib/import/extra/snippet/warn-on-use.h \
 gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
 common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
-common/format.h common/host-defs.h utils.h \
+common/format.h common/host-defs.h common/linux-btrace.h utils.h \
 common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
 
 # Header files that already have srcdir in them, or which are in objdir.
@@ -1944,6 +1944,10 @@ vec.o: ${srcdir}/common/vec.c
 	$(COMPILE) $(srcdir)/common/vec.c
 	$(POSTCOMPILE)
 
+linux-btrace.o: ${srcdir}/common/linux-btrace.c
+	$(COMPILE) $(srcdir)/common/linux-btrace.c
+	$(POSTCOMPILE)
+
 #
 # gdb/tui/ dependencies
 #
diff --git a/gdb/common/linux-btrace.c b/gdb/common/linux-btrace.c
new file mode 100644
index 0000000..da858e1
--- /dev/null
+++ b/gdb/common/linux-btrace.c
@@ -0,0 +1,382 @@
+/* Linux-dependent part of branch trace support for GDB, and GDBserver.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Needed for _ () used in gdb_assert ().  */
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#endif
+
+#include "linux-btrace.h"
+#include "common-utils.h"
+#include "gdb_assert.h"
+
+#if HAVE_LINUX_PERF_EVENT_H
+
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+
+#if defined(__GNUC__)
+#  define memory_barrier() asm volatile ("" : : : "memory")
+#else
+#  define memory_barrier() do {} while (0)
+#endif
+
+/* A branch trace record in perf_event.  */
+struct perf_event_bts
+{
+  uint64_t from;
+  uint64_t to;
+};
+
+/* A perf_event branch trace sample.  */
+struct perf_event_sample
+{
+  struct perf_event_header header;
+  struct perf_event_bts bts;
+};
+
+/* Get the perf_event header.  */
+static inline volatile struct perf_event_mmap_page *
+perf_event_header (struct btrace_target_info* tinfo)
+{
+  return tinfo->buffer;
+}
+
+/* Get the size of the perf_event mmap buffer.  */
+static inline size_t
+perf_event_mmap_size (const struct btrace_target_info *tinfo)
+{
+  /* The branch trace buffer is preceded by a configuration page.  */
+  return (tinfo->size + 1) * PAGE_SIZE;
+}
+
+/* Get the size of the perf_event buffer.  */
+static inline size_t
+perf_event_buffer_size (struct btrace_target_info* tinfo)
+{
+  return tinfo->size * PAGE_SIZE;
+}
+
+/* Get the start address of the perf_event buffer.  */
+static inline const uint8_t *
+perf_event_buffer_begin (struct btrace_target_info* tinfo)
+{
+  return ((const uint8_t *) tinfo->buffer) + PAGE_SIZE;
+}
+
+/* Get the end address of the perf_event buffer.  */
+static inline const uint8_t *
+perf_event_buffer_end (struct btrace_target_info* tinfo)
+{
+  return perf_event_buffer_begin (tinfo) + perf_event_buffer_size (tinfo);
+}
+
+/* Check whether an address is in the kernel.  */
+static inline int
+perf_event_is_kernel_addr (const struct btrace_target_info *tinfo,
+			   uint64_t addr)
+{
+  return tinfo->ptr_bits && (addr & ((uint64_t) 1 << (tinfo->ptr_bits - 1)));
+}
+
+/* Check whether a perf_event record should be skipped.  */
+static inline int
+perf_event_skip_record (const struct btrace_target_info *tinfo,
+			const struct perf_event_bts *bts)
+{
+  return perf_event_is_kernel_addr (tinfo, bts->from);
+}
+
+/* Check whether a perf_event sample record is OK.  */
+static inline int
+perf_event_sample_ok (const struct perf_event_sample *sample)
+{
+  if (sample->header.type != PERF_RECORD_SAMPLE)
+    return 0;
+
+  if (sample->header.size != sizeof (*sample))
+    return 0;
+
+  return 1;
+}
+
+/* Branch trace is collected in a circular buffer [begin; end) as pairs of from
+   and to addresses (plus some header).
+
+   Start points into that buffer at the next sample position.
+   We read the collected samples backwards from start.
+
+   While reading the samples, we convert the information into a list of blocks.
+   For two adjacent samples s1 and s2, we form a block b such that b.begin =
+   s1.to and b.end = s2.from.
+
+   In case the buffer overflows during sampling, samples may be split.  */
+
+static VEC (btrace_block_s) *
+perf_event_read_bts (struct btrace_target_info* tinfo, const uint8_t *begin,
+		     const uint8_t *end, const uint8_t *start)
+{
+  VEC (btrace_block_s) *btrace = NULL;
+  struct perf_event_sample sample;
+  int read = 0, size = (end - begin);
+  struct btrace_block block = { 0, 0 };
+
+  gdb_assert (begin <= start);
+  gdb_assert (start <= end);
+
+  /* The buffer may contain a partial record as its last entry (i.e. when the
+     buffer size is not a mulitple of the sample size).  */
+  read = sizeof (sample) - 1;
+
+  for (; read < size; read += sizeof (sample))
+    {
+      const struct perf_event_sample *psample;
+
+      /* Find the next perf_event sample.  */
+      start -= sizeof (sample);
+      if (begin <= start)
+	psample = (const struct perf_event_sample *) start;
+      else
+	{
+	  int missing = (begin - start);
+
+	  start = (end - missing);
+
+	  if (missing == sizeof (sample))
+	    psample = (const struct perf_event_sample *) start;
+	  else
+	    {
+	      uint8_t *stack = (uint8_t *) &sample;
+
+	      memcpy (stack, start, missing);
+	      memcpy (stack + missing, begin, sizeof (sample) - missing);
+
+	      psample = &sample;
+	    }
+	}
+
+      if (!perf_event_sample_ok (psample))
+	{
+	  warning (_("Branch trace may be incomplete."));
+	  break;
+	}
+
+      if (perf_event_skip_record (tinfo, &psample->bts))
+	continue;
+
+      /* We found a valid sample, so we can complete the current block.  */
+      block.begin = psample->bts.to;
+
+      VEC_safe_push (btrace_block_s, btrace, &block);
+
+      /* Start the next block.  */
+      block.end = psample->bts.from;
+    }
+
+  return btrace;
+}
+
+/* See linux-btrace.h.  */
+int
+linux_supports_btrace (void)
+{
+  return 1;
+}
+
+/* See linux-btrace.h.  */
+int
+linux_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+  volatile struct perf_event_mmap_page *header = perf_event_header (tinfo);
+
+  if (!header)
+    return 0;
+
+  return header->data_head != tinfo->data_head;
+}
+
+/* See linux-btrace.h.  */
+struct btrace_target_info *
+linux_enable_btrace (ptid_t ptid)
+{
+  struct btrace_target_info *tinfo;
+  int pid;
+
+  tinfo = xzalloc (sizeof (*tinfo));
+  tinfo->attr.size = sizeof (tinfo->attr);
+
+  tinfo->attr.type = PERF_TYPE_HARDWARE;
+  tinfo->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
+  tinfo->attr.sample_period = 1;
+
+  /* We sample from and to address.  */
+  tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
+
+  tinfo->attr.exclude_kernel = 1;
+  tinfo->attr.exclude_hv = 1;
+  tinfo->attr.exclude_idle = 1;
+
+  tinfo->ptr_bits = 0;
+
+  pid = ptid_get_lwp (ptid);
+  if (!pid)
+    pid = ptid_get_pid (ptid);
+
+  errno = 0;
+  tinfo->file = syscall (SYS_perf_event_open, &(tinfo->attr), pid, -1, -1, 0);
+  if (tinfo->file < 0)
+    goto err;
+
+  /* We hard-code the trace buffer size.
+     At some later time, we should make this configurable.  */
+  tinfo->size = 1;
+  tinfo->buffer = mmap (NULL, perf_event_mmap_size (tinfo),
+			PROT_READ, MAP_SHARED, tinfo->file, 0);
+  if (tinfo->buffer == MAP_FAILED)
+    goto err_file;
+
+  return tinfo;
+
+err_file:
+  close (tinfo->file);
+
+err:
+  xfree (tinfo);
+  return NULL;
+}
+
+/* See linux-btrace.h.  */
+int
+linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+  int errcode;
+
+  if (!tinfo)
+    return EINVAL;
+
+  errno = 0;
+  errcode = munmap (tinfo->buffer, perf_event_mmap_size (tinfo));
+  if (errcode)
+    return errno;
+
+  close (tinfo->file);
+  xfree (tinfo);
+
+  return 0;
+}
+
+/* See linux-btrace.h.  */
+VEC (btrace_block_s) *
+linux_read_btrace (struct btrace_target_info *tinfo)
+{
+  VEC (btrace_block_s) *btrace = NULL;
+  volatile struct perf_event_mmap_page *header;
+  const uint8_t *begin, *end, *start;
+  unsigned long data_head, retries = 5;
+  size_t buffer_size;
+
+  header = perf_event_header (tinfo);
+  if (!header)
+    return btrace;
+
+  buffer_size = perf_event_buffer_size (tinfo);
+
+  /* We may need to retry reading the trace.  See below.  */
+  while (retries--)
+    {
+      data_head = header->data_head;
+
+      /* Make sure the trace data is up-to-date.  */
+      memory_barrier ();
+
+      /* If there new trace, let's read it.  */
+      if (data_head != tinfo->data_head)
+	{
+	  /* Data_head keeps growing; the buffer itself is circular.  */
+	  begin = perf_event_buffer_begin (tinfo);
+	  start = begin + (data_head % buffer_size);
+
+	  if (data_head <= buffer_size)
+	    end = start;
+	  else
+	    end = perf_event_buffer_end (tinfo);
+
+	  btrace = perf_event_read_bts (tinfo, begin, end, start);
+	}
+
+      /* The stopping thread notifies its ptracer before it is scheduled out.
+	 On multi-core systems, the debugger might therefore run while the
+	 kernel might be writing the last branch trace records.
+
+	 Let's check whether the data head moved while we read the trace.  */
+      if (data_head == header->data_head)
+	break;
+    }
+
+  tinfo->data_head = data_head;
+
+  return btrace;
+}
+
+#else /* !HAVE_LINUX_PERF_EVENT_H */
+
+/* See linux-btrace.h.  */
+int
+linux_supports_btrace (void)
+{
+  return 0;
+}
+
+/* See linux-btrace.h.  */
+int
+linux_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+  return 0;
+}
+
+/* See linux-btrace.h.  */
+struct btrace_target_info *
+linux_enable_btrace (ptid_t ptid)
+{
+  return NULL;
+}
+
+/* See linux-btrace.h.  */
+int
+linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+  return ENOSYS;
+}
+
+/* See linux-btrace.h.  */
+VEC (btrace_block_s) *
+linux_read_btrace (struct btrace_target_info *tinfo)
+{
+}
+
+#endif /* !HAVE_LINUX_PERF_EVENT_H */
diff --git a/gdb/common/linux-btrace.h b/gdb/common/linux-btrace.h
new file mode 100644
index 0000000..b0f8459
--- /dev/null
+++ b/gdb/common/linux-btrace.h
@@ -0,0 +1,76 @@
+/* Linux-dependent part of branch trace support for GDB, and GDBserver.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LINUX_BTRACE_H
+#define LINUX_BTRACE_H
+
+#include "btrace-common.h"
+#include "config.h"
+#include "vec.h"
+#include "ptid.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#if HAVE_LINUX_PERF_EVENT_H
+#  include <linux/perf_event.h>
+#endif
+
+/* Branch trace target information per thread.  */
+struct btrace_target_info
+{
+#if HAVE_LINUX_PERF_EVENT_H
+  /* The Linux perf_event configuration for collecting the branch trace.  */
+  struct perf_event_attr attr;
+
+  /* The mmap configuration mapping the branch trace perf_event buffer.
+
+     file      .. the file descriptor
+     buffer    .. the mmapped memory buffer
+     size      .. the buffer's size in pages without the configuration page
+     data_head .. the data head from the last read  */
+  int file;
+  void *buffer;
+  size_t size;
+  unsigned long data_head;
+#endif /* HAVE_LINUX_PERF_EVENT_H */
+
+  /* The size of a pointer in bits for this thread.
+     The information is used to identify kernel addresses in order to skip
+     records from/to kernel space.  */
+  int ptr_bits;
+};
+
+/* Check whether branch tracing is supported.  */
+extern int linux_supports_btrace (void);
+
+/* Enable branch tracing for @ptid.  */
+extern struct btrace_target_info *linux_enable_btrace (ptid_t ptid);
+
+/* Disable branch tracing and deallocate @tinfo.  */
+extern int linux_disable_btrace (struct btrace_target_info *tinfo);
+
+/* Check whether there is new trace data available.  */
+extern int linux_btrace_has_changed (struct btrace_target_info *);
+
+/* Read branch trace data.  */
+extern VEC (btrace_block_s) *linux_read_btrace (struct btrace_target_info *);
+
+#endif /* LINUX_BTRACE_H */
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index ae5a60e..d571cd5 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -146,7 +146,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/vec.c $(srcdir)/common/gdb_vecs.c \
 	$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
 	$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
-	$(srcdir)/common/buffer.c
+	$(srcdir)/common/buffer.c $(srcdir)/common/linux-btrace.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -415,6 +415,7 @@ signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
 ptid_h = $(srcdir)/../common/ptid.h
 ax_h = $(srcdir)/ax.h
 agent_h = $(srcdir)/../common/agent.h
+linux_btrace_h = $(srcdir)/../common/linux-btrace.h
 linux_osdata_h = $(srcdir)/../common/linux-osdata.h
 vec_h = $(srcdir)/../common/vec.h
 gdb_vecs_h = $(srcdir)/../common/gdb_vecs.h
@@ -532,6 +533,9 @@ format.o: ../common/format.c $(server_h)
 agent.o: ../common/agent.c $(server_h) $(agent_h)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
 
+linux-btrace.o: ../common/linux-btrace.c $(linux_btrace_h) $(server_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $<
+
 # We build vasprintf with -DHAVE_CONFIG_H because we want that unit to
 # include our config.h file.  Otherwise, some system headers do not get
 # included, and the compiler emits a warning about implicitly defined
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 11/16] remote, btrace: add branch trace remote ops
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (8 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 16/16] btrace, x86: restrict to Atom markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 12/16] gdbserver, btrace: add generic btrace support markus.t.metzger
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add the gdb remote target operations for branch tracing. We define the following
packets:

  qbtrace:<ptid>  query if new trace data is available for a thread
                  returns "yes" or "no" or "Enn"

  Qbtrace:on:<ptid>  enable branch tracing for one thread
                     returns "OK" or "Enn"

  Qbtrace:off:<ptid>  disable branch tracing for one thread
                      returns "OK" or "Enn"

  qXfer:btrace:read:<ptid>   read the full branch trace data for one thread

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* target.h (enum target_object): Add TARGET_OBJECT_BTRACE.
	* remote.c (struct btrace_target_info): New struct.
	(remote_supports_btrace): New function.
	(remote_enable_btrace): New function.
	(remote_disable_btrace): New function.
	(remote_btrace_has_changed): New function.
	(remote_read_btrace): New function.
	(init_remote_ops): Add btrace ops.
	(enum <unnamed>): Add btrace packets.
	(struct protocol_feature remote_protocol_features[]): Add btrace packets.
	(_initialize_remote): Add btrace packets.


---
 gdb/remote.c |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/target.h |    4 +-
 2 files changed, 160 insertions(+), 1 deletions(-)

diff --git a/gdb/remote.c b/gdb/remote.c
index a974dc1..a94a979 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -67,6 +67,7 @@
 #include "ax.h"
 #include "ax-gdb.h"
 #include "agent.h"
+#include "btrace.h"
 
 /* Temp hacks for tracepoint encoding migration.  */
 static char *target_buf;
@@ -1292,6 +1293,9 @@ enum {
   PACKET_qXfer_fdpic,
   PACKET_QDisableRandomization,
   PACKET_QAgent,
+  PACKET_qbtrace,
+  PACKET_Qbtrace,
+  PACKET_qXfer_btrace,
   PACKET_MAX
 };
 
@@ -3945,6 +3949,10 @@ static struct protocol_feature remote_protocol_features[] = {
   { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
   { "tracenz", PACKET_DISABLE,
     remote_string_tracing_feature, -1 },
+  { "qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_qbtrace },
+  { "Qbtrace", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace },
+  { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_btrace }
 };
 
 static char *remote_support_xml;
@@ -8671,6 +8679,10 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
 				&remote_protocol_packets[PACKET_qXfer_uib]);
 
+    case TARGET_OBJECT_BTRACE:
+      return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len,
+        &remote_protocol_packets[PACKET_qXfer_btrace]);
+
     default:
       return -1;
     }
@@ -10994,6 +11006,137 @@ remote_can_use_agent (void)
   return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
 }
 
+struct btrace_target_info
+{
+  /* The ptid of the traced thread.  */
+  ptid_t ptid;
+};
+
+/* Check whether the target supports branch tracing.  */
+static int
+remote_supports_btrace (void)
+{
+  if (remote_protocol_packets[PACKET_qbtrace].support != PACKET_ENABLE)
+    return 0;
+  if (remote_protocol_packets[PACKET_Qbtrace].support != PACKET_ENABLE)
+    return 0;
+  if (remote_protocol_packets[PACKET_qXfer_btrace].support != PACKET_ENABLE)
+    return 0;
+
+  return 1;
+}
+
+/* Enable branch tracing for @ptid.  */
+static struct btrace_target_info *
+remote_enable_btrace (ptid_t ptid)
+{
+  struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
+  struct remote_state *rs = get_remote_state ();
+  struct btrace_target_info *tinfo = NULL;
+  char *buf = rs->buf;
+  char *endbuf = rs->buf + get_remote_packet_size ();
+
+  if (packet->support != PACKET_ENABLE)
+    error (_("Target does not support branch tracing."));
+
+  buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+  buf += xsnprintf (buf, endbuf - buf, ":on:");
+  buf = write_ptid (buf, endbuf, ptid);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf, packet) != PACKET_OK)
+    error (_("Could not enable branch tracing for %s."),
+           target_pid_to_str (ptid));
+
+  tinfo = xzalloc (sizeof (*tinfo));
+  tinfo->ptid = ptid;
+
+  return tinfo;
+}
+
+/* Disable branch tracing.  */
+static void
+remote_disable_btrace (struct btrace_target_info *tinfo)
+{
+  struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace];
+  struct remote_state *rs = get_remote_state ();
+  char *buf = rs->buf;
+  char *endbuf = rs->buf + get_remote_packet_size ();
+
+  if (packet->support != PACKET_ENABLE)
+    error (_("Target does not support branch tracing."));
+
+  buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+  buf += xsnprintf (buf, endbuf - buf, ":off:");
+  buf = write_ptid (buf, endbuf, tinfo->ptid);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf, packet) != PACKET_OK)
+    error (_("Could not disable branch tracing for %s."),
+           target_pid_to_str (tinfo->ptid));
+
+  xfree (tinfo);
+}
+
+/* Check whether branch trace data has changed.  */
+static int
+remote_btrace_has_changed (struct btrace_target_info *tinfo)
+{
+  struct packet_config *packet = &remote_protocol_packets[PACKET_qbtrace];
+  struct remote_state *rs = get_remote_state ();
+  char *buf = rs->buf;
+  char *endbuf = rs->buf + get_remote_packet_size ();
+
+  if (packet->support != PACKET_ENABLE)
+    error (_("Target does not support branch tracing."));
+
+  buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
+  buf += xsnprintf (buf, endbuf - buf, ":");
+  buf = write_ptid (buf, endbuf, tinfo->ptid);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf, packet) != PACKET_OK)
+    error (_("Failed to check for branch trace data for %s."),
+           target_pid_to_str (tinfo->ptid));
+
+  return (strcmp (rs->buf, "yes") == 0);
+}
+
+/* Read the branch trace.  */
+static VEC (btrace_block_s) *
+remote_read_btrace (struct btrace_target_info *tinfo)
+{
+  struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
+  struct remote_state *rs = get_remote_state ();
+  char *xml, annex[64], *pend;
+  VEC (btrace_block_s) *btrace = NULL;
+
+  if (packet->support != PACKET_ENABLE)
+    error (_("Target does not support branch tracing."));
+
+#if !defined(HAVE_LIBEXPAT)
+  error (_("Cannot process branch tracing result. XML parsing not supported."));
+#endif
+
+  memset (annex, 0, sizeof (annex));
+  pend = write_ptid (annex, annex + sizeof (annex), tinfo->ptid);
+
+  xml = target_read_stralloc (&current_target,
+                              TARGET_OBJECT_BTRACE, annex);
+  if (xml)
+    {
+      struct cleanup *cleanup = make_cleanup (xfree, xml);
+
+      btrace = parse_xml_btrace (xml);
+      do_cleanups (cleanup);
+    }
+
+  return btrace;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -11110,6 +11253,11 @@ Specify the serial device it is connected to\n\
   remote_ops.to_traceframe_info = remote_traceframe_info;
   remote_ops.to_use_agent = remote_use_agent;
   remote_ops.to_can_use_agent = remote_can_use_agent;
+  remote_ops.to_supports_btrace = remote_supports_btrace;
+  remote_ops.to_enable_btrace = remote_enable_btrace;
+  remote_ops.to_disable_btrace = remote_disable_btrace;
+  remote_ops.to_btrace_has_changed = remote_btrace_has_changed;
+  remote_ops.to_read_btrace = remote_read_btrace;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
@@ -11636,6 +11784,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
 			 "QAgent", "agent", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qbtrace],
+       "qbtrace", "query-btrace", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace],
+       "Qbtrace", "enable-btrace", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
+       "qXfer:btrace", "read-btrace", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
diff --git a/gdb/target.h b/gdb/target.h
index 12cb411..917457e 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -287,7 +287,9 @@ enum target_object
   /* Darwin dynamic linker info data.  */
   TARGET_OBJECT_DARWIN_DYLD_INFO,
   /* OpenVMS Unwind Information Block.  */
-  TARGET_OBJECT_OPENVMS_UIB
+  TARGET_OBJECT_OPENVMS_UIB,
+  /* Branch trace data, in XML format.  */
+  TARGET_OBJECT_BTRACE
   /* Possible future objects: TARGET_OBJECT_FILE, ...  */
 };
 
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 09/16] linux, i386, amd64: enable btrace for 32bit and 64bit linux native
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (6 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 05/16] thread, btrace: add generic branch trace support markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 16/16] btrace, x86: restrict to Atom markus.t.metzger
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Install the btrace target ops for i386-linux-nat and amd64-linux-nat.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* amd64-linux-nat.c: Include btrace.h and linux-btrace.h.
	(_initialize_amd64_linux_nat): Initialize btrace ops.
	* i386-linux.nat.c: Include btrace.h and linux-btrace.h.
	(_initialize_i386_linux_nat): Initialize btrace ops.
	* config/i386/linux.mh: Add linux-btrace.o.
	* config/i386/linux64.mh: Add linux-btrace.o.


---
 gdb/amd64-linux-nat.c      |   51 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/config/i386/linux.mh   |    3 +-
 gdb/config/i386/linux64.mh |    2 +-
 gdb/i386-linux-nat.c       |   51 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 01982ac..3cfa45c 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -25,6 +25,8 @@
 #include "regset.h"
 #include "linux-nat.h"
 #include "amd64-linux-tdep.h"
+#include "linux-btrace.h"
+#include "btrace.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -1079,6 +1081,48 @@ amd64_linux_read_description (struct target_ops *ops)
     }
 }
 
+/* Enable branch tracing for @ptid.  */
+static struct btrace_target_info *
+amd64_linux_enable_btrace (ptid_t ptid)
+{
+  struct btrace_target_info *tinfo;
+
+  errno = 0;
+  tinfo = linux_enable_btrace (ptid);
+
+  if (!tinfo)
+    error (_("Could not enable branch tracing for %s: %s."),
+	   target_pid_to_str (ptid), safe_strerror (errno));
+
+  return tinfo;
+}
+
+/* Disable branch tracing for @ptid.  */
+static void
+amd64_linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+  int errcode = linux_disable_btrace (tinfo);
+
+  if (errcode)
+    error (_("Could not disable branch tracing: %s."), safe_strerror (errcode));
+}
+
+/* Read branch trace data for @tinfo.  */
+static VEC (btrace_block_s) *
+amd64_linux_read_btrace (struct btrace_target_info *tinfo)
+{
+  /* Fill in the number of bits in a pointer for this architecture.  */
+  if (!tinfo->ptr_bits)
+    {
+      struct gdbarch *gdbarch = target_gdbarch;
+
+      if (gdbarch)
+	tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
+    }
+
+  return linux_read_btrace (tinfo);
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_amd64_linux_nat (void);
 
@@ -1117,6 +1161,13 @@ _initialize_amd64_linux_nat (void)
 
   t->to_read_description = amd64_linux_read_description;
 
+  /* Add btrace methods.  */
+  t->to_supports_btrace = linux_supports_btrace;
+  t->to_enable_btrace = amd64_linux_enable_btrace;
+  t->to_disable_btrace = amd64_linux_disable_btrace;
+  t->to_btrace_has_changed = linux_btrace_has_changed;
+  t->to_read_btrace = amd64_linux_read_btrace;
+
   /* Register the target.  */
   linux_nat_add_target (t);
   linux_nat_set_new_thread (t, amd64_linux_new_thread);
diff --git a/gdb/config/i386/linux.mh b/gdb/config/i386/linux.mh
index 8316d87..7c64e83 100644
--- a/gdb/config/i386/linux.mh
+++ b/gdb/config/i386/linux.mh
@@ -4,7 +4,8 @@ NAT_FILE= config/nm-linux.h
 NATDEPFILES= inf-ptrace.o fork-child.o \
 	i386-nat.o i386-linux-nat.o \
 	proc-service.o linux-thread-db.o \
-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
+	linux-btrace.o
 NAT_CDEPS = $(srcdir)/proc-service.list
 
 # The dynamically loaded libthread_db needs access to symbols in the
diff --git a/gdb/config/i386/linux64.mh b/gdb/config/i386/linux64.mh
index d2b95fd..8d782c1 100644
--- a/gdb/config/i386/linux64.mh
+++ b/gdb/config/i386/linux64.mh
@@ -3,7 +3,7 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
 	i386-nat.o amd64-nat.o amd64-linux-nat.o \
 	linux-nat.o linux-osdata.o \
 	proc-service.o linux-thread-db.o linux-fork.o \
-	linux-procfs.o linux-ptrace.o
+	linux-procfs.o linux-ptrace.o linux-btrace.o
 NAT_FILE= config/nm-linux.h
 NAT_CDEPS = $(srcdir)/proc-service.list
 
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 5a65ef6..0248fd7 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -25,6 +25,8 @@
 #include "regset.h"
 #include "target.h"
 #include "linux-nat.h"
+#include "linux-btrace.h"
+#include "btrace.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -1008,6 +1010,48 @@ i386_linux_read_description (struct target_ops *ops)
     return tdesc_i386_linux;
 }
 
+/* Enable branch tracing for @ptid.  */
+static struct btrace_target_info *
+i386_linux_enable_btrace (ptid_t ptid)
+{
+  struct btrace_target_info *tinfo;
+
+  errno = 0;
+  tinfo = linux_enable_btrace (ptid);
+
+  if (!tinfo)
+    error (_("Could not enable branch tracing for %s: %s."),
+	   target_pid_to_str (ptid), safe_strerror (errno));
+
+  return tinfo;
+}
+
+/* Disable branch tracing for @ptid.  */
+static void
+i386_linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+  int errcode = linux_disable_btrace (tinfo);
+
+  if (errcode)
+    error (_("Could not disable branch tracing: %s."), safe_strerror (errcode));
+}
+
+/* Read branch trace data for @tinfo.  */
+static VEC (btrace_block_s) *
+i386_linux_read_btrace (struct btrace_target_info *tinfo)
+{
+  /* Fill in the number of bits in a pointer for this architecture.  */
+  if (!tinfo->ptr_bits)
+    {
+      struct gdbarch *gdbarch = target_gdbarch;
+
+      if (gdbarch)
+	tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
+    }
+
+  return linux_read_btrace (tinfo);
+}
+
 /* -Wmissing-prototypes */
 extern initialize_file_ftype _initialize_i386_linux_nat;
 
@@ -1041,6 +1085,13 @@ _initialize_i386_linux_nat (void)
 
   t->to_read_description = i386_linux_read_description;
 
+  /* Add btrace methods.  */
+  t->to_supports_btrace = linux_supports_btrace;
+  t->to_enable_btrace = i386_linux_enable_btrace;
+  t->to_disable_btrace = i386_linux_disable_btrace;
+  t->to_btrace_has_changed = linux_btrace_has_changed;
+  t->to_read_btrace = i386_linux_read_btrace;
+
   /* Register the target.  */
   linux_nat_add_target (t);
   linux_nat_set_new_thread (t, i386_linux_new_thread);
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 07/16] configure: add check for perf_event header
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (4 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 13/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 05/16] thread, btrace: add generic branch trace support markus.t.metzger
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* configure.ac: check for linux/perf_event.h.
	* config.in: Regenerated.
	* configure: Regenerated.

gdbserver/
	* configure.ac: check for linux/perf_event.h.
	* config.in: Regenerated.
	* configure: Regenerated.


---
 gdb/config.in              |    3 +++
 gdb/configure              |    2 +-
 gdb/configure.ac           |    2 +-
 gdb/gdbserver/config.in    |    3 +++
 gdb/gdbserver/configure    |    2 +-
 gdb/gdbserver/configure.ac |    2 +-
 6 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/gdb/config.in b/gdb/config.in
index 0f795c6..0f6ccb8 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -222,6 +222,9 @@
 /* Define to 1 if you have the <link.h> header file. */
 #undef HAVE_LINK_H
 
+/* Define to 1 if you have the <linux/perf_event.h> header file. */
+#undef HAVE_LINUX_PERF_EVENT_H
+
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
diff --git a/gdb/configure b/gdb/configure
index 90927ff..f9e748b 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -8878,7 +8878,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
 		  sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
 		  sys/types.h sys/wait.h wait.h termios.h termio.h \
 		  sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
-		  dlfcn.h sys/socket.h sys/un.h
+		  dlfcn.h sys/socket.h sys/un.h linux/perf_event.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/gdb/configure.ac b/gdb/configure.ac
index b33de61..19a0716 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1046,7 +1046,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \
 		  sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
 		  sys/types.h sys/wait.h wait.h termios.h termio.h \
 		  sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \
-		  dlfcn.h sys/socket.h sys/un.h])
+		  dlfcn.h sys/socket.h sys/un.h linux/perf_event.h])
 AC_CHECK_HEADERS(link.h, [], [],
 [#if HAVE_SYS_TYPES_H
 # include <sys/types.h>
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index bacf005..19b7a6c 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -76,6 +76,9 @@
 /* Define to 1 if you have the <linux/elf.h> header file. */
 #undef HAVE_LINUX_ELF_H
 
+/* Define to 1 if you have the <linux/perf_event.h> header file. */
+#undef HAVE_LINUX_PERF_EVENT_H
+
 /* Define if the target supports register sets. */
 #undef HAVE_LINUX_REGSETS
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index 69953c2..b524808 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4419,7 +4419,7 @@ $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cach
   cd "$ac_popdir"
 
 
-for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h 		 proc_service.h sys/procfs.h thread_db.h linux/elf.h 		 stdlib.h unistd.h 		 errno.h fcntl.h signal.h sys/file.h malloc.h 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h 		 netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h
+for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h 		 proc_service.h sys/procfs.h thread_db.h linux/elf.h 		 stdlib.h unistd.h 		 errno.h fcntl.h signal.h sys/file.h malloc.h 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h 		 netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h linux/perf_event.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index dc3c3cd..167116f 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -55,7 +55,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 stdlib.h unistd.h dnl
 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
-		 netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h)
+		 netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h linux/perf_event.h)
 AC_CHECK_FUNCS(pread pwrite pread64 readlink)
 AC_REPLACE_FUNCS(vasprintf vsnprintf)
 
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 03/16] source: add flags to print_source_lines ()
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (10 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 12/16] gdbserver, btrace: add generic btrace support markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-09-11 20:14   ` Tom Tromey
  2012-08-14 13:01 ` [patch v3 04/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

The 4th parameter of print_source_lines is a boolean flag noerror. Generalize
this to be a bit vector of flags and make noerror one of the flag bits.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* symtab.h (print_source_lines_flags): New enum.
	* source.c (print_source_lines_base): Change noerror to flags.
	(print_source_lines): Change noerror to flags.


---
 gdb/source.c |   16 ++++++++--------
 gdb/symtab.h |   11 ++++++++++-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/gdb/source.c b/gdb/source.c
index 0ff0782..d4616be 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1245,10 +1245,9 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
 /* Print source lines from the file of symtab S,
    starting with line number LINE and stopping before line number STOPLINE.  */
 
-static void print_source_lines_base (struct symtab *s, int line, int stopline,
-				     int noerror);
 static void
-print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines_base (struct symtab *s, int line, int stopline,
+			 enum print_source_lines_flags flags)
 {
   int c;
   int desc;
@@ -1276,13 +1275,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
       else
 	{
 	  desc = last_source_error;
-	  noerror = 1;
+	  flags |= PRINT_SOURCE_LINES_NOERROR;
 	}
     }
   else
     {
       desc = last_source_error;
-      noerror = 1;
+	  flags |= PRINT_SOURCE_LINES_NOERROR;
       noprint = 1;
     }
 
@@ -1290,7 +1289,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
     {
       last_source_error = desc;
 
-      if (!noerror)
+      if (!(flags & PRINT_SOURCE_LINES_NOERROR))
 	{
 	  char *name = alloca (strlen (s->filename) + 100);
 	  sprintf (name, "%d\t%s", line, s->filename);
@@ -1376,9 +1375,10 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int noerror)
    window otherwise it is simply printed.  */
 
 void
-print_source_lines (struct symtab *s, int line, int stopline, int noerror)
+print_source_lines (struct symtab *s, int line, int stopline,
+		    enum print_source_lines_flags flags)
 {
-  print_source_lines_base (s, line, stopline, noerror);
+  print_source_lines_base (s, line, stopline, flags);
 }
 \f
 /* Print info on range of pc's in a specified line.  */
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 76120a3..750da2a 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1141,7 +1141,16 @@ extern void clear_solib (void);
 
 extern int identify_source_line (struct symtab *, int, int, CORE_ADDR);
 
-extern void print_source_lines (struct symtab *, int, int, int);
+/* Flags passed as 4th argument to print_source_lines.  */
+
+enum print_source_lines_flags
+  {
+    /* Do not print an error message.  */
+    PRINT_SOURCE_LINES_NOERROR = (1 << 0)
+  };
+
+extern void print_source_lines (struct symtab *, int, int,
+				enum print_source_lines_flags);
 
 extern void forget_cached_source_info_for_objfile (struct objfile *);
 extern void forget_cached_source_info (void);
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 00/16] branch tracing support for Atom
@ 2012-08-14 13:01 markus.t.metzger
  2012-08-14 13:00 ` [patch v3 01/16] gdbserver, build: add -DGDBSERVER markus.t.metzger
                   ` (15 more replies)
  0 siblings, 16 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

If I counted correctly, this is the third version, not counting the identical
resend of the first version.

I incorporated review comments from Jan and Tom.

There are still open points regarding documentation, which is completely
missing, and a comment from Tom about the cli, on which the communication got
stuck.

There's a new patch at the end of the series to restrict the feature to Atom
processors using a cpuid whitelist.

The first four patches are generic and may find usage outside of this
series. Maybe there's a chance to approve them independently so the series gets
less intimidating to review.


Here's an overview of the feature:

Branch tracing is very useful to debug problems that do not immediatly result in
a crash. It is particularly useful for bugs that make other debugger features
fail, e.g. a corrupted stack that breaks unwinding.

In comparison with reverse debugging, branch tracing is less powerful but
faster. In addition, the list view (see below) provides a quick overview of
where you are, comparable with the backtrace command.


This series adds commands to enable/disable branch tracing as well as to display
the recorded trace. I do expect some discussion around the commands and their
exact spelling and would therefore postpone documentation.

  - "btrace enable/disable" perform the obvious operation

    They accept an optional range argument specifying the range of threads to
    enable/disable branch tracing for. If no argument is given, they target the
    current thread.

    They further accept the following arguments:

      all    targets all threads
      auto   turns automatic enabling for new threads on/off

  - "btrace list" prints the blocks that have been traced; one line per block.

    The output may be configured using modifiers (default: /fl). It prints:
         the block number
      /a the begin and end code address of that block
      /f the function containing the block
      /l the source lines contained in the block

    It accepts an optional range argument specifying the range of blocks to be
    listed. If no argument is given, all blocks are listed.

    Blocks are ordered from newest to oldest; block 1 always contains the
    current location.

      (gdb) btrace list 24-34
      24     in stdio_file_flush () at ../../../git/gdb/ui-file.c:525-529
      25     in ui_file_data () at ../../../git/gdb/ui-file.c:175-180
      26     in stdio_file_flush () at ../../../git/gdb/ui-file.c:522-523
      27     in gdb_flush () at ../../../git/gdb/ui-file.c:185
      28     in gdb_wait_for_event () at ../../../git/gdb/event-loop.c:840-847
      29     in gdb_do_one_event () at ../../../git/gdb/event-loop.c:461
      30     in gdb_do_one_event () at ../../../git/gdb/event-loop.c:453
      31     in process_event () at ../../../git/gdb/event-loop.c:407
      32     in process_event () at ../../../git/gdb/event-loop.c:361-367
      33     in process_event () at ../../../git/gdb/event-loop.c:1041-1043
      34     in process_event () at ../../../git/gdb/event-loop.c:1041-1045

  - "btrace" prints the branch trace disassembly

    Branch trace is printed block-by-block. Typically, one block at a time is
    printed. Repeated commands will iterate over all blocks similar to the list
    command.

    It supports the /m and /r modifiers accepted by the disassemble command.

    It accepts an optional range argument specifying the range of blocks to be
    printed. If more than one block is given, blocks are printed in reverse
    order to preserve the original control flow.

      (gdb) btrace /m 25
      ../../../git/gdb/ui-file.c:175	{
         0x0000000000635410 <ui_file_data+0>:	sub    $0x8,%rsp
      
      ../../../git/gdb/ui-file.c:176	  if (file->magic != &ui_file_magic)
         0x0000000000635414 <ui_file_data+4>:	cmpq   $0xb33b94,(%rdi)
         0x000000000063541b <ui_file_data+11>:	jne    0x635426 <ui_file_data+22>
      
      ../../../git/gdb/ui-file.c:177	    internal_error (__FILE__, __LINE__,
         0x000000000063541d <ui_file_data+13>:	mov    0x50(%rdi),%rax
      
      ../../../git/gdb/ui-file.c:178			    _("ui_file_data: bad magic number"));
      ../../../git/gdb/ui-file.c:179	  return file->to_data;
      ../../../git/gdb/ui-file.c:180	}
         0x0000000000635421 <ui_file_data+17>:	add    $0x8,%rsp
         0x0000000000635425 <ui_file_data+21>:	retq   

    Mixed source and disassembly does not work very well for inlined functions,
    a problem that it shares with the disassemble command.


Barkha Ahuja (1):
  test, btrace: more branch tracing tests

Markus Metzger (15):
  gdbserver, build: add -DGDBSERVER
  disas: add precise instructions flag
  source: add flags to print_source_lines ()
  source, disasm: optionally prefix source lines with filename
  thread, btrace: add generic branch trace support
  cli, btrace: add btrace cli
  configure: add check for perf_event header
  linux, btrace: perf_event based branch tracing
  linux, i386, amd64: enable btrace for 32bit and 64bit linux native
  xml, btrace: define btrace xml document style
  remote, btrace: add branch trace remote ops
  gdbserver, btrace: add generic btrace support
  gdbserver, linux, btrace: add btrace support for linux-low
  test, btrace: add branch tracing tests
  btrace, x86: restrict to Atom

 gdb/Makefile.in                                  |   13 +-
 gdb/amd64-linux-nat.c                            |   51 ++
 gdb/btrace.c                                     |  866 ++++++++++++++++++++++
 gdb/btrace.h                                     |   77 ++
 gdb/command.h                                    |    2 +-
 gdb/common/btrace-common.h                       |   56 ++
 gdb/common/linux-btrace.c                        |  382 ++++++++++
 gdb/common/linux-btrace.h                        |   76 ++
 gdb/config.in                                    |    3 +
 gdb/config/i386/linux.mh                         |    3 +-
 gdb/config/i386/linux64.mh                       |    2 +-
 gdb/configure                                    |    2 +-
 gdb/configure.ac                                 |    2 +-
 gdb/disasm.c                                     |   38 +-
 gdb/disasm.h                                     |    8 +-
 gdb/features/btrace.dtd                          |   12 +
 gdb/gdbserver/Makefile.in                        |   33 +-
 gdb/gdbserver/config.in                          |    3 +
 gdb/gdbserver/configure                          |    2 +-
 gdb/gdbserver/configure.ac                       |    2 +-
 gdb/gdbserver/configure.srv                      |   34 +-
 gdb/gdbserver/gdbthread.h                        |    5 +
 gdb/gdbserver/inferiors.c                        |    3 +
 gdb/gdbserver/linux-low.c                        |   44 ++
 gdb/gdbserver/linux-low.h                        |    2 +
 gdb/gdbserver/linux-x86-low.c                    |   31 +
 gdb/gdbserver/server.c                           |  167 +++++
 gdb/gdbserver/target.h                           |   33 +
 gdb/gdbthread.h                                  |    4 +
 gdb/i386-linux-nat.c                             |   51 ++
 gdb/i386-linux-tdep.c                            |   34 +
 gdb/i386-linux-tdep.h                            |    3 +
 gdb/infcmd.c                                     |    2 +
 gdb/remote.c                                     |  157 ++++
 gdb/source.c                                     |   21 +-
 gdb/symtab.h                                     |   14 +-
 gdb/target.c                                     |   89 +++
 gdb/target.h                                     |   39 +-
 gdb/testsuite/Makefile.in                        |    3 +-
 gdb/testsuite/configure                          |    3 +-
 gdb/testsuite/configure.ac                       |    2 +-
 gdb/testsuite/gdb.base/page.exp                  |    3 +-
 gdb/testsuite/gdb.btrace/Makefile.in             |   13 +
 gdb/testsuite/gdb.btrace/a.S                     |   23 +
 gdb/testsuite/gdb.btrace/allthreads_trace.exp    |  345 +++++++++
 gdb/testsuite/gdb.btrace/amd64-thr-callback.S    |  116 +++
 gdb/testsuite/gdb.btrace/b.S                     |   23 +
 gdb/testsuite/gdb.btrace/dec.c                   |   23 +
 gdb/testsuite/gdb.btrace/decrement.S             |   32 +
 gdb/testsuite/gdb.btrace/decrement.exp           |  141 ++++
 gdb/testsuite/gdb.btrace/disable_all.exp         |  279 +++++++
 gdb/testsuite/gdb.btrace/enable.exp              |   94 +++
 gdb/testsuite/gdb.btrace/enable_all.exp          |  282 +++++++
 gdb/testsuite/gdb.btrace/enable_range.exp        |  281 +++++++
 gdb/testsuite/gdb.btrace/i386-thr-callback.S     |  116 +++
 gdb/testsuite/gdb.btrace/inc.c                   |   23 +
 gdb/testsuite/gdb.btrace/list.exp                |  175 +++++
 gdb/testsuite/gdb.btrace/list_function.c         |   31 +
 gdb/testsuite/gdb.btrace/list_function.exp       |   50 ++
 gdb/testsuite/gdb.btrace/list_options.exp        |  107 +++
 gdb/testsuite/gdb.btrace/main.S                  |   36 +
 gdb/testsuite/gdb.btrace/main_asm.exp            |  109 +++
 gdb/testsuite/gdb.btrace/main_segv.S             |   32 +
 gdb/testsuite/gdb.btrace/main_segv.exp           |   84 +++
 gdb/testsuite/gdb.btrace/threads.c               |   96 +++
 gdb/testsuite/gdb.btrace/threads_asm.c           |   78 ++
 gdb/testsuite/gdb.btrace/threads_auto.exp        |  123 +++
 gdb/testsuite/gdb.btrace/threads_independent.exp |  125 ++++
 gdb/testsuite/gdb.btrace/threads_nonstop.exp     |  231 ++++++
 gdb/testsuite/gdb.btrace/trace_iteration.exp     |  265 +++++++
 gdb/testsuite/gdb.btrace/x86-list.S              |   70 ++
 gdb/testsuite/lib/btrace.exp                     |   78 ++
 gdb/thread.c                                     |    4 +
 73 files changed, 5796 insertions(+), 66 deletions(-)
 create mode 100644 gdb/btrace.c
 create mode 100644 gdb/btrace.h
 create mode 100644 gdb/common/btrace-common.h
 create mode 100644 gdb/common/linux-btrace.c
 create mode 100644 gdb/common/linux-btrace.h
 create mode 100644 gdb/features/btrace.dtd
 create mode 100755 gdb/testsuite/gdb.btrace/Makefile.in
 create mode 100755 gdb/testsuite/gdb.btrace/a.S
 create mode 100755 gdb/testsuite/gdb.btrace/allthreads_trace.exp
 create mode 100755 gdb/testsuite/gdb.btrace/amd64-thr-callback.S
 create mode 100755 gdb/testsuite/gdb.btrace/b.S
 create mode 100644 gdb/testsuite/gdb.btrace/dec.c
 create mode 100755 gdb/testsuite/gdb.btrace/decrement.S
 create mode 100755 gdb/testsuite/gdb.btrace/decrement.exp
 create mode 100755 gdb/testsuite/gdb.btrace/disable_all.exp
 create mode 100644 gdb/testsuite/gdb.btrace/enable.exp
 create mode 100755 gdb/testsuite/gdb.btrace/enable_all.exp
 create mode 100755 gdb/testsuite/gdb.btrace/enable_range.exp
 create mode 100755 gdb/testsuite/gdb.btrace/i386-thr-callback.S
 create mode 100644 gdb/testsuite/gdb.btrace/inc.c
 create mode 100644 gdb/testsuite/gdb.btrace/list.exp
 create mode 100644 gdb/testsuite/gdb.btrace/list_function.c
 create mode 100644 gdb/testsuite/gdb.btrace/list_function.exp
 create mode 100755 gdb/testsuite/gdb.btrace/list_options.exp
 create mode 100755 gdb/testsuite/gdb.btrace/main.S
 create mode 100755 gdb/testsuite/gdb.btrace/main_asm.exp
 create mode 100755 gdb/testsuite/gdb.btrace/main_segv.S
 create mode 100755 gdb/testsuite/gdb.btrace/main_segv.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads.c
 create mode 100755 gdb/testsuite/gdb.btrace/threads_asm.c
 create mode 100755 gdb/testsuite/gdb.btrace/threads_auto.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads_independent.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads_nonstop.exp
 create mode 100755 gdb/testsuite/gdb.btrace/trace_iteration.exp
 create mode 100644 gdb/testsuite/gdb.btrace/x86-list.S
 create mode 100644 gdb/testsuite/lib/btrace.exp

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 13/16] gdbserver, linux, btrace: add btrace support for linux-low
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (3 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 07/16] configure: add check for perf_event header markus.t.metzger
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Implement btrace target ops in target linux-low using the common linux-btrace
functions.

Add linux-btrace.o to all targets that link linux-low.o. I'd rather not link it
to targets that do not support branch tracing, but this would require changing
the way target ops are defined for gdbserver.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

gdbserver/
	* linux-low: Include linux-btrace.h.
	(linux_low_enable_btrace): New function.
	(linux_low_read_btrace): New function.
	(linux_target_ops): Add btrace ops.
	* configure.srv: Add linux-btrace.o.


---
 gdb/gdbserver/configure.srv |   34 +++++++++++++++++-----------------
 gdb/gdbserver/linux-low.c   |   31 +++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index d1e04a9..ae247b8 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -47,7 +47,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} arm-with-vfpv3.o"
 			srv_regobj="${srv_regobj} arm-with-neon.o"
 			srv_tgtobj="linux-low.o linux-osdata.o linux-arm-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_xmlfiles="arm-with-iwmmxt.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
@@ -70,19 +70,19 @@ case "${target}" in
 			;;
   bfin-*-*linux*)	srv_regobj=reg-bfin.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-bfin-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-crisv32-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   cris-*-linux*)	srv_regobj=reg-cris.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-cris-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
@@ -97,7 +97,7 @@ case "${target}" in
 			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
 			fi
 			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -129,12 +129,12 @@ case "${target}" in
 			;;
   ia64-*-linux*)	srv_regobj=reg-ia64.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-ia64-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			;;
   m32r*-*-linux*)	srv_regobj=reg-m32r.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-m32r-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
  			srv_linux_thread_db=yes
 			;;
@@ -144,7 +144,7 @@ case "${target}" in
                           srv_regobj=reg-m68k.o
                         fi
 			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -155,7 +155,7 @@ case "${target}" in
                           srv_regobj=reg-m68k.o
                         fi
 			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -165,7 +165,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} mips64-linux.o"
 			srv_regobj="${srv_regobj} mips64-dsp-linux.o"
 			srv_tgtobj="linux-low.o linux-osdata.o linux-mips-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_xmlfiles="mips-linux.xml"
 			srv_xmlfiles="${srv_xmlfiles} mips-dsp-linux.xml"
 			srv_xmlfiles="${srv_xmlfiles} mips-cpu.xml"
@@ -198,7 +198,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o"
 			srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
 			srv_tgtobj="linux-low.o linux-osdata.o linux-ppc-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_xmlfiles="rs6000/powerpc-32l.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-altivec32l.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-cell32l.xml"
@@ -241,7 +241,7 @@ case "${target}" in
 			srv_regobj="${srv_regobj} s390x-linux64v1.o"
 			srv_regobj="${srv_regobj} s390x-linux64v2.o"
 			srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_xmlfiles="s390-linux32.xml"
 			srv_xmlfiles="${srv_xmlfiles} s390-linux32v1.xml"
 			srv_xmlfiles="${srv_xmlfiles} s390-linux32v2.xml"
@@ -262,14 +262,14 @@ case "${target}" in
 			;;
   sh*-*-linux*)		srv_regobj=reg-sh.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-sh-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   sparc*-*-linux*)	srv_regobj=reg-sparc64.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-sparc-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
@@ -286,14 +286,14 @@ case "${target}" in
 			srv_xmlfiles="${srv_xmlfiles} tic6x-gp.xml"
 			srv_xmlfiles="${srv_xmlfiles} tic6x-c6xp.xml"
   			srv_tgtobj="linux-low.o linux-osdata.o linux-tic6x-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_regsets=yes
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
   x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
 			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
 			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
@@ -308,7 +308,7 @@ case "${target}" in
 
   xtensa*-*-linux*)	srv_regobj=reg-xtensa.o
 			srv_tgtobj="linux-low.o linux-osdata.o linux-xtensa-low.o linux-procfs.o"
-			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+			srv_tgtobj="${srv_tgtobj} linux-ptrace.o linux-btrace.o"
 			srv_linux_regsets=yes
 			;;
   tilegx-*-linux*)	srv_regobj=reg-tilegx.o
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index a476031..20b1ca5 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,7 @@
 #include "linux-low.h"
 #include "linux-osdata.h"
 #include "agent.h"
+#include "linux-btrace.h"
 
 #include <sys/wait.h>
 #include <stdio.h>
@@ -5792,6 +5793,31 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
   return len;
 }
 
+/* Read branch trace data for @tinfo as btrace xml document into @buffer.  */
+static void
+linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer)
+{
+  VEC (btrace_block_s) *btrace;
+  struct btrace_block *block;
+  int i;
+
+  if (!tinfo->ptr_bits)
+    tinfo->ptr_bits = register_size (0) * 8;
+
+  btrace = linux_read_btrace (tinfo);
+
+  buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
+  buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+
+  for (i = 0; VEC_iterate (btrace_block_s, btrace, i, block); i++)
+    buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+		       paddress (block->begin), paddress (block->end));
+
+  buffer_grow_str (buffer, "</btrace>\n");
+
+  VEC_free (btrace_block_s, btrace);
+}
+
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_attach,
@@ -5856,6 +5882,11 @@ static struct target_ops linux_target_ops = {
   linux_get_min_fast_tracepoint_insn_len,
   linux_qxfer_libraries_svr4,
   linux_supports_agent,
+  linux_supports_btrace,
+  linux_enable_btrace,
+  linux_disable_btrace,
+  linux_btrace_has_changed,
+  linux_low_read_btrace,
 };
 
 static void
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 12/16] gdbserver, btrace: add generic btrace support
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (9 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 11/16] remote, btrace: add branch trace remote ops markus.t.metzger
@ 2012-08-14 13:01 ` markus.t.metzger
  2012-08-14 13:01 ` [patch v3 03/16] source: add flags to print_source_lines () markus.t.metzger
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:01 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add support to gdbserver to understand branch trace related packages.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

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_btrace_enable): New function.
	(handle_btrace_disable): 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    |  167 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/target.h    |   33 +++++++++
 4 files changed, 208 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 547552f..f51845f 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -444,6 +444,82 @@ write_qxfer_response (char *buf, const void *data, int len, int is_more)
 
 /* Handle all of the extended 'Q' packets.  */
 
+/* Handle btrace enabling.  */
+static int
+handle_btrace_enable (char *ptid_str)
+{
+  ptid_t ptid = read_ptid (ptid_str, NULL);
+  struct thread_info *thread = find_thread_ptid (ptid);
+  int err = 1;
+
+  if (!thread)
+    fprintf (stderr, "No such thread: %s.\n", ptid_str);
+  else if (thread->btrace)
+    fprintf (stderr, "Btrace already enabled for %s.\n", ptid_str);
+  else if (!the_target->enable_btrace)
+    fprintf (stderr, "Target does not support branch tracing.");
+  else
+    {
+      thread->btrace = target_enable_btrace (thread->entry.id);
+      if (!thread->btrace)
+        fprintf (stderr, "Could not enable btrace for %s.\n", ptid_str);
+      else
+        err = 0;
+    }
+
+  return err;
+}
+
+/* Handle btrace disabling.  */
+static int
+handle_btrace_disable (char *ptid_str)
+{
+  ptid_t ptid = read_ptid (ptid_str, NULL);
+  struct thread_info *thread = find_thread_ptid (ptid);
+  int err = 1;
+
+  if (!thread)
+    fprintf (stderr, "No such thread: %s.\n", ptid_str);
+  else if (!thread->btrace)
+    fprintf (stderr, "Branch tracing not enabled for %s.\n", ptid_str);
+  else if (!the_target->disable_btrace)
+    fprintf (stderr, "Target does not support branch tracing.");
+  else if (target_disable_btrace (thread->btrace) != 0)
+    fprintf (stderr, "Could not disable branch tracing for %s.\n", ptid_str);
+  else
+    {
+      thread->btrace = NULL;
+      err = 0;
+    }
+
+  return err;
+}
+
+/* Handle the "Qbtrace" packet.  */
+static int
+handle_btrace_general_set (char *own_buf)
+{
+  char *operation = own_buf + strlen ("Qbtrace:");
+  int err = 1;
+
+  if (strncmp ("Qbtrace:", own_buf, strlen ("Qbtrace:")) != 0)
+    return 0;
+
+  if (strncmp ("on:", operation, strlen ("on:")) == 0)
+    err = handle_btrace_enable (operation + strlen ("on:"));
+  else if (strncmp ("off:", operation, strlen ("off:")) == 0)
+    err = handle_btrace_disable (operation + strlen ("off:"));
+  else
+    fprintf (stderr, "Unknown btrace operation: %s. Use on or off.\n", own_buf);
+
+  if (err)
+    write_enn (own_buf);
+  else
+    write_ok (own_buf);
+
+  return 1;
+}
+
 static void
 handle_general_set (char *own_buf)
 {
@@ -598,6 +674,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;
@@ -1296,6 +1375,55 @@ handle_qxfer_fdpic (const char *annex, gdb_byte *readbuf,
   return (*the_target->read_loadmap) (annex, offset, readbuf, len);
 }
 
+/* Handle branch trace data transfer.  */
+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;
+
+  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);
+
+      target_read_btrace (thread->btrace, &cache);
+    }
+  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 },
@@ -1309,6 +1437,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
@@ -1465,6 +1594,34 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
 
 /* Handle all of the extended 'q' packets.  */
 
+/* Handle the "qbtrace" packet.  */
+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)
 {
@@ -1692,6 +1849,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;
     }
 
@@ -1882,6 +2046,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 9f96e04..952c973 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,22 @@ 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.  */
+  void (*read_btrace) (struct btrace_target_info *, struct buffer *);
 };
 
 extern struct target_ops *the_target;
@@ -520,6 +538,21 @@ int kill_inferior (int);
   (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) (ptid)
+
+#define target_disable_btrace(tinfo)            \
+  (*the_target->disable_btrace) (tinfo)
+
+#define target_btrace_has_changed(tinfo)        \
+  (*the_target->btrace_has_changed) (tinfo)
+
+#define target_read_btrace(tinfo, buffer)       \
+  (*the_target->read_btrace) (tinfo, buffer)
+
 /* Start non-stop mode, returns 0 on success, -1 on failure.   */
 
 int start_non_stop (int nonstop);
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 14/16] test, btrace: add branch tracing tests
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (14 preceding siblings ...)
  2012-08-14 13:03 ` [patch v3 06/16] cli, btrace: add btrace cli markus.t.metzger
@ 2012-08-14 13:03 ` markus.t.metzger
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:03 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add tests covering btrace enable/disable/auto and btrace list.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

testsuite/
	* configure.ac: Add gdb.btrace makefile.
	* configure: Regenerated.
	* lib/btrace.exp: New file.
	* gdb.btrace/Makefile.in: New file.
	* gdb.btrace/enable.exp: New file.
	* gdb.btrace/list.exp: New file.
	* gdb.btrace/x86-list.S: New file.


---
 gdb/testsuite/Makefile.in                  |    3 +-
 gdb/testsuite/configure                    |    3 +-
 gdb/testsuite/configure.ac                 |    2 +-
 gdb/testsuite/gdb.btrace/Makefile.in       |   13 ++
 gdb/testsuite/gdb.btrace/dec.c             |   23 ++++
 gdb/testsuite/gdb.btrace/enable.exp        |   94 +++++++++++++++
 gdb/testsuite/gdb.btrace/inc.c             |   23 ++++
 gdb/testsuite/gdb.btrace/list.exp          |  175 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.btrace/list_function.c   |   31 +++++
 gdb/testsuite/gdb.btrace/list_function.exp |   50 ++++++++
 gdb/testsuite/gdb.btrace/x86-list.S        |   70 +++++++++++
 gdb/testsuite/lib/btrace.exp               |   78 ++++++++++++
 12 files changed, 562 insertions(+), 3 deletions(-)
 create mode 100755 gdb/testsuite/gdb.btrace/Makefile.in
 create mode 100644 gdb/testsuite/gdb.btrace/dec.c
 create mode 100644 gdb/testsuite/gdb.btrace/enable.exp
 create mode 100644 gdb/testsuite/gdb.btrace/inc.c
 create mode 100644 gdb/testsuite/gdb.btrace/list.exp
 create mode 100644 gdb/testsuite/gdb.btrace/list_function.c
 create mode 100644 gdb/testsuite/gdb.btrace/list_function.exp
 create mode 100644 gdb/testsuite/gdb.btrace/x86-list.S
 create mode 100644 gdb/testsuite/lib/btrace.exp

diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in
index fab124e..62fcd1f 100644
--- a/gdb/testsuite/Makefile.in
+++ b/gdb/testsuite/Makefile.in
@@ -33,7 +33,8 @@ SHELL = @SHELL@
 EXEEXT = @EXEEXT@
 SUBDIRS = @subdirs@
 RPATH_ENVVAR = @RPATH_ENVVAR@
-ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.cell gdb.cp gdb.disasm \
+ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.btrace gdb.cell \
+	gdb.cp gdb.disasm \
 	gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
 	gdb.java gdb.linespec gdb.mi gdb.modula2 gdb.multi \
 	gdb.objc gdb.opencl gdb.opt gdb.pascal gdb.python gdb.server \
diff --git a/gdb/testsuite/configure b/gdb/testsuite/configure
index 0c8c344..a40c144 100755
--- a/gdb/testsuite/configure
+++ b/gdb/testsuite/configure
@@ -3448,7 +3448,7 @@ done
 
 
 
-ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
+ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -4153,6 +4153,7 @@ do
     "gdb.arch/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.arch/Makefile" ;;
     "gdb.asm/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.asm/Makefile" ;;
     "gdb.base/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.base/Makefile" ;;
+    "gdb.btrace/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.btrace/Makefile" ;;
     "gdb.cell/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.cell/Makefile" ;;
     "gdb.cp/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.cp/Makefile" ;;
     "gdb.disasm/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.disasm/Makefile" ;;
diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac
index d9ab9f7..1884b64 100644
--- a/gdb/testsuite/configure.ac
+++ b/gdb/testsuite/configure.ac
@@ -89,7 +89,7 @@ AC_EXEEXT
 
 AC_OUTPUT([Makefile \
   gdb.ada/Makefile \
-  gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile \
+  gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile \
   gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile \
   gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile \
   gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile \
diff --git a/gdb/testsuite/gdb.btrace/Makefile.in b/gdb/testsuite/gdb.btrace/Makefile.in
new file mode 100755
index 0000000..16afe0a
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/Makefile.in
@@ -0,0 +1,13 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+.PHONY: all clean mostlyclean distclean realclean
+
+all info install-info dvi install uninstall installcheck check:
+	@echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+	-rm -f *.o *.x *.diff *~ *.bad core
+
+distclean maintainer-clean realclean: clean
+	-rm -f Makefile config.status config.log gdb.log gdb.sum
diff --git a/gdb/testsuite/gdb.btrace/dec.c b/gdb/testsuite/gdb.btrace/dec.c
new file mode 100644
index 0000000..5b9187e
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/dec.c
@@ -0,0 +1,23 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+extern int dec (int x)
+{
+    return x - 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp
new file mode 100644
index 0000000..ab4bd0e
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable.exp
@@ -0,0 +1,94 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+    verbose "Tests ignored for all but x86 based targets."
+    return
+}
+
+load_lib btrace.exp
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+
+# automatic enabling can be turned on without an inferior
+gdb_test_no_output "btrace enable auto" "btrace enable 1.0"
+
+# we cannot enable it twice
+gdb_test "btrace enable auto" "Automatic branch trace enabling already on." "btrace enable 1.1"
+
+# but we can disable it
+gdb_test_no_output "btrace disable auto" "btrace enable 1.2"
+
+# we cannot disable it twice
+gdb_test "btrace disable auto" "Automatic branch trace enabling already off." "btrace enable 1.3"
+
+# we cannot enable/disable trace without a thread
+gdb_test "btrace enable"  "Couldn't enable branch tracing: no inferior thread."  "btrace enable 2.0"
+gdb_test "btrace disable" "Couldn't disable branch tracing: no inferior thread." "btrace enable 2.1"
+
+# we don't have trace, yet
+gdb_test "btrace" "No thread\." "btrace enable 2.2"
+gdb_test "btrace /m" "No thread\." "btrace enable 2.3"
+gdb_test "btrace list /fal" "No thread\." "btrace enable 2.4"
+gdb_test "btrace list /t" "No thread\." "btrace enable 2.5"
+
+set testfile "x86-list"
+
+# start a debuggee program
+if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+    untested ${testfile}.exp
+    return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# automatic enabling is off.
+if ![runto test_1] {
+	fail "runto test function, 1"
+	return -1
+}
+
+# since we support btrace, we should be able to enable it
+gdb_test_no_output "btrace enable" "btrace enable 3.0"
+
+# btrace is now enabled; we should not be able to enable it twice
+gdb_test "btrace enable" "Branch tracing already enabled.*" "btrace enable 3.1"
+
+# btrace is still enabled; we should be able to disable it
+gdb_test_no_output "btrace disable" "btrace enable 3.2"
+
+# btrace is now disabled; we should not be able to disable it twice
+gdb_test "btrace disable" "Branch tracing not enabled.*" "btrace enable 3.3"
+
+# rerun with automatic enabling on
+gdb_test_no_output "btrace enable auto"
+if ![runto test_1] {
+	fail "runto test function, 2"
+	return -1
+}
+
+# btrace is implicitly enabled; we should not be able to enable it twice
+gdb_test "btrace enable" "Branch tracing already enabled.*" "btrace enable 4.0"
+
+return 0
diff --git a/gdb/testsuite/gdb.btrace/inc.c b/gdb/testsuite/gdb.btrace/inc.c
new file mode 100644
index 0000000..a012268
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/inc.c
@@ -0,0 +1,23 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+extern int inc (int x)
+{
+    return x + 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/list.exp b/gdb/testsuite/gdb.btrace/list.exp
new file mode 100644
index 0000000..169764c
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list.exp
@@ -0,0 +1,175 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+    verbose "Tests ignored for all but x86 based targets."
+    return
+}
+
+load_lib btrace.exp
+
+set testfile "x86-list"
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+    untested ${testfile}.exp
+    return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Automatically enable branch tracing.
+gdb_test_no_output "btr enable auto"
+
+# Make sure we don't die when enabling trace for a newly created thread.
+if ![runto test_1] {
+	fail "runto test function, 1"
+	return -1
+}
+
+# we expect some trace at this point, but we don't really know how much or how
+# it would look like. Ignore it.
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.1"
+
+# We assume 5 bytes for call.
+gdb_test "stepi" "0x0*400215 in test_1.*" ""
+
+# We assume 5 bytes for call.
+gdb_test "btr list /af" "
+1 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.2"
+
+gdb_test "stepi" "0x0*400200 in test_1_sub.*" ""
+gdb_test "stepi" "0x0*40021a in test_1.*" ""
+
+# We assume 5 bytes for call.
+gdb_test "btr list /af" "
+1 *0x0*40021a - 0x0*40021a in test_1 \\(\\)\r
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.3"
+
+# List a single block.
+gdb_test "btr list /af 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.4"
+
+# List a range of blocks.
+gdb_test "btr list /af 2-4" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)\r
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.5"
+
+# We ignore too big upper bounds.
+gdb_test "btr list /af 3-9" "
+3 *0x0*400215 - 0x0*400215 in test_1 \\(\\)\r
+4 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.6"
+
+# If the entire range is out of bounds, the list is empty.
+gdb_test "btr list /a 9-18" "" "btrace list 1.7"
+
+# Check modifiers individually
+gdb_test "btr list /a 2" "
+2 *0x0*400200 - 0x0*400200" "btrace list 1.8"
+
+gdb_test "btr list /f 2" "
+2 *in test_1_sub \\(\\)" "btrace list 1.9"
+
+# Check order of modifiers
+gdb_test "btr list /fa 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.10"
+
+gdb_test "btr list /f /a 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.11"
+
+gdb_test "btr list /a /f 2" "
+2 *0x0*400200 - 0x0*400200 in test_1_sub \\(\\)" "btrace list 1.12"
+
+
+# Proceed to the next test.
+gdb_breakpoint "test_2"
+gdb_continue_to_breakpoint "proceed to test 2" ".*test_2.*"
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400231 in test_2.*" ""
+
+# We have not seen a branch, yet, so there is no trace.
+gdb_test "btr list" "No trace\." "btrace list 2.1"
+
+gdb_test "stepi" "0x0*400220 in test_2_sub.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400220 in test_2_sub \\(\\)" "btrace list 2.2"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400221 in test_2_sub.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400221 in test_2_sub \\(\\)" "btrace list 2.3"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400222 in test_2_sub.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400220 - 0x0*400222 in test_2_sub \\(\\)" "btrace list 2.4"
+
+
+# Proceed to the next test.
+gdb_breakpoint "test_3"
+gdb_continue_to_breakpoint "proceed to test 3" ".*test_3.*"
+
+# Reset branch trace so we get predictable output.
+btrace_reset_trace
+
+gdb_test "stepi" "0x0*400260 in test_3.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.1"
+
+gdb_test "stepi" "0x0*400250 in test_3.*" ""
+
+gdb_test "btr list /af" "
+1 *0x0*400250 - 0x0*400250 in test_3 \\(\\)\r
+2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.2"
+
+# We assume 1 byte for nop.
+gdb_test "stepi" "0x0*400251 in test_3.*" ""
+
+# We assume 1 byte for nop.
+gdb_test "btr list /af" "
+1 *0x0*400250 - 0x0*400251 in test_3 \\(\\)\r
+2 *0x0*400260 - 0x0*400260 in test_3 \\(\\)" "btrace list 3.3"
+
+return 0
diff --git a/gdb/testsuite/gdb.btrace/list_function.c b/gdb/testsuite/gdb.btrace/list_function.c
new file mode 100644
index 0000000..b10ab34
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_function.c
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+extern int inc (int);
+extern int dec (int);
+
+extern int main (void)
+{
+    int x = 0;
+
+    x = inc (x);
+    x = dec (x);
+
+    return x; /* bp.1 */
+}
diff --git a/gdb/testsuite/gdb.btrace/list_function.exp b/gdb/testsuite/gdb.btrace/list_function.exp
new file mode 100644
index 0000000..c108b13
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_function.exp
@@ -0,0 +1,50 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib btrace.exp
+
+set testfile "list_function"
+set sources [list $testfile.c inc.c dec.c]
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+if [prepare_for_testing list_function.exp $testfile.x $sources {debug}] {
+     untested list_function.exp
+     return -1
+}
+
+if ![runto_main] then {
+	fail "runto test function, 1"
+	return -1
+}
+
+set bp_location [gdb_get_line_number "bp.1" $testfile.c]
+
+gdb_breakpoint $bp_location
+
+gdb_test_no_output "btr enable"
+
+gdb_continue_to_breakpoint "cont to $bp_location" ".*$testfile.c:$bp_location.*"
+
+gdb_test "btr list /f" "
+1 *in main \\(\\)\r
+2 *in dec \\(\\)\r
+3 *in main \\(\\)\r
+4 *in inc \\(\\)" "btrace list function 1.0"
+
+return 0
diff --git a/gdb/testsuite/gdb.btrace/x86-list.S b/gdb/testsuite/gdb.btrace/x86-list.S
new file mode 100644
index 0000000..7956db2
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/x86-list.S
@@ -0,0 +1,70 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+        .text
+        .globl _start
+        .globl main
+        .globl test_1
+        .globl test_2
+        .globl test_3
+        .align 0x100    # 0x400100
+_start:
+        call main
+        hlt
+
+        .align 0x10     # 0x400110
+main:
+        call test_1
+        call test_2
+        call test_3
+        ret
+
+        .align 0x100    # 0x400200
+test_1_sub:
+        ret
+
+        .align 0x10     # 0x400210
+test_1:
+        call test_1_sub
+        call test_1_sub
+        nop
+        ret
+
+        .align 0x10     # 0x400220
+test_2_sub:
+        nop
+        nop
+        ret
+
+        .align 0x10     # 0x400230
+test_2:
+        nop
+        call test_2_sub
+        ret
+
+        .align 0x10     # 0x400240
+test_3:
+        jmp .L3.1
+        .align 0x10     # 0x400250
+.L3.2:
+        nop
+        ret
+        .align 0x10     # 0x400260
+.L3.1:
+        jmp .L3.2
diff --git a/gdb/testsuite/lib/btrace.exp b/gdb/testsuite/lib/btrace.exp
new file mode 100644
index 0000000..eb516fa
--- /dev/null
+++ b/gdb/testsuite/lib/btrace.exp
@@ -0,0 +1,78 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+proc btrace_assemble { testfile } {
+    global srcdir
+    global objdir
+    global subdir
+
+    set srcfile ${srcdir}/${subdir}/${testfile}.S
+    set objfile ${objdir}/${subdir}/${testfile}.o
+    set binfile ${objdir}/${subdir}/${testfile}.x
+
+    if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return "" }
+
+    if {[target_link ${objfile} ${binfile} "-Ttext 0x400100"] != ""} { return "" }
+
+    return ${binfile}
+}
+
+proc skip_btrace_tests {} {
+    global gdb_prompt
+
+    set testfile "x86-list"
+    set skip 0
+
+    if { [set binfile [btrace_assemble ${testfile}]] == "" } {
+        return 1
+    }
+
+    gdb_exit
+    gdb_start
+    gdb_load $binfile
+
+    runto main
+
+    gdb_test_multiple "btrace enable" "check btrace support" {
+        -re "You can't do that when your target is.*\r\n$gdb_prompt $" {
+            xfail "check btrace support"
+            set skip 1
+        }
+        -re "Target does not support branch tracing.*\r\n$gdb_prompt $" {
+            xfail "check btrace support"
+            set skip 1
+        }
+        -re "Could not enable branch tracing.*\r\n$gdb_prompt $" {
+            xfail "check btrace support"
+            set skip 1
+        }
+        -re "$gdb_prompt $" {
+			pass "check btrace support"
+		}
+    }
+    gdb_exit
+    remote_file build delete $testfile
+
+    return $skip
+}
+
+proc btrace_reset_trace {} {
+    gdb_test_no_output "btr disable"
+    gdb_test_no_output "btr enable"
+
+    gdb_test "btr list" "No trace." "reset btrace"
+}
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 06/16] cli, btrace: add btrace cli
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (13 preceding siblings ...)
  2012-08-14 13:03 ` [patch v3 15/16] test, btrace: more branch tracing tests markus.t.metzger
@ 2012-08-14 13:03 ` markus.t.metzger
  2012-08-14 13:03 ` [patch v3 14/16] test, btrace: add branch tracing tests markus.t.metzger
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:03 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis,
	Markus Metzger

From: Markus Metzger <markus.t.metzger@intel.com>

Add branch trace commands:

  - "btrace enable/disable" perform the obvious operation

    ""     on the current thread.
    "all"  on each existing thread.
    "auto" on each newly created thread.

    Actually, "btrace enable auto" turns on automatic enabling for new threads,
    and "btrace disable auto" turns it off, again.

  - "btrace list" prints the blocks that have been traced.

    The output may be configured using modifiers. It prints:
      -  the block number
      /a the begin and end code address of that block
      /f the function containing the block
      /l the source lines contained in the block

    With the /t modifier, it prints the total number of blocks and exits.

    It accepts an optional range argument specifying the range of blocks to be
    listed. If no argument is given, all blocks are listed.

    The block number can be used to print the trace for one particular block or
    for a range of blocks.

  - "btrace" prints the branch trace disassembly for the current thread.

    Branch trace is printed block-by-block. Typically, one block at a time is
    printed.

    By default, the disassembly for the next block is printed, thus iterating
    over the full branch trace.

    The command supports the /m and /r modifiers accepted by the disassemble
    command.

    In addition, the command supports the following arguments:
      - "<n>"      set the iterator to the <n>-th block
      - "+[<n>]"   advance the iterator by <n>  (default: 1)
      - "-[<n>]"   advance the iterator by -<n> (default: 1)
      - "<l>-<h>"  set the iterator to the <h>'th block and
                   print the blocks in the range in reverse (i.e. original
                   control flow) order.

    Mixed source and disassembly does not work very well for inlined functions,
    a problem that it shares with the disassemble command.

2012-08-14 Markus Metzger <markus.t.metzger@intel.com>

	* command.h (enum command_class): Add class_btrace.
	* btrace.c (thread_callback): New function.
	(for_each_thread): New function.
	(warn_enable_btrace): New function.
	(warn_disable_btrace): New function.
	(enable_btrace_list): New function.
	(cmd_btrace_enable): New function.
	(cmd_btrace_enable_all): New function.
	(cmd_btrace_enable_auto): New function.
	(disable_btrace_list): New function.
	(cmd_btrace_disable): New function.
	(cmd_btrace_disable_all): New function.
	(cmd_btrace_disable_auto): New function.
	(do_btrace_list_address): New function.
	(do_btrace_list_function): New function.
	(do_btrace_list_line): New function.
	(do_btrace_list): New function.
	(cmd_btrace_list): New function.
	(do_btrace): New function.
	(do_btrace_range): New function.
	(do_prev_btrace): New function.
	(do_next_btrace): New function.
	(cmd_btrace): New function.
	(_initialize_btrace): New function.


---
 gdb/btrace.c                    |  602 +++++++++++++++++++++++++++++++++++++++
 gdb/command.h                   |    2 +-
 gdb/testsuite/gdb.base/page.exp |    3 +-
 3 files changed, 605 insertions(+), 2 deletions(-)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index 05fc627..0953be6 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -25,6 +25,28 @@
 #include "exceptions.h"
 #include "inferior.h"
 #include "target.h"
+#include "observer.h"
+#include "command.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-utils.h"
+#include "arch-utils.h"
+#include "disasm.h"
+#include "gdbarch.h"
+
+#include <ctype.h>
+#include <string.h>
+
+/* A new thread observer enabling branch tracing for the new thread.  */
+static struct observer *btrace_thread_observer;
+
+/* Branch tracing command list.  */
+static struct cmd_list_element *btcmdlist;
+
+/* Branch tracing enable command list.  */
+static struct cmd_list_element *btencmdlist;
+
+/* Branch tracing disable command list.  */
+static struct cmd_list_element *btdiscmdlist;
 
 /* See btrace.h.  */
 void
@@ -173,3 +195,583 @@ next_btrace (struct thread_info *tp)
 
   return VEC_index (btrace_block_s, btp->btrace, btp->iterator);
 }
+
+/* An iterate_over_threads callback to call a new thread observer function.  */
+static int
+thread_callback (struct thread_info *tp, void *arg)
+{
+  observer_new_thread_ftype *tfun = arg;
+
+  tfun (tp);
+
+  return 0;
+}
+
+/* Call @tfun for each thread.  */
+static void
+for_each_thread (observer_new_thread_ftype *tfun)
+{
+  iterate_over_threads (thread_callback, tfun);
+}
+
+/* Enable branch tracing. Turn errors into warnings.  */
+static void
+warn_enable_btrace (struct thread_info *tp)
+{
+  volatile struct gdb_exception error;
+
+  TRY_CATCH (error, RETURN_MASK_ERROR)
+    enable_btrace (tp);
+
+  if (error.message)
+    warning (_("%s"), error.message);
+}
+
+/* Disable branch tracing. Turn errors into warnings.  */
+static void
+warn_disable_btrace (struct thread_info *tp)
+{
+  volatile struct gdb_exception error;
+
+  TRY_CATCH (error, RETURN_MASK_ERROR)
+    disable_btrace (tp);
+
+  if (error.message)
+    warning (_("%s"), error.message);
+}
+
+/* Thread iteration callback to enable branch tracing if @tp is in the @arg
+   range of thread nums.  */
+static int
+enable_btrace_list (struct thread_info *tp, void *arg)
+{
+  char *range = (char *)arg;
+
+  if (number_is_in_list (range, tp->num))
+    warn_enable_btrace (tp);
+
+  return 0;
+}
+
+/* The "btrace enable" command.  */
+static void
+cmd_btrace_enable (char *args, int from_tty)
+{
+  if (args && *args)
+    iterate_over_threads (enable_btrace_list, args);
+  else
+    {
+      struct thread_info *tp = find_thread_ptid (inferior_ptid);
+
+      if (!tp)
+	error (_("Couldn't enable branch tracing: no inferior thread."));
+
+      enable_btrace (tp);
+    }
+}
+
+/* The "btrace enable all" command.  */
+static void
+cmd_btrace_enable_all (char *args, int from_tty)
+{
+  if (args && *args)
+    error (_("Invalid argument."));
+
+  for_each_thread (warn_enable_btrace);
+}
+
+/* The "btrace enable auto" command.  */
+static void
+cmd_btrace_enable_auto (char *args, int from_tty)
+{
+  if (args && *args)
+    error (_("Invalid argument."));
+
+  if (btrace_thread_observer)
+    error (_("Automatic branch trace enabling already on."));
+
+  btrace_thread_observer =
+    observer_attach_new_thread (warn_enable_btrace);
+}
+
+/* Thread iteration callback to disable branch tracing if @tp is in the @arg
+   range of thread nums.  */
+static int
+disable_btrace_list (struct thread_info *tp, void *arg)
+{
+  char *range = (char *)arg;
+
+  if (number_is_in_list (range, tp->num))
+    warn_disable_btrace (tp);
+
+  return 0;
+}
+
+/* The "btrace disable" command.  */
+static void
+cmd_btrace_disable (char *args, int from_tty)
+{
+  if (args && *args)
+    iterate_over_threads (disable_btrace_list, args);
+  else
+    {
+      struct thread_info *tp = find_thread_ptid (inferior_ptid);
+
+      if (!tp)
+	error (_("Couldn't disable branch tracing: no inferior thread."));
+
+      disable_btrace (tp);
+    }
+}
+
+/* The "btrace disable all" command.  */
+static void
+cmd_btrace_disable_all (char *args, int from_tty)
+{
+  if (args && *args)
+    error (_("Invalid argument."));
+
+  for_each_thread (warn_disable_btrace);
+}
+
+/* The "btrace disable auto" command.  */
+static void
+cmd_btrace_disable_auto (char *args, int from_tty)
+{
+  if (args && *args)
+    error (_("Invalid argument."));
+
+  if (!btrace_thread_observer)
+    error (_("Automatic branch trace enabling already off."));
+
+  observer_detach_new_thread (btrace_thread_observer);
+  btrace_thread_observer = NULL;
+}
+
+/* Flags controlling the output of a btrace list command.  */
+enum btrace_list_flags
+{
+  /* Print code addresses.  */
+  BTR_LIST_ADDRESS  = (1 << 0),
+
+  /* Print function names.  */
+  BTR_LIST_FUNCTION = (1 << 1),
+
+  /* Print line information.  */
+  BTR_LIST_LINE     = (1 << 2),
+
+  /* Print the total number of btrace blocks.  */
+  BTR_LIST_TOTAL    = (1 << 3)
+};
+
+/* Print the addresses for the btrace list item @trace.  */
+static void
+do_btrace_list_address (struct btrace_block *trace)
+{
+  struct gdbarch *gdbarch = target_gdbarch;
+
+  ui_out_field_core_addr (current_uiout, "begin", gdbarch, trace->begin);
+  ui_out_text (current_uiout, " - ");
+  ui_out_field_core_addr (current_uiout, "end", gdbarch, trace->end);
+}
+
+/* Print the function containing the btrace list item @trace.  */
+static void
+do_btrace_list_function (struct btrace_block *trace)
+{
+  struct symbol *symbol = find_pc_function (trace->begin);
+
+  ui_out_text (current_uiout, " in ");
+  if (symbol)
+    ui_out_field_string (current_uiout, "function",
+			 SYMBOL_PRINT_NAME (symbol));
+  else
+    {
+      struct minimal_symbol *msymbol =
+	lookup_minimal_symbol_by_pc (trace->begin);
+
+      if (msymbol)
+	ui_out_field_string (current_uiout, "function",
+			     SYMBOL_PRINT_NAME (msymbol));
+      else
+	ui_out_text (current_uiout, "??");
+    }
+
+  ui_out_text (current_uiout, " ()");
+}
+
+/* Print the line information for the btrace list item @trace.  */
+static void
+do_btrace_list_line (struct btrace_block *trace)
+{
+  struct symbol *symbol = find_pc_function (trace->begin);
+  struct symtab *symtab = NULL;
+  struct linetable *linetable = NULL;
+  const char *filename = NULL;
+
+  if (symbol)
+    symtab = symbol->symtab;
+  if (!symtab)
+    symtab = find_pc_symtab (trace->begin);
+  if (symtab)
+    {
+      linetable = symtab->linetable;
+      filename = symtab->filename;
+    }
+
+  if (filename)
+    {
+      ui_out_text (current_uiout, " at ");
+      ui_out_field_string (current_uiout, "file", filename);
+
+      if (linetable)
+	{
+	  struct linetable_entry *line = linetable->item;
+	  int nitems = linetable->nitems, i = 0;
+	  int begin = INT_MAX, end = 0;
+
+	  /* Skip all preceding entries.  */
+	  for (; i < (nitems - 1) && line[i + 1].pc <= trace->begin; ++i);
+
+	  for (; i < nitems && line[i].pc <= trace->end; ++i)
+	    {
+	      begin = min (begin, line[i].line);
+	      end = max (end, line[i].line);
+	    }
+
+	  if (begin <= end)
+	    {
+	      ui_out_text (current_uiout, ":");
+	      ui_out_field_int (current_uiout, "lbegin", begin);
+
+	      if (begin < end)
+		{
+		  ui_out_text (current_uiout, "-");
+		  ui_out_field_int (current_uiout, "lend", end);
+		}
+	    }
+	}
+    }
+}
+
+/* Print the btrace list item @trace based on @flags.  */
+static void
+do_btrace_list_item (struct btrace_block *trace, enum btrace_list_flags flags)
+{
+  if (flags & BTR_LIST_ADDRESS)
+    do_btrace_list_address (trace);
+
+  if (flags & BTR_LIST_FUNCTION)
+    do_btrace_list_function (trace);
+
+  if (flags & BTR_LIST_LINE)
+    do_btrace_list_line (trace);
+}
+
+/* Print the btrace list for a range of blocks.  */
+static void
+do_btrace_list (VEC (btrace_block_s) *btrace, char *range,
+		enum btrace_list_flags flags)
+{
+  struct cleanup *ui_out_chain =
+    make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
+  unsigned int block = 0;
+  struct btrace_block *trace;
+
+  while (VEC_iterate (btrace_block_s, btrace, block, trace))
+    {
+      ++block;
+
+      if (number_is_in_list (range, block))
+	{
+	  ui_out_field_fmt_int (current_uiout, 5, ui_left, "block", block);
+	  do_btrace_list_item (trace, flags);
+	  ui_out_text (current_uiout, "\n");
+	}
+    }
+
+  do_cleanups (ui_out_chain);
+}
+
+/* The "btrace list" command.  */
+static void
+cmd_btrace_list (char *args, int from_tty)
+{
+  struct thread_info *tp = find_thread_ptid (inferior_ptid);
+  enum btrace_list_flags flags = BTR_LIST_FUNCTION | BTR_LIST_LINE;
+  VEC (btrace_block_s) *btrace;
+
+  if (!tp)
+    error (_("No thread."));
+
+  btrace = get_btrace (tp);
+
+  /* Parse modifier.  */
+  if (args && *args)
+    {
+      if (*args == '/')
+	flags = 0;
+
+      while (*args == '/')
+	{
+	  ++args;
+
+	  if (*args == '\0')
+	    error (_("Missing modifier."));
+
+	  for (; *args; ++args)
+	    {
+	      if (isspace (*args))
+		break;
+
+	      if (*args == '/')
+		continue;
+
+	      switch (*args)
+		{
+		case 'a':
+		  flags |= BTR_LIST_ADDRESS;
+		  break;
+		case 'f':
+		  flags |= BTR_LIST_FUNCTION;
+		  break;
+		case 'l':
+		  flags |= BTR_LIST_LINE;
+		  break;
+		case 't':
+		  flags |= BTR_LIST_TOTAL;
+		  break;
+		default:
+		  error (_("Invalid modifier: %c."), *args);
+		}
+	    }
+
+	  args = skip_spaces (args);
+	}
+    }
+
+  if (flags & BTR_LIST_TOTAL)
+    {
+      struct cleanup *ui_out_chain =
+	make_cleanup_ui_out_tuple_begin_end (current_uiout, "btrace blocks");
+      unsigned int total = VEC_length (btrace_block_s, btrace);
+
+      ui_out_text (current_uiout, "total: ");
+      ui_out_field_int (current_uiout, "total", total);
+      ui_out_text (current_uiout, "\n");
+
+      do_cleanups (ui_out_chain);
+    }
+  else if (btrace)
+    do_btrace_list (btrace, args, flags);
+  else
+    error (_("No trace."));
+}
+
+/* Print the disassembly of @trace based on @flags.  */
+static void
+do_btrace (struct btrace_block *trace, int flags)
+{
+  struct gdbarch *gdbarch = target_gdbarch;
+
+  if (!trace)
+    error (_("No trace."));
+
+  if (trace->end < trace->begin)
+    warning (_("Bad trace: %s - %s"), paddress (gdbarch, trace->begin),
+	     paddress (gdbarch, trace->end));
+
+  gdb_disassembly (gdbarch, current_uiout, 0, flags, -1,
+		   trace->begin, trace->end + 1);
+}
+
+/* Print the branch trace disassembly for a range of btrace blocks.  */
+static void
+do_btrace_range (struct thread_info *tp, int flags, char *args)
+{
+  struct get_number_or_range_state state;
+  unsigned int i;
+  VEC (btrace_block_s) *btrace = NULL;
+  struct cleanup *cleanup =
+    make_cleanup (VEC_cleanup (btrace_block_s), &btrace);
+
+  /* We store the relevant blocks into a separate vector, so we can display
+     them in reverse order.  */
+  init_number_or_range (&state, args);
+  while (!state.finished)
+    {
+      int index = get_number_or_range (&state);
+      struct btrace_block *trace;
+
+      if (!index)
+	error (_("Args must be numbers or '$' variables."));
+
+      trace = read_btrace (tp, index - 1);
+      if (!trace)
+	continue;
+
+      VEC_safe_push (btrace_block_s, btrace, trace);
+    }
+
+  i = VEC_length (btrace_block_s, btrace);
+  while (i--)
+    do_btrace (VEC_index (btrace_block_s, btrace, i), flags);
+
+  do_cleanups (cleanup);
+}
+
+/* Print the branch trace disassembly for a preceding block.  */
+static void
+do_prev_btrace (struct thread_info *tp, int flags, char *args)
+{
+  struct btrace_block *trace = NULL;
+  size_t skip = 1;
+
+  if (args[0])
+    skip = get_number (&args);
+
+  while (skip--)
+    trace = prev_btrace (tp);
+
+  if (args[0])
+    error (_("Junk after argument: %s"), args);
+
+  do_btrace (trace, flags);
+}
+
+/* Print the branch trace disassembly for a succeding block.  */
+static void
+do_next_btrace (struct thread_info *tp, int flags, char *args)
+{
+  struct btrace_block *trace = NULL;
+  size_t skip = 1;
+
+  if (args[0])
+    skip = get_number (&args);
+
+  while (skip--)
+    trace = next_btrace (tp);
+
+  if (args[0])
+    error (_("Junk after argument: %s"), args);
+
+  do_btrace (trace, flags);
+}
+
+/* The "btrace" command.  */
+static void
+cmd_btrace (char *args, int from_tty)
+{
+  struct thread_info *tp = find_thread_ptid (inferior_ptid);
+  struct btrace_block *trace = NULL;
+  int flags = 0;
+
+  if (!tp)
+    error (_("No thread."));
+
+  /* Parse modifier.  We accept the same modifiers as the disas command.  */
+  if (args && *args)
+    {
+      while (*args == '/')
+	{
+	  ++args;
+
+	  if (*args == '\0')
+	    error (_("Missing modifier."));
+
+	  for (; *args; ++args)
+	    {
+	      if (isspace (*args))
+		break;
+
+	      if (*args == '/')
+		continue;
+
+	      switch (*args)
+		{
+		case 'm':
+		  flags |= DISASSEMBLY_SOURCE;
+		  flags |= DISASSEMBLY_PRECISE_INSN;
+		  flags |= DISASSEMBLY_FILENAME;
+		  break;
+		case 'r':
+		  flags |= DISASSEMBLY_RAW_INSN;
+		  break;
+		default:
+		  error (_("Invalid modifier: %c."), *args);
+		}
+	    }
+
+	  args = skip_spaces (args);
+	}
+    }
+
+  if (!args || !*args)
+    do_btrace (prev_btrace (tp), flags);
+  else if (args[0] == '+')
+    do_prev_btrace (tp, flags, args+1);
+  else if (args[0] == '-')
+    do_next_btrace (tp, flags, args+1);
+  else
+    do_btrace_range (tp, flags, args);
+}
+
+void _initialize_btrace (void);
+
+/* Initialize btrace commands.  */
+void
+_initialize_btrace (void)
+{
+  struct cmd_list_element *c;
+
+  add_cmd ("branchtrace", class_btrace, NULL, _("Recording a branch trace."),
+	   &cmdlist);
+
+  add_prefix_cmd ("btrace", class_btrace, cmd_btrace, _("\
+Disassemble the selected branch trace block.\n\n\
+With a /m modifier, source lines are included (if available).\n\
+With a /r modifier, raw instructions in hex are included.\n\n\
+Without arguments, selects the chronologically preceding block.\n\
+With \"+[<n>]\" argument, selects the n-th chronologically preceding block.\n\
+With \"-[<n>]\" argument, selects the n-th chronologically succeeding block.\n\
+With one positive integer argument, selects the respective block.\n\
+With a range argument \"<l>-<h>\", selects the h-th block and disassembles \
+blocks in the range in reverse (i.e. original control flow) order.\n"),
+		  &btcmdlist, "btrace ", 1, &cmdlist);
+
+  add_prefix_cmd ("enable", class_btrace, cmd_btrace_enable, _("\
+Enable branch trace recording for the current thread.\n"),
+		  &btencmdlist, "btrace enable ", 1, &btcmdlist);
+
+  add_cmd ("all", class_btrace, cmd_btrace_enable_all, _("\
+Enable branch trace recording for all existing threads.\n"),
+	   &btencmdlist);
+
+  add_cmd ("auto", class_btrace, cmd_btrace_enable_auto, _("\
+Enable branch trace recording for each new thread.\n"),
+	   &btencmdlist);
+
+  add_prefix_cmd ("disable", class_btrace, cmd_btrace_disable, _("\
+Disable branch trace recording for the current thread.\n"),
+		  &btdiscmdlist, "btrace disable ", 1, &btcmdlist);
+
+  add_cmd ("all", class_btrace, cmd_btrace_disable_all, _("\
+Disable branch trace recording for all existing threads.\n"),
+	   &btdiscmdlist);
+
+  add_cmd ("auto", class_btrace, cmd_btrace_disable_auto, _("\
+Stop enabling branch trace recording for each new thread.\n"),
+	   &btdiscmdlist);
+
+  add_cmd ("list", class_btrace, cmd_btrace_list, _("\
+List branch trace blocks.\n\n\
+Prints a list of all blocks for which branch trace is available.\n\
+With a /a modifier, addresses are included.\n\
+With a /f modifier, the function name is included (if available).\n\
+With a /l modifier, source lines are include (if available).\n\
+With a /t modifier, prints the total number of trace blocks and stops.\n\
+Without any modifier, behaves as if /fl were specified.\n\n\
+Without arguments, the full list of blocks is listed.\n\
+With a range (<start>[-<end>]) argument, lists all blocks in that range.\n"),
+	   &btcmdlist);
+}
diff --git a/gdb/command.h b/gdb/command.h
index 88895bb..3991f78 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -39,7 +39,7 @@ enum command_class
   no_class = -1, class_run = 0, class_vars, class_stack, class_files,
   class_support, class_info, class_breakpoint, class_trace,
   class_alias, class_bookmark, class_obscure, class_maintenance,
-  class_pseudo, class_tui, class_user, class_xdb,
+  class_pseudo, class_tui, class_user, class_xdb, class_btrace,
   no_set_class	/* Used for "show" commands that have no corresponding
 		   "set" command.  */
 };
diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
index 0629807..d9b3899 100644
--- a/gdb/testsuite/gdb.base/page.exp
+++ b/gdb/testsuite/gdb.base/page.exp
@@ -25,6 +25,7 @@ gdb_test_sequence "help" "unpaged help" {
     "List of classes of commands:"
     ""
     "aliases -- Aliases of other commands"
+    "branchtrace -- Recording a branch trace"
     "breakpoints -- Making program stop at certain points"
     "data -- Examining data"
     "files -- Specifying and examining files"
@@ -52,12 +53,12 @@ gdb_expect_list "paged help" \
     "List of classes of commands:"
     ""
     "aliases -- Aliases of other commands"
+    "branchtrace -- Recording a branch trace"
     "breakpoints -- Making program stop at certain points"
     "data -- Examining data"
     "files -- Specifying and examining files"
     "internals -- Maintenance commands"
     "obscure -- Obscure features"
-    "running -- Running the program"
 }
 gdb_test "q"
 
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [patch v3 15/16] test, btrace: more branch tracing tests
  2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
                   ` (12 preceding siblings ...)
  2012-08-14 13:01 ` [patch v3 04/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
@ 2012-08-14 13:03 ` markus.t.metzger
  2012-08-14 13:03 ` [patch v3 06/16] cli, btrace: add btrace cli markus.t.metzger
  2012-08-14 13:03 ` [patch v3 14/16] test, btrace: add branch tracing tests markus.t.metzger
  15 siblings, 0 replies; 30+ messages in thread
From: markus.t.metzger @ 2012-08-14 13:03 UTC (permalink / raw)
  To: gdb-patches
  Cc: markus.t.metzger, jan.kratochvil, palves, tromey, kettenis, Barkha Ahuja

From: Barkha Ahuja <barkha.ahuja@intel.com>

Non-stop tests are failing with gdbserver and are thus skipped.

2012-08-14 Barkha Ahuja <barkha.ahuja@intel.com>

testsuite/
 	* gdb.btrace/a.S: New file
	* gdb.btrace/allthreads_trace.exp: New file
	* gdb.btrace/b.S: New file
	* gdb.btrace/decrement.exp: New file
	* gdb.btrace/decrement.S: New file
	* gdb.btrace/disable_all.exp: New file
	* gdb.btrace/enable_all.exp: New file
	* gdb.btrace/enable_range.exp: New file
	* gdb.btrace/list_options.exp: New file
	* gdb.btrace/main.S: New file
	* gdb.btrace/main_asm.exp: New file
	* gdb.btrace/main_segv.exp: New file
	* gdb.btrace/main_segv.S: New file
	* gdb.btrace/sanity_crash.exp: New file
	* gdb.btrace/sanity_crash.S: New file
	* gdb.btrace/amd64-thr-callback.S: New file
	* gdb.btrace/i386-thr-callback.S: New file
	* gdb.btrace/threads.c: New file
	* gdb.btrace/threads_asm.c: New file
	* gdb.btrace/threads_auto.exp: New file
	* gdb.btrace/threads_independent.exp: New file
	* gdb.btrace/threads_nonstop.exp: New file
	* gdb.btrace/trace_iteration.exp: New file


---
 gdb/testsuite/gdb.btrace/a.S                     |   23 ++
 gdb/testsuite/gdb.btrace/allthreads_trace.exp    |  345 ++++++++++++++++++++++
 gdb/testsuite/gdb.btrace/amd64-thr-callback.S    |  116 ++++++++
 gdb/testsuite/gdb.btrace/b.S                     |   23 ++
 gdb/testsuite/gdb.btrace/decrement.S             |   32 ++
 gdb/testsuite/gdb.btrace/decrement.exp           |  141 +++++++++
 gdb/testsuite/gdb.btrace/disable_all.exp         |  279 +++++++++++++++++
 gdb/testsuite/gdb.btrace/enable_all.exp          |  282 ++++++++++++++++++
 gdb/testsuite/gdb.btrace/enable_range.exp        |  281 ++++++++++++++++++
 gdb/testsuite/gdb.btrace/i386-thr-callback.S     |  116 ++++++++
 gdb/testsuite/gdb.btrace/list_options.exp        |  107 +++++++
 gdb/testsuite/gdb.btrace/main.S                  |   36 +++
 gdb/testsuite/gdb.btrace/main_asm.exp            |  109 +++++++
 gdb/testsuite/gdb.btrace/main_segv.S             |   32 ++
 gdb/testsuite/gdb.btrace/main_segv.exp           |   84 ++++++
 gdb/testsuite/gdb.btrace/threads.c               |   96 ++++++
 gdb/testsuite/gdb.btrace/threads_asm.c           |   78 +++++
 gdb/testsuite/gdb.btrace/threads_auto.exp        |  123 ++++++++
 gdb/testsuite/gdb.btrace/threads_independent.exp |  125 ++++++++
 gdb/testsuite/gdb.btrace/threads_nonstop.exp     |  231 +++++++++++++++
 gdb/testsuite/gdb.btrace/trace_iteration.exp     |  265 +++++++++++++++++
 21 files changed, 2924 insertions(+), 0 deletions(-)
 create mode 100755 gdb/testsuite/gdb.btrace/a.S
 create mode 100755 gdb/testsuite/gdb.btrace/allthreads_trace.exp
 create mode 100755 gdb/testsuite/gdb.btrace/amd64-thr-callback.S
 create mode 100755 gdb/testsuite/gdb.btrace/b.S
 create mode 100755 gdb/testsuite/gdb.btrace/decrement.S
 create mode 100755 gdb/testsuite/gdb.btrace/decrement.exp
 create mode 100755 gdb/testsuite/gdb.btrace/disable_all.exp
 create mode 100755 gdb/testsuite/gdb.btrace/enable_all.exp
 create mode 100755 gdb/testsuite/gdb.btrace/enable_range.exp
 create mode 100755 gdb/testsuite/gdb.btrace/i386-thr-callback.S
 create mode 100755 gdb/testsuite/gdb.btrace/list_options.exp
 create mode 100755 gdb/testsuite/gdb.btrace/main.S
 create mode 100755 gdb/testsuite/gdb.btrace/main_asm.exp
 create mode 100755 gdb/testsuite/gdb.btrace/main_segv.S
 create mode 100755 gdb/testsuite/gdb.btrace/main_segv.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads.c
 create mode 100755 gdb/testsuite/gdb.btrace/threads_asm.c
 create mode 100755 gdb/testsuite/gdb.btrace/threads_auto.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads_independent.exp
 create mode 100755 gdb/testsuite/gdb.btrace/threads_nonstop.exp
 create mode 100755 gdb/testsuite/gdb.btrace/trace_iteration.exp

diff --git a/gdb/testsuite/gdb.btrace/a.S b/gdb/testsuite/gdb.btrace/a.S
new file mode 100755
index 0000000..b457975
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/a.S
@@ -0,0 +1,23 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+	.text
+        .globl  callA
+        .type   callA, @function
+callA:
+	nop
+	ret
diff --git a/gdb/testsuite/gdb.btrace/allthreads_trace.exp b/gdb/testsuite/gdb.btrace/allthreads_trace.exp
new file mode 100755
index 0000000..41e1935
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/allthreads_trace.exp
@@ -0,0 +1,345 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace  for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, i386-thr-callback.S, amd64-thr-callback.S
+# Compiled using '-g -lpthread' option.
+#executed as :
+#                    make check  RUNTESTFLAGS="GDB=<path to gdb>  gdb.trace/allthreads_trace.exp"
+###############
+
+load_lib btrace.exp
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "allthreads_trace.exp"
+	return -1
+}
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/allthreads_trace.x
+set options "{debug}"
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[istarget "i?86-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/i386-thr-callback.S
+} elseif {[istarget "x86_64-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/amd64-thr-callback.S
+} else {
+	warning "host platform not supported "
+	untested allthreads_trace.exp
+	return -1
+}
+set objfiles "${objmain}  ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+	untested allthreads_trace.exp
+	return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+	untested allthreads_trace.exp
+	return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+	untested allthreads_trace.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr-callback.S:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+gdb_test "btr enable auto"
+
+set test "continue running..."
+gdb_test_multiple "continue" $test {
+      -re "Breakpoint 3, mybarrier \\(\\) at.*thr-callback.S:114.*"
+	{
+	  pass "continuing"
+	}
+	timeout {fail "(timeout) continue into program"}
+}
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+	-re ".*\n" {
+		pass $test
+	}
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+gdb_test_multiple "thread 2" "switching to thread 2" {
+    -re ".*Switching to thread 2.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 2, 1.3"
+    }
+    timeout {
+	fail "switching to thread 2 (timeout), 1.3"
+    }
+}
+
+# 64 bit platform
+if {[istarget "x86_64-*-*"]} {
+
+# trace for thread 2
+gdb_test "btr list /a" "
+1     0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2     0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+.*" "BTR listing for thread 2, 1.4"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 2, 1.5"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_a\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_a\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 2, 1.6"
+
+# trace for thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.7"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.7"
+    }
+}
+
+gdb_test "btr list /la" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*amd64-thr-callback.S:112-114\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*amd64-thr-callback.S:44-45\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*amd64-thr-callback.S:85-89\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*amd64-thr-callback.S:40-43\r
+.*" "BTR listing for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 3, 1.9"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 3, 1.10"
+
+# trace for thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.11"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.11"
+    }
+}
+
+gdb_test "btr list /lf" "
+1 *in mybarrier \\(\\) at.*amd64-thr-callback.S:112-114\r
+2 *in th_c \\(\\) at.*amd64-thr-callback.S:56-57\r
+3 *in call_C \\(\\) at.*amd64-thr-callback.S:94-98\r
+4 *in th_c \\(\\) at.*amd64-thr-callback.S:52-55\r
+.*" "BTR listing for thread 4, 1.12"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 4, 1.13"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_c\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_c\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 4, 1.14"
+
+# trace for thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.15"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.15"
+    }
+}
+
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*" "BTR listing for thread 5, 1.16"
+
+gdb_test "btr " "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 5, 1.17"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_d\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_d\\+19>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 5, 1.18"
+
+ gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_D\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_D\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+4>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+9>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_D\\+10>:\[\[:blank:\]\]*ret.*\r" " BTR of 3 for thread 5, 1.19"
+
+} elseif {[istarget "i?86-*-*"]} {
+# 32 bit platform
+
+#trace for thread 2
+gdb_test "btr list /a" "
+1     0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2     0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+.*" "BTR listing for thread 2, 1.4"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 2, 1.5"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_a\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_a\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 2, 1.6"
+
+#switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.7"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.7"
+    }
+}
+
+#trace for thread 3
+gdb_test "btr list /la" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*i386-thr-callback.S:112-114\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*i386-thr-callback.S:44-45\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*i386-thr-callback.S:85-89\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* at .*i386-thr-callback.S:40-43\r
+.*" "BTR listing for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 3, 1.9"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 3, 1.10"
+
+#switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.11"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.11"
+    }
+}
+
+#trace for thread 4
+gdb_test "btr list /lf" "
+1 *in mybarrier \\(\\) at.*i386-thr-callback.S:112-114\r
+2 *in th_c \\(\\) at.*i386-thr-callback.S:56-57\r
+3 *in call_C \\(\\) at.*i386-thr-callback.S:94-98\r
+4 *in th_c \\(\\) at.*i386-thr-callback.S:52-55\r
+.*" "BTR listing for thread 4, 1.12"
+
+gdb_test "btr /m 1" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 4, 1.13"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_c\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_c\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 4, 1.14"
+
+#switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.15"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.15"
+    }
+}
+
+#trace for thread 5
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*" "BTR listing for thread 5, 1.16"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> *0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" " BTR of 1 for thread 5, 1.17"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_d\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_d\\+18>:\[\[:blank:\]\]*call.*" " BTR of 2 for thread 5, 1.18"
+
+ gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_D\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_D\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+3>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_D\\+8>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_D\\+9>:\[\[:blank:\]\]*ret.*\r" " BTR of 3 for thread 5, 1.19"
+
+} else {
+  note "Platform not supported"
+  untested allthreads_trace.exp
+}
diff --git a/gdb/testsuite/gdb.btrace/amd64-thr-callback.S b/gdb/testsuite/gdb.btrace/amd64-thr-callback.S
new file mode 100755
index 0000000..871f76d
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/amd64-thr-callback.S
@@ -0,0 +1,116 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+###############
+# threads.c calls th_a(), th_b(),th_c() and th_d() as callback methods
+# for 4 threads being created.
+###############
+
+
+	.globl th_a
+	.type	th_a, @function
+th_a:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	call	call_A
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_b
+	.type	th_b @function
+th_b:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	call	call_B
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_c
+	.type	th_c @function
+th_c:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	call	call_C
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_d
+	.type	th_d @function
+th_d:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	call	call_D
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl call_A
+	.type	call_A, @function
+call_A:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_B
+	.type	call_B @function
+call_B:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_C
+	.type	call_C @function
+call_C:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_D
+	.type	call_D @function
+call_D:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl mybarrier
+	.type	mybarrier @function
+mybarrier:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$0, %eax
+	leave
+	ret
diff --git a/gdb/testsuite/gdb.btrace/b.S b/gdb/testsuite/gdb.btrace/b.S
new file mode 100755
index 0000000..09d376d
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/b.S
@@ -0,0 +1,23 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+	.text
+        .globl  callB
+        .type   callB, @function
+callB:
+	nop
+	ret
diff --git a/gdb/testsuite/gdb.btrace/decrement.S b/gdb/testsuite/gdb.btrace/decrement.S
new file mode 100755
index 0000000..38bb254
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/decrement.S
@@ -0,0 +1,32 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#Decrements the number 5 by 1 untill it is 0. The
+	.text
+	.globl _start
+_start:
+	.align 0x10    		# 0x400010
+	movl $5, %eax
+	.align 0x10    		# 0x400010
+	movl $1, %ebx
+	call L1
+
+L1:	cmpl $0, %eax		#compare 0 with value in eax
+	je L2			        #jump to L2 if 0==eax (je - jump if equal)
+	decl %eax		        #decrement eax
+	jmp L1			# unconditional jump to L1
+L2: 	ret
diff --git a/gdb/testsuite/gdb.btrace/decrement.exp b/gdb/testsuite/gdb.btrace/decrement.exp
new file mode 100755
index 0000000..8d6b7d3
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/decrement.exp
@@ -0,0 +1,141 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Fix a location while linking, where teh debuggee will be loaded and then
+# see that trace gives the correct addresses.
+# Source file: decrement.s
+###############
+
+load_lib btrace.exp
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+set srcfile ${srcdir}/${subdir}/decrement.S
+set objfile ${objdir}/${subdir}/decrement.o
+set binfile ${objdir}/${subdir}/decrement.x
+set options "{debug}"
+#compile
+if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return "" }
+#link
+if {[target_link ${objfile} ${binfile} " -Ttext 0x400400 "] != ""} {
+	untested decrement.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto L1] then {
+   fail "Can't run to test L1"
+   return 0
+}
+
+#Enable tracing
+gdb_test_no_output "btr enable"
+
+gdb_continue_to_breakpoint "L1"
+
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)" "list L1, 1.1"
+
+gdb_continue_to_breakpoint "L1"
+
+if {[istarget "x86_64-*-*"]} {
+#We enter the loop for 5 times from here.
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400421 in L1 \\(\\)" "list L1 again , 1.2"
+} elseif {[istarget "i?86-*-*"]} {
+#We enter the loop for 5 times from here.
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400420 in L1 \\(\\)" "list L1 again, 1.2"
+}
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint  "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+if {[istarget "x86_64-*-*"]} {
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /lfa" "
+1 *0x0*400423 - 0x0*400423 in L2 \\(\\)\r
+2 *0x0*40041a - 0x0*40041d in L1 \\(\\)\r
+3 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+4 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+5 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r
+6 *0x0*40041a - 0x0*400421 in L1 \\(\\)\r" "BTR listing at L2, 1.3"
+
+# Exit the loop
+gdb_test "btr /m 1" "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*ret.*\r" "BTR at block 1, 1.4"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr /m 2" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 *<L2>" "BTR at block 2, 1.5"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at block 3, 1.6"
+
+} elseif {[istarget "i?86-*-*"]} {
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /lfa" "
+1 *0x0*400422 - 0x0*400422 in L2 \\(\\)\r
+2 *0x0*40041a - 0x0*40041d in L1 \\(\\)\r
+3 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+4 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+5 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r
+6 *0x0*40041a - 0x0*400420 in L1 \\(\\)\r" "BTR listing at L2, 1.3"
+
+# Exit the loop
+gdb_test "btr /m 1" "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret.*\r" "BTR at block 1, 1.4"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr /m 2" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at block 2, 1.5"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at block 3, 1.6"
+
+} else {
+	warning "host platform not supported "
+	return -1
+}
+
diff --git a/gdb/testsuite/gdb.btrace/disable_all.exp b/gdb/testsuite/gdb.btrace/disable_all.exp
new file mode 100755
index 0000000..f988399
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/disable_all.exp
@@ -0,0 +1,279 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace  for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c, i386-thr-callback.S, amd64-thr-callback.S
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as
+#                    make check  RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/thread_auto.exp"
+#executed on 64 bit as :
+#                    make check  RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host x86_64-linux-gnu --target x86_64-linux-gnu gdb.trace/thread_auto.exp"
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "disable_all.exp"
+	return -1
+}
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/disable_all.x
+set options "{debug}"
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[istarget "i?86-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/i386-thr-callback.S
+} elseif {[istarget "x86_64-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/amd64-thr-callback.S
+} else {
+	warning "host platform not supported "
+	untested disable_all.exp
+	return -1
+}
+set objfiles "${objmain}  ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+	untested disable_all.exp
+	return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+	untested disable_all.exp
+	return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+	untested disable_all.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr-callback.S:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+gdb_test "btr enable auto"
+
+set test "continue running..."
+gdb_test_multiple "continue" $test {
+      -re "Breakpoint 3, mybarrier \\(\\) at.*thr-callback.S:114.*"
+	{
+	  pass "continuing"
+	}
+	timeout {fail "(timeout) continue into program"}
+}
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+	-re ".*\n" {
+		pass $test
+	}
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr disable all"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+# switch to thread 2
+gdb_test_multiple "thread 2" "switching to thread 2" {
+    -re ".*Switching to thread 2.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 2, 1.7"
+    }
+    timeout {
+	fail "switching to thread 2 (timeout), 1.7"
+    }
+}
+
+# 64 bit platform
+if {[istarget "x86_64-*-*"]} {
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+No trace." " BTR of thread 2, 1.9"
+
+# trace for thread 3
+# switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+No trace." " BTR of thread 3, 1.12"
+
+# trace for thread 4
+#gdb_test "thread 4" ".*Switching to thread 4.*mybarrier.*" " switch to thread 4, 1.13"
+#switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+# switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} elseif {[istarget "i?86-*-*"]} {
+# 32 bit platform
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+No trace." " BTR of thread 2, 1.9"
+
+# trace for thread 3
+# switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+No trace." " BTR of thread 3, 1.12"
+
+# trace for thread 4
+# switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+# switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+}
diff --git a/gdb/testsuite/gdb.btrace/enable_all.exp b/gdb/testsuite/gdb.btrace/enable_all.exp
new file mode 100755
index 0000000..53a28ed
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable_all.exp
@@ -0,0 +1,282 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace  for all the threads by "btr enable auto" on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c,  i386-thr-callback.S, amd64-thr-callback.S
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as :
+#                    make check  RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/enable_all.exp"
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "enable_all.exp"
+	return -1
+}
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/enable_all.x
+set options "{debug}"
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[istarget "i?86-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/i386-thr-callback.S
+} elseif {[istarget "x86_64-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/amd64-thr-callback.S
+} else {
+	warning "host platform not supported "
+	untested enable_all.exp
+	return -1
+}
+set objfiles "${objmain}  ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+	untested enable_all.exp
+	return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+	untested enable_all.exp
+	return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+	untested enable_all.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*-thr-callback.S:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*-thr-callback.S, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*-thr-callback.S, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*-thr-callback.S, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*-thr-callback.S, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+# enable trace in primary thread, which automatically enables trace in all new threads crated.
+set test "continue running..."
+gdb_test_multiple "continue" $test {
+      -re "Breakpoint 3, mybarrier \\(\\) at.*-thr-callback.S:114.*"
+	{
+	  pass "continuing"
+	}
+	timeout {fail "(timeout) continue into program"}
+}
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+	-re ".*\n$gdb_prompt $" {
+		pass $test
+	}
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr enable all"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+#switch to thread 2
+gdb_test_multiple "thread 2" "switching to thread 2" {
+    -re ".*Switching to thread 2.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 2, 1.7"
+    }
+    timeout {
+	fail "switching to thread 2 (timeout), 1.7"
+    }
+}
+
+# 64 bit platform
+if {[istarget "x86_64-*-*"]} {
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*-thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+# switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*-thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+# switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*-thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_c\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_c\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 4, 1.15"
+
+# trace for thread 5
+# switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*-thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_d\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_d\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 5, 1.18"
+
+} elseif {[istarget "i?86-*-*"]} {
+# 32 bit platform
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*-thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+# switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*-thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+# switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*-thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_c\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_c\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 4, 1.15"
+
+# trace for thread 5
+# switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*-thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_d\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_d\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+ untested enable_all.exp
+}
diff --git a/gdb/testsuite/gdb.btrace/enable_range.exp b/gdb/testsuite/gdb.btrace/enable_range.exp
new file mode 100755
index 0000000..ee21246
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/enable_range.exp
@@ -0,0 +1,281 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, Enable trace  for a range of threads on primary thread and check the trace availability for all the threads
+# Sourcefiles : threads_asm.c,  i386-thr-callback.S, amd64-thr-callback.S
+# Compiled using '-g -lpthread' option.
+#executed on 32 bit as :
+#                    make check  RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/enable_range.exp"
+###############
+
+load_lib btrace.exp
+
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "enable_range.exp"
+	return -1
+}
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/enable_range.x
+set options "{debug}"
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+#Load different callback files for 32 and 64 bit.
+# 32 bit platform
+if {[istarget "i?86-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/i386-thr-callback.S
+} elseif {[istarget "x86_64-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/amd64-thr-callback.S
+} else {
+	warning "host platform not supported "
+	untested enable_range.exp
+	return -1
+}
+set objfiles "${objmain}  ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} {
+	untested enable_range.exp
+	return -1
+}
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} {
+	untested enable_range.exp
+	return -1
+}
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+	untested enable_range.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+if ![runto main] {
+    fail "could not run to main."
+    return -1
+}
+
+# set breakpoint at line 67, at call to mybarrier() for primary thread.
+gdb_breakpoint "67" "Breakpoint 2 at.*: file.*threads_asm.c, line 67." " breakpoint at line 67, 1.1"
+
+# set a breakpoint at mybarrier() to halt all the new threads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 3, mybarrier \\(\\) at .*thr-callback.S:114" "Breakpoint at my barrier for all the threads to stop, 1.2"
+
+gdb_breakpoint "${srccallback}:35" "Breakpoint 4 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 35." "Breakpoint after the barrier for thread 2, 1.3"
+
+gdb_breakpoint "${srccallback}:47" "Breakpoint 5 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 47." "Breakpoint after the barrier for thread 3, 1.4"
+gdb_breakpoint "${srccallback}:59" "Breakpoint 6 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 59." "Breakpoint after the barrier for thread 4, 1.5"
+gdb_breakpoint "${srccallback}:71" "Breakpoint 7 at 0x\[a-f0-9\]*: file .*thr-callback.S, line 71." "Breakpoint after the barrier for thread 5, 1.6"
+
+set test "continue running..."
+gdb_test_multiple "continue" $test {
+      -re "Breakpoint 3, mybarrier \\(\\) at.*thr-callback.S:114.*"
+	{
+	  pass $test
+	}
+	timeout {fail "(timeout) continue into program"}
+      }
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+	-re ".*\n$gdb_prompt $" {
+		pass $test
+	}
+}
+
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# Enable btrace on all threads
+gdb_test "btr enable 2-3"
+
+# We need to do a seperate listing from here, since the instr length is different
+# on different platforms.
+#switch to thread 2
+gdb_test_multiple "thread 2" "switching to thread 2" {
+    -re ".*Switching to thread 2.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 2, 1.7"
+    }
+    timeout {
+	fail "switching to thread 2 (timeout), 1.7"
+    }
+}
+
+# 64 bit platform
+if {[istarget "x86_64-*-*"]} {
+
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+#switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+25>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+#switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+#switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} elseif {[istarget "i?86-*-*"]} {
+# 32 bit platform
+
+# trace for thread 2
+gdb_test "continue" ".*
+Breakpoint 4, th_a \\(\\) at .*thr-callback.S:35.*" "BTR listing for thread 2, 1.8"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_a\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_a\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 2, 1.9"
+
+# trace for thread 3
+#switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.10"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.10"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 5, th_b \\(\\) at .*thr-callback.S:47.*" "BTR listing for thread 3, 1.11"
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <th_b\\+23>:\[\[:blank:\]\]*leave.*\r
+=> *0x\[a-f0-9\]* <th_b\\+24>:\[\[:blank:\]\]*ret.*" " BTR of thread 3, 1.12"
+
+# trace for thread 4
+#switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c \\(\\) at .*thr-callback.S:59.*" "BTR listing for thread 4, 1.14"
+
+gdb_test "btr" "
+No trace." " BTR of thread 4, 1.15"
+
+# trace for thread 5
+#switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.16"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.16"
+    }
+}
+
+
+gdb_test "continue" ".*
+Breakpoint 7, th_d \\(\\) at .*thr-callback.S:71.*" "BTR listing for thread 5, 1.17"
+
+gdb_test "btr" "
+No trace." " BTR of thread 5, 1.18"
+
+} else {
+ note "Platform not supported"
+ untested enable_range.exp
+}
diff --git a/gdb/testsuite/gdb.btrace/i386-thr-callback.S b/gdb/testsuite/gdb.btrace/i386-thr-callback.S
new file mode 100755
index 0000000..0356aa4
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/i386-thr-callback.S
@@ -0,0 +1,116 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+###############
+# threads.c calls th_a(), th_b(),th_c() and th_d() as callback methods
+# for 4 threads being created.
+###############
+
+
+	.globl th_a
+	.type	th_a, @function
+th_a:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	call	call_A
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_b
+	.type	th_b @function
+th_b:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	call	call_B
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_c
+	.type	th_c @function
+th_c:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	call	call_C
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl th_d
+	.type	th_d @function
+th_d:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	call	call_D
+	movl	$0, %eax
+	call	mybarrier
+	leave
+	ret
+
+	.globl call_A
+	.type	call_A, @function
+call_A:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_B
+	.type	call_B @function
+call_B:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_C
+	.type	call_C @function
+call_C:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl call_D
+	.type	call_D @function
+call_D:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	leave
+	ret
+
+	.globl mybarrier
+	.type	mybarrier @function
+mybarrier:
+	pushl	%ebp
+	movl	%esp, %ebp
+	movl	$0, %eax
+	leave
+	ret
diff --git a/gdb/testsuite/gdb.btrace/list_options.exp b/gdb/testsuite/gdb.btrace/list_options.exp
new file mode 100755
index 0000000..1973ae1
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/list_options.exp
@@ -0,0 +1,107 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Testing the other options of btrace list like /t, /af
+#Also tests the other commands like giving a range to btr list "btr list n1-n2"
+# Sourcefiles : main.S, a.S, b.S
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main.S
+set srcfilea ${srcdir}/${subdir}/a.S
+set srcfileb ${srcdir}/${subdir}/b.S
+set objfilemain ${objdir}/${subdir}/main_asm.o
+set objfilea ${objdir}/${subdir}/a.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/list_options.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfilea} ${objfilea}  ${options}]!= ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb}  ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain}  ${objfilea} ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} {
+	untested list_options.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto main] { return -1 }
+
+gdb_breakpoint "35" "Breakpoint 3 at .*:.*main\.S, line 35\." "Breakpoint at line 35, 1.2"
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+gdb_test "c" "Continuing.*Breakpoint.*main\.S:35.*" "continue to end, 1.3"
+
+gdb_test "btr list /t" "total: 4" "total number of btrace blocks, 1.4"
+
+#Get the trace listing after it returns from callB
+gdb_test "btr list /af" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in main \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callB \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in main \\(\\)\r
+4 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callA \\(\\)\r" "Listing at return, 1.5"
+
+#Get the trace listing for only 1-3
+gdb_test "btr list /lf 1-3" "
+1 *in main \\(\\) at .*main\\.S:34-35\r
+2 *in callB \\(\\) at .*b\.S:22-23\r
+3 *in main \\(\\) at .*main\\.S:32-33\r" "Listing at return, 1.6"
+
+#Get the trace listing for only 2-3
+gdb_test "btr list /lf 2-4" "
+2 *in callB \\(\\) at .*b\.S:22-23\r
+3 *in main \\(\\) at .*main\.S:32-33\r
+4 *in callA \\(\\) at .*a\.S:22-23\r" "Listing at return, 1.7"
+
+gdb_test "btrace /m 3"  "
+.*main\.S:32\[\[:blank:\]\]*movl *.0, %eax\r
+ *0x\[a-f0-9\]* <main\\+10>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+\r
+.*main\.S:33\[\[:blank:\]\]*call\[\[:blank:\]\]*callB\r
+ *0x\[a-f0-9\]* <main\\+15>:\[\[:blank:\]\]*call. *0x\[a-f0-9\]* *<callB>"  "btrace for 1 to 3, 1.8"
+
+gdb_test "btrace /r 3" "
+ *0x\[a-f0-9\]* <main\\+10>:.*mov *.0x0,%eax\r
+ *0x\[a-f0-9\]* <main\\+15>:.*call. *0x\[a-f0-9\]* <callB>" "btrace with /r options at 3, 1.9"
+
+
+gdb_test "btrace /r -" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*90\[\[:blank:\]\]*nop *\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*c3\[\[:blank:\]\]*ret. *" " btrace with /r option at 2, 1.10"
diff --git a/gdb/testsuite/gdb.btrace/main.S b/gdb/testsuite/gdb.btrace/main.S
new file mode 100755
index 0000000..916a7f6
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main.S
@@ -0,0 +1,36 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+###################
+# main.s, uses a.s and b.s
+###################
+
+	.text
+        .globl  _start
+        .globl  _main
+        .type   _start, @function
+        .type   _main, @function
+_start:
+        call main
+        hlt
+main:
+        movl    $0, %eax
+        call    callA
+        movl    $0, %eax
+        call    callB
+        movl    $0, %eax
+        leave
+        ret
diff --git a/gdb/testsuite/gdb.btrace/main_asm.exp b/gdb/testsuite/gdb.btrace/main_asm.exp
new file mode 100755
index 0000000..e9df431
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_asm.exp
@@ -0,0 +1,109 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works when we step into multiple source files in '.s' format
+# Sourcefiles : main.s, a.s, b.s
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main.S
+set srcfilea ${srcdir}/${subdir}/a.S
+set srcfileb ${srcdir}/${subdir}/b.S
+set objfilemain ${objdir}/${subdir}/main_asm.o
+set objfilea ${objdir}/${subdir}/a.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/main_asm.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfilea} ${objfilea}  ${options}]!= ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb}  ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain}  ${objfilea} ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} {
+	untested main_asm.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto_main] {
+	return -1
+}
+
+# Set the breakpoints we'll need later on.
+gdb_breakpoint "33" "Breakpoint \[0-9\]+ at .*:.*main.S, line 33." "Breakpoint at line 33, 1.1"
+gdb_breakpoint "34" "Breakpoint \[0-9\]+ at .*:.*main.S, line 34." "Breakpoint at line 34, 1.2"
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+# run to callB
+gdb_test "c" ".*Breakpoint \[0-9\]+, main .* at.*main.S:33\r
+33.*call.*callB" "Run to Breakpoint at line 33, 1.3"
+
+#get BTR listing in CallB
+gdb_test "btr list /f" "
+1 * in main \\(\\)\r
+2 * in callA \\(\\)\r" "BTR listing at line 28, 1.4"
+
+#return to main
+gdb_test "c" ".*Breakpoint \[0-9\]+, main .* at.*main.S:34\r
+34.*movl.*" "Run to Breakpoint at line 30, 1.5"
+
+# we do get trace for main, callB, main, callA here
+gdb_test "btr list /f" "
+1 *in main \\(\\)\r
+2 *in callB \\(\\)\r
+3 *in main \\(\\)\r
+4 *in callA \\(\\)\r" "BTR listing at line 30, 1.6"
+
+
+gdb_test "btr /m 1" "
+.*main.S:34\[\[:blank:\]\]*movl *.0, %eax\r
+=>  *0x\[a-f0-9\]* <main\\+20>:\[\[:blank:\]\]*mov *.0x0,%eax" "BTR of 1, 1.7"
+
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 2, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <main\\+10>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+ *0x\[a-f0-9\]* <main\\+15>:\[\[:blank:\]\]*call.*<callB>." "BTR of 3, 1.9"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callA\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callA\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 4, 1.10"
diff --git a/gdb/testsuite/gdb.btrace/main_segv.S b/gdb/testsuite/gdb.btrace/main_segv.S
new file mode 100755
index 0000000..1d3df2e
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_segv.S
@@ -0,0 +1,32 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+###################
+# main.s, uses callB from b.s
+###################
+
+	.text
+        .globl  _start
+        .type   _start, @function
+        .type   _main, @function
+_start:
+        call main
+        hlt
+main:
+        call    callB
+        movl    $0, %eax
+        leave
+        ret
diff --git a/gdb/testsuite/gdb.btrace/main_segv.exp b/gdb/testsuite/gdb.btrace/main_segv.exp
new file mode 100755
index 0000000..0555047
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/main_segv.exp
@@ -0,0 +1,84 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace shows up when the debugge crashes with SIGSEGV
+# Sourcefiles : main_segv.S, b.s,
+# Compiled using '-g' option.
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+set testfile "main"
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/main_segv.S
+set srcfileb ${srcdir}/${subdir}/b.S
+set objfilemain ${objdir}/${subdir}/main_segv.o
+set objfileb ${objdir}/${subdir}/b.o
+set binfile ${objdir}/${subdir}/main_segv.x
+set options " -g "
+#compile
+if {[target_assemble ${srcfilemain} ${objfilemain} ${options}] != ""} { return "" }
+if {[target_assemble ${srcfileb} ${objfileb}  ${options}]!= ""} { return "" }
+
+set objfiles "${objfilemain}  ${objfileb}"
+#link
+if {[target_link ${objfiles} ${binfile} " "] != ""} { return "" }
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto_main] {
+	return -1
+}
+
+# Enable branch trace to trace the startup.
+gdb_test_no_output "btr enable"
+
+gdb_test "stepi" ".*22.*" "Stepping into callB, 1.1"
+
+gdb_test "btr list /lfa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in callB \\(\\) at .*b.S.*" "BTR listing in b.S, 1.2"
+
+#check that we got SEGV
+gdb_test "c" ".*Program received signal SIGSEGV, Segmentation fault.\r
+main.*at.*main_segv.S:31.*" "Program received SEGV at line 31, 1.3"
+
+#Check that we do get trace after SEGV too.
+gdb_test "btr list /a" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]*\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]*" "BTR of 1, 1.4"
+
+#Check where we got SEGV
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <main\\+5>:\[\[:blank:\]\]*mov *.0x0,%eax\r
+=> 0x\[a-f0-9\]* <main\\+10>:\[\[:blank:\]\]*leave.*" "BTR of 2, 1.5"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <callB\\+0>:\[\[:blank:\]\]*nop\r
+ *0x\[a-f0-9\]* <callB\\+1>:\[\[:blank:\]\]*ret.*" "BTR of 3, 1.6"
diff --git a/gdb/testsuite/gdb.btrace/threads.c b/gdb/testsuite/gdb.btrace/threads.c
new file mode 100755
index 0000000..9c49563
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads.c
@@ -0,0 +1,96 @@
+/*
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp.  <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#This program spawns 4 threads and each thread has a seperate callback function and
+# a diffierent function call from callback function.
+# Purpose: To check the trace functionality of gdb, ("btr auto on" and "btr enable" for individual threads)
+###############
+*/
+#include <pthread.h>
+#include <stdio.h>
+
+
+//function being called by Thread[0],
+int call_A(){ return 0;}
+//function being called by Thread[1]
+int call_B(){ return 0;}
+//function being called by Thread[2]
+int call_C(){ return 0;}
+//function being called by Thread[3]
+int call_D(){ return 0;}
+
+//Callback function for thread[0]
+void* th_a(void* arg){
+	int number = *((int*) arg);
+	call_A();
+	return arg;
+}
+//Callback function for thread[1]
+void* th_b(void* arg){
+	int number = *((int*) arg);
+	call_B();
+	return arg;
+}
+//Callback function for thread[2]
+void* th_c(void* arg){
+	int number = *((int*) arg);
+	call_C();
+	return arg;
+}
+//Callback function for thread[3]
+void* th_d(void* arg){
+	int number = *((int*) arg);
+	call_D();
+	return arg;
+}
+// Terminate the already created thread
+int join_thread(pthread_t *thr)
+{
+	int* resultp;
+	if (pthread_join(*thr, (void**) &resultp))
+	{
+		printf("ERROR: pthread_join failed, aborting!\n");
+		return(1);
+	}
+	return(0);
+}
+
+int main(){
+	const int THREADS = 4;
+	pthread_t thread[THREADS];
+	int args[THREADS];
+	args[0]=0;
+	args[1]=1;
+	args[2]=2;
+	args[3]=3;
+
+	// To be deterministic, we have to first terminate the
+	// created thread before creating a new one.
+	pthread_create(&thread[0], 0, th_a ,&args[0]);
+	join_thread(&thread[0]);
+	pthread_create(&thread[1], 0, th_b ,&args[1]);
+	join_thread(&thread[1]);
+	pthread_create(&thread[2], 0, th_c ,&args[2]);
+	join_thread(&thread[2]);
+	pthread_create(&thread[3], 0, th_d ,&args[3]);
+	join_thread(&thread[3]);
+
+	return 1;
+}
diff --git a/gdb/testsuite/gdb.btrace/threads_asm.c b/gdb/testsuite/gdb.btrace/threads_asm.c
new file mode 100755
index 0000000..eb58ecf
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_asm.c
@@ -0,0 +1,78 @@
+/*
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#This program spawns 4 threads and each thread has a seperate callback function and
+# a different function call from callback function.
+# th_a(), th_b(), th_c() and th_d are called from file th_callback.s
+#
+# Purpose: To check the trace functionality of gdb, ("btr auto on" and "btr enable" for individual threads and "btr enable" in GDb non-stop mode)
+###############
+*/
+#include <pthread.h>
+#include <stdio.h>
+
+pthread_barrier_t bar;
+
+void* th_a(void* arg);
+void* th_b(void* arg);
+void* th_c(void* arg);
+void* th_d(void* arg);
+
+// Terminate the already created thread
+int join_thread(pthread_t *thr)
+{
+	int* resultp;
+	if (pthread_join(*thr, (void**) &resultp))
+	{
+		printf("ERROR: pthread_join failed, aborting!\n");
+		return(1);
+	}
+	return(-1);
+}
+
+int main(){
+	const int THREADS = 4;
+	pthread_t thread[THREADS];
+	int args[THREADS];
+	int i;
+	args[0]=0;
+	args[1]=1;
+	args[2]=2;
+	args[3]=3;
+	pthread_barrier_init(&bar, NULL, 5);
+
+	//create 4 threads having different callback fucntions.
+	pthread_create(&thread[0], 0, th_a ,&args[0]);
+	pthread_create(&thread[1], 0, th_b ,&args[1]);
+	pthread_create(&thread[2], 0, th_c ,&args[2]);
+	pthread_create(&thread[3], 0, th_d ,&args[3]);
+	mybarrier();
+	printf(" All the threads are created by now ");
+	//wait for all the threads to terminate
+
+	for(i=0;i<4;i++) {
+		join_thread(&thread[i]);
+	}
+	//destroy barrier
+	pthread_barrier_destroy(&bar);
+
+	return 1;
+}
+
diff --git a/gdb/testsuite/gdb.btrace/threads_auto.exp b/gdb/testsuite/gdb.btrace/threads_auto.exp
new file mode 100755
index 0000000..613422f
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_auto.exp
@@ -0,0 +1,123 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works for multi-threaded application and the trace is automatically enabled for all the threads created, if we execute the GDB command "btr enable auto".
+# Sourcefiles : threads.c
+# Compiled using '-g -lpthread' option.
+#executed as :
+#                    make check  RUNTESTFLAGS="GDB=<path to gdb> gdb.trace/threads_auto.exp"
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "threads_auto.exp"
+	return -1
+}
+
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads.c
+set objfilemain ${objdir}/${subdir}/threads.o
+set binfile ${objdir}/${subdir}/threads_auto.x
+set options "{debug}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objfilemain} "object" ${options}] != ""} {
+	untested threads_auto.exp
+	return -1
+}
+if {[gdb_compile_pthreads ${objfilemain} ${binfile} "executable" ""] != ""} {
+	untested threads_auto.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Make sure we don't die when running to main
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "43" "Breakpoint 2 at .*:.*, line 43." "Breakpoint at line 42, 1.1"
+
+gdb_breakpoint "49" "Breakpoint 3 at .*:.*, line 49." "Breakpoint at line 48, 1.2"
+
+gdb_breakpoint "55" "Breakpoint 4 at .*:.*, line 55." "Breakpoint at line 54, 1.3"
+
+gdb_breakpoint "61" "Breakpoint 5 at .*:.*, line 61." "Breakpoint at line 60, 1.4"
+
+# Reset branch trace on all new threads automatically
+gdb_test_no_output "btr enable auto"
+
+gdb_test "continue" ".*
+Breakpoint 2, th_a.*threads\.c:43\r
+43\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 2, line 43, 1.5"
+
+#Get the trace listing after it returns from call_A, while ignoring the trace listing of trace pthread libs.
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_A \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+.*\r" "listing is not correct thread\[0\], 1.6"
+
+
+gdb_test "continue" ".*
+Breakpoint 3, th_b.*threads\.c:49\r
+49\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 32, line 49, 1.7"
+
+#Get the trace listing after it returns from call_B
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_B \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\)\r
+.*\r" "listing is not correct thread\[1\], 1.8"
+
+gdb_test "continue" ".*
+Breakpoint 4, th_c.*threads\.c:55\r
+55\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 4, line 55, 1.9"
+
+#Get the trace listing after it returns from call_C
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_C \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+.*\r" "listing is not correct thread\[2\], 1.10"
+
+gdb_test "continue" ".*
+Breakpoint 5, th_d.*threads\.c:61\r
+61\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 52, line 61, 1.11"
+
+#Get the trace listing after it returns from call_D
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_D \\(\\)\r
+3 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_d \\(\\)\r
+.*\r" "listing is not correct for thread\[3\], 1.12"
diff --git a/gdb/testsuite/gdb.btrace/threads_independent.exp b/gdb/testsuite/gdb.btrace/threads_independent.exp
new file mode 100755
index 0000000..9962e80
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_independent.exp
@@ -0,0 +1,125 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: The trace works for multi-threaded application and the trace is enabled for only the current thread.
+# Sourcefiles : threads.c
+# Compiled using '-g -lpthread' option.
+#executed as :
+#                    make check  RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/threads_independent.exp"
+###############
+
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads.c
+set objfilemain ${objdir}/${subdir}/threads.o
+set binfile ${objdir}/${subdir}/threads_independent.x
+set options "{debug}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${binfile} "executable" ${options}] != ""} {
+	untested threads_independent.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+# Make sure we don't die when running to main
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "th_a" "Breakpoint 2 at .*:.*, line 41." "Breakpoint at th_a, 1.1"
+
+gdb_breakpoint "th_c" "Breakpoint 4 at .*:.*, line 53." "Breakpoint at th_c, 1.2"
+
+#set a breakpoint at the end of each callback function of each thread
+gdb_breakpoint "43" "Breakpoint 6 at .*:.*, line 43." "Breakpoint at line 43, 1.3"
+
+gdb_breakpoint "49" "Breakpoint 7 at .*:.*, line 49." "Breakpoint at line 49, 1.4"
+
+gdb_breakpoint "55" "Breakpoint 8 at .*:.*, line 55." "Breakpoint at line 55, 1.5"
+
+gdb_breakpoint "61" "Breakpoint 9 at .*:.*, line 61." "Breakpoint at line 61, 1.6"
+
+# move to th_a for thread[0]and enable trace
+gdb_test "continue" ".*
+Breakpoint 2, th_a.*threads\.c:41\r.*" "Stopping at breakpoint 2, th_a, 1.7"
+
+# Reset branch trace
+gdb_test_no_output "btrace enable"
+
+gdb_test "continue" ".*
+Breakpoint 4, th_a.*threads\.c:43\r
+43\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 4, line 43, 1.8"
+
+#Get the trace listing after it returns from call_A
+gdb_test "btrace list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_a \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_A \\(\\)" "listing of thread\[0\], 1.9"
+
+
+# move to th_b for thread[1]and do not enable trace
+gdb_test "continue" ".*
+Breakpoint 5, th_b.*threads\.c:49\r
+49\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 5, line 49, 1.10"
+
+#Get the trace listing after it returns from call_B
+gdb_test "btr list" "No trace." "No trace for thread\[1\], 1.11"
+
+
+# move to th_c and enable trace
+gdb_test "continue" ".*
+Breakpoint 3, th_c.*threads\.c:53\r
+53.*" "Stopping at breakpoint 3, th_c, 1.12"
+
+
+# Reset branch trace for thread[2]
+gdb_test_no_output "btrace enable"
+
+gdb_test "continue" ".*
+Breakpoint 6, th_c.*threads\.c:55\r
+55\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 6, line 55, 1.13"
+
+#Get the trace listing after it returns from call_C
+gdb_test "btr list /fa" "
+1 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_c \\(\\)\r
+2 *0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_C \\(\\)" "listing of  thread\[2\], 1.14"
+
+
+# move to th_d and do not enable trace
+gdb_test "continue" ".*
+Breakpoint 7, th_d.*threads\.c:61\r
+61\[\[:blank:\]\]*return arg.*" "Stopping at breakpoint 7, line 61, 1.15"
+
+#Get the trace listing after it returns from call_D
+gdb_test "btr list" "No trace." "No trace for thread\[3\], 1.16"
diff --git a/gdb/testsuite/gdb.btrace/threads_nonstop.exp b/gdb/testsuite/gdb.btrace/threads_nonstop.exp
new file mode 100755
index 0000000..95405d3
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/threads_nonstop.exp
@@ -0,0 +1,231 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+###############
+#Test Purpose: In GDB non-stop mode, when btrace is enabled for only one thread (created by pthread_create()), then trace is also generated for only that thread and not for all threads
+# Sourcefiles : threads_asm.c,  i386-thr-callback.S, amd64-thr-callback.S
+# Compiled using '-g -lpthread' option.
+#executed as :
+#                    make check  RUNTESTFLAGS="GDB=/users/bahuja/work_gdb/gdb_32/gdb --host i686-linux-gnu --target i686-linux-gnu gdb.trace/threads_nonstop.exp"
+###############
+
+load_lib btrace.exp
+
+#check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# the tests do currently not work with gdbserver
+if [is_remote target] {
+	untested "threads_nonstop.exp"
+	return -1
+}
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+global srcdir
+global objdir
+global subdir
+
+set srcfilemain ${srcdir}/${subdir}/threads_asm.c
+set objcallback ${objdir}/${subdir}/thr_callback.o
+set objmain ${objdir}/${subdir}/threads_asm.o
+set binfile ${objdir}/${subdir}/threads_nonstop.x
+set options "{debug}"
+
+if { ![support_displaced_stepping] } {
+    unsupported "displaced stepping"
+    return -1
+}
+
+# We need to do a seperate listing from here, since the instr lenght is different
+# on different platforms.
+# 32 bit platform
+if {[istarget "i?86-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/i386-thr-callback.S
+} elseif {[istarget "x86_64-*-*"]} {
+	set srccallback ${srcdir}/${subdir}/amd64-thr-callback.S
+} else {
+	warning "host platform not supported "
+	return -1
+}
+
+set objfiles "${objmain}  ${objcallback}"
+
+#compile
+if {[gdb_compile_pthreads ${srcfilemain} ${objmain} "object" ${options}] != ""} { return "" }
+if {[gdb_compile ${srccallback} ${objcallback} "object" ${options}] != ""} { return "" }
+
+if {[gdb_compile_pthreads ${objfiles} ${binfile} "executable" ${options}] != ""} {
+	untested threads_nonstop.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+gdb_test_no_output "set pagination off"
+gdb_test_no_output "set target-async 1"
+gdb_test_no_output "set non-stop 1"
+
+# Make sure we don't die when running to main
+if ![runto_main] then {
+   fail "Can't run to main"
+   return 0
+}
+#set breakpoint at mybarrier to prevent all the pthreads from exiting.
+gdb_breakpoint "mybarrier" "Breakpoint 2 at .*:\[i386|amd64\]-thr-callback.S, line .*." "Breakpoint in reach barrier, 1.1"
+
+#set a breakpoint in callback of thread 3, where we enable trace for only thread 3
+gdb_breakpoint "th_b" "Breakpoint 3 at .*:\[i386|amd64\]-thr-callback.S.*" "Breakpoint in reach barrier, 1.2"
+
+set test "continue running..."
+gdb_test_multiple "continue" $test {
+      -re "Breakpoint 2.*"
+	{
+	  pass "continuing"
+	}
+}
+# this is added to get the prompt, which is missing.
+gdb_test "" ""
+
+# This "info threads" is needed to get a $gdb_prompt, since gdb seems to get hanged at this particular location.
+set test "info for threads"
+gdb_test_multiple "info threads" $test {
+	-re ".*\n$gdb_prompt $" {
+		pass $test
+	}
+}
+
+# this is added to get the prompt, which is missing after creating new threads in non-stop mode.
+gdb_test "" ""
+
+# thread 3 reaches its callback th_b(), while all threads wait at mybarrier()
+gdb_test "info threads" "  Id   Target Id         Frame \r
+  5    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+  4    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+  3    Thread 0x\[a-f0-9\]*.*th_b \\(\\) at.*thr-callback.S:42\r
+  2    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+.* 1    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114" "info threads before thread 3 reaches mybarrier(), 1.3"
+
+#switch to thread 3
+gdb_test_multiple "thread 3" "switching to thread 3" {
+    -re ".*Switching to thread 3.*th_b.*$gdb_prompt $" {
+	pass  "switch to thread 3, 1.4"
+    }
+    timeout {
+	fail "switching to thread 3 (timeout), 1.4"
+    }
+}
+
+#enable trace for only thread 3
+
+gdb_test "btr enable"
+# thread 3 also continues to mybarrier()
+
+gdb_test "continue" ".*Breakpoint 2, mybarrier \\(\\) at .*thr-callback.S:114.*" " thread 3 also reached at breakpoint 1 at line 53, 1.5"
+# back trace for thread 3.
+
+gdb_test "btr list /lfa" "
+1     0x\[a-f0-9\]* - 0x\[a-f0-9\]* in mybarrier \\(\\) at.*thr-callback.S:112-114\r
+2     0x\[a-f0-9\]* - 0x\[a-f0-9\]* in th_b \\(\\) at.*thr-callback.S:44-45\r
+3     0x\[a-f0-9\]* - 0x\[a-f0-9\]* in call_B \\(\\) at.*thr-callback.S:85-89" "BTR listing at line mybarrier for thread 3, 1.6"
+
+# 32 bit host
+if {[istarget "i?86-*-*"]} {
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> 0x\[a-f0-9\]* <mybarrier\\+3>:\[\[:blank:\]\]*mov.*" "btr 0 for thread 3, 1.7"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+13>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+18>:\[\[:blank:\]\]*call.*<mybarrier>" "btr 1 for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_B\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_B\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+3>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+8>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_B\\+9>:\[\[:blank:\]\]*ret.*\r" "btr 1 for thread 3, 1.9"
+
+} elseif {[istarget "x86_64-*-*"]} {
+# 64 bit host
+
+gdb_test "btr" "
+ *0x\[a-f0-9\]* <mybarrier\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <mybarrier\\+1>:\[\[:blank:\]\]*mov.*\r
+=> 0x\[a-f0-9\]* <mybarrier\\+4>:\[\[:blank:\]\]*mov.*" "btr 0 for thread 3, 1.7"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <th_b\\+14>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <th_b\\+19>:\[\[:blank:\]\]*call.*<mybarrier>" "btr 1 for thread 3, 1.8"
+
+gdb_test "btr +" "
+ *0x\[a-f0-9\]* <call_B\\+0>:\[\[:blank:\]\]*push.*\r
+ *0x\[a-f0-9\]* <call_B\\+1>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+4>:\[\[:blank:\]\]*mov.*\r
+ *0x\[a-f0-9\]* <call_B\\+9>:\[\[:blank:\]\]*leave.*\r
+ *0x\[a-f0-9\]* <call_B\\+10>:\[\[:blank:\]\]*ret.*\r" "btr 1 for thread 3, 1.9"
+
+}
+# All the threads are at mybarrier()
+gdb_test "info threads" "  Id   Target Id         Frame \r
+  5    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+  4    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+.* 3    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+  2    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114\r
+  1    Thread 0x\[a-f0-9\]*.*mybarrier \\(\\) at.*thr-callback.S:114" "Info threads, when all threads reached barrier, 1.10"
+
+# trace was enabled for only thread 3, and none other thread has trace
+#switch to thread 2
+gdb_test_multiple "thread 2" "switching to thread 2" {
+    -re ".*Switching to thread 2.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 2, 1.11"
+    }
+    timeout {
+	fail "switching to thread 2 (timeout), 1.11"
+    }
+}
+
+gdb_test "btr list" "No trace\." " no trace for thread 2, 1.12"
+
+#switch to thread 4
+gdb_test_multiple "thread 4" "switching to thread 4" {
+    -re ".*Switching to thread 4.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 4, 1.13"
+    }
+    timeout {
+	fail "switching to thread 4 (timeout), 1.13"
+    }
+}
+
+gdb_test "btr list" "No trace\." " no trace for thread 4, 1.14"
+
+#switch to thread 5
+gdb_test_multiple "thread 5" "switching to thread 5" {
+    -re ".*Switching to thread 5.*mybarrier.*$gdb_prompt $" {
+	pass  "switch to thread 5, 1.15"
+    }
+    timeout {
+	fail "switching to thread 5 (timeout), 1.15"
+    }
+}
+
+gdb_test "btr list" "No trace\." " no trace for thread 5, 1.16"
diff --git a/gdb/testsuite/gdb.btrace/trace_iteration.exp b/gdb/testsuite/gdb.btrace/trace_iteration.exp
new file mode 100755
index 0000000..d6e638b
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/trace_iteration.exp
@@ -0,0 +1,265 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# Contributed by Barkha Ahuja <barkha.ahuja@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+###############
+#Test Purpose: Fix a location while linking, where the debuggee will be loaded and then
+# see that trace gives the correct addresses.
+# Iterate over the btrace using the commands "btr", "btr +", "btr -", and check that it gives the correct output.
+# Source file: decrement.s
+###############
+
+load_lib btrace.exp
+# check for btrace support
+if { [skip_btrace_tests] } { return -1 }
+
+# start fresh - without an executable
+gdb_exit
+gdb_start
+
+set srcfile ${srcdir}/${subdir}/decrement.S
+set objfile ${objdir}/${subdir}/decrement.o
+set binfile ${objdir}/${subdir}/trace_iteration.x
+set options "{debug}"
+#compile
+if {[target_assemble ${srcfile} ${objfile} ""] != ""} { return -1 }
+#link
+if {[target_link ${objfile} ${binfile} " -Ttext 0x400400 "] != ""} {
+	untested trace_iteration.exp
+	return -1
+}
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if ![runto L1] then {
+    fail "Can't run to L1"
+    return 0
+}
+
+
+# Enable branch trace.
+gdb_test_no_output "btr enable"
+
+gdb_continue_to_breakpoint "L1, 1.2"
+
+gdb_test "btr list /lfa" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)" "list L1, 1.1"
+
+gdb_continue_to_breakpoint "L1, 1.2"
+
+if {[istarget "x86_64-*-*"]} {
+#64 bit host
+
+#We enter the loop for 5 times from here.
+gdb_test "btr list /af" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400421 in L1 \\(\\)" "list L1 again, 1.3"
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint  "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /a" "
+1 *0x0*400423 - 0x0*400423\r
+2 *0x0*40041a - 0x0*40041d\r
+3 *0x0*40041a - 0x0*400421\r
+4 *0x0*40041a - 0x0*400421\r
+5 *0x0*40041a - 0x0*400421\r.*" "BTR listing at L2, 1.4"
+
+# Exit the loop
+gdb_test "btr " "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR of 0, 1.5"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.6"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.7"
+
+gdb_test "btr " "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR of 1, 1.8"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2, 1.9"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.10"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2 second time, 1.11"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3 second time, 1.12"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r" "BTR at 2 third time, 1.13"
+
+#in the loop
+gdb_test "btr -" "
+=> 0x0*400423 *<L2\\+0>:\[\[:blank:\]\]*retq *" "BTR at 1 Again, 1.14"
+
+gdb_test "btr 6" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6, 1.15"
+
+gdb_test "btr +" "
+No trace." "BTR of non existing at end, 1.16"
+
+gdb_test "btr" "
+No trace." "BTR still at 6 , 1.17"
+
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400423 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400421 *<L1\\+7>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6, 1.18"
+
+} elseif {[istarget "i?86-*-*"]} {
+#32 bit host
+
+#We enter the loop for 5 times from here.
+gdb_test "btr list /af" "
+1 *0x0*40041a - 0x0*40041a in L1 \\(\\)\r
+2 *0x0*40041a - 0x0*400420 in L1 \\(\\)" "list L1 again, 1.3"
+
+#Delete all Breakpoints
+delete_breakpoints
+
+#Set a Breakpoint at L2
+gdb_breakpoint  "L2"
+
+#Continue to L2
+gdb_continue_to_breakpoint "L2"
+
+# BTR listing in method L2, when the loop exits
+gdb_test "btr list /a" "
+1 *0x0*400422 - 0x0*400422\r
+2 *0x0*40041a - 0x0*40041d\r
+3 *0x0*40041a - 0x0*400420\r
+4 *0x0*40041a - 0x0*400420\r
+5 *0x0*40041a - 0x0*400420\r
+6 *0x0*40041a - 0x0*400420\r" "BTR listing at L2, 1.4"
+
+# Exit the loop
+gdb_test "btr " "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret *" "BTR of 1, 1.5"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.6"
+
+#BTR of non existing trace
+gdb_test "btr -" "
+No trace." "BTR of non-existing trace, 1.7"
+
+#BTR of non existing trace
+gdb_test "btr " "
+=> 0x0*400422 *<L2\\+0>:\[\[:blank:\]\]*ret *" "BTR of 1, 1.8"
+
+# Comparison, if we are exiting the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at 2, 1.9"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.10"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3, 1.11"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 2 second time, 1.12"
+
+#in the loop
+gdb_test "btr +" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 3 second time, 1.13"
+
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 2nd third time, 1.14"
+#in the loop
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 *<L2>" "BTR at 1 Again, 1.15"
+
+gdb_test "btr 6" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR at 6,  1.16"
+
+gdb_test "btr +" "" "BTR of non existing at end, 1.17"
+
+gdb_test "btr" "" "BTR still at 6 , 1.18"
+
+gdb_test "btr -" "
+ *0x0*40041a *<L1\\+0>:\[\[:blank:\]\]*cmp *.0x0,%eax\r
+ *0x0*40041d *<L1\\+3>:\[\[:blank:\]\]*je *0x400422 <L2>\r
+ *0x0*40041f *<L1\\+5>:\[\[:blank:\]\]*dec *%eax\r
+ *0x0*400420 *<L1\\+6>:\[\[:blank:\]\]*jmp *0x40041a <L1>" "BTR still at 6 , 1.19"
+
+ }  else {
+	warning "host platform not supported "
+}
+
+#reset the trace
+btrace_reset_trace
+
+gdb_test "btr list" "No trace." "No trace should be available now"
-- 
1.7.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-08-14 13:01 ` [patch v3 16/16] btrace, x86: restrict to Atom markus.t.metzger
@ 2012-08-14 13:27   ` Mark Kettenis
       [not found]     ` <A78C989F6D9628469189715575E55B2307ACF558@IRSMSX102.ger.corp.intel.com>
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Kettenis @ 2012-08-14 13:27 UTC (permalink / raw)
  To: markus.t.metzger
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey,
	markus.t.metzger

> From: markus.t.metzger@intel.com
> Date: Tue, 14 Aug 2012 14:59:31 +0200
> 
> From: Markus Metzger <markus.t.metzger@intel.com>
> 
> Restrict branch tracing support to Atom processors.

Did you explain anywhere why this is restricted to Atom?

Even with such an explanation, the approach taken here is wrong:

> diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
> index 8475d7a..b0f7b43 100644
> --- a/gdb/i386-linux-tdep.c
> +++ b/gdb/i386-linux-tdep.c
> @@ -37,6 +37,7 @@
>  #include "symtab.h"
>  #include "arch-utils.h"
>  #include "xml-syscall.h"
> +#include "linux-btrace.h"
>  
>  #include "i387-tdep.h"
>  #include "i386-xstate.h"
> @@ -704,6 +705,39 @@ i386_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
>    return closure;
>  }
>  
> +/* See i386-linux-tdep.h.  */
> +int
> +i386_linux_supports_btrace (void)
> +{
> +  unsigned int cpuid, model, family;
> +
> +  if (!linux_supports_btrace ())
> +    return 0;
> +
> +  __asm__ __volatile__ ("movl   $1, %%eax;"
> +			"cpuid;"
> +			: "=a" (cpuid)
> +			:: "%ebx", "%ecx", "%edx");
> +
> +  family = (cpuid >> 8) & 0xf;
> +  model = (cpuid >> 4) & 0xf;
> +
> +  switch (family)
> +    {
> +    case 6:
> +      model += (cpuid >> 12) & 0xf0;
> +
> +      switch (model)
> +        {
> +	case 28: /* Atom.  */
> +	case 38:
> +	  return 1;
> +	}
> +    }
> +
> +  return 0;
> +}

You can't have this function in a -tdep.c, since this file needs to be
compilable everywhere (not just on i386/amd64).  But even in a -nat.c
file you shouldn't use inline assembly, since it isn't a standardized
C feature.  I can only guess why you want to restrict this feature to
Atom only, but I suspect that the proper solution is to query the
target whether branch tracing is supported.  That means the -nat.c
code should have code to query for support in the Linux kernel.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* FW: [patch v3 16/16] btrace, x86: restrict to Atom
       [not found]     ` <A78C989F6D9628469189715575E55B2307ACF558@IRSMSX102.ger.corp.intel.com>
@ 2012-08-14 15:57       ` Metzger, Markus T
  2012-09-24 12:23       ` Metzger, Markus T
  1 sibling, 0 replies; 30+ messages in thread
From: Metzger, Markus T @ 2012-08-14 15:57 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey

Resend. The original reply bounced.

Apologies for the spam to those who received multiple copies of this email.

-----Original Message-----
From: Metzger, Markus T
Sent: Tuesday, August 14, 2012 3:42 PM
To: Mark Kettenis
Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com; palves@redhat.com; tromey@redhat.com
Subject: RE: [patch v3 16/16] btrace, x86: restrict to Atom

> -----Original Message-----
> From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> Sent: Tuesday, August 14, 2012 3:27 PM

Thanks for your feedback!


> > +int
> > +i386_linux_supports_btrace (void)
> > +{
> > +  unsigned int cpuid, model, family;
> > +
> > +  if (!linux_supports_btrace ())
> > +    return 0;
> > +
> > +  __asm__ __volatile__ ("movl   $1, %%eax;"
> > +                   "cpuid;"
> > +                   : "=a" (cpuid)
> > +                   :: "%ebx", "%ecx", "%edx");
> > +

[...]

> You can't have this function in a -tdep.c, since this file needs to be
> compilable everywhere (not just on i386/amd64).  But even in a -nat.c
> file you shouldn't use inline assembly, since it isn't a standardized
> C feature.  I can only guess why you want to restrict this feature to
> Atom only, but I suspect that the proper solution is to query the
> target whether branch tracing is supported.  That means the -nat.c
> code should have code to query for support in the Linux kernel.

I agree that it would be better to have this check done in the kernel. The problem is that such a patch will take very long before
it becomes available in distributions. And even then, we would need to handle kernels without the patch, so we would need something
similar to this in gdb, as well.

I took the cpuid bits from gdb/go32-nat.c. I have not seen any compilation guard around it.

I thought that the i386-tdep files are meant to contain i386 specific code, that's why I put the code there. Where would be the
right place to put such code?

Thanks,
Markus.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer, Christian Lamprechter
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 01/16] gdbserver, build: add -DGDBSERVER
  2012-08-14 13:00 ` [patch v3 01/16] gdbserver, build: add -DGDBSERVER markus.t.metzger
@ 2012-08-15  0:41   ` Doug Evans
  2012-08-15  7:59     ` Metzger, Markus T
  0 siblings, 1 reply; 30+ messages in thread
From: Doug Evans @ 2012-08-15  0:41 UTC (permalink / raw)
  To: markus.t.metzger
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey, kettenis

On Tue, Aug 14, 2012 at 5:59 AM,  <markus.t.metzger@intel.com> wrote:
> From: Markus Metzger <markus.t.metzger@intel.com>
>
> A use of common/vec.h in gdbserver may result in compile errors if GDBSERVER is
> not defined.
>
> Add -DGDBSERVER to all gdbserver cflags.
>
> 2012-08-14 Markus Metzger <markus.t.metzger@intel.com>
>
> gdbserver/
>         * Makefile.in: (INTERNAL_CFLAGS): Add -DGDBSERVER
>         (various make rules): Remove -DGDBSERVER
>
>
> ---
>  gdb/gdbserver/Makefile.in |   27 +++++++++++++++------------
>  1 files changed, 15 insertions(+), 12 deletions(-)
>
> diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
> index f62799e..ae5a60e 100644
> --- a/gdb/gdbserver/Makefile.in
> +++ b/gdb/gdbserver/Makefile.in
> @@ -113,6 +113,9 @@ INTERNAL_CFLAGS_BASE =  ${CFLAGS} ${GLOBAL_CFLAGS} \
>  INTERNAL_WARN_CFLAGS =  ${INTERNAL_CFLAGS_BASE} $(WARN_CFLAGS)
>  INTERNAL_CFLAGS =  ${INTERNAL_WARN_CFLAGS} $(WERROR_CFLAGS)
>
> +# Let all files know we're compiling for gdbserver.
> +INTERNAL_CFLAGS += -DGDBSERVER
> +
>  # LDFLAGS is specifically reserved for setting from the command line
>  # when running make.
>  LDFLAGS = @LDFLAGS@
> @@ -447,7 +450,7 @@ UST_CFLAGS = $(ustinc) -DCONFIG_UST_GDB_INTEGRATION
>  # Note, we only build the IPA if -fvisibility=hidden is supported in
>  # the first place.
>  IPAGENT_CFLAGS = $(CPPFLAGS) $(INTERNAL_CFLAGS) $(UST_CFLAGS) \
> -       -fPIC -DGDBSERVER -DIN_PROCESS_AGENT \
> +       -fPIC -DIN_PROCESS_AGENT \
>         -fvisibility=hidden

"+=" is a GNU make-ism, I think we can't use it here.

Plus you missed one:

gdb_vecs.o: ../common/gdb_vecs.c $(vec_h) $(gdb_vecs_h) $(host_defs_h)
        $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [patch v3 01/16] gdbserver, build: add -DGDBSERVER
  2012-08-15  0:41   ` Doug Evans
@ 2012-08-15  7:59     ` Metzger, Markus T
  0 siblings, 0 replies; 30+ messages in thread
From: Metzger, Markus T @ 2012-08-15  7:59 UTC (permalink / raw)
  To: Doug Evans
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey, kettenis

> -----Original Message-----
> From: Doug Evans [mailto:dje@google.com]
> Sent: Wednesday, August 15, 2012 2:41 AM

Thanks for your review!

[...]

> > +# Let all files know we're compiling for gdbserver.
> > +INTERNAL_CFLAGS += -DGDBSERVER

[...]

> "+=" is a GNU make-ism, I think we can't use it here.
> 
> Plus you missed one:
> 
> gdb_vecs.o: ../common/gdb_vecs.c $(vec_h) $(gdb_vecs_h) $(host_defs_h)
>         $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER

Fixed both. Gdb/common is growing very fast - that's good.  I'll send an updated patch.

Regards,
Markus.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer, Christian Lamprechter
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 03/16] source: add flags to print_source_lines ()
  2012-08-14 13:01 ` [patch v3 03/16] source: add flags to print_source_lines () markus.t.metzger
@ 2012-09-11 20:14   ` Tom Tromey
  2012-09-12  8:34     ` Metzger, Markus T
  0 siblings, 1 reply; 30+ messages in thread
From: Tom Tromey @ 2012-09-11 20:14 UTC (permalink / raw)
  To: markus.t.metzger
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, kettenis

>>>>> "Markus" == markus t metzger <markus.t.metzger@intel.com> writes:

Markus> 2012-08-14 Markus Metzger <markus.t.metzger@intel.com>
Markus> 	* symtab.h (print_source_lines_flags): New enum.
Markus> 	* source.c (print_source_lines_base): Change noerror to flags.
Markus> 	(print_source_lines): Change noerror to flags.

This is ok.  I think it is fine to put it in immediately if you want.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 04/16] source, disasm: optionally prefix source lines with filename
  2012-08-14 13:01 ` [patch v3 04/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
@ 2012-09-11 20:21   ` Tom Tromey
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Tromey @ 2012-09-11 20:21 UTC (permalink / raw)
  To: markus.t.metzger
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, kettenis

>>>>> "Markus" == markus t metzger <markus.t.metzger@intel.com> writes:

Markus> 	* source.c (print_source_lines_base): Prefix source line with filename if

This line looks over-long.

Markus> +		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);

A few of these lines look too long as well, they should be split.

Otherwise this seems ok.

Tom

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [patch v3 03/16] source: add flags to print_source_lines ()
  2012-09-11 20:14   ` Tom Tromey
@ 2012-09-12  8:34     ` Metzger, Markus T
  0 siblings, 0 replies; 30+ messages in thread
From: Metzger, Markus T @ 2012-09-12  8:34 UTC (permalink / raw)
  To: Tom Tromey
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, kettenis

> -----Original Message-----
> From: Tom Tromey [mailto:tromey@redhat.com]
> Sent: Tuesday, September 11, 2012 10:14 PM
> To: Metzger, Markus T
> Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com; palves@redhat.com;
> kettenis@gnu.org
> Subject: Re: [patch v3 03/16] source: add flags to print_source_lines ()
> 
> >>>>> "Markus" == markus t metzger <markus.t.metzger@intel.com> writes:
> 
> Markus> 2012-08-14 Markus Metzger <markus.t.metzger@intel.com>
> Markus> 	* symtab.h (print_source_lines_flags): New enum.
> Markus> 	* source.c (print_source_lines_base): Change noerror to flags.
> Markus> 	(print_source_lines): Change noerror to flags.
> 
> This is ok.  I think it is fine to put it in immediately if you want.

Thanks. I'll commit patches 1, 3, and 4, then, as soon as I my write-after-approval request has been granted. How about patch 2?

Regards,
Markus.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [patch v3 16/16] btrace, x86: restrict to Atom
       [not found]     ` <A78C989F6D9628469189715575E55B2307ACF558@IRSMSX102.ger.corp.intel.com>
  2012-08-14 15:57       ` FW: " Metzger, Markus T
@ 2012-09-24 12:23       ` Metzger, Markus T
  2012-09-27  7:08         ` Joel Brobecker
  2012-09-28  2:40         ` Mark Kettenis
  1 sibling, 2 replies; 30+ messages in thread
From: Metzger, Markus T @ 2012-09-24 12:23 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey

Ping.

> -----Original Message-----
> From: Metzger, Markus T
> Sent: Tuesday, August 14, 2012 3:42 PM
> To: Mark Kettenis
> Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com; palves@redhat.com;
> tromey@redhat.com
> Subject: RE: [patch v3 16/16] btrace, x86: restrict to Atom
>
> > -----Original Message-----
> > From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> > Sent: Tuesday, August 14, 2012 3:27 PM
>
> Thanks for your feedback!
>
>
> > > +int
> > > +i386_linux_supports_btrace (void)
> > > +{
> > > +  unsigned int cpuid, model, family;
> > > +
> > > +  if (!linux_supports_btrace ())
> > > +    return 0;
> > > +
> > > +  __asm__ __volatile__ ("movl   $1, %%eax;"
> > > +                 "cpuid;"
> > > +                 : "=a" (cpuid)
> > > +                 :: "%ebx", "%ecx", "%edx");
> > > +
>
> [...]
>
> > You can't have this function in a -tdep.c, since this file needs to be
> > compilable everywhere (not just on i386/amd64).  But even in a -nat.c
> > file you shouldn't use inline assembly, since it isn't a standardized
> > C feature.  I can only guess why you want to restrict this feature to
> > Atom only, but I suspect that the proper solution is to query the
> > target whether branch tracing is supported.  That means the -nat.c
> > code should have code to query for support in the Linux kernel.
>
> I agree that it would be better to have this check done in the kernel. The problem is that such a patch will take very long before
> it becomes available in distributions. And even then, we would need to handle kernels without the patch, so we would need
> something
> similar to this in gdb, as well.
>
> I took the cpuid bits from gdb/go32-nat.c. I have not seen any compilation guard around it.
>
> I thought that the i386-tdep files are meant to contain i386 specific code, that's why I put the code there. Where would be the
> right place to put such code?
>
> Thanks,
> Markus.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-09-24 12:23       ` Metzger, Markus T
@ 2012-09-27  7:08         ` Joel Brobecker
  2012-09-28  2:40         ` Mark Kettenis
  1 sibling, 0 replies; 30+ messages in thread
From: Joel Brobecker @ 2012-09-27  7:08 UTC (permalink / raw)
  To: Metzger, Markus T
  Cc: Mark Kettenis, gdb-patches, markus.t.metzger, jan.kratochvil,
	palves, tromey

> > > > +  __asm__ __volatile__ ("movl   $1, %%eax;"
> > > > +                 "cpuid;"
> > > > +                 : "=a" (cpuid)
> > > > +                 :: "%ebx", "%ecx", "%edx");

[...]

> > > You can't have this function in a -tdep.c, since this file needs to be
> > > compilable everywhere (not just on i386/amd64).

[...]

> > I agree that it would be better to have this check done in the
> > kernel. The problem is that such a patch will take very long before
> > it becomes available in distributions. And even then, we would need
> > to handle kernels without the patch, so we would need something
> > similar to this in gdb, as well.

[...]

> > I thought that the i386-tdep files are meant to contain i386
> > specific code, that's why I put the code there. Where would be the
> > right place to put such code?

The -tdep files are target-support files, and are independent of
the host. For instance, you can very well have an x86-solaris debugger
hosted on x86_64-windows.

The code should be in a -nat file. If this is specific to x86 and
Linux kernels, I would say i386-linux-nat.c.

If you need to access this information from the tdep file, then
things get a little more tricky, since the tdep file cannot assume
that it is running on an x86-linux host. For that, we use a transfer
mechanism. See how we use TARGET_OBJECT_HPUX_SOLIB_GOT in
ia64-hpux-tdep.c for instance.

-- 
Joel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-09-24 12:23       ` Metzger, Markus T
  2012-09-27  7:08         ` Joel Brobecker
@ 2012-09-28  2:40         ` Mark Kettenis
  2012-09-28  6:51           ` Metzger, Markus T
  1 sibling, 1 reply; 30+ messages in thread
From: Mark Kettenis @ 2012-09-28  2:40 UTC (permalink / raw)
  To: markus.t.metzger
  Cc: mark.kettenis, gdb-patches, markus.t.metzger, jan.kratochvil,
	palves, tromey

> From: "Metzger, Markus T" <markus.t.metzger@intel.com>
> Date: Mon, 24 Sep 2012 12:22:42 +0000
> 
> Ping.

Native code can only go into -nat.c files.

But I still think putting CPU model specific checks anywhere in GDB is
wrong.  If there are broken kernels out there, figure out a way to
detect them.

> > -----Original Message-----
> > From: Metzger, Markus T
> > Sent: Tuesday, August 14, 2012 3:42 PM
> > To: Mark Kettenis
> > Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com; palves@redhat.com;
> > tromey@redhat.com
> > Subject: RE: [patch v3 16/16] btrace, x86: restrict to Atom
> >
> > > -----Original Message-----
> > > From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> > > Sent: Tuesday, August 14, 2012 3:27 PM
> >
> > Thanks for your feedback!
> >
> >
> > > > +int
> > > > +i386_linux_supports_btrace (void)
> > > > +{
> > > > +  unsigned int cpuid, model, family;
> > > > +
> > > > +  if (!linux_supports_btrace ())
> > > > +    return 0;
> > > > +
> > > > +  __asm__ __volatile__ ("movl   $1, %%eax;"
> > > > +                 "cpuid;"
> > > > +                 : "=a" (cpuid)
> > > > +                 :: "%ebx", "%ecx", "%edx");
> > > > +
> >
> > [...]
> >
> > > You can't have this function in a -tdep.c, since this file needs to be
> > > compilable everywhere (not just on i386/amd64).  But even in a -nat.c
> > > file you shouldn't use inline assembly, since it isn't a standardized
> > > C feature.  I can only guess why you want to restrict this feature to
> > > Atom only, but I suspect that the proper solution is to query the
> > > target whether branch tracing is supported.  That means the -nat.c
> > > code should have code to query for support in the Linux kernel.
> >
> > I agree that it would be better to have this check done in the kernel. The problem is that such a patch will take very long before
> > it becomes available in distributions. And even then, we would need to handle kernels without the patch, so we would need
> > something
> > similar to this in gdb, as well.
> >
> > I took the cpuid bits from gdb/go32-nat.c. I have not seen any compilation guard around it.
> >
> > I thought that the i386-tdep files are meant to contain i386 specific code, that's why I put the code there. Where would be the
> > right place to put such code?
> >
> > Thanks,
> > Markus.
> Intel GmbH
> Dornacher Strasse 1
> 85622 Feldkirchen/Muenchen, Deutschland
> Sitz der Gesellschaft: Feldkirchen bei Muenchen
> Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
> Registergericht: Muenchen HRB 47456
> Ust.-IdNr./VAT Registration No.: DE129385895
> Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
> 
> 
> 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-09-28  2:40         ` Mark Kettenis
@ 2012-09-28  6:51           ` Metzger, Markus T
  2012-10-01 19:24             ` Mark Kettenis
  0 siblings, 1 reply; 30+ messages in thread
From: Metzger, Markus T @ 2012-09-28  6:51 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: gdb-patches, markus.t.metzger, jan.kratochvil, palves, tromey

> -----Original Message-----
> From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> Sent: Friday, September 28, 2012 4:40 AM
> To: Metzger, Markus T
> Cc: mark.kettenis@xs4all.nl; gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com;
> palves@redhat.com; tromey@redhat.com
> Subject: Re: [patch v3 16/16] btrace, x86: restrict to Atom
> 
> > From: "Metzger, Markus T" <markus.t.metzger@intel.com>
> > Date: Mon, 24 Sep 2012 12:22:42 +0000
> >
> > Ping.
> 
> Native code can only go into -nat.c files.

Thanks. I sent out an updated patch.


> But I still think putting CPU model specific checks anywhere in GDB is
> wrong.  If there are broken kernels out there, figure out a way to
> detect them.

The cpuid check is simple and reliable. Anything else will be more complicated and also less straight-forward to understand.

Regards,
Markus.
> 
> > > -----Original Message-----
> > > From: Metzger, Markus T
> > > Sent: Tuesday, August 14, 2012 3:42 PM
> > > To: Mark Kettenis
> > > Cc: gdb-patches@sourceware.org; markus.t.metzger@gmail.com; jan.kratochvil@redhat.com; palves@redhat.com;
> > > tromey@redhat.com
> > > Subject: RE: [patch v3 16/16] btrace, x86: restrict to Atom
> > >
> > > > -----Original Message-----
> > > > From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> > > > Sent: Tuesday, August 14, 2012 3:27 PM
> > >
> > > Thanks for your feedback!
> > >
> > >
> > > > > +int
> > > > > +i386_linux_supports_btrace (void)
> > > > > +{
> > > > > +  unsigned int cpuid, model, family;
> > > > > +
> > > > > +  if (!linux_supports_btrace ())
> > > > > +    return 0;
> > > > > +
> > > > > +  __asm__ __volatile__ ("movl   $1, %%eax;"
> > > > > +                 "cpuid;"
> > > > > +                 : "=a" (cpuid)
> > > > > +                 :: "%ebx", "%ecx", "%edx");
> > > > > +
> > >
> > > [...]
> > >
> > > > You can't have this function in a -tdep.c, since this file needs to be
> > > > compilable everywhere (not just on i386/amd64).  But even in a -nat.c
> > > > file you shouldn't use inline assembly, since it isn't a standardized
> > > > C feature.  I can only guess why you want to restrict this feature to
> > > > Atom only, but I suspect that the proper solution is to query the
> > > > target whether branch tracing is supported.  That means the -nat.c
> > > > code should have code to query for support in the Linux kernel.
> > >
> > > I agree that it would be better to have this check done in the kernel. The problem is that such a patch will take very long before
> > > it becomes available in distributions. And even then, we would need to handle kernels without the patch, so we would need
> > > something
> > > similar to this in gdb, as well.
> > >
> > > I took the cpuid bits from gdb/go32-nat.c. I have not seen any compilation guard around it.
> > >
> > > I thought that the i386-tdep files are meant to contain i386 specific code, that's why I put the code there. Where would be the
> > > right place to put such code?
> > >
> > > Thanks,
> > > Markus.
> > Intel GmbH
> > Dornacher Strasse 1
> > 85622 Feldkirchen/Muenchen, Deutschland
> > Sitz der Gesellschaft: Feldkirchen bei Muenchen
> > Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
> > Registergericht: Muenchen HRB 47456
> > Ust.-IdNr./VAT Registration No.: DE129385895
> > Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
> >
> >
> >
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-09-28  6:51           ` Metzger, Markus T
@ 2012-10-01 19:24             ` Mark Kettenis
  2012-10-04  7:51               ` Metzger, Markus T
  0 siblings, 1 reply; 30+ messages in thread
From: Mark Kettenis @ 2012-10-01 19:24 UTC (permalink / raw)
  To: markus.t.metzger; +Cc: gdb-patches, markus.t.metzger

> From: "Metzger, Markus T" <markus.t.metzger@intel.com>
> Date: Fri, 28 Sep 2012 06:51:24 +0000
> 
> > But I still think putting CPU model specific checks anywhere in GDB is
> > wrong.  If there are broken kernels out there, figure out a way to
> > detect them.
> 
> The cpuid check is simple and reliable. Anything else will be more
> complicated and also less straight-forward to understand.

But what if btrace support shows up for other CPUs, or if a next
generation Atom shows up that has a different cpuid?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [patch v3 16/16] btrace, x86: restrict to Atom
  2012-10-01 19:24             ` Mark Kettenis
@ 2012-10-04  7:51               ` Metzger, Markus T
  0 siblings, 0 replies; 30+ messages in thread
From: Metzger, Markus T @ 2012-10-04  7:51 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches, markus.t.metzger

> -----Original Message-----
> From: Mark Kettenis [mailto:mark.kettenis@xs4all.nl]
> Sent: Monday, October 01, 2012 9:24 PM
> To: Metzger, Markus T

[...]

> > The cpuid check is simple and reliable. Anything else will be more
> > complicated and also less straight-forward to understand.
> 
> But what if btrace support shows up for other CPUs, or if a next
> generation Atom shows up that has a different cpuid?

For every new cpu that supports branch tracing, we will test it and send out a patch adding the new cpuid. This will be part of the general enabling for new cpus, e.g. new instructions or registers.

Regards,
Markus.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Peter Gleissner, Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2012-10-04  7:51 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-14 13:01 [patch v3 00/16] branch tracing support for Atom markus.t.metzger
2012-08-14 13:00 ` [patch v3 01/16] gdbserver, build: add -DGDBSERVER markus.t.metzger
2012-08-15  0:41   ` Doug Evans
2012-08-15  7:59     ` Metzger, Markus T
2012-08-14 13:00 ` [patch v3 02/16] disas: add precise instructions flag markus.t.metzger
2012-08-14 13:00 ` [patch v3 10/16] xml, btrace: define btrace xml document style markus.t.metzger
2012-08-14 13:01 ` [patch v3 08/16] linux, btrace: perf_event based branch tracing markus.t.metzger
2012-08-14 13:01 ` [patch v3 13/16] gdbserver, linux, btrace: add btrace support for linux-low markus.t.metzger
2012-08-14 13:01 ` [patch v3 07/16] configure: add check for perf_event header markus.t.metzger
2012-08-14 13:01 ` [patch v3 05/16] thread, btrace: add generic branch trace support markus.t.metzger
2012-08-14 13:01 ` [patch v3 09/16] linux, i386, amd64: enable btrace for 32bit and 64bit linux native markus.t.metzger
2012-08-14 13:01 ` [patch v3 16/16] btrace, x86: restrict to Atom markus.t.metzger
2012-08-14 13:27   ` Mark Kettenis
     [not found]     ` <A78C989F6D9628469189715575E55B2307ACF558@IRSMSX102.ger.corp.intel.com>
2012-08-14 15:57       ` FW: " Metzger, Markus T
2012-09-24 12:23       ` Metzger, Markus T
2012-09-27  7:08         ` Joel Brobecker
2012-09-28  2:40         ` Mark Kettenis
2012-09-28  6:51           ` Metzger, Markus T
2012-10-01 19:24             ` Mark Kettenis
2012-10-04  7:51               ` Metzger, Markus T
2012-08-14 13:01 ` [patch v3 11/16] remote, btrace: add branch trace remote ops markus.t.metzger
2012-08-14 13:01 ` [patch v3 12/16] gdbserver, btrace: add generic btrace support markus.t.metzger
2012-08-14 13:01 ` [patch v3 03/16] source: add flags to print_source_lines () markus.t.metzger
2012-09-11 20:14   ` Tom Tromey
2012-09-12  8:34     ` Metzger, Markus T
2012-08-14 13:01 ` [patch v3 04/16] source, disasm: optionally prefix source lines with filename markus.t.metzger
2012-09-11 20:21   ` Tom Tromey
2012-08-14 13:03 ` [patch v3 15/16] test, btrace: more branch tracing tests markus.t.metzger
2012-08-14 13:03 ` [patch v3 06/16] cli, btrace: add btrace cli markus.t.metzger
2012-08-14 13:03 ` [patch v3 14/16] test, btrace: add branch tracing tests markus.t.metzger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).