aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2011-03-06 21:39:53 +0000
committerAurelien Jarno <aurelien@aurel32.net>2011-03-07 09:26:06 +0100
commit27bfd83c336283d1f7a5345ee386c4cd7b80db61 (patch)
tree21e8fb770030f606b15f09087262e2db2e3a7549 /tcg/tcg.c
parent6ed221b637713aec903136e3061e714fa4809bdd (diff)
tcg: Add support for debugging leakage of temporaries
Add support (if CONFIG_DEBUG_TCG is defined) for debugging leakage of temporary variables. Generally any temporaries created by a target while it is translating an instruction should be freed by the end of that instruction; otherwise carefully crafted guest code could cause TCG to run out of temporaries and assert. By calling tcg_check_temp_count() after each instruction we can check that we are not leaking temporaries in this way. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r--tcg/tcg.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 5dd6a2c613..8748c05b5a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -450,6 +450,10 @@ static inline int tcg_temp_new_internal(TCGType type, int temp_local)
s->nb_temps++;
}
}
+
+#if defined(CONFIG_DEBUG_TCG)
+ s->temps_in_use++;
+#endif
return idx;
}
@@ -475,6 +479,13 @@ static inline void tcg_temp_free_internal(int idx)
TCGTemp *ts;
int k;
+#if defined(CONFIG_DEBUG_TCG)
+ s->temps_in_use--;
+ if (s->temps_in_use < 0) {
+ fprintf(stderr, "More temporaries freed than allocated!\n");
+ }
+#endif
+
assert(idx >= s->nb_globals && idx < s->nb_temps);
ts = &s->temps[idx];
assert(ts->temp_allocated != 0);
@@ -528,6 +539,27 @@ TCGv_i64 tcg_const_local_i64(int64_t val)
return t0;
}
+#if defined(CONFIG_DEBUG_TCG)
+void tcg_clear_temp_count(void)
+{
+ TCGContext *s = &tcg_ctx;
+ s->temps_in_use = 0;
+}
+
+int tcg_check_temp_count(void)
+{
+ TCGContext *s = &tcg_ctx;
+ if (s->temps_in_use) {
+ /* Clear the count so that we don't give another
+ * warning immediately next time around.
+ */
+ s->temps_in_use = 0;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
void tcg_register_helper(void *func, const char *name)
{
TCGContext *s = &tcg_ctx;