Print this page
11506 smatch resync


  62 DECLARE_PTR_LIST(returned_member_cb_list, struct returned_member_callback);
  63 static struct returned_member_cb_list *returned_member_callbacks;
  64 
  65 struct db_implies_callback {
  66         int type;
  67         void (*callback)(struct expression *call, struct expression *arg, char *key, char *value);
  68 };
  69 ALLOCATOR(db_implies_callback, "return_implies callbacks");
  70 DECLARE_PTR_LIST(db_implies_cb_list, struct db_implies_callback);
  71 static struct db_implies_cb_list *return_implies_cb_list;
  72 static struct db_implies_cb_list *call_implies_cb_list;
  73 
  74 /* silently truncates if needed. */
  75 char *escape_newlines(const char *str)
  76 {
  77         char buf[1024] = "";
  78         bool found = false;
  79         int i, j;
  80 
  81         for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
  82                 if (str[i] != '\n') {
  83                         buf[j] = str[i];
  84                         continue;
  85                 }
  86 
  87                 found = true;
  88                 buf[j++] = '\\';
  89                 if (j == sizeof(buf))
  90                          break;
  91                 buf[j] = 'n';
  92         }
  93 
  94         if (!found)
  95                 return alloc_sname(str);
  96 
  97         if (j == sizeof(buf))
  98                 buf[j - 1] = '\0';
  99         return alloc_sname(buf);
 100 }
 101 
 102 static int print_sql_output(void *unused, int argc, char **argv, char **azColName)


 235         if (!option_info)
 236                 return;
 237 
 238         if (strncmp(fn, "__builtin_", 10) == 0)
 239                 return;
 240         if (type != INTERNAL && is_common_function(fn))
 241                 return;
 242 
 243         sm_outfd = caller_info_fd;
 244         sm_msg("SQL_caller_info: insert into caller_info values ("
 245                "'%s', '%s', '%s', %%CALL_ID%%, %d, %d, %d, '%s', '%s');",
 246                get_base_file(), get_function(), fn, is_static(call->fn),
 247                type, param, key, value);
 248         sm_outfd = tmp_fd;
 249 
 250         free_string(fn);
 251 }
 252 
 253 void sql_insert_function_ptr(const char *fn, const char *struct_name)
 254 {
 255         sql_insert(function_ptr, "'%s', '%s', '%s', 0", get_base_file(), fn,
 256                    struct_name);
 257 }
 258 
 259 void sql_insert_return_implies(int type, int param, const char *key, const char *value)
 260 {
 261         sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 262                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 263                 fn_static(), type, param, key, value);
 264 }
 265 
 266 void sql_insert_call_implies(int type, int param, const char *key, const char *value)
 267 {
 268         sql_insert_or_ignore(call_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 269                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 270                 fn_static(), type, param, key, value);
 271 }
 272 
 273 void sql_insert_function_type_size(const char *member, const char *ranges)
 274 {
 275         sql_insert(function_type_size, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), member, ranges);
 276 }


 314         data_name = get_data_info_name(data);
 315         if (!data_name)
 316                 return;
 317         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 318                    is_static(data) ? get_base_file() : "extern",
 319                    data_name, type, value);
 320 }
 321 
 322 void sql_insert_data_info_var_sym(const char *var, struct symbol *sym, int type, const char *value)
 323 {
 324         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 325                    (sym->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 326                    var, type, value);
 327 }
 328 
 329 void sql_save_constraint(const char *con)
 330 {
 331         if (!option_info)
 332                 return;
 333 
 334         sm_msg("SQL: insert or ignore into constraints (str) values('%s');", con);
 335 }
 336 
 337 void sql_save_constraint_required(const char *data, int op, const char *limit)
 338 {
 339         sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
 340 }
 341 
 342 void sql_copy_constraint_required(const char *new_limit, const char *old_limit)
 343 {
 344         if (!option_info)
 345                 return;
 346 
 347         sm_msg("SQL_late: insert or ignore into constraints_required (data, op, bound) "
 348                 "select constraints_required.data, constraints_required.op, '%s' from "
 349                 "constraints_required where bound = '%s';", new_limit, old_limit);
 350 }
 351 
 352 void sql_insert_fn_ptr_data_link(const char *ptr, const char *data)
 353 {
 354         sql_insert_or_ignore(fn_ptr_data_link, "'%s', '%s'", ptr, data);
 355 }
 356 
 357 void sql_insert_fn_data_link(struct expression *fn, int type, int param, const char *key, const char *value)
 358 {
 359         if (fn->type != EXPR_SYMBOL || !fn->symbol->ident)
 360                 return;
 361 
 362         sql_insert(fn_data_link, "'%s', '%s', %d, %d, %d, '%s', '%s'",
 363                    (fn->symbol->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 364                    fn->symbol->ident->name,
 365                    !!(fn->symbol->ctype.modifiers & MOD_STATIC),
 366                    type, param, key, value);
 367 }
 368 
 369 void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
 370 {
 371         sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
 372                    tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
 373 }
 374 
 375 void sql_insert_mtag_data(mtag_t tag, const char *var, int offset, int type, const char *value)
 376 {
 377         sql_insert(mtag_data, "%lld, '%s', %d, %d, '%s'", tag, var, offset, type, value);
 378 }
 379 
 380 void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
 381 {
 382         sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
 383 }
 384 
 385 void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
 386 {
 387         sql_insert(mtag_alias, "%lld, %lld", orig, alias);
 388 }
 389 
 390 static int save_mtag(void *_tag, int argc, char **argv, char **azColName)
 391 {
 392         mtag_t *saved_tag = _tag;
 393         mtag_t new_tag;
 394 
 395         new_tag = strtoll(argv[0], NULL, 10);
 396 
 397         if (!*saved_tag)
 398                 *saved_tag = new_tag;
 399         else if (*saved_tag != new_tag)


 733 
 734         /*
 735          * we just want to record something in the database so that if we have
 736          * two calls like:  frob(4); frob(some_unkown); then on the receiving
 737          * side we know that sometimes frob is called with unknown parameters.
 738          */
 739 
 740         sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
 741 }
 742 
 743 static char *show_offset(int offset)
 744 {
 745         static char buf[64];
 746 
 747         buf[0] = '\0';
 748         if (offset != -1)
 749                 snprintf(buf, sizeof(buf), "(-%d)", offset);
 750         return buf;
 751 }
 752 



























 753 static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 754         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 755 {
 756         struct sm_state *sm;

 757         char *name;
 758         struct symbol *sym;
 759         int len;
 760         char printed_name[256];
 761         int is_address = 0;

 762         struct symbol *type;
 763 
 764         expr = strip_expr(expr);
 765         if (!expr)
 766                 return;




 767         if (expr->type == EXPR_PREOP && expr->op == '&') {
 768                 expr = strip_expr(expr->unop);
 769                 is_address = 1;
 770         }
 771 
 772         type = get_type(expr);
 773         if (type && type_bits(type) < type_bits(&ulong_ctype))
 774                 return;
 775 
 776         name = expr_to_var_sym(expr, &sym);
 777         if (!name || !sym)
 778                 goto free;
 779 
 780         len = strlen(name);
 781         FOR_EACH_SM(stree, sm) {
 782                 if (sm->sym != sym)
 783                         continue;
 784                 if (strcmp(name, sm->name) == 0) {







 785                         if (is_address)
 786                                 snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 787                         else /* these are already handled. fixme: handle them here */
 788                                 continue;
 789                 } else if (sm->name[0] == '*' && strcmp(name, sm->name + 1) == 0) {
 790                         snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 791                 } else if (strncmp(name, sm->name, len) == 0) {
 792                         if (isalnum(sm->name[len]))

 793                                 continue;
 794                         if (is_address)
 795                                 snprintf(printed_name, sizeof(printed_name), "$%s->%s", show_offset(offset), sm->name + len + 1);


 796                         else
 797                                 snprintf(printed_name, sizeof(printed_name), "$%s%s", show_offset(offset), sm->name + len);


 798                 } else {
 799                         continue;
 800                 }


 801                 callback(call, param, printed_name, sm);
 802         } END_FOR_EACH_SM(sm);
 803 free:
 804         free_string(name);
 805 }
 806 
 807 static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
 808 {
 809         char **container = _container;
 810         static char buf[256];
 811 
 812         snprintf(buf, sizeof(buf), "%s", argv[0]);
 813         *container = buf;
 814         return 0;
 815 }
 816 
 817 static void print_container_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
 818         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 819 {
 820         struct expression *tmp;


 992                         def_callback->callback(name, sym, key, value);
 993         } END_FOR_EACH_PTR(def_callback);
 994 
 995         return 0;
 996 }
 997 
 998 static struct string_list *ptr_names_done;
 999 static struct string_list *ptr_names;
