• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "abs_int_inl.h"
17 #include "handle_gen.h"
18 
19 namespace ark::verifier {
20 
IsRegDefined(int reg)21 bool AbsIntInstructionHandler::IsRegDefined(int reg)
22 {
23     bool isDefined = ExecCtx().CurrentRegContext().IsRegDefined(reg);
24 #ifndef NDEBUG
25     if (!isDefined) {
26         if (!ExecCtx().CurrentRegContext().WasConflictOnReg(reg)) {
27             SHOW_MSG(UndefinedRegister)
28             LOG_VERIFIER_UNDEFINED_REGISTER(RegisterName(reg, true));
29             END_SHOW_MSG();
30         } else {
31             SHOW_MSG(RegisterTypeConflict)
32             LOG_VERIFIER_REGISTER_TYPE_CONFLICT(RegisterName(reg, false));
33             END_SHOW_MSG();
34         }
35     }
36 #endif
37     return isDefined;
38 }
39 
CheckRegType(int reg,Type tgtType)40 bool AbsIntInstructionHandler::CheckRegType(int reg, Type tgtType)
41 {
42     if (!IsRegDefined(reg)) {
43         return false;
44     }
45     auto type = GetRegType(reg);
46     if (CheckType(type, tgtType)) {
47         return true;
48     }
49 
50     SHOW_MSG(BadRegisterType)
51     LOG_VERIFIER_BAD_REGISTER_TYPE(RegisterName(reg, true), ToString(type), ToString(tgtType));
52     END_SHOW_MSG();
53     return false;
54 }
55 
GetReg(int regIdx)56 const AbstractTypedValue &AbsIntInstructionHandler::GetReg(int regIdx)
57 {
58     return context_.ExecCtx().CurrentRegContext()[regIdx];
59 }
60 
GetRegType(int regIdx)61 Type AbsIntInstructionHandler::GetRegType(int regIdx)
62 {
63     return GetReg(regIdx).GetAbstractType();
64 }
65 
SetReg(int regIdx,const AbstractTypedValue & val)66 void AbsIntInstructionHandler::SetReg(int regIdx, const AbstractTypedValue &val)
67 {
68     if (job_->Options().ShowRegChanges()) {
69         PandaString prevAtvImage {"<none>"};
70         if (ExecCtx().CurrentRegContext().IsRegDefined(regIdx)) {
71             prevAtvImage = ToString(&GetReg(regIdx));
72         }
73         auto newAtvImage = ToString(&val);
74         LOG_VERIFIER_DEBUG_REGISTER_CHANGED(RegisterName(regIdx), prevAtvImage, newAtvImage);
75     }
76     // RegContext extends flexibly for any number of registers, though on AbsInt instruction
77     // handling stage it is not a time to add a new register! The regsiter set (vregs and aregs)
78     // is normally initialized on PrepareVerificationContext.
79     if (!context_.ExecCtx().CurrentRegContext().IsValid(regIdx)) {
80         auto const *method = job_->JobMethod();
81         auto numVregs = method->GetNumVregs();
82         auto numAregs = GetTypeSystem()->GetMethodSignature(method)->args.size();
83         if (regIdx > (int)(numVregs + numAregs)) {
84             LOG_VERIFIER_UNDEFINED_REGISTER(RegisterName(regIdx, true));
85             SET_STATUS_FOR_MSG(UndefinedRegister, ERROR);
86         }
87     }
88     context_.ExecCtx().CurrentRegContext()[regIdx] = val;
89 }
90 
SetReg(int regIdx,Type type)91 void AbsIntInstructionHandler::SetReg(int regIdx, Type type)
92 {
93     SetReg(regIdx, MkVal(type));
94 }
95 
SetRegAndOthersOfSameOrigin(int regIdx,const AbstractTypedValue & val)96 void AbsIntInstructionHandler::SetRegAndOthersOfSameOrigin(int regIdx, const AbstractTypedValue &val)
97 {
98     context_.ExecCtx().CurrentRegContext().ChangeValuesOfSameOrigin(regIdx, val);
99 }
100 
SetRegAndOthersOfSameOrigin(int regIdx,Type type)101 void AbsIntInstructionHandler::SetRegAndOthersOfSameOrigin(int regIdx, Type type)
102 {
103     SetRegAndOthersOfSameOrigin(regIdx, MkVal(type));
104 }
105 
GetAcc()106 const AbstractTypedValue &AbsIntInstructionHandler::GetAcc()
107 {
108     return context_.ExecCtx().CurrentRegContext()[ACC];
109 }
110 
GetAccType()111 Type AbsIntInstructionHandler::GetAccType()
112 {
113     return GetAcc().GetAbstractType();
114 }
115 
SetAcc(const AbstractTypedValue & val)116 void AbsIntInstructionHandler::SetAcc(const AbstractTypedValue &val)
117 {
118     SetReg(ACC, val);
119 }
120 
SetAcc(Type type)121 void AbsIntInstructionHandler::SetAcc(Type type)
122 {
123     SetReg(ACC, type);
124 }
125 
SetAccAndOthersOfSameOrigin(const AbstractTypedValue & val)126 void AbsIntInstructionHandler::SetAccAndOthersOfSameOrigin(const AbstractTypedValue &val)
127 {
128     SetRegAndOthersOfSameOrigin(ACC, val);
129 }
130 
SetAccAndOthersOfSameOrigin(Type type)131 void AbsIntInstructionHandler::SetAccAndOthersOfSameOrigin(Type type)
132 {
133     SetRegAndOthersOfSameOrigin(ACC, type);
134 }
135 
MkVal(Type t)136 AbstractTypedValue AbsIntInstructionHandler::MkVal(Type t)
137 {
138     return AbstractTypedValue {t, context_.NewVar(), GetInst()};
139 }
140 
TypeOfClass(Class const * klass)141 Type AbsIntInstructionHandler::TypeOfClass(Class const *klass)
142 {
143     return Type {klass};
144 }
145 
ReturnType()146 Type AbsIntInstructionHandler::ReturnType()
147 {
148     return context_.ReturnType();
149 }
150 
ExecCtx()151 ExecContext &AbsIntInstructionHandler::ExecCtx()
152 {
153     return context_.ExecCtx();
154 }
155 
DumpRegs(const RegContext & ctx)156 void AbsIntInstructionHandler::DumpRegs(const RegContext &ctx)
157 {
158     LOG_VERIFIER_DEBUG_REGISTERS("registers =", ctx.DumpRegs(GetTypeSystem()));
159 }
160 
Sync()161 void AbsIntInstructionHandler::Sync()
162 {
163     auto addr = inst_.GetAddress();
164     ExecContext &execCtx = ExecCtx();
165     // NOTE(vdyadov): add verification options to show current context and contexts diff in case of incompatibility
166 #ifndef NDEBUG
167     execCtx.StoreCurrentRegContextForAddr(
168         addr, [this, printHdr = true](int regIdx, const auto &src, const auto &dst) mutable {
169             if (printHdr) {
170                 LOG_VERIFIER_REGISTER_CONFLICT_HEADER();
171                 printHdr = false;
172             }
173             LOG_VERIFIER_REGISTER_CONFLICT(RegisterName(regIdx), ToString(src.GetAbstractType()),
174                                            ToString(dst.GetAbstractType()));
175             return true;
176         });
177 #else
178     execCtx.StoreCurrentRegContextForAddr(addr);
179 #endif
180 }
181 
182 }  // namespace ark::verifier
183