From d66be8a94a102f111da64b930a37726941de6ffa Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Dec 2017 17:37:45 +0300 Subject: [PATCH] db: introduce get_mtag_name_expr() This is quite similar to get_param_name() but the difference is that mtags are always pointers. So if you have a global "int my_global;" then the mtag name for that is "*$". Or if you have "foo.bar" that becomes "$->bar". Signed-off-by: Dan Carpenter --- smatch.h | 2 ++ smatch_db.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/smatch.h b/smatch.h index 2b32768b..76ce7745 100644 --- a/smatch.h +++ b/smatch.h @@ -756,6 +756,8 @@ char *get_variable_from_key(struct expression *arg, const char *key, struct symb const char *state_name_to_param_name(const char *state_name, const char *param_name); const char *get_param_name_var_sym(const char *name, struct symbol *sym); const char *get_param_name(struct sm_state *sm); +const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym); +const char *get_mtag_name_expr(struct expression *expr); char *get_data_info_name(struct expression *expr); #define run_sql(call_back, data, sql...) \ diff --git a/smatch_db.c b/smatch_db.c index 37e770ac..b8267653 100644 --- a/smatch_db.c +++ b/smatch_db.c @@ -2199,6 +2199,57 @@ const char *get_param_name_var_sym(const char *name, struct symbol *sym) return state_name_to_param_name(name, sym->ident->name); } +const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym) +{ + struct symbol *type; + const char *sym_name; + int name_len; + static char buf[256]; + + /* + * mtag_name is different from param_name because mtags can be a struct + * instead of a struct pointer. But we want to treat it like a pointer + * because really an mtag is a pointer. Or in other words, if you pass + * a struct foo then you want to talk about foo.bar but with an mtag + * you want to refer to it as foo->bar. + * + */ + + if (!sym || !sym->ident) + return NULL; + + type = get_real_base_type(sym); + if (type && type->type == SYM_BASETYPE) + return "*$"; + + sym_name = sym->ident->name; + name_len = strlen(sym_name); + + if (state_name[name_len] == '.' && /* check for '-' from "->" */ + strncmp(state_name, sym_name, name_len) == 0) { + snprintf(buf, sizeof(buf), "$->%s", state_name + name_len + 1); + return buf; + } + + return state_name_to_param_name(state_name, sym_name); +} + +const char *get_mtag_name_expr(struct expression *expr) +{ + char *name; + struct symbol *sym; + const char *ret = NULL; + + name = expr_to_var_sym(expr, &sym); + if (!name || !sym) + goto free; + + ret = get_mtag_name_var_sym(name, sym); +free: + free_string(name); + return ret; +} + const char *get_param_name(struct sm_state *sm) { return get_param_name_var_sym(sm->name, sm->sym); -- 2.11.4.GIT