]> git.cworth.org Git - fips/blobdiff - metrics.c
Fix buffer overrun in accumulate_program_metrics
[fips] / metrics.c
index 71fe82da1b3d5ff06cf6dd94aa541f14f0b38a33..9f66ded156bc997e8572fce88c258aa60f3f7313 100644 (file)
--- a/metrics.c
+++ b/metrics.c
@@ -191,9 +191,6 @@ metrics_group_info_fini (metrics_group_info_t *group)
        free (group->name);
 }
 
-static void
-metrics_info_fini (metrics_info_t *info);
-
 /* A helper function, part of metrics_info_init below. */
 
 typedef enum {
@@ -265,9 +262,6 @@ metrics_info_init (void)
        GLuint *group_ids;
        metrics_info_t *info = &current_context.metrics_info;
 
-       if (info->initialized)
-               metrics_info_fini (info);
-
        glGetPerfMonitorGroupsAMD ((int *) &info->num_groups, 0, NULL);
 
        group_ids = xmalloc (info->num_groups * sizeof (GLuint));
@@ -306,20 +300,50 @@ metrics_info_init (void)
        info->initialized = 1;
 }
 
-static void
-metrics_info_fini (metrics_info_t *info)
+void
+metrics_info_fini (void)
 {
+       metrics_info_t *info = &current_context.metrics_info;
        unsigned i;
+       timer_query_t *timer, *timer_next;
+       monitor_t *monitor, *monitor_next;
+
+       if (! info->initialized)
+               return;
+
+       for (timer = current_context.timer_head;
+            timer;
+            timer = timer_next)
+       {
+               timer_next = timer->next;
+               free (timer);
+       }
+       current_context.timer_head = NULL;
+       current_context.timer_tail = NULL;
+
+       for (monitor = current_context.monitor_head;
+            monitor;
+            monitor = monitor_next)
+       {
+               monitor_next = monitor->next;
+               free (monitor);
+       }
+       current_context.monitor_head = NULL;
+       current_context.monitor_tail = NULL;
 
        for (i = 0; i < info->num_groups; i++)
                metrics_group_info_fini (&info->groups[i]);
 
        free (info->groups);
+       info->groups = NULL;
 
        for (i = 0; i < info->num_shader_stages; i++)
                free (info->stages[i].name);
 
        free (info->stages);
+       info->stages = NULL;
+
+       info->initialized = 0;
 }
 
 static const char *
@@ -508,6 +532,7 @@ accumulate_program_metrics (metrics_op_t op, GLuint *result, GLuint size)
 
        context_t *ctx = &current_context;
        metrics_info_t *info = &ctx->metrics_info;
+       op_metrics_t *metrics = ctx_get_op_metrics (ctx, op);
        unsigned char *p = (unsigned char *) result;
 
        while (p < ((unsigned char *) result) + size)
@@ -561,7 +586,7 @@ accumulate_program_metrics (metrics_op_t op, GLuint *result, GLuint size)
                        break;
                }
 
-               ctx->op_metrics[op].counters[group_index][counter_index] += value;
+               metrics->counters[group_index][counter_index] += value;
        }
 }
 
@@ -776,7 +801,7 @@ metrics_exit (void)
        if (verbose)
                printf ("fips: terminating\n");
 
-       metrics_info_fini (&current_context.metrics_info);
+       metrics_info_fini ();
 }