356 struct expression *expr;
357 struct range_list *rl;
358 int left;
359 struct stree *stree;
360 struct db_implies_list *callbacks;
361 int prev_return_id;
362 int cull;
363 int has_states;
364 char *ret_str;
365 struct smatch_state *ret_state;
366 struct expression *var_expr;
367 int handled;
368 };
369
370 static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
371 {
372 db_info->ret_str = alloc_sname(ret_str),
373 db_info->ret_state = state;
374 }
375
376 static bool fake_a_param_assignment(struct expression *expr, const char *return_str)
377 {
378 struct expression *arg, *left, *right, *tmp, *fake_assign;
379 char *p;
380 int param;
381 char buf[256];
382 char *str;
383
384 if (expr->type != EXPR_ASSIGNMENT || expr->op != '=')
385 return false;
386 left = expr->left;
387 right = expr->right;
388
389 while (right->type == EXPR_ASSIGNMENT)
390 right = strip_expr(right->right);
391 if (!right || right->type != EXPR_CALL)
392 return false;
393
394 p = strchr(return_str, '[');
395 if (!p)
396 return false;
420 tmp = get_assigned_expr(arg);
421 if (tmp)
422 arg = tmp;
423
424 /*
425 * This is a sanity check to prevent side effects from evaluating stuff
426 * twice.
427 */
428 str = expr_to_chunk_sym_vsl(arg, NULL, NULL);
429 if (!str)
430 return false;
431 free_string(str);
432
433 right = gen_expression_from_key(arg, buf);
434 if (!right) /* Mostly fails for binops like [$0 + 4032] */
435 return false;
436 fake_assign = assign_expression(left, '=', right);
437 __in_fake_parameter_assign++;
438 __split_expr(fake_assign);
439 __in_fake_parameter_assign--;
440 return true;
441 }
442
443 static void set_return_assign_state(struct db_callback_info *db_info)
444 {
445 struct expression *expr = db_info->expr->left;
446 struct smatch_state *state;
447
448 if (!db_info->ret_state)
449 return;
450
451 state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
452 set_extra_expr_mod(expr, state);
453 db_info->ret_state = NULL;
454 fake_a_param_assignment(db_info->expr, db_info->ret_str);
455 db_info->ret_str = NULL;
456 }
457
458 static void set_other_side_state(struct db_callback_info *db_info)
459 {
460 struct expression *expr = db_info->var_expr;
461 struct smatch_state *state;
462
463 if (!db_info->ret_state)
464 return;
465
466 state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
467 set_extra_expr_nomod(expr, state);
468 db_info->ret_state = NULL;
469 db_info->ret_str = NULL;
470 }
471
472 static void handle_ret_equals_param(char *ret_string, struct range_list *rl, struct expression *call)
473 {
474 char *str;
1075 db_info->cull = 1;
1076 return 0;
1077 }
1078 if (is_impossible_data(type, db_info->expr, param, key, value)) {
1079 db_info->cull = 1;
1080 return 0;
1081 }
1082
1083 if (type == PARAM_LIMIT)
1084 param_limit_implications(db_info->expr, param, key, value);
1085
1086 call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
1087 ret_range = cast_rl(get_type(db_info->expr), ret_range);
1088
1089 if (type == INTERNAL) {
1090 set_state(-1, "unnull_path", NULL, &true_state);
1091 __add_return_comparison(strip_expr(db_info->expr), ret_str);
1092 __add_return_to_param_mapping(db_info->expr, ret_str);
1093 }
1094
1095
1096 FOR_EACH_PTR(db_return_states_list, tmp) {
1097 if (tmp->type == type)
1098 tmp->callback(db_info->expr, param, key, value);
1099 } END_FOR_EACH_PTR(tmp);
1100
1101 /*
1102 * We want to store the return values so that we can split the strees
1103 * in smatch_db.c. This uses set_state() directly because it's not a
1104 * real smatch_extra state.
1105 */
1106 snprintf(buf, sizeof(buf), "return %p", db_info->expr);
1107 set_state(SMATCH_EXTRA, buf, NULL, alloc_estate_rl(ret_range));
1108
1109 return 0;
1110 }
1111
1112 static void db_return_states(struct expression *expr)
1113 {
1114 struct sm_state *sm;
1115 struct stree *stree;
1153 } END_FOR_EACH_PTR_REVERSE(tmp);
1154
1155 return 0;
1156 }
1157
1158 static void db_return_states_call(struct expression *expr)
1159 {
1160 if (unreachable())
1161 return;
1162
1163 if (is_assigned_call(expr))
1164 return;
1165 if (is_condition_call(expr))
1166 return;
1167 db_return_states(expr);
1168 }
1169
1170 static void match_function_call(struct expression *expr)
1171 {
1172 struct call_back_list *call_backs;
1173
1174 if (expr->fn->type == EXPR_SYMBOL && expr->fn->symbol) {
1175 call_backs = search_callback(func_hash, (char *)expr->fn->symbol->ident->name);
1176 if (call_backs)
1177 call_call_backs(call_backs, REGULAR_CALL,
1178 expr->fn->symbol->ident->name, expr);
1179 }
1180 db_return_states_call(expr);
1181 }
1182
1183 static void match_macro_assign(struct expression *expr)
1184 {
1185 struct call_back_list *call_backs;
1186 const char *macro;
1187 struct expression *right;
1188
1189 right = strip_expr(expr->right);
1190 macro = get_macro_name(right->pos);
1191 call_backs = search_callback(func_hash, (char *)macro);
1192 if (!call_backs)
1193 return;
1194 call_call_backs(call_backs, MACRO_ASSIGN, macro, expr);
1195 call_call_backs(call_backs, MACRO_ASSIGN_EXTRA, macro, expr);
1196 }
1197
1198 int get_implied_return(struct expression *expr, struct range_list **rl)
|
356 struct expression *expr;
357 struct range_list *rl;
358 int left;
359 struct stree *stree;
360 struct db_implies_list *callbacks;
361 int prev_return_id;
362 int cull;
363 int has_states;
364 char *ret_str;
365 struct smatch_state *ret_state;
366 struct expression *var_expr;
367 int handled;
368 };
369
370 static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
371 {
372 db_info->ret_str = alloc_sname(ret_str),
373 db_info->ret_state = state;
374 }
375
376 static bool fake_a_param_assignment(struct expression *expr, const char *return_str, struct smatch_state *orig)
377 {
378 struct expression *arg, *left, *right, *tmp, *fake_assign;
379 char *p;
380 int param;
381 char buf[256];
382 char *str;
383
384 if (expr->type != EXPR_ASSIGNMENT || expr->op != '=')
385 return false;
386 left = expr->left;
387 right = expr->right;
388
389 while (right->type == EXPR_ASSIGNMENT)
390 right = strip_expr(right->right);
391 if (!right || right->type != EXPR_CALL)
392 return false;
393
394 p = strchr(return_str, '[');
395 if (!p)
396 return false;
420 tmp = get_assigned_expr(arg);
421 if (tmp)
422 arg = tmp;
423
424 /*
425 * This is a sanity check to prevent side effects from evaluating stuff
426 * twice.
427 */
428 str = expr_to_chunk_sym_vsl(arg, NULL, NULL);
429 if (!str)
430 return false;
431 free_string(str);
432
433 right = gen_expression_from_key(arg, buf);
434 if (!right) /* Mostly fails for binops like [$0 + 4032] */
435 return false;
436 fake_assign = assign_expression(left, '=', right);
437 __in_fake_parameter_assign++;
438 __split_expr(fake_assign);
439 __in_fake_parameter_assign--;
440
441 /*
442 * If the return is "0-65531[$0->nla_len - 4]" the faked expression
443 * is maybe (-4)-65531 but we know it is in the 0-65531 range so both
444 * parts have to be considered. We use _nomod() because it's not really
445 * another modification, it's just a clarification.
446 *
447 */
448 if (estate_rl(orig)) {
449 struct smatch_state *faked;
450 struct range_list *rl;
451
452 faked = get_extra_state(left);
453 if (estate_rl(faked)) {
454 rl = rl_intersection(estate_rl(faked), estate_rl(orig));
455 if (rl)
456 set_extra_expr_nomod(expr, alloc_estate_rl(rl));
457 }
458 }
459
460 return true;
461 }
462
463 static void set_return_assign_state(struct db_callback_info *db_info)
464 {
465 struct expression *expr = db_info->expr->left;
466 struct smatch_state *state;
467
468 if (!db_info->ret_state)
469 return;
470
471 state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
472 if (!fake_a_param_assignment(db_info->expr, db_info->ret_str, state))
473 set_extra_expr_mod(expr, state);
474
475 db_info->ret_state = NULL;
476 db_info->ret_str = NULL;
477 }
478
479 static void set_other_side_state(struct db_callback_info *db_info)
480 {
481 struct expression *expr = db_info->var_expr;
482 struct smatch_state *state;
483
484 if (!db_info->ret_state)
485 return;
486
487 state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
488 set_extra_expr_nomod(expr, state);
489 db_info->ret_state = NULL;
490 db_info->ret_str = NULL;
491 }
492
493 static void handle_ret_equals_param(char *ret_string, struct range_list *rl, struct expression *call)
494 {
495 char *str;
1096 db_info->cull = 1;
1097 return 0;
1098 }
1099 if (is_impossible_data(type, db_info->expr, param, key, value)) {
1100 db_info->cull = 1;
1101 return 0;
1102 }
1103
1104 if (type == PARAM_LIMIT)
1105 param_limit_implications(db_info->expr, param, key, value);
1106
1107 call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
1108 ret_range = cast_rl(get_type(db_info->expr), ret_range);
1109
1110 if (type == INTERNAL) {
1111 set_state(-1, "unnull_path", NULL, &true_state);
1112 __add_return_comparison(strip_expr(db_info->expr), ret_str);
1113 __add_return_to_param_mapping(db_info->expr, ret_str);
1114 }
1115
1116 FOR_EACH_PTR(db_return_states_list, tmp) {
1117 if (tmp->type == type)
1118 tmp->callback(db_info->expr, param, key, value);
1119 } END_FOR_EACH_PTR(tmp);
1120
1121 /*
1122 * We want to store the return values so that we can split the strees
1123 * in smatch_db.c. This uses set_state() directly because it's not a
1124 * real smatch_extra state.
1125 */
1126 snprintf(buf, sizeof(buf), "return %p", db_info->expr);
1127 set_state(SMATCH_EXTRA, buf, NULL, alloc_estate_rl(ret_range));
1128
1129 return 0;
1130 }
1131
1132 static void db_return_states(struct expression *expr)
1133 {
1134 struct sm_state *sm;
1135 struct stree *stree;
1173 } END_FOR_EACH_PTR_REVERSE(tmp);
1174
1175 return 0;
1176 }
1177
1178 static void db_return_states_call(struct expression *expr)
1179 {
1180 if (unreachable())
1181 return;
1182
1183 if (is_assigned_call(expr))
1184 return;
1185 if (is_condition_call(expr))
1186 return;
1187 db_return_states(expr);
1188 }
1189
1190 static void match_function_call(struct expression *expr)
1191 {
1192 struct call_back_list *call_backs;
1193 struct expression *fn;
1194
1195 fn = strip_expr(expr->fn);
1196 if (fn->type == EXPR_SYMBOL && fn->symbol) {
1197 call_backs = search_callback(func_hash, (char *)fn->symbol->ident->name);
1198 if (call_backs)
1199 call_call_backs(call_backs, REGULAR_CALL,
1200 fn->symbol->ident->name, expr);
1201 }
1202 db_return_states_call(expr);
1203 }
1204
1205 static void match_macro_assign(struct expression *expr)
1206 {
1207 struct call_back_list *call_backs;
1208 const char *macro;
1209 struct expression *right;
1210
1211 right = strip_expr(expr->right);
1212 macro = get_macro_name(right->pos);
1213 call_backs = search_callback(func_hash, (char *)macro);
1214 if (!call_backs)
1215 return;
1216 call_call_backs(call_backs, MACRO_ASSIGN, macro, expr);
1217 call_call_backs(call_backs, MACRO_ASSIGN_EXTRA, macro, expr);
1218 }
1219
1220 int get_implied_return(struct expression *expr, struct range_list **rl)
|