1000 
1001 static int get_ptr_name(void *unused, int argc, char **argv, char **azColName)
1002 {
1003         insert_string(&ptr_names, alloc_string(argv[0]));
1004         return 0;
1005 }
1006 
1007 static char *get_next_ptr_name(void)
1008 {
1009         char *ptr;
1010 
1011         FOR_EACH_PTR(ptr_names, ptr) {
1012                 if (list_has_string(ptr_names_done, ptr))
1013                         continue;
1014                 insert_string(&ptr_names_done, ptr);
1015                 return ptr;
1016         } END_FOR_EACH_PTR(ptr);
1017         return NULL;
1018 }
1019 
1020 static void get_ptr_names(const char *file, const char *name)
1021 {
1022         char sql_filter[1024];
1023         int before, after;
1024 
1025         if (file) {
1026                 snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
1027                          file, name);
1028         } else {
1029                 snprintf(sql_filter, 1024, "function = '%s';", name);
1030         }
1031 
1032         before = ptr_list_size((struct ptr_list *)ptr_names);
1033 
1034         run_sql(get_ptr_name, NULL,


1207         info.sym = expr->fn->symbol;
1208         sql_select_implies("function, type, parameter, key, value", &info,
1209                            return_implies_callbacks);
1210 }
1211 
1212 static void match_call_implies(struct symbol *sym)
1213 {
1214         struct implies_info info = {
1215                 .type = CALL_IMPLIES,
1216                 .cb_list = call_implies_cb_list,
1217         };
1218 
1219         if (!sym || !sym->ident)
1220                 return;
1221 
1222         info.sym = sym;
1223         sql_select_implies("function, type, parameter, key, value", &info,
1224                            call_implies_callbacks);
1225 }
1226 
1227 static void print_initializer_list(struct expression_list *expr_list,
1228                 struct symbol *struct_type)
1229 {
1230         struct expression *expr;
1231         struct symbol *base_type;
1232         char struct_name[256];

1233 
1234         FOR_EACH_PTR(expr_list, expr) {
1235                 if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
1236                         print_initializer_list(expr->idx_expression->expr_list, struct_type);
1237                         continue;
1238                 }
1239                 if (expr->type != EXPR_IDENTIFIER)
1240                         continue;
1241                 if (!expr->expr_ident)
1242                         continue;
1243                 if (!expr->ident_expression || !expr->ident_expression->symbol_name)
1244                         continue;
1245                 base_type = get_type(expr->ident_expression);
1246                 if (!base_type || base_type->type != SYM_FN)
1247                         continue;
1248                 snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
1249                          struct_type->ident->name, expr->expr_ident->name);
1250                 sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
1251                                         struct_name);
1252         } END_FOR_EACH_PTR(expr);
1253 }
1254 
1255 static void global_variable(struct symbol *sym)
1256 {
1257         struct symbol *struct_type;
1258 
1259         if (!sym->ident)
1260                 return;
1261         if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
1262                 return;
1263         struct_type = get_base_type(sym);
1264         if (!struct_type)
1265                 return;
1266         if (struct_type->type == SYM_ARRAY) {
1267                 struct_type = get_base_type(struct_type);
1268                 if (!struct_type)
1269                         return;


















1270         }
1271         if (struct_type->type != SYM_STRUCT || !struct_type->ident)
1272                 return;
1273         print_initializer_list(sym->initializer->expr_list, struct_type);





























1274 }
1275 
1276 static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1277 {
1278         sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1279 }
1280 
1281 static void call_return_state_hooks_conditional(struct expression *expr)
1282 {
1283         struct returned_state_callback *cb;
1284         struct range_list *rl;
1285         char *return_ranges;
1286         int final_pass_orig = final_pass;
1287 
1288         __push_fake_cur_stree();
1289 
1290         final_pass = 0;
1291         __split_whole_condition(expr->conditional);
1292         final_pass = final_pass_orig;
1293 
1294         if (get_implied_rl(expr->cond_true, &rl))
1295                 rl = cast_rl(cur_func_return_type(), rl);
1296         else
1297                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_true)));
1298         return_ranges = show_rl(rl);
1299         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1300 
1301         return_id++;
1302         FOR_EACH_PTR(returned_state_callbacks, cb) {
1303                 cb->callback(return_id, return_ranges, expr->cond_true);
1304         } END_FOR_EACH_PTR(cb);
1305 
1306         __push_true_states();
1307         __use_false_states();
1308 
1309         if (get_implied_rl(expr->cond_false, &rl))
1310                 rl = cast_rl(cur_func_return_type(), rl);
1311         else
1312                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr->cond_false)));
1313         return_ranges = show_rl(rl);
1314         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1315 
1316         return_id++;
1317         FOR_EACH_PTR(returned_state_callbacks, cb) {
1318                 cb->callback(return_id, return_ranges, expr->cond_false);
1319         } END_FOR_EACH_PTR(cb);
1320 
1321         __merge_true_states();
1322         __free_fake_cur_stree();
1323 }
1324 
1325 static void call_return_state_hooks_compare(struct expression *expr)
1326 {
1327         struct returned_state_callback *cb;
1328         char *return_ranges;
1329         int final_pass_orig = final_pass;
1330         sval_t sval = { .type = &int_ctype };
1331         sval_t ret;
1332 
1333         if (!get_implied_value(expr, &ret))
1334                 ret.value = -1;
1335 
1336         __push_fake_cur_stree();
1337 
1338         final_pass = 0;


1363                         cb->callback(return_id, return_ranges, expr);
1364                 } END_FOR_EACH_PTR(cb);
1365         }
1366 
1367         __merge_true_states();
1368         __free_fake_cur_stree();
1369 }
1370 
1371 static int ptr_in_list(struct sm_state *sm, struct state_list *slist)
1372 {
1373         struct sm_state *tmp;
1374 
1375         FOR_EACH_PTR(slist, tmp) {
1376                 if (strcmp(tmp->state->name, sm->state->name) == 0)
1377                         return 1;
1378         } END_FOR_EACH_PTR(tmp);
1379 
1380         return 0;
1381 }
1382 
1383 static char *get_return_compare_str(struct expression *expr)
1384 {
1385         char *compare_str;
1386         char *var;
1387         char buf[256];
1388         int comparison;
1389         int param;
1390 
1391         compare_str = expr_lte_to_param(expr, -1);
1392         if (compare_str)
1393                 return compare_str;
1394         param = get_param_num(expr);
1395         if (param < 0)
1396                 return NULL;
1397 
1398         var = expr_to_var(expr);
1399         if (!var)
1400                 return NULL;
1401         snprintf(buf, sizeof(buf), "%s orig", var);
1402         comparison = get_comparison_strings(var, buf);
1403         free_string(var);
1404 
1405         if (!comparison)
1406                 return NULL;
1407 
1408         snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
1409         return alloc_sname(buf);
1410 }
1411 
1412 static int split_possible_helper(struct sm_state *sm, struct expression *expr)
1413 {
1414         struct returned_state_callback *cb;
1415         struct range_list *rl;
1416         char *return_ranges;
1417         struct sm_state *tmp;
1418         int ret = 0;
1419         int nr_possible, nr_states;
1420         char *compare_str = NULL;
1421         char buf[128];
1422         struct state_list *already_handled = NULL;

1423 
1424         if (!sm || !sm->merged)
1425                 return 0;
1426 
1427         if (too_many_possible(sm))
1428                 return 0;
1429 
1430         /* bail if it gets too complicated */
1431         nr_possible = ptr_list_size((struct ptr_list *)sm->possible);





1432         nr_states = get_db_state_count();
1433         if (nr_states * nr_possible >= 2000)
1434                 return 0;
1435 
1436         FOR_EACH_PTR(sm->possible, tmp) {
1437                 if (tmp->merged)
1438                         continue;
1439                 if (ptr_in_list(tmp, already_handled))
1440                         continue;
1441                 add_ptr_list(&already_handled, tmp);
1442 
1443                 ret = 1;
1444                 __push_fake_cur_stree();
1445 
1446                 overwrite_states_using_pool(sm, tmp);
1447 
1448                 rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
1449                 return_ranges = show_rl(rl);
1450                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));

1451                 compare_str = get_return_compare_str(expr);
1452                 if (compare_str) {
1453                         snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1454                         return_ranges = alloc_sname(buf);
1455                 }

