1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "job_fill_gen.h"
17 #include "verification/absint/absint.h"
18 #include "verification/cflow/cflow_check.h"
19 #include "verification/config/debug_breakpoint/breakpoint.h"
20 #include "verification/jobs/job.h"
21
22 namespace panda::verifier {
UpdateTypes(PandaTypes & types) const23 bool Job::UpdateTypes(PandaTypes &types) const
24 {
25 bool result = true;
26 auto has_type = [&](const LibCache::CachedClass &klass) {
27 bool is_valid = types.TypeOf(klass).IsValid();
28 if (!is_valid) {
29 LOG(WARNING, VERIFIER) << "Cached class " << klass.GetName() << " doesn't have a valid type in typesystem";
30 }
31 return is_valid;
32 };
33 ForAllCachedClasses([&](const LibCache::CachedClass &klass) { result = result && has_type(klass); });
34 ForAllCachedMethods([&types](const LibCache::CachedMethod &method) { types.NormalizedMethodSignature(method); });
35 ForAllCachedFields([&](const LibCache::CachedField &field) {
36 result = result && has_type(field.klass) && has_type(LibCache::GetRef(field.type));
37 });
38 return result;
39 }
40
Verify(PandaTypes & types) const41 bool Job::Verify(PandaTypes &types) const
42 {
43 auto verif_context = PrepareVerificationContext(types, *this);
44 auto result = VerifyMethod(verif_context);
45 return result != VerificationStatus::ERROR;
46 }
47
DoChecks(LibCache & cache,PandaTypes & types)48 bool Job::DoChecks(LibCache &cache, PandaTypes &types)
49 {
50 const auto &check = Options().Check();
51
52 if (check[MethodOption::CheckType::RESOLVE_ID]) {
53 if (!ResolveIdentifiers(cache)) {
54 LOG(WARNING, VERIFIER) << "Failed to resolve identifiers for method " << method_.GetFullName(true);
55 return false;
56 }
57 }
58
59 if (check[MethodOption::CheckType::CFLOW]) {
60 auto cflow_info = CheckCflow(cached_method_, Options(), cache);
61 if (!cflow_info) {
62 LOG(WARNING, VERIFIER) << "Failed to check control flow for method " << method_.GetFullName(true);
63 return false;
64 }
65 cflow_info_ = std::move(cflow_info);
66 }
67
68 DBG_MANAGED_BRK(cached_method_.id, 0xFFFF);
69
70 if (check[MethodOption::CheckType::TYPING]) {
71 if (!UpdateTypes(types)) {
72 LOG(WARNING, VERIFIER) << "Cannot update types from cached classes for method "
73 << method_.GetFullName(true);
74 return false;
75 }
76 }
77
78 if (check[MethodOption::CheckType::ABSINT]) {
79 if (!Verify(types)) {
80 LOG(WARNING, VERIFIER) << "Abstract interpretation failed for method " << method_.GetFullName(true);
81 return false;
82 }
83 }
84
85 return true;
86 }
87 } // namespace panda::verifier
88