| 1508 | } |
| 1509 | |
| 1510 | int RGDAstParser::parse_gep(dfsan_label ptr_label, uptr ptr, |
| 1511 | dfsan_label index_label, int64_t index, |
| 1512 | uint64_t num_elems, uint64_t elem_size, |
| 1513 | int64_t current_offset, bool enum_index, |
| 1514 | std::vector<uint64_t> &tasks) { |
| 1515 | // check validity of the labels |
| 1516 | if (index_label < CONST_OFFSET || index_label == __dfsan::kInitializingLabel |
| 1517 | || index_label >= size_) { |
| 1518 | return -1; |
| 1519 | } |
| 1520 | |
| 1521 | // update ast_size and branch_to_inputs caches |
| 1522 | // if the index_label has been scanned before, it won't be scanned again |
| 1523 | if (!scan_labels(index_label)) { |
| 1524 | return -1; |
| 1525 | } |
| 1526 | |
| 1527 | // sanity checks |
| 1528 | if (unlikely(ast_size_cache.size() <= index_label)) { |
| 1529 | WARNF("invalid label %u, larger than ast_size_cache: %lu\n", index_label, ast_size_cache.size()); |
| 1530 | return -1; |
| 1531 | } |
| 1532 | if (unlikely(nested_cmp_cache.at(index_label) > 0)) { |
| 1533 | WARNF("unexpected nested cmp in parse_gep for %u, skip\n", index_label); |
| 1534 | return -1; |
| 1535 | } |
| 1536 | |
| 1537 | auto ast_size = ast_size_cache.at(index_label); |
| 1538 | if (unlikely(ast_size == 0)) { |
| 1539 | WARNF("invalid label %u, ast_size_cache is 0\n", index_label); |
| 1540 | return 0; |
| 1541 | } else if (unlikely(ast_size > max_ast_size_)) { |
| 1542 | DEBUGF("skip large AST (%lu) in parse_gep for %u\n", ast_size, index_label); |
| 1543 | return 0; // not an error, just skip |
| 1544 | } |
| 1545 | |
| 1546 | // early return if nothing to do |
| 1547 | if (!enum_index || // if we are not enumerating the index |
| 1548 | (num_elems == 0 && // if the GEP type is not an array, |
| 1549 | // and we also don't have a pointer label |
| 1550 | ptr_label)) { |
| 1551 | return 0; |
| 1552 | } |
| 1553 | |
| 1554 | // hmm, since the gep constraints we want to solve are not in the union table, |
| 1555 | // which means parse_constraint will not work, |
| 1556 | // so we have to construct the tasks directly here |
| 1557 | // |
| 1558 | |
| 1559 | // first, parse the index_label into a partial constraint |
| 1560 | // again, the index_label is not a cmp node |
| 1561 | constraint_t partial_constraint = nullptr; |
| 1562 | // check cache first |
| 1563 | auto itr = constraint_cache.find(index_label); |
| 1564 | if (itr != constraint_cache.end()) { |
| 1565 | partial_constraint = itr->second; |
| 1566 | } else { |
| 1567 | // otherwise, parse the AST into a constraint |
no test coverage detected