• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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