All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser
@ 2016-01-08 16:36 Peer Adelt
  2016-01-08 16:36 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt
  2016-01-08 16:36 ` [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension Peer Adelt
  0 siblings, 2 replies; 4+ messages in thread
From: Peer Adelt @ 2016-01-08 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: kbastian, Peer Adelt

The XML file contains a control flow graph, where each edge
is annotated with a context-dependent value. The parser reads
this information into a data structure within CPUState.

Signed-off-by: Peer Adelt <peer.adelt@c-lab.de>
---
 include/qom/cpu.h                            |   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +++++
 include/tb-annotation/tb-annotation.h        |  64 ++++++++++
 tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
 4 files changed, 276 insertions(+)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/tb-annotation-parser.c

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 51a1323..afc532b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -30,6 +30,10 @@
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
 
+#ifdef CONFIG_TB_ANNOTATION
+#include "tb-annotation/tb-annotation.h"
+#endif
+
 typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
                                      void *opaque);
 
@@ -329,6 +333,11 @@ struct CPUState {
      */
     bool throttle_thread_scheduled;
 
+#ifdef CONFIG_TB_ANNOTATION
+    /* Used to annotate cpu state during tb execution */
+    TbAnnotation *tb_annotation;
+#endif
+
     /* Note that this is accessed at the start of every TB via a negative
        offset from AREG0.  Leave this field at the end so as to make the
        (absolute value) offset as small as possible.  This reduces code
diff --git a/include/tb-annotation/tb-annotation-parser.h b/include/tb-annotation/tb-annotation-parser.h
new file mode 100644
index 0000000..aacab8e
--- /dev/null
+++ b/include/tb-annotation/tb-annotation-parser.h
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_PARSER_H_
+#define INCLUDE_TB_ANNOTATION_PARSER_H_
+
+#include "tb-annotation/tb-annotation.h"
+
+void tb_annotation_xml_init(const char *filename);
+void tb_annotation_xml_close(void);
+TbAnnotation *tb_annotation_parse(const char *filename);
+
+#endif /* INCLUDE_TB_ANNOTATION_PARSER_H_ */
diff --git a/include/tb-annotation/tb-annotation.h b/include/tb-annotation/tb-annotation.h
new file mode 100644
index 0000000..e1093b2
--- /dev/null
+++ b/include/tb-annotation/tb-annotation.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INCLUDE_TB_ANNOTATION_H_
+#define INCLUDE_TB_ANNOTATION_H_
+
+#include <glib.h>
+
+typedef struct tb_leaving_edge_tuple TbAnnotationLeavingEdgeTuple;
+typedef struct tb_annotation_block TbAnnotationBlock;
+typedef struct tb_annotation_edge TbAnnotationEdge;
+typedef struct tb_annotation TbAnnotation;
+
+struct tb_leaving_edge_tuple {
+    TbAnnotationEdge *out1;
+    TbAnnotationEdge *out2;
+};
+
+struct tb_annotation_block {
+    uint8_t is_end_block;
+    const char *id;
+    unsigned int address;
+    /* This hashtable points to all pairs of leaving edges
+     * from all source contexts.
+     * Note: string -> tb_leaving_edge_tuple
+     */
+    GHashTable *out_edges_hash_table;
+};
+
+struct tb_annotation_edge {
+    TbAnnotationBlock *source;
+    TbAnnotationBlock *target;
+    const char *source_context;
+    const char *target_context;
+    unsigned int value;
+};
+
+struct tb_annotation {
+
+    TbAnnotationBlock *last_block;
+    const char *last_ctx;
+    /* Hashes from PC to TbAnnotationBlock */
+    GHashTable *tb_annotation_blocks;
+    unsigned int value_sum;
+
+};
+
+#endif /* INCLUDE_TB_ANNOTATION_H_ */
diff --git a/tb-annotation/tb-annotation-parser.c b/tb-annotation/tb-annotation-parser.c
new file mode 100644
index 0000000..b3cb2e7
--- /dev/null
+++ b/tb-annotation/tb-annotation-parser.c
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (c) 2015-2016 Bastian Koppelmann
+ *                          Peer Adelt
+ *                          C-Lab/Paderborn University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/tree.h>
+
+#include "tb-annotation/tb-annotation.h"
+#include "tb-annotation/tb-annotation-parser.h"
+
+xmlDocPtr tb_annotation_doc;
+xmlXPathContextPtr tb_annotation_xpathctx;
+xmlXPathObjectPtr tb_annotation_xpath;
+
+void tb_annotation_xml_init(const char *filename)
+{
+
+    /* Load XML file */
+    tb_annotation_doc = xmlParseFile(filename);
+    assert(tb_annotation_doc);
+
+    /* Create XPath evaluation context */
+    tb_annotation_xpathctx = xmlXPathNewContext(tb_annotation_doc);
+    assert(tb_annotation_xpathctx);
+}
+
+void tb_annotation_xml_close(void)
+{
+
+    xmlXPathFreeObject(tb_annotation_xpath);
+    xmlXPathFreeContext(tb_annotation_xpathctx);
+    xmlFreeDoc(tb_annotation_doc);
+}
+
+static int32_t tb_annotation_xml_evalxpath(const char *xpath,
+        xmlNodeSetPtr *nodes)
+{
+
+    /* Evaluate the expression */
+    tb_annotation_xpath = xmlXPathEvalExpression(BAD_CAST xpath,
+            tb_annotation_xpathctx);
+    assert(tb_annotation_xpath);
+
+    /* Set the return value */
+    *nodes = tb_annotation_xpath->nodesetval;
+    return tb_annotation_xpath->nodesetval->nodeNr;
+}
+
+TbAnnotation *tb_annotation_parse(const char *filename)
+{
+    int32_t i;
+    xmlNodeSetPtr nodes = NULL;
+    TbAnnotationBlock *cur_block;
+    TbAnnotationLeavingEdgeTuple *cur_leaving_edge_tuple;
+    TbAnnotationEdge *cur_edge;
+    GHashTable *id_to_block = g_hash_table_new(g_str_hash, g_str_equal);
+    TbAnnotation *tba = g_new0(TbAnnotation, 1);
+    tba->tb_annotation_blocks = g_hash_table_new(g_int_hash, g_int_equal);
+
+    /* Open XML file */
+    tb_annotation_xml_init(filename);
+
+    /* Parse Blocks */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Blocks/Block", &nodes);
+    for (i = 0; i < nodes->nodeNr; i++) {
+
+        /* Read XML description of current block */
+        const char *id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "id");
+        const char *address_str = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "address");
+
+        /* Create the block */
+        cur_block = g_new0(TbAnnotationBlock, 1);
+        cur_block->out_edges_hash_table = g_hash_table_new(
+                g_str_hash, g_str_equal);
+        cur_block->id = id;
+        cur_block->address = -1;
+
+        if (g_strcmp0("None", address_str) == 0) {
+
+            cur_block->is_end_block = 1;
+
+        } else {
+
+            cur_block->is_end_block = 0;
+            sscanf(address_str, "%x", &cur_block->address);
+
+            /* Store current block in TbAnnotations PC -> block map */
+            g_hash_table_insert(tba->tb_annotation_blocks, &cur_block->address,
+                    cur_block);
+        }
+
+        /* Store in id -> block map for edge creation */
+        g_hash_table_insert(id_to_block, (gpointer) id, cur_block);
+    }
+
+    /* Parse Edges (also adding out_edges to blocks) */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Edges/Edge", &nodes);
+    for (i = 0; i < nodes->nodeNr; i++) {
+
+        /* Read XML description of current edge */
+        const char *source_id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "source");
+        const char *source_ctx = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "source_context");
+        const char *target_id = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "target");
+        const char *target_ctx = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "target_context");
+        const char *value_str = (const char *) xmlGetNoNsProp(
+                nodes->nodeTab[i], BAD_CAST "value");
+
+        /* Create the edge */
+        cur_edge = g_new0(TbAnnotationEdge, 1);
+        cur_edge->source = g_hash_table_lookup(id_to_block, source_id);
+        cur_edge->target = g_hash_table_lookup(id_to_block, target_id);
+        cur_edge->source_context = source_ctx;
+        cur_edge->target_context = target_ctx;
+        sscanf(value_str, "%u", &cur_edge->value);
+
+        /* Store this edge in source blocks leaving_edge_tuple */
+        cur_leaving_edge_tuple = g_hash_table_lookup(
+                cur_edge->source->out_edges_hash_table,
+                cur_edge->source_context);
+        if (cur_leaving_edge_tuple == NULL) {
+            cur_leaving_edge_tuple = g_new0(TbAnnotationLeavingEdgeTuple, 1);
+            g_hash_table_insert(cur_edge->source->out_edges_hash_table,
+                    (gpointer) cur_edge->source_context,
+                    cur_leaving_edge_tuple);
+        }
+        /* There must be free space in the leaving_edge_tuple ... */
+        assert(cur_leaving_edge_tuple->out1 == NULL ||
+               cur_leaving_edge_tuple->out2 == NULL);
+        if (cur_leaving_edge_tuple->out1 == NULL) {
+            cur_leaving_edge_tuple->out1 = cur_edge;
+        } else {
+            cur_leaving_edge_tuple->out2 = cur_edge;
+        }
+    }
+
+    /* Parse Startcontext */
+    tb_annotation_xml_evalxpath("/QEMU-annotation/Start-context", &nodes);
+    assert(nodes->nodeNr == 1);
+    tba->last_ctx = (const char *) xmlGetNoNsProp(nodes->nodeTab[0],
+    BAD_CAST "value");
+
+    /* Destroy temporary block id -> block map */
+    g_hash_table_destroy(id_to_block);
+
+    /* Close XML file */
+    tb_annotation_xml_close();
+
+    /* Return TbAnnotation data */
+    return tba;
+}
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism
@ 2016-01-14 10:55 Peer Adelt
  2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
  0 siblings, 1 reply; 4+ messages in thread
From: Peer Adelt @ 2016-01-14 10:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peer Adelt, kbastian

Hey guys :)

We have developed a generic concept to annotate TranslationBlocks during
runtime. The initial idea was to use it for time annotation with data from
static analysis tools. However, we have kept this approach as generic as
possible to allow other kinds of annotation (e.g. power consumption, etc.).

Our extension expects an XML file specifying the CFG of the program (similar
to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
with the data, that QEMU ought to accumulate during program execution. Each
edge has a source and target context in which it is executed.
For example: a for-loop that runs several times has its own context dependent
edge for each iteration. We plan on making this more flexible by allowing
to specify iterative context edges, i.e. from context n to context n+1.

This approach is not limited to one target architecture but we only tested
it for ARM and TriCore so far.

To show the current state of this patch we have attached a very small example
consisting of an ARM STM32F205 program and a timing annotation XML file (see
reply to this letter). You can provide the XML file to QEMU with the 
"-annotation <XML-File>" option. During execution, the "value_sum" field of
the CPUState data structure will accumulate a total value of 70 (cycles).

Are there any comments? Is this in general a good idea to be added to upstream
QEMU?

All the best,
Peer

Peer Adelt (3):
  tb-annotation: Added annotation XML file parser
  tb-annotation: Add control flow graph mapper
  tb-annotation: Activate annotation extension

 Makefile                                     |   5 +-
 Makefile.objs                                |   4 +
 Makefile.target                              |   4 +-
 configure                                    |  13 ++
 include/exec/gen-icount.h                    |  18 +++
 include/qom/cpu.h                            |   9 ++
 include/tb-annotation/tb-annotation-parser.h |  29 +++++
 include/tb-annotation/tb-annotation.h        |  64 ++++++++++
 qemu-options.hx                              |   8 ++
 tb-annotation/Makefile.objs                  |   1 +
 tb-annotation/tb-annotation-parser.c         | 174 +++++++++++++++++++++++++++
 tcg-runtime.c                                |  99 +++++++++++++++
 tcg/tcg-runtime.h                            |   4 +
 vl.c                                         |  25 ++++
 14 files changed, 454 insertions(+), 3 deletions(-)
 create mode 100644 include/tb-annotation/tb-annotation-parser.h
 create mode 100644 include/tb-annotation/tb-annotation.h
 create mode 100644 tb-annotation/Makefile.objs
 create mode 100644 tb-annotation/tb-annotation-parser.c

-- 
2.5.0

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

end of thread, other threads:[~2016-01-14 10:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-08 16:36 [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt
2016-01-08 16:36 ` [Qemu-devel] [RFC PATCH 2/3] tb-annotation: Add control flow graph mapper Peer Adelt
2016-01-08 16:36 ` [Qemu-devel] [RFC PATCH 3/3] tb-annotation: Activate annotation extension Peer Adelt
2016-01-14 10:55 [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism Peer Adelt
2016-01-14 10:55 ` [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser Peer Adelt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.