1 /* 2 * Copyright (C) 2013 Oracle. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt 16 */ 17 18 #include "smatch.h" 19 #include "smatch_slist.h" 20 #include "smatch_extra.h" 21 22 static int my_id; 23 24 static char *get_source_parameter(struct expression *expr) 25 { 26 struct expression *tmp; 27 const char *param_name; 28 struct symbol *sym; 29 char *name; 30 int param; 31 char *ret = NULL; 32 char buf[32]; 33 int cnt = 0; 34 bool modified = false; 35 36 tmp = expr; 37 while ((tmp = get_assigned_expr(tmp))) { 38 expr = tmp; 39 if (cnt++ > 3) 40 break; 41 } 42 43 expr = strip_expr(expr); 44 if (expr->type != EXPR_SYMBOL) 45 return NULL; 46 47 name = expr_to_var_sym(expr, &sym); 48 if (!name || !sym) 49 goto free; 50 param = get_param_num_from_sym(sym); 51 if (param < 0) 52 goto free; 53 param_name = get_param_name_var_sym(name, sym); 54 if (!param_name) 55 goto free; 56 if (param_was_set_var_sym(name, sym)) 57 modified = true; 58 59 snprintf(buf, sizeof(buf), "$%d%s%s", param, param_name + 1, 60 modified ? " [m]" : ""); 61 ret = alloc_string(buf); 62 63 free: 64 free_string(name); 65 return ret; 66 } 67 68 static char *get_source_assignment(struct expression *expr) 69 { 70 struct expression *right; 71 char *name; 72 char buf[64]; 73 char *ret; 74 75 right = get_assigned_expr(expr); 76 right = strip_expr(right); 77 if (!right) 78 return NULL; 79 if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL) 80 return NULL; 81 if (is_fake_call(right)) 82 return NULL; 83 name = expr_to_str(right->fn); 84 if (!name) 85 return NULL; 86 snprintf(buf, sizeof(buf), "r %s", name); 87 ret = alloc_string(buf); 88 free_string(name); 89 return ret; 90 } 91 92 static char *get_source_str(struct expression *arg) 93 { 94 char *source; 95 96 source = get_source_parameter(arg); 97 if (source) 98 return source; 99 return get_source_assignment(arg); 100 } 101 102 static void match_caller_info(struct expression *expr) 103 { 104 struct expression *arg; 105 char *source; 106 int i; 107 108 i = -1; 109 FOR_EACH_PTR(expr->args, arg) { 110 i++; 111 source = get_source_str(arg); 112 if (!source) 113 continue; 114 sql_insert_caller_info(expr, DATA_SOURCE, i, "$", source); 115 free_string(source); 116 } END_FOR_EACH_PTR(arg); 117 } 118 119 void register_data_source(int id) 120 { 121 // if (!option_info) 122 // return; 123 my_id = id; 124 add_hook(&match_caller_info, FUNCTION_CALL_HOOK); 125 } 126