[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file pa
From: |
Peer Adelt |
Subject: |
[Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser |
Date: |
Fri, 8 Jan 2016 17:36:46 +0100 |
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 <address@hidden>
---
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
- [Qemu-devel] [RFC PATCH 1/3] tb-annotation: Added annotation XML file parser,
Peer Adelt <=