1456 
1457                 return_id++;
1458                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1459                         cb->callback(return_id, return_ranges, expr);
1460                 } END_FOR_EACH_PTR(cb);
1461 
1462                 __free_fake_cur_stree();
1463         } END_FOR_EACH_PTR(tmp);
1464 
1465         free_slist(&already_handled);
1466 
1467         return ret;
1468 }
1469 
1470 static int call_return_state_hooks_split_possible(struct expression *expr)
1471 {
1472         struct sm_state *sm;
1473 
1474         if (!expr || expr_equal_to_param(expr, -1))
1475                 return 0;
1476 
1477         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1478         return split_possible_helper(sm, expr);
1479 }
1480 
1481 static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
1482 {
1483         struct range_list *rl;
1484         char *return_ranges;
1485         sval_t sval;
1486         char *compare_str;
1487         char *math_str;
1488         char buf[128];
1489 
1490         *rl_p = NULL;
1491 
1492         if (!expr)
1493                 return alloc_sname("");
1494 
1495         if (get_implied_value(expr, &sval)) {
1496                 sval = sval_cast(cur_func_return_type(), sval);
1497                 *rl_p = alloc_rl(sval, sval);
1498                 return sval_to_str(sval);
1499         }
1500 
1501         compare_str = expr_equal_to_param(expr, -1);
1502         math_str = get_value_in_terms_of_parameter_math(expr);
1503 
1504         if (get_implied_rl(expr, &rl)) {
1505                 rl = cast_rl(cur_func_return_type(), rl);
1506                 return_ranges = show_rl(rl);
1507         } else if (get_imaginary_absolute(expr, &rl)){
1508                 rl = cast_rl(cur_func_return_type(), rl);
1509                 return alloc_sname(show_rl(rl));
1510         } else {
1511                 rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr)));
1512                 return_ranges = show_rl(rl);
1513         }
1514         *rl_p = rl;
1515 
1516         if (compare_str) {
1517                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1518                 return alloc_sname(buf);
1519         }
1520         if (math_str) {
1521                 snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
1522                 return alloc_sname(buf);
1523         }
1524         compare_str = get_return_compare_str(expr);
1525         if (compare_str) {
1526                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1527                 return alloc_sname(buf);
1528         }
1529 
1530         return return_ranges;
1531 }
1532 
1533 static bool has_possible_negative(struct sm_state *sm)
1534 {
1535         struct sm_state *tmp;
1536 
1537         FOR_EACH_PTR(sm->possible, tmp) {
1538                 if (!estate_rl(tmp->state))
1539                         continue;
1540                 if (sval_is_negative(estate_min(tmp->state)) &&
1541                     sval_is_negative(estate_max(tmp->state)))
1542                         return true;
1543         } END_FOR_EACH_PTR(tmp);
1544 
1545         return false;
1546 }
1547 
1548 static bool has_possible_zero_null(struct sm_state *sm)
1549 {
1550         struct sm_state *tmp;
1551         sval_t sval;
1552 
1553         FOR_EACH_PTR(sm->possible, tmp) {
1554                 if (!estate_get_single_value(tmp->state, &sval))
1555                         continue;
1556                 if (sval.value == 0)
1557                         return true;
1558         } END_FOR_EACH_PTR(tmp);
1559 
1560         return false;
1561 }
1562 
1563 static int split_positive_from_negative(struct expression *expr)
1564 {
1565         struct sm_state *sm;
1566         struct returned_state_callback *cb;
1567         struct range_list *rl;
1568         const char *return_ranges;
1569         struct range_list *ret_rl;
1570         int undo;

1571 
1572         /* We're going to print the states 3 times */
1573         if (get_db_state_count() > 10000 / 3)
1574                 return 0;
1575 
1576         if (!get_implied_rl(expr, &rl) || !rl)
1577                 return 0;
1578         if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1579                 return 0;
1580         /* Forget about INT_MAX and larger */
1581         if (rl_max(rl).value <= 0)
1582                 return 0;
1583         if (!sval_is_negative(rl_min(rl)))
1584                 return 0;
1585 
1586         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1587         if (!sm)
1588                 return 0;
1589         if (!has_possible_negative(sm))
1590                 return 0;

1591 
1592         if (!assume(compare_expression(expr, '>', zero_expr())))
1593                 return 0;
1594 
1595         return_id++;
1596         return_ranges = get_return_ranges_str(expr, &ret_rl);
1597         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1598         FOR_EACH_PTR(returned_state_callbacks, cb) {
1599                 cb->callback(return_id, (char *)return_ranges, expr);
1600         } END_FOR_EACH_PTR(cb);
1601 
1602         end_assume();
1603 
1604         if (rl_has_sval(rl, sval_type_val(rl_type(rl), 0))) {
1605                 undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1606 
1607                 return_id++;
1608                 return_ranges = get_return_ranges_str(expr, &ret_rl);
1609                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1610                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1611                         cb->callback(return_id, (char *)return_ranges, expr);
1612                 } END_FOR_EACH_PTR(cb);
1613 
1614                 if (undo)
1615                         end_assume();
1616         }
1617 
1618         undo = assume(compare_expression(expr, '<', zero_expr()));
1619 
1620         return_id++;
1621         return_ranges = get_return_ranges_str(expr, &ret_rl);
1622         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1623         FOR_EACH_PTR(returned_state_callbacks, cb) {
1624                 cb->callback(return_id, (char *)return_ranges, expr);
1625         } END_FOR_EACH_PTR(cb);
1626 
1627         if (undo)
1628                 end_assume();
1629 
1630         return 1;
1631 }
1632 
1633 static int call_return_state_hooks_split_null_non_null(struct expression *expr)
1634 {
1635         struct returned_state_callback *cb;
1636         struct range_list *rl;
1637         struct range_list *nonnull_rl;
1638         sval_t null_sval;
1639         struct range_list *null_rl = NULL;
1640         char *return_ranges;
1641         struct sm_state *sm;
1642         struct smatch_state *state;
1643         int nr_states;
1644         int final_pass_orig = final_pass;
1645 
1646         if (!expr || expr_equal_to_param(expr, -1))
1647                 return 0;
1648         if (expr->type == EXPR_CALL)
1649                 return 0;
1650         if (!is_pointer(expr))
1651                 return 0;
1652 
1653         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1654         if (!sm)
1655                 return 0;
1656         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1657                 return 0;
1658         state = sm->state;
1659         if (!estate_rl(state))
1660                 return 0;
1661         if (estate_min(state).value == 0 && estate_max(state).value == 0)
1662                 return 0;
1663         if (!has_possible_zero_null(sm))
1664                 return 0;
1665 
1666         nr_states = get_db_state_count();
1667         if (option_info && nr_states >= 1500)
1668                 return 0;
1669 
1670         rl = estate_rl(state);
1671 


1975 
1976         if (__path_is_null())
1977                 return;
1978 
1979         expr = strip_expr(expr);
1980         expr = strip_expr_statement(expr);
1981 
1982         if (is_impossible_path())
1983                 goto vanilla;
1984 
1985         if (expr && (expr->type == EXPR_COMPARE ||
1986                      !get_implied_value(expr, &sval)) &&
1987             (is_condition(expr) || is_boolean(expr))) {
1988                 call_return_state_hooks_compare(expr);
1989                 return;
1990         } else if (is_conditional(expr)) {
1991                 call_return_state_hooks_conditional(expr);
1992                 return;
1993         } else if (call_return_state_hooks_split_possible(expr)) {
1994                 return;
1995         } else if (call_return_state_hooks_split_null_non_null(expr)) {
1996                 return;


1997         } else if (call_return_state_hooks_split_success_fail(expr)) {
1998                 return;
1999         } else if (splitable_function_call(expr)) {
2000                 return;
2001         } else if (split_positive_from_negative(expr)) {
2002                 return;
2003         } else if (split_by_bool_param(expr)) {
2004         } else if (split_by_null_nonnull_param(expr)) {
2005                 return;
2006         }
2007 
2008 vanilla:
2009         return_ranges = get_return_ranges_str(expr, &ret_rl);
2010         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
2011 
2012         return_id++;
2013         nr_states = get_db_state_count();
2014         if (nr_states >= 10000) {
2015                 match_return_info(return_id, (char *)return_ranges, expr);
2016                 mark_all_params_untracked(return_id, (char *)return_ranges, expr);
2017                 return;
2018         }
2019         FOR_EACH_PTR(returned_state_callbacks, cb) {
2020                 cb->callback(return_id, (char *)return_ranges, expr);
2021         } END_FOR_EACH_PTR(cb);
2022 }


