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 "abs_int_inl.h"
17
18 namespace panda::verifier {
19
IsRegDefined(int reg)20 bool AbsIntInstructionHandler::IsRegDefined(int reg)
21 {
22 bool is_defined = ExecCtx().CurrentRegContext().IsRegDefined(reg);
23 #ifndef NDEBUG
24 if (!is_defined) {
25 if (!ExecCtx().CurrentRegContext().WasConflictOnReg(reg)) {
26 SHOW_MSG(UndefinedRegister)
27 LOG_VERIFIER_UNDEFINED_REGISTER(RegisterName(reg, true));
28 END_SHOW_MSG();
29 } else {
30 SHOW_MSG(RegisterTypeConflict)
31 LOG_VERIFIER_REGISTER_TYPE_CONFLICT(RegisterName(reg, false));
32 END_SHOW_MSG();
33 }
34 }
35 #endif
36 return is_defined;
37 }
38
ImageOf(const Type & type)39 const PandaString &AbsIntInstructionHandler::ImageOf(const Type &type)
40 {
41 return Types().ImageOf(type);
42 }
43
ImageOf(const AbstractType & abstract_type)44 PandaString AbsIntInstructionHandler::ImageOf(const AbstractType &abstract_type)
45 {
46 return abstract_type.Image([this](const Type &type) { return ImageOf(type); });
47 }
48
ImageOf(const TypeSet & types)49 PandaString AbsIntInstructionHandler::ImageOf(const TypeSet &types)
50 {
51 return types.Image([this](const Type &type) { return ImageOf(type); });
52 }
53
SubtypesOf(const PandaVector<Type> & types)54 PandaVector<Type> AbsIntInstructionHandler::SubtypesOf(const PandaVector<Type> &types)
55 {
56 PandaUnorderedSet<Type> set;
57 for (const auto &type : types) {
58 type.ForAllSubtypes([&set](const auto &t) {
59 set.insert(t);
60 return true;
61 });
62 }
63 return PandaVector<Type> {set.cbegin(), set.cend()};
64 }
65
SubtypesOf(std::initializer_list<Type> types)66 PandaVector<Type> AbsIntInstructionHandler::SubtypesOf(std::initializer_list<Type> types)
67 {
68 PandaUnorderedSet<Type> set;
69 for (const auto &type : types) {
70 type.ForAllSubtypes([&set](const auto &t) {
71 set.insert(t);
72 return true;
73 });
74 }
75 return PandaVector<Type> {set.cbegin(), set.cend()};
76 }
77
SupertypesOf(const PandaVector<Type> & types)78 PandaVector<Type> AbsIntInstructionHandler::SupertypesOf(const PandaVector<Type> &types)
79 {
80 PandaUnorderedSet<Type> set;
81 for (const auto &type : types) {
82 type.ForAllSupertypes([&set](const auto &t) {
83 set.insert(t);
84 return true;
85 });
86 }
87 return PandaVector<Type> {set.cbegin(), set.cend()};
88 }
89
SupertypesOf(std::initializer_list<Type> types)90 PandaVector<Type> AbsIntInstructionHandler::SupertypesOf(std::initializer_list<Type> types)
91 {
92 PandaUnorderedSet<Type> set;
93 for (const auto &type : types) {
94 type.ForAllSupertypes([&set](const auto &t) {
95 set.insert(t);
96 return true;
97 });
98 }
99 return PandaVector<Type> {set.cbegin(), set.cend()};
100 }
101
CheckRegTypes(int reg,std::initializer_list<Type> types)102 bool AbsIntInstructionHandler::CheckRegTypes(int reg, std::initializer_list<Type> types)
103 {
104 return CheckRegTypes<std::initializer_list<Type>>(reg, types);
105 }
106
CheckTypes(const Type & type,std::initializer_list<Type> types)107 bool AbsIntInstructionHandler::CheckTypes(const Type &type, std::initializer_list<Type> types)
108 {
109 return CheckTypes<std::initializer_list<Type>>(type, types);
110 }
111
GetReg(int reg_idx)112 const AbstractTypedValue &AbsIntInstructionHandler::GetReg(int reg_idx)
113 {
114 return context_.ExecCtx().CurrentRegContext()[reg_idx];
115 }
116
GetRegType(int reg_idx)117 const AbstractType &AbsIntInstructionHandler::GetRegType(int reg_idx)
118 {
119 return GetReg(reg_idx).GetAbstractType();
120 }
121
SetReg(int reg_idx,const AbstractTypedValue & val)122 void AbsIntInstructionHandler::SetReg(int reg_idx, const AbstractTypedValue &val)
123 {
124 if (CurrentJob.Options().ShowRegChanges()) {
125 PandaString prev_atv_image {"<none>"};
126 auto img_of = [this](const auto &t) { return ImageOf(t); };
127 if (ExecCtx().CurrentRegContext().IsRegDefined(reg_idx)) {
128 prev_atv_image = GetReg(reg_idx).Image(img_of);
129 }
130 auto new_atv_image = val.Image(img_of);
131 LOG_VERIFIER_DEBUG_REGISTER_CHANGED(RegisterName(reg_idx), prev_atv_image, new_atv_image);
132 }
133 context_.ExecCtx().CurrentRegContext()[reg_idx] = val;
134 }
135
SetReg(int reg_idx,const AbstractType & type)136 void AbsIntInstructionHandler::SetReg(int reg_idx, const AbstractType &type)
137 {
138 SetReg(reg_idx, MkVal(type));
139 }
140
SetRegAndOthersOfSameOrigin(int reg_idx,const AbstractTypedValue & val)141 void AbsIntInstructionHandler::SetRegAndOthersOfSameOrigin(int reg_idx, const AbstractTypedValue &val)
142 {
143 context_.ExecCtx().CurrentRegContext().ChangeValuesOfSameOrigin(reg_idx, val);
144 }
145
SetRegAndOthersOfSameOrigin(int reg_idx,const AbstractType & type)146 void AbsIntInstructionHandler::SetRegAndOthersOfSameOrigin(int reg_idx, const AbstractType &type)
147 {
148 SetRegAndOthersOfSameOrigin(reg_idx, MkVal(type));
149 }
150
GetAcc()151 const AbstractTypedValue &AbsIntInstructionHandler::GetAcc()
152 {
153 return context_.ExecCtx().CurrentRegContext()[ACC];
154 }
155
GetAccType()156 const AbstractType &AbsIntInstructionHandler::GetAccType()
157 {
158 return GetAcc().GetAbstractType();
159 }
160
SetAcc(const AbstractTypedValue & val)161 void AbsIntInstructionHandler::SetAcc(const AbstractTypedValue &val)
162 {
163 SetReg(ACC, val);
164 }
165
SetAcc(const AbstractType & type)166 void AbsIntInstructionHandler::SetAcc(const AbstractType &type)
167 {
168 SetReg(ACC, type);
169 }
170
SetAccAndOthersOfSameOrigin(const AbstractTypedValue & val)171 void AbsIntInstructionHandler::SetAccAndOthersOfSameOrigin(const AbstractTypedValue &val)
172 {
173 SetRegAndOthersOfSameOrigin(ACC, val);
174 }
175
SetAccAndOthersOfSameOrigin(const AbstractType & type)176 void AbsIntInstructionHandler::SetAccAndOthersOfSameOrigin(const AbstractType &type)
177 {
178 SetRegAndOthersOfSameOrigin(ACC, type);
179 }
180
MkVal(const AbstractType & t)181 AbstractTypedValue AbsIntInstructionHandler::MkVal(const AbstractType &t)
182 {
183 return AbstractTypedValue {t, context_.NewVar(), GetInst()};
184 }
185
Types()186 PandaTypes &AbsIntInstructionHandler::Types()
187 {
188 return context_.Types();
189 }
190
ReturnType()191 const Type &AbsIntInstructionHandler::ReturnType()
192 {
193 return context_.ReturnType();
194 }
195
ExecCtx()196 ExecContext &AbsIntInstructionHandler::ExecCtx()
197 {
198 return context_.ExecCtx();
199 }
200
DumpRegs(const RegContext & ctx)201 void AbsIntInstructionHandler::DumpRegs(const RegContext &ctx)
202 {
203 LOG_VERIFIER_DEBUG_REGISTERS("registers =", ctx.DumpRegs([this](const auto &t) { return ImageOf(t); }));
204 }
205
Sync()206 void AbsIntInstructionHandler::Sync()
207 {
208 auto addr = inst_.GetAddress();
209 ExecContext &exec_ctx = ExecCtx();
210 // TODO(vdyadov): add verification options to show current context and contexts diff in case of incompatibility
211 #ifndef NDEBUG
212 exec_ctx.StoreCurrentRegContextForAddr(
213 addr, [this, print_hdr = true](int reg_idx, const auto &src, const auto &dst) mutable {
214 if (print_hdr) {
215 LOG_VERIFIER_REGISTER_CONFLICT_HEADER();
216 print_hdr = false;
217 }
218 LOG_VERIFIER_REGISTER_CONFLICT(RegisterName(reg_idx), ImageOf(src.GetAbstractType()),
219 ImageOf(dst.GetAbstractType()));
220 return true;
221 });
222 #else
223 exec_ctx.StoreCurrentRegContextForAddr(addr);
224 #endif
225 }
226
227 } // namespace panda::verifier
228