Print this page
12724 update smatch to 0.6.1-rc1-il-5

@@ -66,46 +66,68 @@
         *tag &= ~MTAG_OFFSET_MASK;
 
         return *tag;
 }
 
-const struct {
-        const char *name;
-        int size_arg;
-} allocator_info[] = {
-        { "kmalloc", 0 },
-        { "kzalloc", 0 },
-        { "devm_kmalloc", 1},
-        { "devm_kzalloc", 1},
-};
+static int save_allocator(void *_allocator, int argc, char **argv, char **azColName)
+{
+        char **allocator = _allocator;
 
-static bool is_mtag_call(struct expression *expr)
+        if (*allocator) {
+                if (strcmp(*allocator, argv[0]) == 0)
+                        return 0;
+                /* should be impossible */
+                free_string(*allocator);
+                *allocator = alloc_string("unknown");
+                return 0;
+        }
+        *allocator = alloc_string(argv[0]);
+        return 0;
+}
+
+char *get_allocator_info_from_tag(mtag_t tag)
 {
-        struct expression *arg;
-        int i;
+        char *allocator = NULL;
+
+        run_sql(save_allocator, &allocator,
+                "select value from mtag_info where tag = %lld and type = %d;",
+                tag, ALLOCATOR);
+
+        return allocator;
+}
+
+static char *get_allocator_info(struct expression *expr, struct smatch_state *state)
+{
         sval_t sval;
 
+        if (expr->type != EXPR_ASSIGNMENT)
+                return NULL;
+        if (estate_get_single_value(state, &sval))
+                return get_allocator_info_from_tag(sval.value);
+
+        expr = strip_expr(expr->right);
         if (expr->type != EXPR_CALL ||
-            expr->fn->type != EXPR_SYMBOL ||
-            !expr->fn->symbol)
-                return false;
+            !expr->fn ||
+            expr->fn->type != EXPR_SYMBOL)
+                return NULL;
+        return expr_to_str(expr->fn);
+}
 
-        for (i = 0; i < ARRAY_SIZE(allocator_info); i++) {
-                if (strcmp(expr->fn->symbol->ident->name, allocator_info[i].name) == 0)
-                        break;
-        }
-        if (i == ARRAY_SIZE(allocator_info))
-                return false;
+static void update_mtag_info(struct expression *expr, mtag_t tag,
+                             const char *left_name, const char *tag_info,
+                             struct smatch_state *state)
+{
+        char *allocator;
 
-        arg = get_argument_from_call_expr(expr->args, allocator_info[i].size_arg);
-        if (!get_implied_value(arg, &sval))
-                return false;
+        sql_insert_mtag_about(tag, left_name, tag_info);
 
-        return true;
+        allocator = get_allocator_info(expr, state);
+        if (allocator)
+                sql_insert_mtag_info(tag, ALLOCATOR, allocator);
 }
 
-struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_state *state)
+struct smatch_state *get_mtag_return(struct expression *expr, struct smatch_state *state)
 {
         struct expression *left, *right;
         char *left_name, *right_name;
         struct symbol *left_sym;
         struct range_list *rl;

@@ -112,24 +134,22 @@
         char buf[256];
         mtag_t tag;
         sval_t tag_sval;
 
         if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=')
-                return state;
+                return NULL;
+        if (!is_fresh_alloc(expr->right))
+                return NULL;
+        if (!rl_intersection(estate_rl(state), valid_ptr_rl))
+                return NULL;
 
-        if (!estate_rl(state) || strcmp(state->name, "0,4096-ptr_max") != 0)
-                return state;
-
         left = strip_expr(expr->left);
         right = strip_expr(expr->right);
 
-        if (!is_mtag_call(right))
-                return state;
-
         left_name = expr_to_str_sym(left, &left_sym);
         if (!left_name || !left_sym)
-                return state;
+                return NULL;
         right_name = expr_to_str(right);
 
         snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(),
                  left_name, right_name);
         tag = str_to_mtag(buf);

@@ -138,11 +158,11 @@
 
         rl = rl_filter(estate_rl(state), valid_ptr_rl);
         rl = clone_rl(rl);
         add_range(&rl, tag_sval, tag_sval);
 
-        sql_insert_mtag_about(tag, left_name, buf);
+        update_mtag_info(expr, tag, left_name, buf, state);
 
         free_string(left_name);
         free_string(right_name);
 
         return alloc_estate_rl(rl);