2191                 if (rc != SQLITE_OK) {
2192                         sm_ierror("SQL error #2: %s", err);
2193                         sm_ierror("%s", buf);
2194                 }
2195         }
2196 }
2197 
2198 static int save_cache_data(void *_table, int argc, char **argv, char **azColName)
2199 {
2200         static char buf[4096];
2201         char tmp[256];
2202         char *p = buf;
2203         char *table = _table;
2204         int i;
2205 
2206 
2207         p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
2208         for (i = 0; i < argc; i++) {
2209                 if (i)
2210                         p += snprintf(p, 4096 - (p - buf), ", ");
2211                 sqlite3_snprintf(sizeof(tmp), tmp, "%q", argv[i]);
2212                 p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
2213 
2214         }
2215         p += snprintf(p, 4096 - (p - buf), ");");
2216         if (p - buf > 4096)
2217                 return 0;
2218 
2219         sm_msg("SQL: %s", buf);
2220         return 0;
2221 }
2222 
2223 static void dump_cache(struct symbol_list *sym_list)
2224 {
2225         if (!option_info)
2226                 return;
2227         cache_sql(&save_cache_data, (char *)"type_info", "select * from type_info;");
2228         cache_sql(&save_cache_data, (char *)"return_implies", "select * from return_implies;");
2229         cache_sql(&save_cache_data, (char *)"call_implies", "select * from call_implies;");
2230         cache_sql(&save_cache_data, (char *)"mtag_data", "select * from mtag_data;");
2231         cache_sql(&save_cache_data, (char *)"sink_info", "select * from sink_info;");


2344                 return;
2345         }
2346         replace_table = malloc(replace_count * sizeof(char *));
2347 
2348         p = buf;
2349         i = 0;
2350         while (*p) {
2351                 func = alloc_string(get_next_string(&p));
2352                 orig = alloc_string(get_next_string(&p));
2353                 new  = alloc_string(get_next_string(&p));
2354 
2355                 replace_table[i++] = func;
2356                 replace_table[i++] = orig;
2357                 replace_table[i++] = new;
2358         }
2359 }
2360 
2361 void register_definition_db_callbacks(int id)
2362 {
2363         add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2364         add_hook(&global_variable, BASE_HOOK);
2365         add_hook(&global_variable, DECLARATION_HOOK);
2366         add_split_return_callback(match_return_info);
2367         add_split_return_callback(print_returned_struct_members);
2368         add_hook(&call_return_state_hooks, RETURN_HOOK);
2369         add_hook(&match_end_func_info, END_FUNC_HOOK);
2370         add_hook(&match_after_func, AFTER_FUNC_HOOK);
2371 
2372         add_hook(&match_data_from_db, FUNC_DEF_HOOK);
2373         add_hook(&match_call_implies, FUNC_DEF_HOOK);
2374         add_hook(&match_return_implies, CALL_HOOK_AFTER_INLINE);
2375 
2376         register_common_funcs();
2377         register_return_replacements();
2378 
2379         add_hook(&dump_cache, END_FILE_HOOK);
2380 }
2381 
2382 void register_db_call_marker(int id)
2383 {
2384         add_hook(&match_call_marker, FUNCTION_CALL_HOOK);
2385 }
2386 
2387 char *return_state_to_var_sym(struct expression *expr, int param, const char *key, struct symbol **sym)
2388 {
2389         struct expression *arg;
2390         char *name = NULL;
2391         char member_name[256];
2392 
2393         *sym = NULL;
2394 
2395         if (param == -1) {
2396                 const char *star = "";
2397 
2398                 if (expr->type != EXPR_ASSIGNMENT)
2399                         return NULL;


2400                 name = expr_to_var_sym(expr->left, sym);
2401                 if (!name)
2402                         return NULL;
2403                 if (key[0] == '*') {
2404                         star = "*";
2405                         key++;
2406                 }
2407                 if (strncmp(key, "$", 1) != 0)
2408                         return name;
2409                 snprintf(member_name, sizeof(member_name), "%s%s%s", star, name, key + 1);
2410                 free_string(name);
2411                 return alloc_string(member_name);
2412         }
2413 
2414         while (expr->type == EXPR_ASSIGNMENT)
2415                 expr = strip_expr(expr->right);
2416         if (expr->type != EXPR_CALL)
2417                 return NULL;
2418 
2419         arg = get_argument_from_call_expr(expr->args, param);
2420         if (!arg)
2421                 return NULL;
2422 
2423         return get_variable_from_key(arg, key, sym);
2424 }
2425 
2426 char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2427 {
2428         char buf[256];
2429         char *tmp;

2430 
2431         if (!arg)
2432                 return NULL;
2433 
2434         arg = strip_expr(arg);
2435 
2436         if (strcmp(key, "$") == 0)
2437                 return expr_to_var_sym(arg, sym);
2438 
2439         if (strcmp(key, "*$") == 0) {
2440                 if (arg->type == EXPR_PREOP && arg->op == '&') {
2441                         arg = strip_expr(arg->unop);
2442                         return expr_to_var_sym(arg, sym);
2443                 } else {
2444                         tmp = expr_to_var_sym(arg, sym);
2445                         if (!tmp)
2446                                 return NULL;
2447                         snprintf(buf, sizeof(buf), "*%s", tmp);
2448                         free_string(tmp);
2449                         return alloc_string(buf);
2450                 }
2451         }
2452 





2453         if (arg->type == EXPR_PREOP && arg->op == '&') {
2454                 arg = strip_expr(arg->unop);
2455                 tmp = expr_to_var_sym(arg, sym);
2456                 if (!tmp)
2457                         return NULL;
2458                 snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 3);

2459                 return alloc_string(buf);
2460         }
2461 
2462         tmp = expr_to_var_sym(arg, sym);
2463         if (!tmp)
2464                 return NULL;
2465         snprintf(buf, sizeof(buf), "%s%s", tmp, key + 1);
2466         free_string(tmp);
2467         return alloc_string(buf);
2468 }
2469 
2470 char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2471 {
2472         *vsl = NULL;
2473 
2474         if (strcmp("$", key) == 0)
2475                 return expr_to_chunk_sym_vsl(arg, sym, vsl);
2476         return get_variable_from_key(arg, key, sym);
2477 }
2478 
2479 const char *state_name_to_param_name(const char *state_name, const char *param_name)
2480 {
2481         int name_len;
2482         static char buf[256];

2483 
2484         name_len = strlen(param_name);
2485 





2486         if (strcmp(state_name, param_name) == 0) {
2487                 return "$";
2488         } else if (state_name[name_len] == '-' && /* check for '-' from "->" */



2489             strncmp(state_name, param_name, name_len) == 0) {
2490                 snprintf(buf, sizeof(buf), "$%s", state_name + name_len);

2491                 return buf;
2492         } else if (state_name[0] == '*' && strcmp(state_name + 1, param_name) == 0) {
2493                 return "*$";
2494         }
2495         return NULL;
2496 }
2497 
2498 const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2499 {
2500         if (!sym || !sym->ident)
2501                 return NULL;
2502 
2503         return state_name_to_param_name(name, sym->ident->name);
2504 }
2505 
2506 const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym)
2507 {
2508         struct symbol *type;
2509         const char *sym_name;
2510         int name_len;
2511         static char buf[256];
2512 
2513         /*




  62 DECLARE_PTR_LIST(returned_member_cb_list, struct returned_member_callback);
  63 static struct returned_member_cb_list *returned_member_callbacks;
  64 
  65 struct db_implies_callback {
  66         int type;
  67         void (*callback)(struct expression *call, struct expression *arg, char *key, char *value);
  68 };
  69 ALLOCATOR(db_implies_callback, "return_implies callbacks");
  70 DECLARE_PTR_LIST(db_implies_cb_list, struct db_implies_callback);
  71 static struct db_implies_cb_list *return_implies_cb_list;
  72 static struct db_implies_cb_list *call_implies_cb_list;
  73 
  74 /* silently truncates if needed. */
  75 char *escape_newlines(const char *str)
  76 {
  77         char buf[1024] = "";
  78         bool found = false;
  79         int i, j;
  80 
  81         for (i = 0, j = 0; str[i] != '\0' && j != sizeof(buf); i++, j++) {
  82                 if (str[i] != '\r' && str[i] != '\n') {
  83                         buf[j] = str[i];
  84                         continue;
  85                 }
  86 
  87                 found = true;
  88                 buf[j++] = '\\';
  89                 if (j == sizeof(buf))
  90                          break;
  91                 buf[j] = 'n';
  92         }
  93 
  94         if (!found)
  95                 return alloc_sname(str);
  96 
  97         if (j == sizeof(buf))
  98                 buf[j - 1] = '\0';
  99         return alloc_sname(buf);
 100 }
 101 
 102 static int print_sql_output(void *unused, int argc, char **argv, char **azColName)


 235         if (!option_info)
 236                 return;
 237 
 238         if (strncmp(fn, "__builtin_", 10) == 0)
 239                 return;
 240         if (type != INTERNAL && is_common_function(fn))
 241                 return;
 242 
 243         sm_outfd = caller_info_fd;
 244         sm_msg("SQL_caller_info: insert into caller_info values ("
 245                "'%s', '%s', '%s', %%CALL_ID%%, %d, %d, %d, '%s', '%s');",
 246                get_base_file(), get_function(), fn, is_static(call->fn),
 247                type, param, key, value);
 248         sm_outfd = tmp_fd;
 249 
 250         free_string(fn);
 251 }
 252 
 253 void sql_insert_function_ptr(const char *fn, const char *struct_name)
 254 {
 255         sql_insert_or_ignore(function_ptr, "'%s', '%s', '%s', 0",
 256                              get_base_file(), fn, struct_name);
 257 }
 258 
 259 void sql_insert_return_implies(int type, int param, const char *key, const char *value)
 260 {
 261         sql_insert_or_ignore(return_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 262                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 263                 fn_static(), type, param, key, value);
 264 }
 265 
 266 void sql_insert_call_implies(int type, int param, const char *key, const char *value)
 267 {
 268         sql_insert_or_ignore(call_implies, "'%s', '%s', %lu, %d, %d, %d, '%s', '%s'",
 269                 get_base_file(), get_function(), (unsigned long)__inline_fn,
 270                 fn_static(), type, param, key, value);
 271 }
 272 
 273 void sql_insert_function_type_size(const char *member, const char *ranges)
 274 {
 275         sql_insert(function_type_size, "'%s', '%s', '%s', '%s'", get_base_file(), get_function(), member, ranges);
 276 }


 314         data_name = get_data_info_name(data);
 315         if (!data_name)
 316                 return;
 317         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 318                    is_static(data) ? get_base_file() : "extern",
 319                    data_name, type, value);
 320 }
 321 
 322 void sql_insert_data_info_var_sym(const char *var, struct symbol *sym, int type, const char *value)
 323 {
 324         sql_insert(data_info, "'%s', '%s', %d, '%s'",
 325                    (sym->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 326                    var, type, value);
 327 }
 328 
 329 void sql_save_constraint(const char *con)
 330 {
 331         if (!option_info)
 332                 return;
 333 
 334         sm_msg("SQL: insert or ignore into constraints (str) values('%s');", escape_newlines(con));
 335 }
 336 
 337 void sql_save_constraint_required(const char *data, int op, const char *limit)
 338 {
 339         sql_insert_or_ignore(constraints_required, "'%s', '%s', '%s'", data, show_special(op), limit);
 340 }
 341 
 342 void sql_copy_constraint_required(const char *new_limit, const char *old_limit)
 343 {
 344         if (!option_info)
 345                 return;
 346 
 347         sm_msg("SQL_late: insert or ignore into constraints_required (data, op, bound) "
 348                 "select constraints_required.data, constraints_required.op, '%s' from "
 349                 "constraints_required where bound = '%s';", new_limit, old_limit);
 350 }
 351 
 352 void sql_insert_fn_ptr_data_link(const char *ptr, const char *data)
 353 {
 354         sql_insert_or_ignore(fn_ptr_data_link, "'%s', '%s'", ptr, data);
 355 }
 356 
 357 void sql_insert_fn_data_link(struct expression *fn, int type, int param, const char *key, const char *value)
 358 {
 359         if (fn->type != EXPR_SYMBOL || !fn->symbol->ident)
 360                 return;
 361 
 362         sql_insert(fn_data_link, "'%s', '%s', %d, %d, %d, '%s', '%s'",
 363                    (fn->symbol->ctype.modifiers & MOD_STATIC) ? get_base_file() : "extern",
 364                    fn->symbol->ident->name,
 365                    !!(fn->symbol->ctype.modifiers & MOD_STATIC),
 366                    type, param, key, value);
 367 }
 368 
 369 void sql_insert_mtag_about(mtag_t tag, const char *left_name, const char *right_name)
 370 {
 371         sql_insert(mtag_about, "%lld, '%s', '%s', %d, '%s', '%s'",
 372                    tag, get_filename(), get_function(), get_lineno(), left_name, right_name);
 373 }
 374 





 375 void sql_insert_mtag_map(mtag_t tag, int offset, mtag_t container)
 376 {
 377         sql_insert(mtag_map, "%lld, %d, %lld", tag, offset, container);
 378 }
 379 
 380 void sql_insert_mtag_alias(mtag_t orig, mtag_t alias)
 381 {
 382         sql_insert(mtag_alias, "%lld, %lld", orig, alias);
 383 }
 384 
 385 static int save_mtag(void *_tag, int argc, char **argv, char **azColName)
 386 {
 387         mtag_t *saved_tag = _tag;
 388         mtag_t new_tag;
 389 
 390         new_tag = strtoll(argv[0], NULL, 10);
 391 
 392         if (!*saved_tag)
 393                 *saved_tag = new_tag;
 394         else if (*saved_tag != new_tag)


 728 
 729         /*
 730          * we just want to record something in the database so that if we have
 731          * two calls like:  frob(4); frob(some_unkown); then on the receiving
 732          * side we know that sometimes frob is called with unknown parameters.
 733          */
 734 
 735         sql_insert_caller_info(expr, INTERNAL, -1, "%call_marker%", type_to_str(type));
 736 }
 737 
 738 static char *show_offset(int offset)
 739 {
 740         static char buf[64];
 741 
 742         buf[0] = '\0';
 743         if (offset != -1)
 744                 snprintf(buf, sizeof(buf), "(-%d)", offset);
 745         return buf;
 746 }
 747 
 748 int is_recursive_member(const char *name)
 749 {
 750         char buf[256];
 751         const char *p, *next;
 752         int size;
 753 
 754         p = strchr(name, '>');
 755         if (!p)
 756                 return 0;
 757         p++;
 758         while (true) {
 759                 next = strchr(p, '>');
 760                 if (!next)
 761                         return 0;
 762                 next++;
 763 
 764                 size = next - p;
 765                 if (size >= sizeof(buf))
 766                         return 0;
 767                 memcpy(buf, p, size);
 768                 buf[size] = '\0';
 769                 if (strstr(next, buf))
 770                         return 1;
 771                 p = next;
 772         }
 773 }
 774 
 775 static void print_struct_members(struct expression *call, struct expression *expr, int param, int offset, struct stree *stree,
 776         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 777 {
 778         struct sm_state *sm;
 779         const char *sm_name;
 780         char *name;
 781         struct symbol *sym;
 782         int len;
 783         char printed_name[256];
 784         int is_address = 0;
 785         bool add_star;
 786         struct symbol *type;
 787 
 788         expr = strip_expr(expr);
 789         if (!expr)
 790                 return;
 791         type = get_type(expr);
 792         if (type && type_bits(type) < type_bits(&ulong_ctype))
 793                 return;
 794 
 795         if (expr->type == EXPR_PREOP && expr->op == '&') {
 796                 expr = strip_expr(expr->unop);
 797                 is_address = 1;
 798         }
 799 




 800         name = expr_to_var_sym(expr, &sym);
 801         if (!name || !sym)
 802                 goto free;
 803 
 804         len = strlen(name);
 805         FOR_EACH_SM(stree, sm) {
 806                 if (sm->sym != sym)
 807                         continue;
 808                 sm_name = sm->name;
 809                 add_star = false;
 810                 if (sm_name[0] == '*') {
 811                         add_star = true;
 812                         sm_name++;
 813                 }
 814                 // FIXME: simplify?
 815                 if (!add_star && strcmp(name, sm_name) == 0) {
 816                         if (is_address)
 817                                 snprintf(printed_name, sizeof(printed_name), "*$%s", show_offset(offset));
 818                         else /* these are already handled. fixme: handle them here */
 819                                 continue;
 820                 } else if (add_star && strcmp(name, sm_name) == 0) {
 821                         snprintf(printed_name, sizeof(printed_name), "%s*$%s",
 822                                  is_address ? "*" : "", show_offset(offset));
 823                 } else if (strncmp(name, sm_name, len) == 0) {
 824                         if (sm_name[len] != '.' && sm_name[len] != '-')
 825                                 continue;
 826                         if (is_address)
 827                                 snprintf(printed_name, sizeof(printed_name),
 828                                          "%s$%s->%s", add_star ? "*" : "",
 829                                          show_offset(offset), sm_name + len + 1);
 830                         else
 831                                 snprintf(printed_name, sizeof(printed_name),
 832                                          "%s$%s%s", add_star ? "*" : "",
 833                                          show_offset(offset), sm_name + len);
 834                 } else {
 835                         continue;
 836                 }
 837                 if (is_recursive_member(printed_name))
 838                         continue;
 839                 callback(call, param, printed_name, sm);
 840         } END_FOR_EACH_SM(sm);
 841 free:
 842         free_string(name);
 843 }
 844 
 845 static int param_used_callback(void *_container, int argc, char **argv, char **azColName)
 846 {
 847         char **container = _container;
 848         static char buf[256];
 849 
 850         snprintf(buf, sizeof(buf), "%s", argv[0]);
 851         *container = buf;
 852         return 0;
 853 }
 854 
 855 static void print_container_struct_members(struct expression *call, struct expression *expr, int param, struct stree *stree,
 856         void (*callback)(struct expression *call, int param, char *printed_name, struct sm_state *sm))
 857 {
 858         struct expression *tmp;


1030                         def_callback->callback(name, sym, key, value);
1031         } END_FOR_EACH_PTR(def_callback);
1032 
1033         return 0;
1034 }
1035 
1036 static struct string_list *ptr_names_done;
1037 static struct string_list *ptr_names;
1038 
1039 static int get_ptr_name(void *unused, int argc, char **argv, char **azColName)
1040 {
1041         insert_string(&ptr_names, alloc_string(argv[0]));
1042         return 0;
1043 }
1044 
1045 static char *get_next_ptr_name(void)
1046 {
1047         char *ptr;
1048 
1049         FOR_EACH_PTR(ptr_names, ptr) {
1050                 if (!insert_string(&ptr_names_done, ptr))
1051                         continue;

1052                 return ptr;
1053         } END_FOR_EACH_PTR(ptr);
1054         return NULL;
1055 }
1056 
1057 static void get_ptr_names(const char *file, const char *name)
1058 {
1059         char sql_filter[1024];
1060         int before, after;
1061 
1062         if (file) {
1063                 snprintf(sql_filter, 1024, "file = '%s' and function = '%s';",
1064                          file, name);
1065         } else {
1066                 snprintf(sql_filter, 1024, "function = '%s';", name);
1067         }
1068 
1069         before = ptr_list_size((struct ptr_list *)ptr_names);
1070 
1071         run_sql(get_ptr_name, NULL,


1244         info.sym = expr->fn->symbol;
1245         sql_select_implies("function, type, parameter, key, value", &info,
1246                            return_implies_callbacks);
1247 }
1248 
1249 static void match_call_implies(struct symbol *sym)
1250 {
1251         struct implies_info info = {
1252                 .type = CALL_IMPLIES,
1253                 .cb_list = call_implies_cb_list,
1254         };
1255 
1256         if (!sym || !sym->ident)
1257                 return;
1258 
1259         info.sym = sym;
1260         sql_select_implies("function, type, parameter, key, value", &info,
1261                            call_implies_callbacks);
1262 }
1263 
1264 static char *get_return_compare_is_param(struct expression *expr)

1265 {
1266         char *var;
1267         char buf[256];
1268         int comparison;
1269         int param;
1270 
1271         param = get_param_num(expr);
1272         if (param < 0)
1273                 return NULL;
1274 
1275         var = expr_to_var(expr);
1276         if (!var)
1277                 return NULL;
1278         snprintf(buf, sizeof(buf), "%s orig", var);
1279         comparison = get_comparison_strings(var, buf);
1280         free_string(var);
1281 
1282         if (!comparison)
1283                 return NULL;
1284 
1285         snprintf(buf, sizeof(buf), "[%s$%d]", show_special(comparison), param);
1286         return alloc_sname(buf);



1287 }
1288 
1289 static char *get_return_compare_str(struct expression *expr)
1290 {
1291         char *compare_str;
1292 
1293         compare_str = get_return_compare_is_param(expr);
1294         if (compare_str)
1295                 return compare_str;
1296 
1297         compare_str = expr_lte_to_param(expr, -1);
1298         if (compare_str)
1299                 return compare_str;
1300 
1301         return expr_param_comparison(expr, -1);
1302 }
1303 
1304 static const char *get_return_ranges_str(struct expression *expr, struct range_list **rl_p)
1305 {
1306         struct range_list *rl;
1307         char *return_ranges;
1308         sval_t sval;
1309         char *compare_str;
1310         char *math_str;
1311         char buf[128];
1312 
1313         *rl_p = NULL;
1314 
1315         if (!expr)
1316                 return alloc_sname("");
1317 
1318         if (get_implied_value(expr, &sval)) {
1319                 sval = sval_cast(cur_func_return_type(), sval);
1320                 *rl_p = alloc_rl(sval, sval);
1321                 return sval_to_str_or_err_ptr(sval);
1322         }
1323 
1324         compare_str = expr_equal_to_param(expr, -1);
1325         math_str = get_value_in_terms_of_parameter_math(expr);
1326 
1327         if (get_implied_rl(expr, &rl) && !is_whole_rl(rl)) {
1328                 rl = cast_rl(cur_func_return_type(), rl);
1329                 return_ranges = show_rl(rl);
1330         } else if (get_imaginary_absolute(expr, &rl)){
1331                 rl = cast_rl(cur_func_return_type(), rl);
1332                 return alloc_sname(show_rl(rl));
1333         } else {
1334                 get_absolute_rl(expr, &rl);
1335                 rl = cast_rl(cur_func_return_type(), rl);
1336                 return_ranges = show_rl(rl);
1337         }
1338         *rl_p = rl;
1339 
1340         if (compare_str) {
1341                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1342                 return alloc_sname(buf);
1343         }
1344         if (math_str) {
1345                 snprintf(buf, sizeof(buf), "%s[%s]", return_ranges, math_str);
1346                 return alloc_sname(buf);
1347         }
1348         compare_str = get_return_compare_str(expr);
1349         if (compare_str) {
1350                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1351                 return alloc_sname(buf);
1352         }
1353 
1354         return return_ranges;
1355 }
1356 
1357 static void match_return_info(int return_id, char *return_ranges, struct expression *expr)
1358 {
1359         sql_insert_return_states(return_id, return_ranges, INTERNAL, -1, "", function_signature());
1360 }
1361 
1362 static void call_return_state_hooks_conditional(struct expression *expr)
1363 {
1364         struct returned_state_callback *cb;
1365         struct range_list *rl;
1366         const char *return_ranges;
1367         int final_pass_orig = final_pass;
1368 
1369         __push_fake_cur_stree();
1370 
1371         final_pass = 0;
1372         __split_whole_condition(expr->conditional);
1373         final_pass = final_pass_orig;
1374 
1375         return_ranges = get_return_ranges_str(expr->cond_true ?: expr->conditional, &rl);
1376 



1377         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1378 
1379         return_id++;
1380         FOR_EACH_PTR(returned_state_callbacks, cb) {
1381                 cb->callback(return_id, (char *)return_ranges, expr->cond_true);
1382         } END_FOR_EACH_PTR(cb);
1383 
1384         __push_true_states();
1385         __use_false_states();
1386 
1387         return_ranges = get_return_ranges_str(expr->cond_false, &rl);




1388         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(rl));
1389 
1390         return_id++;
1391         FOR_EACH_PTR(returned_state_callbacks, cb) {
1392                 cb->callback(return_id, (char *)return_ranges, expr->cond_false);
1393         } END_FOR_EACH_PTR(cb);
1394 
1395         __merge_true_states();
1396         __free_fake_cur_stree();
1397 }
1398 
1399 static void call_return_state_hooks_compare(struct expression *expr)
1400 {
1401         struct returned_state_callback *cb;
1402         char *return_ranges;
1403         int final_pass_orig = final_pass;
1404         sval_t sval = { .type = &int_ctype };
1405         sval_t ret;
1406 
1407         if (!get_implied_value(expr, &ret))
1408                 ret.value = -1;
1409 
1410         __push_fake_cur_stree();
1411 
1412         final_pass = 0;


1437                         cb->callback(return_id, return_ranges, expr);
1438                 } END_FOR_EACH_PTR(cb);
1439         }
1440 
1441         __merge_true_states();
1442         __free_fake_cur_stree();
1443 }
1444 
1445 static int ptr_in_list(struct sm_state *sm, struct state_list *slist)
1446 {
1447         struct sm_state *tmp;
1448 
1449         FOR_EACH_PTR(slist, tmp) {
1450                 if (strcmp(tmp->state->name, sm->state->name) == 0)
1451                         return 1;
1452         } END_FOR_EACH_PTR(tmp);
1453 
1454         return 0;
1455 }
1456 





























