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 struct symbol *sym; 28 char *name; 29 int param; 30 char *ret = NULL; 31 char buf[32]; 32 int cnt = 0; 33 34 tmp = expr; 35 while ((tmp = get_assigned_expr(tmp))) { 36 expr = tmp; 37 if (cnt++ > 3) 38 break; 39 } 40 41 expr = strip_expr(expr); 42 if (expr->type != EXPR_SYMBOL) 43 return NULL; 44 45 name = expr_to_var_sym(expr, &sym); 46 if (!name || !sym) 47 goto free; 48 param = get_param_num_from_sym(sym); 49 if (param < 0) 50 goto free; 51 if (param_was_set(expr)) 52 goto free; 53 54 snprintf(buf, sizeof(buf), "p %d", param); 55 ret = alloc_string(buf); 56 57 free: 58 free_string(name); 59 return ret; 60 } 61 62 static char *get_source_assignment(struct expression *expr) 63 { 64 struct expression *right; 65 char *name; 66 char buf[64]; 67 char *ret; 68 69 right = get_assigned_expr(expr); 70 right = strip_expr(right); 71 if (!right) 72 return NULL; 73 if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL) 74 return NULL; 75 if (is_fake_call(right)) 76 return NULL; 77 name = expr_to_str(right->fn); 78 if (!name) 79 return NULL; 80 snprintf(buf, sizeof(buf), "r %s", name); 81 ret = alloc_string(buf); 82 free_string(name); 83 return ret; 84 } 85 86 static char *get_source_str(struct expression *arg) 87 { 88 char *source; 89 90 source = get_source_parameter(arg); 91 if (source) 92 return source; 93 return get_source_assignment(arg); 94 } 95 96 static void match_caller_info(struct expression *expr) 97 { 98 struct expression *arg; 99 char *source; 100 int i; 101 102 i = -1; 103 FOR_EACH_PTR(expr->args, arg) { 104 i++; 105 source = get_source_str(arg); 106 if (!source) 107 continue; 108 sql_insert_caller_info(expr, DATA_SOURCE, i, "$", source); 109 free_string(source); 110 } END_FOR_EACH_PTR(arg); 111 } 112 113 void register_data_source(int id) 114 { 115 // if (!option_info) 116 // return; 117 my_id = id; 118 add_hook(&match_caller_info, FUNCTION_CALL_HOOK); 119 }