1 /**
2 * Copyright (c) 2021-2024 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 "runtime/include/thread_scopes.h"
18 #include "verification/absint/absint.h"
19 #include "verification/cflow/cflow_check.h"
20 #include "verification/config/debug_breakpoint/breakpoint.h"
21 #include "verification/jobs/job.h"
22 #include "verification/public_internal.h"
23
24 namespace ark::verifier {
UpdateTypes(TypeSystem *types) const25 bool Job::UpdateTypes(TypeSystem *types) const
26 {
27 bool result = true;
28 Job::ErrorHandler handler;
29
30 auto hasType = [&](Class const *klass) {
31 types->MentionClass(klass);
32 return true;
33 };
34 ForAllCachedTypes([&](Type type) {
35 if (type.IsClass()) {
36 result = result && hasType(type.GetClass());
37 }
38 });
39 ForAllCachedMethods([&](Method const *method) { types->GetMethodSignature(method); });
40 ForAllCachedFields([&](Field const *field) {
41 result = result && hasType(field->GetClass());
42 if (field->GetType().IsReference()) {
43 ScopedChangeThreadStatus st(ManagedThread::GetCurrent(), ThreadStatus::RUNNING);
44 result = result && hasType(field->ResolveTypeClass(&handler));
45 }
46 });
47 return result;
48 }
49
Verify(TypeSystem *types) const50 bool Job::Verify(TypeSystem *types) const
51 {
52 auto verifContext = PrepareVerificationContext(types, this);
53 auto result = VerifyMethod(verifContext);
54 return result != VerificationStatus::ERROR;
55 }
56
DoChecks(TypeSystem *types)57 bool Job::DoChecks(TypeSystem *types)
58 {
59 const auto &check = Options().Check();
60
61 if (check[MethodOption::CheckType::RESOLVE_ID]) {
62 if (!ResolveIdentifiers()) {
63 LOG(WARNING, VERIFIER) << "Failed to resolve identifiers for method " << method_->GetFullName(true);
64 return false;
65 }
66 }
67
68 if (check[MethodOption::CheckType::CFLOW]) {
69 auto cflowInfo = CheckCflow(method_);
70 if (!cflowInfo) {
71 LOG(WARNING, VERIFIER) << "Failed to check control flow for method " << method_->GetFullName(true);
72 return false;
73 }
74 cflowInfo_ = std::move(cflowInfo);
75 }
76
77 DBG_MANAGED_BRK(&service_->debugCtx, method_->GetUniqId(), 0xFFFF);
78
79 if (check[MethodOption::CheckType::TYPING]) {
80 if (!UpdateTypes(types)) {
81 LOG(WARNING, VERIFIER) << "Cannot update types from cached classes for method "
82 << method_->GetFullName(true);
83 return false;
84 }
85 }
86
87 if (check[MethodOption::CheckType::ABSINT]) {
88 if (!Verify(types)) {
89 LOG(WARNING, VERIFIER) << "Abstract interpretation failed for method " << method_->GetFullName(true);
90 return false;
91 }
92 }
93
94 // Clean up temporary types
95 types->ResetTypeSpans();
96
97 return true;
98 }
99
OnError([[maybe_unused]] ClassLinker::Error error, PandaString const &message)100 void Job::ErrorHandler::OnError([[maybe_unused]] ClassLinker::Error error, PandaString const &message)
101 {
102 LOG(ERROR, VERIFIER) << "Class linker error: " << message;
103 }
104
105 } // namespace ark::verifier
106