1457 static int split_possible_helper(struct sm_state *sm, struct expression *expr)
1458 {
1459         struct returned_state_callback *cb;
1460         struct range_list *rl;
1461         char *return_ranges;
1462         struct sm_state *tmp;
1463         int ret = 0;
1464         int nr_possible, nr_states;
1465         char *compare_str;
1466         char buf[128];
1467         struct state_list *already_handled = NULL;
1468         sval_t sval;
1469 
1470         if (!sm || !sm->merged)
1471                 return 0;
1472 
1473         if (too_many_possible(sm))
1474                 return 0;
1475 
1476         /* bail if it gets too complicated */
1477         nr_possible = 0;
1478         FOR_EACH_PTR(sm->possible, tmp) {
1479                 if (tmp->merged)
1480                         continue;
1481                 nr_possible++;
1482         } END_FOR_EACH_PTR(tmp);
1483         nr_states = get_db_state_count();
1484         if (nr_states * nr_possible >= 2000)
1485                 return 0;
1486 
1487         FOR_EACH_PTR(sm->possible, tmp) {
1488                 if (tmp->merged)
1489                         continue;
1490                 if (ptr_in_list(tmp, already_handled))
1491                         continue;
1492                 add_ptr_list(&already_handled, tmp);
1493 
1494                 ret = 1;
1495                 __push_fake_cur_stree();
1496 
1497                 overwrite_states_using_pool(sm, tmp);
1498 
1499                 rl = cast_rl(cur_func_return_type(), estate_rl(tmp->state));
1500                 return_ranges = show_rl(rl);
1501                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(clone_rl(rl)));
1502                 if (!rl_to_sval(rl, &sval)) {
1503                         compare_str = get_return_compare_str(expr);
1504                         if (compare_str) {
1505                                 snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str);
1506                                 return_ranges = alloc_sname(buf);
1507                         }
1508                 }
1509 
1510                 return_id++;
1511                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1512                         cb->callback(return_id, return_ranges, expr);
1513                 } END_FOR_EACH_PTR(cb);
1514 
1515                 __free_fake_cur_stree();
1516         } END_FOR_EACH_PTR(tmp);
1517 
1518         free_slist(&already_handled);
1519 
1520         return ret;
1521 }
1522 
1523 static int call_return_state_hooks_split_possible(struct expression *expr)
1524 {
1525         struct sm_state *sm;
1526 
1527         if (!expr || expr_equal_to_param(expr, -1))
1528                 return 0;
1529 
1530         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1531         return split_possible_helper(sm, expr);
1532 }
1533 




















































