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