1534 static bool has_possible_negative(struct sm_state *sm)
1535 {
1536         struct sm_state *tmp;
1537 
1538         FOR_EACH_PTR(sm->possible, tmp) {
1539                 if (!estate_rl(tmp->state))
1540                         continue;
1541                 if (sval_is_negative(estate_min(tmp->state)) &&
1542                     sval_is_negative(estate_max(tmp->state)))
1543                         return true;
1544         } END_FOR_EACH_PTR(tmp);
1545 
1546         return false;
1547 }
1548 
1549 static bool has_possible_zero_null(struct sm_state *sm)
1550 {
1551         struct sm_state *tmp;
1552         sval_t sval;
1553 
1554         FOR_EACH_PTR(sm->possible, tmp) {
1555                 if (!estate_get_single_value(tmp->state, &sval))
1556                         continue;
1557                 if (sval.value == 0)
1558                         return true;
1559         } END_FOR_EACH_PTR(tmp);
1560 
1561         return false;
1562 }
1563 
1564 static int split_positive_from_negative(struct expression *expr)
1565 {
1566         struct sm_state *sm;
1567         struct returned_state_callback *cb;
1568         struct range_list *rl;
1569         const char *return_ranges;
1570         struct range_list *ret_rl;
1571         int undo;
1572         bool has_zero;
1573 
1574         /* We're going to print the states 3 times */
1575         if (get_db_state_count() > 10000 / 3)
1576                 return 0;
1577 
1578         if (!get_implied_rl(expr, &rl) || !rl)
1579                 return 0;
1580         if (is_whole_rl(rl) || is_whole_rl_non_zero(rl))
1581                 return 0;
1582         /* Forget about INT_MAX and larger */
1583         if (rl_max(rl).value <= 0)
1584                 return 0;
1585         if (!sval_is_negative(rl_min(rl)))
1586                 return 0;
1587 
1588         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1589         if (!sm)
1590                 return 0;
1591         if (!has_possible_negative(sm))
1592                 return 0;
1593         has_zero = has_possible_zero_null(sm);
1594 
1595         if (!assume(compare_expression(expr, has_zero ? '>' : SPECIAL_GTE, zero_expr())))
1596                 return 0;
1597 
1598         return_id++;
1599         return_ranges = get_return_ranges_str(expr, &ret_rl);
1600         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1601         FOR_EACH_PTR(returned_state_callbacks, cb) {
1602                 cb->callback(return_id, (char *)return_ranges, expr);
1603         } END_FOR_EACH_PTR(cb);
1604 
1605         end_assume();
1606 
1607         if (has_zero) {
1608                 undo = assume(compare_expression(expr, SPECIAL_EQUAL, zero_expr()));
1609 
1610                 return_id++;
1611                 return_ranges = get_return_ranges_str(expr, &ret_rl);
1612                 set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1613                 FOR_EACH_PTR(returned_state_callbacks, cb) {
1614                         cb->callback(return_id, (char *)return_ranges, expr);
1615                 } END_FOR_EACH_PTR(cb);
1616 
1617                 if (undo)
1618                         end_assume();
1619         }
1620 
1621         undo = assume(compare_expression(expr, '<', zero_expr()));
1622 
1623         return_id++;
1624         return_ranges = get_return_ranges_str(expr, &ret_rl);
1625         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
1626         FOR_EACH_PTR(returned_state_callbacks, cb) {
1627                 cb->callback(return_id, (char *)return_ranges, expr);
1628         } END_FOR_EACH_PTR(cb);
1629 
1630         if (undo)
1631                 end_assume();
1632 
1633         return 1;
1634 }
1635 
1636 static int call_return_state_hooks_split_null_non_null_zero(struct expression *expr)
1637 {
1638         struct returned_state_callback *cb;
1639         struct range_list *rl;
1640         struct range_list *nonnull_rl;
1641         sval_t null_sval;
1642         struct range_list *null_rl = NULL;
1643         char *return_ranges;
1644         struct sm_state *sm;
1645         struct smatch_state *state;
1646         int nr_states;
1647         int final_pass_orig = final_pass;
1648 
1649         if (!expr || expr_equal_to_param(expr, -1))
1650                 return 0;
1651         if (expr->type == EXPR_CALL)
1652                 return 0;


1653 
1654         sm = get_sm_state_expr(SMATCH_EXTRA, expr);
1655         if (!sm)
1656                 return 0;
1657         if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
1658                 return 0;
1659         state = sm->state;
1660         if (!estate_rl(state))
1661                 return 0;
1662         if (estate_min(state).value == 0 && estate_max(state).value == 0)
1663                 return 0;
1664         if (!has_possible_zero_null(sm))
1665                 return 0;
1666 
1667         nr_states = get_db_state_count();
1668         if (option_info && nr_states >= 1500)
1669                 return 0;
1670 
1671         rl = estate_rl(state);
1672 


1976 
1977         if (__path_is_null())
1978                 return;
1979 
1980         expr = strip_expr(expr);
1981         expr = strip_expr_statement(expr);
1982 
1983         if (is_impossible_path())
1984                 goto vanilla;
1985 
1986         if (expr && (expr->type == EXPR_COMPARE ||
1987                      !get_implied_value(expr, &sval)) &&
1988             (is_condition(expr) || is_boolean(expr))) {
1989                 call_return_state_hooks_compare(expr);
1990                 return;
1991         } else if (is_conditional(expr)) {
1992                 call_return_state_hooks_conditional(expr);
1993                 return;
1994         } else if (call_return_state_hooks_split_possible(expr)) {
1995                 return;
1996         } else if (split_positive_from_negative(expr)) {
1997                 return;
1998         } else if (call_return_state_hooks_split_null_non_null_zero(expr)) {
1999                 return;
2000         } else if (call_return_state_hooks_split_success_fail(expr)) {
2001                 return;
2002         } else if (splitable_function_call(expr)) {
2003                 return;


2004         } else if (split_by_bool_param(expr)) {
2005         } else if (split_by_null_nonnull_param(expr)) {
2006                 return;
2007         }
2008 
2009 vanilla:
2010         return_ranges = get_return_ranges_str(expr, &ret_rl);
2011         set_state(RETURN_ID, "return_ranges", NULL, alloc_estate_rl(ret_rl));
2012 
2013         return_id++;
2014         nr_states = get_db_state_count();
2015         if (nr_states >= 10000) {
2016                 match_return_info(return_id, (char *)return_ranges, expr);
2017                 mark_all_params_untracked(return_id, (char *)return_ranges, expr);
2018                 return;
2019         }
2020         FOR_EACH_PTR(returned_state_callbacks, cb) {
2021                 cb->callback(return_id, (char *)return_ranges, expr);
2022         } END_FOR_EACH_PTR(cb);
2023 }


2192                 if (rc != SQLITE_OK) {
2193                         sm_ierror("SQL error #2: %s", err);
2194                         sm_ierror("%s", buf);
2195                 }
2196         }
2197 }
2198 
2199 static int save_cache_data(void *_table, int argc, char **argv, char **azColName)
2200 {
2201         static char buf[4096];
2202         char tmp[256];
2203         char *p = buf;
2204         char *table = _table;
2205         int i;
2206 
2207 
2208         p += snprintf(p, 4096 - (p - buf), "insert or ignore into %s values (", table);
2209         for (i = 0; i < argc; i++) {
2210                 if (i)
2211                         p += snprintf(p, 4096 - (p - buf), ", ");
2212                 sqlite3_snprintf(sizeof(tmp), tmp, "%q", escape_newlines(argv[i]));
2213                 p += snprintf(p, 4096 - (p - buf), "'%s'", tmp);
2214 
2215         }
2216         p += snprintf(p, 4096 - (p - buf), ");");
2217         if (p - buf > 4096)
2218                 return 0;
2219 
2220         sm_msg("SQL: %s", buf);
2221         return 0;
2222 }
2223 
2224 static void dump_cache(struct symbol_list *sym_list)
2225 {
2226         if (!option_info)
2227                 return;
2228         cache_sql(&save_cache_data, (char *)"type_info", "select * from type_info;");
2229         cache_sql(&save_cache_data, (char *)"return_implies", "select * from return_implies;");
2230         cache_sql(&save_cache_data, (char *)"call_implies", "select * from call_implies;");
2231         cache_sql(&save_cache_data, (char *)"mtag_data", "select * from mtag_data;");
2232         cache_sql(&save_cache_data, (char *)"sink_info", "select * from sink_info;");


2345                 return;
2346         }
2347         replace_table = malloc(replace_count * sizeof(char *));
2348 
2349         p = buf;
2350         i = 0;
2351         while (*p) {
2352                 func = alloc_string(get_next_string(&p));
2353                 orig = alloc_string(get_next_string(&p));
2354                 new  = alloc_string(get_next_string(&p));
2355 
2356                 replace_table[i++] = func;
2357                 replace_table[i++] = orig;
2358                 replace_table[i++] = new;
2359         }
2360 }
2361 
2362 void register_definition_db_callbacks(int id)
2363 {
2364         add_hook(&match_call_info, FUNCTION_CALL_HOOK);


2365         add_split_return_callback(match_return_info);
2366         add_split_return_callback(print_returned_struct_members);
2367         add_hook(&call_return_state_hooks, RETURN_HOOK);
2368         add_hook(&match_end_func_info, END_FUNC_HOOK);
2369         add_hook(&match_after_func, AFTER_FUNC_HOOK);
2370 
2371         add_hook(&match_data_from_db, FUNC_DEF_HOOK);
2372         add_hook(&match_call_implies, FUNC_DEF_HOOK);
2373         add_hook(&match_return_implies, CALL_HOOK_AFTER_INLINE);
2374 
2375         register_common_funcs();
2376         register_return_replacements();
2377 
2378         add_hook(&dump_cache, END_FILE_HOOK);
2379 }
2380 
2381 void register_db_call_marker(int id)
2382 {
2383         add_hook(&match_call_marker, FUNCTION_CALL_HOOK);
2384 }
2385 
2386 char *return_state_to_var_sym(struct expression *expr, int param, const char *key, struct symbol **sym)
2387 {
2388         struct expression *arg;
2389         char *name = NULL;
2390         char member_name[256];
2391 
2392         *sym = NULL;
2393 
2394         if (param == -1) {
2395                 const char *star = "";
2396 
2397                 if (expr->type != EXPR_ASSIGNMENT)
2398                         return NULL;
2399                 if (get_type(expr->left) == &int_ctype && strcmp(key, "$") != 0)
2400                         return NULL;
2401                 name = expr_to_var_sym(expr->left, sym);
2402                 if (!name)
2403                         return NULL;
2404                 if (key[0] == '*') {
2405                         star = "*";
2406                         key++;
2407                 }
2408                 if (strncmp(key, "$", 1) != 0)
2409                         return name;
2410                 snprintf(member_name, sizeof(member_name), "%s%s%s", star, name, key + 1);
2411                 free_string(name);
2412                 return alloc_string(member_name);
2413         }
2414 
2415         while (expr->type == EXPR_ASSIGNMENT)
2416                 expr = strip_expr(expr->right);
2417         if (expr->type != EXPR_CALL)
2418                 return NULL;
2419 
2420         arg = get_argument_from_call_expr(expr->args, param);
2421         if (!arg)
2422                 return NULL;
2423 
2424         return get_variable_from_key(arg, key, sym);
2425 }
2426 
2427 char *get_variable_from_key(struct expression *arg, const char *key, struct symbol **sym)
2428 {
2429         char buf[256];
2430         char *tmp;
2431         bool add_star = false;
2432 
2433         if (!arg)
2434                 return NULL;
2435 
2436         arg = strip_expr(arg);
2437 
2438         if (strcmp(key, "$") == 0)
2439                 return expr_to_var_sym(arg, sym);
2440 
2441         if (strcmp(key, "*$") == 0) {
2442                 if (arg->type == EXPR_PREOP && arg->op == '&') {
2443                         arg = strip_expr(arg->unop);
2444                         return expr_to_var_sym(arg, sym);
2445                 } else {
2446                         tmp = expr_to_var_sym(arg, sym);
2447                         if (!tmp)
2448                                 return NULL;
2449                         snprintf(buf, sizeof(buf), "*%s", tmp);
2450                         free_string(tmp);
2451                         return alloc_string(buf);
2452                 }
2453         }
2454 
2455         if (key[0] == '*') {
2456                 add_star = true;
2457                 key++;
2458         }
2459 
2460         if (arg->type == EXPR_PREOP && arg->op == '&') {
2461                 arg = strip_expr(arg->unop);
2462                 tmp = expr_to_var_sym(arg, sym);
2463                 if (!tmp)
2464                         return NULL;
2465                 snprintf(buf, sizeof(buf), "%s%s.%s",
2466                          add_star ? "*" : "", tmp, key + 3);
2467                 return alloc_string(buf);
2468         }
2469 
2470         tmp = expr_to_var_sym(arg, sym);
2471         if (!tmp)
2472                 return NULL;
2473         snprintf(buf, sizeof(buf), "%s%s%s", add_star ? "*" : "", tmp, key + 1);
2474         free_string(tmp);
2475         return alloc_string(buf);
2476 }
2477 
2478 char *get_chunk_from_key(struct expression *arg, char *key, struct symbol **sym, struct var_sym_list **vsl)
2479 {
2480         *vsl = NULL;
2481 
2482         if (strcmp("$", key) == 0)
2483                 return expr_to_chunk_sym_vsl(arg, sym, vsl);
2484         return get_variable_from_key(arg, key, sym);
2485 }
2486 
2487 const char *state_name_to_param_name(const char *state_name, const char *param_name)
2488 {
2489         int name_len;
2490         static char buf[256];
2491         bool add_star = false;
2492 
2493         name_len = strlen(param_name);
2494 
2495         if (state_name[0] == '*') {
2496                 add_star = true;
2497                 state_name++;
2498         }
2499 
2500         if (strcmp(state_name, param_name) == 0) {
2501                 snprintf(buf, sizeof(buf), "%s$", add_star ? "*" : "");
2502                 return buf;
2503         }
2504 
2505         if (state_name[name_len] == '-' && /* check for '-' from "->" */
2506             strncmp(state_name, param_name, name_len) == 0) {
2507                 snprintf(buf, sizeof(buf), "%s$%s",
2508                          add_star ? "*" : "", state_name + name_len);
2509                 return buf;


2510         }
2511         return NULL;
2512 }
2513 
2514 const char *get_param_name_var_sym(const char *name, struct symbol *sym)
2515 {
2516         if (!sym || !sym->ident)
2517                 return NULL;
2518 
2519         return state_name_to_param_name(name, sym->ident->name);
2520 }
2521 
2522 const char *get_mtag_name_var_sym(const char *state_name, struct symbol *sym)
2523 {
2524         struct symbol *type;
2525         const char *sym_name;
2526         int name_len;
2527         static char buf[256];
2528 
2529         /*