00001
00002
00003
00004 #ifndef findConstants_H
00005 #define findConstants_H
00006
00007 #include "x86InstructionSemantics.h"
00008 #include "integerOps.h"
00009 #include "flowEquations.h"
00010
00011 #include <cassert>
00012 #include <cstdio>
00013 #include <boost/lexical_cast.hpp>
00014
00024 template <size_t Len>
00025 struct LatticeElement {
00026 bool isTop;
00027 uint64_t name;
00028 SgAsmx86Instruction* definingInstruction;
00029 bool negate;
00030 uint64_t offset;
00031
00032
00033 LatticeElement()
00034 : isTop(true), name(0), definingInstruction(NULL), negate(false), offset(0)
00035 {}
00036
00037
00038 static LatticeElement nonconstant(uint64_t name, SgAsmx86Instruction* definingInstruction) {
00039 return LatticeElement(name, definingInstruction, false, 0);
00040 }
00041
00042
00043 LatticeElement(uint64_t name, SgAsmx86Instruction* definingInstruction, bool negate, uint64_t offset)
00044 : isTop(false), name(name), definingInstruction(definingInstruction), negate(negate),
00045 offset(offset & (IntegerOps::GenMask<uint64_t, Len>::value))
00046 {}
00047
00048
00049 LatticeElement(bool isTop, uint64_t name, SgAsmx86Instruction* definingInstruction, bool negate, uint64_t offset)
00050 : isTop(isTop), name(name), definingInstruction(definingInstruction), negate(negate),
00051 offset(offset & (IntegerOps::GenMask<uint64_t, Len>::value))
00052 {}
00053
00054
00055 static LatticeElement constant(uint64_t c, SgAsmx86Instruction* definingInstruction) {
00056 return LatticeElement(0, definingInstruction, false, c);
00057 }
00058
00059 friend bool operator==(const LatticeElement& a, const LatticeElement& b) {
00060 if (a.isTop != b.isTop) return false;
00061 if (a.isTop) return true;
00062 return a.name == b.name && (a.name == 0 || a.negate == b.negate) && a.offset == b.offset;
00063 }
00064 friend bool operator<(const LatticeElement& a, const LatticeElement& b) {
00065 if (a.isTop < b.isTop) return true;
00066 if (b.isTop < a.isTop) return false;
00067 if (a.name < b.name) return true;
00068 if (b.name < a.name) return false;
00069 if (a.name != 0 && a.negate < b.negate) return true;
00070 if (a.name != 0 && b.negate < a.negate) return false;
00071 return a.offset < b.offset;
00072 }
00073 void merge(const LatticeElement& elt, uint64_t newName, SgAsmx86Instruction* def) {
00074 if (elt.isTop) return;
00075 if (this->isTop) {
00076 *this = elt;
00077 return;
00078 }
00079 if (*this == elt)
00080 return;
00081 this->isTop = false;
00082 this->name = newName;
00083 this->definingInstruction = def;
00084 this->negate = false;
00085 this->offset = 0;
00086 return;
00087 }
00088 };
00089
00096 template <size_t Len>
00097 std::ostream& operator<<(std::ostream& o, const LatticeElement<Len>& e)
00098 {
00099 if (e.isTop) {
00100 o << "<top>";
00101 } else {
00102 uint64_t sign_bit = (uint64_t)1 << (Len-1);
00103 uint64_t val_mask = sign_bit - 1;
00104 uint64_t negative = (e.offset & sign_bit) ? (~e.offset & val_mask) + 1 : 0;
00105
00106 if (e.name!=0) {
00107
00108 const char *sign = e.negate ? "-" : "";
00109 o <<sign <<"v" <<std::dec <<e.name;
00110 if (negative) {
00111 o <<"-0x" <<std::hex <<negative;
00112 } else if (e.offset) {
00113 o <<"+0x" <<std::hex <<e.offset;
00114 }
00115 } else {
00116
00117 ROSE_ASSERT(!e.negate);
00118 o <<"0x" <<std::hex <<e.offset;
00119 if (negative)
00120 o <<" (-0x" <<std::hex <<negative <<")";
00121 }
00122 if (e.definingInstruction!=NULL)
00123 o << " [from " << unparseInstructionWithAddress(e.definingInstruction) << "]";
00124 }
00125 return o;
00126 }
00127
00129 extern uint64_t xvarNameCounter;
00130
00133 extern SgAsmx86Instruction* currentInstruction;
00134
00135 template <size_t Len>
00136 struct XVariable: public Variable {
00137 LatticeElement<Len> value;
00138 uint64_t myName;
00139 SgAsmx86Instruction* def;
00140 XVariable()
00141 : value(), myName(++xvarNameCounter), def(currentInstruction)
00142 {}
00143
00145 void set(const LatticeElement<Len>& le) {
00146 LatticeElement<Len> newValue = value;
00147 newValue.merge(le, myName, def);
00148 if (value == newValue)
00149 return;
00150 value = newValue;
00151 this->pushChanges();
00152 }
00153
00155 LatticeElement<Len> get() const {
00156 return value;
00157 }
00158 };
00159
00161 template <size_t Len>
00162 struct XVariablePtr {
00163 XVariable<Len>* var;
00164 XVariablePtr()
00165 : var(NULL)
00166 {}
00167 XVariablePtr(XVariable<Len>* var)
00168 : var(var)
00169 {}
00170 operator XVariable<Len>*() const {
00171 return var;
00172 }
00173 XVariable<Len>* operator->() const {
00174 return var;
00175 }
00176 static XVariablePtr bottom() {
00177 struct BottomConstraint: public Constraint {
00178 XVariablePtr<Len> var;
00179 BottomConstraint(XVariablePtr<Len> var)
00180 : var(var)
00181 {}
00182 virtual void run() const {
00183 var->set(LatticeElement<Len>::nonconstant(var->myName, var->def));
00184 }
00185 virtual void markDependencies() {}
00186 };
00187 XVariablePtr<Len> var = new XVariable<Len>();
00188 (new BottomConstraint(var))->activate();
00189 return var;
00190 }
00191 };
00192
00193 template <size_t Len>
00194 std::ostream& operator<<(std::ostream& o, XVariablePtr<Len> v) {
00195 o << v->value;
00196 return o;
00197 }
00198
00201 struct MemoryWrite {
00202 LatticeElement<32> address;
00203 LatticeElement<32> data;
00204 unsigned int len;
00205 friend bool operator==(const MemoryWrite& a, const MemoryWrite& b) {
00206 return a.address == b.address && a.data == b.data && a.len == b.len;
00207 }
00208 friend bool operator<(const MemoryWrite& a, const MemoryWrite& b) {
00209 return a.address < b.address;
00210 }
00211 };
00212
00213 bool mayAlias(const MemoryWrite&, const MemoryWrite&);
00214 bool mustAlias(const MemoryWrite&, const MemoryWrite&);
00215
00216 template <size_t From, size_t To>
00217 XVariablePtr<To> unsignedExtend(XVariablePtr<From>);
00218
00219 template <size_t From, size_t To, size_t Len>
00220 XVariablePtr<To - From> extract(XVariablePtr<Len>);
00221
00223
00224 struct MemoryWriteSet {
00225 bool isTop;
00226 std::vector<MemoryWrite> writes;
00227
00228 MemoryWriteSet()
00229 : isTop(true), writes()
00230 {}
00231
00233 void addWrite(LatticeElement<32> address, LatticeElement<32> data, unsigned int len) {
00234 isTop = false;
00235 MemoryWrite mw;
00236 mw.address = address;
00237 mw.data = data;
00238 mw.len = len;
00239 std::vector<MemoryWrite> newWrites;
00240 for (size_t i = 0; i < writes.size(); ++i) {
00241 if (!mayAlias(writes[i], mw))
00242 newWrites.push_back(writes[i]);
00243 }
00244 newWrites.push_back(mw);
00245 writes = newWrites;
00246 std::sort(writes.begin(), writes.end());
00247 }
00248
00250 template <size_t Len>
00251 bool getValueAtAddress(LatticeElement<32> address, LatticeElement<Len>& result, uint32_t resultName,
00252 SgAsmx86Instruction* resultDef) const {
00253
00254 MemoryWrite mw;
00255 mw.address = address;
00256 mw.data = LatticeElement<32>::constant(0, resultDef);
00257 mw.len = Len / 8;
00258
00259
00260 for (size_t i = 0; i < writes.size(); ++i) {
00261 if (mustAlias(writes[i], mw)) {
00262
00263 const LatticeElement<32>& data = writes[i].data;
00264 result = LatticeElement<Len>(data.isTop, data.name, data.definingInstruction, data.negate, data.offset);
00265 return true;
00266 }
00267 }
00268
00269
00270 result = isTop ? LatticeElement<Len>() : LatticeElement<Len>::nonconstant(resultName, resultDef);
00271 return false;
00272 }
00273
00274 static MemoryWriteSet bottom() {
00275 MemoryWriteSet mws;
00276 mws.isTop = false;
00277 mws.writes.clear();
00278 return mws;
00279 }
00280
00281 bool mergeIn(const MemoryWriteSet& o) {
00282 if (o.isTop)
00283 return false;
00284 if (this->isTop) {
00285 *this = o;
00286 return !o.isTop;
00287 }
00288 bool result = !writes.empty();
00289 *this = bottom();
00290 return result;
00291 }
00292
00293 friend bool operator==(const MemoryWriteSet& a, const MemoryWriteSet& b) {
00294 return a.isTop == b.isTop && (a.isTop || a.writes == b.writes);
00295 }
00296 };
00297
00298 struct MemoryVariable: public Variable {
00299 MemoryWriteSet mws;
00300 MemoryVariable()
00301 : mws()
00302 {}
00303 void set(const MemoryWriteSet& s) {
00304 if (mws.mergeIn(s)) this->pushChanges();
00305 }
00306 const MemoryWriteSet& get() const {
00307 return mws;
00308 }
00309 };
00310
00311 template <size_t OutputLen>
00312 struct NullaryConstraint: public Constraint {
00313 XVariablePtr<OutputLen> result;
00314 NullaryConstraint(XVariablePtr<OutputLen> result): result(result) {}
00315 virtual void run() const {
00316 uint64_t newVal = this->compute();
00317 result->set(LatticeElement<OutputLen>::constant(newVal, result->def));
00318 }
00319 virtual void markDependencies() {}
00320 virtual uint64_t compute() const = 0;
00321 };
00322
00323 template <size_t InputLen, size_t OutputLen>
00324 struct UnaryConstraint: public Constraint {
00325 XVariablePtr<OutputLen> result;
00326 XVariablePtr<InputLen> var;
00327 UnaryConstraint(XVariablePtr<OutputLen> result, XVariablePtr<InputLen> var)
00328 : result(result), var(var)
00329 {}
00330 virtual void run() const {
00331 LatticeElement<InputLen> le = var->get();
00332 if (le.isTop) {result->set(LatticeElement<OutputLen>()); return;}
00333 if (le.name != 0) {result->set(LatticeElement<OutputLen>::nonconstant(result->myName, result->def)); return;}
00334 uint64_t newVal = this->compute(le.offset);
00335 result->set(LatticeElement<OutputLen>::constant(newVal, result->def));
00336 }
00337 virtual void markDependencies() {
00338 addDependency(var);
00339 }
00340 virtual uint64_t compute(uint64_t a) const = 0;
00341 };
00342
00343 #define UNARY_COMPUTATION(name, InLen, OutLen, Formula) \
00344 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen)> a) { \
00345 XVariablePtr<(OutLen)> result = new XVariable<(OutLen)>(); \
00346 struct IC: public UnaryConstraint<(InLen), (OutLen)> { \
00347 IC(XVariablePtr<(OutLen)> result, XVariablePtr<(InLen)> var1) \
00348 : UnaryConstraint<(InLen), (OutLen)>(result, var1) \
00349 {} \
00350 virtual uint64_t compute(uint64_t a) const { \
00351 Formula \
00352 } \
00353 }; \
00354 (new IC(result, a))->activate(); \
00355 return result; \
00356 }
00357
00358 #define UNARY_COMPUTATION_SPECIAL(name, InLen1, OutLen, Formula) \
00359 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen1)> a) { \
00360 XVariablePtr<(OutLen)> result = new XVariable<(OutLen)>(); \
00361 struct IC: public UnaryConstraint<(InLen1), (OutLen)> { \
00362 IC(XVariablePtr<(OutLen)> result, XVariablePtr<(InLen1)> var1) \
00363 : UnaryConstraint<(InLen1), (OutLen)>(result, var1) \
00364 {} \
00365 virtual void run() const { \
00366 LatticeElement<(InLen1)> le1 = UnaryConstraint<(InLen1), (OutLen)>::var->get(); \
00367 XVariablePtr<(OutLen)> result = UnaryConstraint<(InLen1), (OutLen)>::result; \
00368 if (le1.isTop) {result->set(LatticeElement<(OutLen)>()); return;} \
00369 Formula \
00370 } \
00371 virtual uint64_t compute(uint64_t) const {abort();} \
00372 }; \
00373 (new IC(result, a))->activate(); \
00374 return result; \
00375 }
00376
00377 template <size_t InputLen1, size_t InputLen2, size_t OutputLen>
00378 struct BinaryConstraint: public Constraint {
00379 XVariablePtr<OutputLen> result;
00380 XVariablePtr<InputLen1> var1;
00381 XVariablePtr<InputLen2> var2;
00382
00383 BinaryConstraint(XVariablePtr<OutputLen> result, XVariablePtr<InputLen1> var1, XVariablePtr<InputLen2> var2)
00384 : result(result), var1(var1), var2(var2)
00385 {}
00386
00387 virtual void run() const {
00388 LatticeElement<InputLen1> le1 = var1->get();
00389 LatticeElement<InputLen2> le2 = var2->get();
00390 if (le1.isTop || le2.isTop) {
00391 result->set(LatticeElement<OutputLen>());
00392 return;
00393 }
00394 if (le1.name != 0 || le2.name != 0) {
00395 result->set(LatticeElement<OutputLen>::nonconstant(result->myName, result->def));
00396 return;
00397 }
00398 uint64_t newVal = this->compute(le1.offset, le2.offset);
00399 result->set(LatticeElement<OutputLen>::constant(newVal, result->def));
00400 }
00401
00402 virtual void markDependencies() {
00403 addDependency(var1);
00404 addDependency(var2);
00405 }
00406 virtual uint64_t compute(uint64_t a, uint64_t b) const = 0;
00407 };
00408
00409 #define BINARY_COMPUTATION(name, InLen1, InLen2, OutLen, Formula) \
00410 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen1)> a, XVariablePtr<(InLen2)> b) { \
00411 XVariablePtr<(OutLen)> result = new XVariable<(OutLen)>(); \
00412 struct IC: public BinaryConstraint<(InLen1), (InLen2), (OutLen)> { \
00413 IC(XVariablePtr<(OutLen)> result, XVariablePtr<(InLen1)> var1, XVariablePtr<(InLen2)> var2) \
00414 : BinaryConstraint<(InLen1), (InLen2), (OutLen)>(result, var1, var2) \
00415 {} \
00416 virtual uint64_t compute(uint64_t a, uint64_t b) const { \
00417 Formula \
00418 } \
00419 }; \
00420 (new IC(result, a, b))->activate(); \
00421 return result; \
00422 }
00423
00424 #define BINARY_COMPUTATION_SPECIAL(name, InLen1, InLen2, OutLen, Formula) \
00425 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen1)> a, XVariablePtr<(InLen2)> b) { \
00426 XVariablePtr<(OutLen)> result = new XVariable<(OutLen)>(); \
00427 struct IC: public BinaryConstraint<(InLen1), (InLen2), (OutLen)> { \
00428 IC(XVariablePtr<(OutLen)> result, XVariablePtr<(InLen1)> var1, XVariablePtr<(InLen2)> var2) \
00429 : BinaryConstraint<(InLen1), (InLen2), (OutLen)>(result, var1, var2) \
00430 {} \
00431 virtual void run() const { \
00432 LatticeElement<(InLen1)> le1 = BinaryConstraint<(InLen1), (InLen2), (OutLen)>::var1->get(); \
00433 LatticeElement<(InLen2)> le2 = BinaryConstraint<(InLen1), (InLen2), (OutLen)>::var2->get(); \
00434 XVariablePtr<(OutLen)> result = BinaryConstraint<(InLen1), (InLen2), (OutLen)>::result; \
00435 if (le1.isTop || le2.isTop) { \
00436 result->set(LatticeElement<(OutLen)>()); \
00437 return; \
00438 } \
00439 Formula \
00440 } \
00441 virtual uint64_t compute(uint64_t, uint64_t) const { \
00442 abort(); \
00443 } \
00444 }; \
00445 (new IC(result, a, b))->activate(); \
00446 return result; \
00447 }
00448
00449 template <size_t InputLen1, size_t InputLen2, size_t InputLen3, size_t OutputLen>
00450 struct TernaryConstraint: public Constraint {
00451 XVariablePtr<OutputLen> result;
00452 XVariablePtr<InputLen1> var1;
00453 XVariablePtr<InputLen2> var2;
00454 XVariablePtr<InputLen3> var3;
00455
00456 TernaryConstraint(XVariablePtr<OutputLen> result,
00457 XVariablePtr<InputLen1> var1, XVariablePtr<InputLen2> var2, XVariablePtr<InputLen3> var3)
00458 : result(result), var1(var1), var2(var2), var3(var3)
00459 {}
00460
00461 virtual void run() const {
00462 LatticeElement<InputLen1> le1 = var1->get();
00463 LatticeElement<InputLen2> le2 = var2->get();
00464 LatticeElement<InputLen3> le3 = var3->get();
00465 if (le1.isTop || le2.isTop || le3.isTop) {
00466 result->set(LatticeElement<OutputLen>());
00467 return;
00468 }
00469 if (le1.name != 0 || le2.name != 0 || le3.name != 0) {
00470 result->set(LatticeElement<OutputLen>::nonconstant(result->myName, result->def));
00471 return;
00472 }
00473 uint64_t newVal = this->compute(le1.offset, le2.offset, le3.offset);
00474 result->set(LatticeElement<OutputLen>::constant(newVal, result->def));
00475 }
00476
00477 virtual void markDependencies() {
00478 addDependency(var1);
00479 addDependency(var2);
00480 addDependency(var3);
00481 }
00482
00483 virtual uint64_t compute(uint64_t a, uint64_t b, uint64_t c) const = 0;
00484 };
00485
00486 #define TERNARY_COMPUTATION(name, InLen1, InLen2, InLen3, OutLen, Formula) \
00487 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen1)> a, XVariablePtr<(InLen2)> b, XVariablePtr<(InLen3)> c) { \
00488 XVariable<(OutLen)>* result = new XVariable<(OutLen)>(); \
00489 struct IC: public TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)> { \
00490 IC(XVariablePtr<(OutLen)> result, \
00491 XVariablePtr<(InLen1)> var1, XVariablePtr<(InLen2)> var2, XVariablePtr<(InLen3)> var3) \
00492 : TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>(result, var1, var2, var3) \
00493 {} \
00494 virtual uint64_t compute(uint64_t a, uint64_t b, uint64_t c) const { \
00495 Formula \
00496 } \
00497 }; \
00498 (new IC(result, a, b, c))->activate(); \
00499 return result; \
00500 }
00501
00502 #define TERNARY_COMPUTATION_SPECIAL(name, InLen1, InLen2, InLen3, OutLen, Formula) \
00503 XVariablePtr<(OutLen)> name(XVariablePtr<(InLen1)> a, XVariablePtr<(InLen2)> b, XVariablePtr<(InLen3)> c) { \
00504 XVariablePtr<(OutLen)> result = new XVariable<(OutLen)>(); \
00505 struct IC: public TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)> { \
00506 IC(XVariablePtr<(OutLen)> result, \
00507 XVariablePtr<(InLen1)> var1, XVariablePtr<(InLen2)> var2, XVariablePtr<(InLen3)> var3) \
00508 : TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>(result, var1, var2, var3) \
00509 {} \
00510 virtual void run() const { \
00511 LatticeElement<(InLen1)> le1 = TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>::var1->get(); \
00512 LatticeElement<(InLen2)> le2 = TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>::var2->get(); \
00513 LatticeElement<(InLen3)> le3 = TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>::var3->get(); \
00514 XVariablePtr<(OutLen)> result = TernaryConstraint<(InLen1), (InLen2), (InLen3), (OutLen)>::result; \
00515 if (le1.isTop || le2.isTop || le3.isTop) { \
00516 result->set(LatticeElement<(OutLen)>()); \
00517 return; \
00518 } \
00519 Formula \
00520 } \
00521 virtual uint64_t compute(uint64_t, uint64_t, uint64_t) const { \
00522 abort(); \
00523 } \
00524 }; \
00525 (new IC(result, a, b, c))->activate(); \
00526 return result; \
00527 }
00528
00529
00530 template <size_t Len>
00531 struct MergeConstraint: public Constraint {
00532 XVariablePtr<Len> result;
00533 XVariablePtr<Len> var1;
00534 MergeConstraint(XVariablePtr<Len> result, XVariablePtr<Len> var1)
00535 : result(result), var1(var1)
00536 {}
00537 virtual void run() const {
00538 result->set(var1->get());
00539 }
00540 virtual void markDependencies() {
00541 addDependency(var1);
00542 }
00543 };
00544
00545 struct MemoryMergeConstraint: public Constraint {
00546 MemoryVariable* result;
00547 MemoryVariable* var1;
00548 MemoryMergeConstraint(MemoryVariable* result, MemoryVariable* var1)
00549 : result(result), var1(var1)
00550 {}
00551 virtual void run() const {
00552 result->set(var1->get());
00553 }
00554 virtual void markDependencies() {
00555 addDependency(var1);
00556 }
00557 };
00558
00559 struct RegisterSet {
00560 static const size_t n_gprs = 8;
00561 static const size_t n_segregs = 6;
00562 static const size_t n_flags = 32;
00564 XVariablePtr<32> gpr[n_gprs];
00565 XVariablePtr<16> segreg[n_segregs];
00566 XVariablePtr<1> flag[n_flags];
00567 MemoryVariable* memoryWrites;
00568
00569 RegisterSet() {
00570 for (size_t i = 0; i < n_gprs; ++i)
00571 gpr[i] = new XVariable<32>();
00572 for (size_t i = 0; i < n_segregs; ++i)
00573 segreg[i] = new XVariable<16>();
00574 for (size_t i = 0; i < 16; ++i)
00575 flag[i] = new XVariable<1>();
00576 memoryWrites = new MemoryVariable();
00577 }
00578
00579 void setToBottom() {
00580 for (size_t i = 0; i < n_gprs; ++i)
00581 gpr[i] = XVariablePtr<32>::bottom();
00582 for (size_t i = 0; i < n_segregs; ++i)
00583 segreg[i] = XVariablePtr<16>::bottom();
00584 for (size_t i = 0; i < 16; ++i)
00585 flag[i] = XVariablePtr<1>::bottom();
00586 memoryWrites->set(MemoryWriteSet::bottom());
00587 }
00588
00589 void mergeIn(const RegisterSet& rs) {
00590 for (size_t i = 0; i < n_gprs; ++i)
00591 (new MergeConstraint<32>(gpr[i], rs.gpr[i]))->activate();
00592 for (size_t i = 0; i < n_segregs; ++i)
00593 (new MergeConstraint<16>(segreg[i], rs.segreg[i]))->activate();
00594 for (size_t i = 0; i < 16; ++i)
00595 (new MergeConstraint<1>(flag[i], rs.flag[i]))->activate();
00596 (new MemoryMergeConstraint(memoryWrites, rs.memoryWrites))->activate();
00597 }
00598
00600 std::string diff(const RegisterSet &orig, std::string prefix="") {
00601 std::ostringstream s;
00602 for (size_t i=0; i<n_gprs; i++) {
00603 if (!(orig.gpr[i]->get()==gpr[i]->get())) {
00604 s <<prefix <<gprToString((X86GeneralPurposeRegister)i) <<" = " <<gpr[i] <<"\n";
00605 }
00606 }
00607 for (size_t i=0; i<n_segregs; i++) {
00608 if (!(orig.segreg[i]->get()==segreg[i]->get())) {
00609 s <<prefix <<segregToString((X86SegmentRegister)i) <<" = " <<segreg[i] <<"\n";
00610 }
00611 }
00612 for (size_t i=0; i<16; i++) {
00613 if (!(orig.flag[i]->get()==flag[i]->get())) {
00614 s <<prefix <<flagToString((X86Flag)i) << " = " <<flag[i] <<"\n";
00615 }
00616 }
00617
00618 if (!memoryWrites->get().isTop) {
00619 for (size_t i=0; i<memoryWrites->get().writes.size(); i++) {
00620 LatticeElement<32> addr = memoryWrites->get().writes[i].address;
00621 LatticeElement<32> orig_data;
00622 if (!orig.memoryWrites->get().getValueAtAddress(addr, orig_data, 0, NULL) ||
00623 !(orig_data==memoryWrites->get().writes[i].data)) {
00624 s <<prefix <<"mem @ " <<addr <<" = " <<memoryWrites->get().writes[i].data <<"\n";
00625 }
00626 }
00627 }
00628
00629
00630 return s.str();
00631 }
00632
00633 };
00634
00635 std::ostream&
00636 operator<<(std::ostream& o, const RegisterSet& rs);
00637
00638 struct FindConstantsPolicy {
00639 std::map<uint64_t, RegisterSet> rsets;
00640 RegisterSet cur_state, *orig_state;
00641 uint32_t addr;
00642 XVariablePtr<32> newIp;
00643 const RegisterDictionary *regdict;
00644
00645 struct Exception {
00646 Exception(const std::string &mesg): mesg(mesg) {}
00647 friend std::ostream& operator<<(std::ostream &o, const Exception &e) {
00648 o <<"VirtualMachineSemantics exception: " <<e.mesg;
00649 return o;
00650 }
00651 std::string mesg;
00652 };
00653
00654 FindConstantsPolicy()
00655 : orig_state(NULL), addr(0), regdict(NULL)
00656 {
00657 newIp = number<32>(0);
00658 }
00659
00660
00661
00662 FindConstantsPolicy(RegisterSet *initial_rs)
00663 : orig_state(initial_rs), addr(0), regdict(NULL) {}
00664
00666 const RegisterDictionary *get_register_dictionary() const {
00667 return regdict ? regdict : RegisterDictionary::dictionary_pentium4();
00668 }
00669
00671 void set_register_dictionary(const RegisterDictionary *regdict) {
00672 this->regdict = regdict;
00673 }
00674
00675
00676
00677
00678 template <size_t Len>
00679 struct NumberConstraint: public NullaryConstraint<Len> {
00680 uint64_t val;
00681 NumberConstraint(XVariablePtr<Len> var, uint64_t val)
00682 : NullaryConstraint<Len>(var), val(val)
00683 {}
00684 virtual uint64_t compute() const {
00685 return val;
00686 }
00687 };
00688
00689 template <size_t Len>
00690 XVariablePtr<Len> number(uint64_t n) {
00691 XVariablePtr<Len> var = new XVariable<Len>();
00692 (new NumberConstraint<Len>(var, n))->activate();
00693 return var;
00694 }
00695
00696
00697
00698 template <size_t Len, size_t Len2>
00699 static UNARY_COMPUTATION_SPECIAL(unsignedExtend, Len, Len2, {
00700 result->set(LatticeElement<Len2>(le1.name, le1.definingInstruction, le1.negate, le1.offset));
00701 })
00702
00703 template <size_t From, size_t To, size_t Len>
00704 static UNARY_COMPUTATION_SPECIAL(extract, Len, To - From, {
00705 if (From == 0) {
00706 result->set(LatticeElement<To - From>(le1.name, le1.definingInstruction, le1.negate, le1.offset));
00707 return;
00708 }
00709 if (le1.name != 0) {
00710 result->set(LatticeElement<To - From>::nonconstant(result->myName, result->def));
00711 return;
00712 }
00713 result->set(LatticeElement<To - From>::constant((le1.offset >> From) & (IntegerOps::SHL1<uint64_t, To - From>::value - 1),
00714 result->def));
00715 })
00716
00717
00718 template <size_t Len1, size_t Len2>
00719 BINARY_COMPUTATION(concat, Len1, Len2, Len1 + Len2, {
00720 return a | (b << Len1);
00721 })
00722
00723 XVariablePtr<1> false_() {
00724 return number<1>(0);
00725 }
00726 XVariablePtr<1> true_() {
00727 return number<1>(1);
00728 }
00729 XVariablePtr<1> undefined_() {
00730 return new XVariable<1>();
00731 }
00732
00733 template <size_t Len>
00734 UNARY_COMPUTATION_SPECIAL(invert, Len, Len, {
00735 if (le1.name == 0)
00736 result->set(LatticeElement<Len>::constant(~le1.offset, result->def));
00737 else
00738 result->set(LatticeElement<Len>(le1.name, le1.definingInstruction, !le1.negate, ~le1.offset));
00739 })
00740
00741 template <size_t Len>
00742 UNARY_COMPUTATION_SPECIAL(negate, Len, Len, {
00743 if (le1.name == 0)
00744 result->set(LatticeElement<Len>::constant(-le1.offset, result->def));
00745 else
00746 result->set(LatticeElement<Len>(le1.name, le1.definingInstruction, !le1.negate, -le1.offset));
00747 })
00748
00749 template <size_t Len>
00750 BINARY_COMPUTATION(and_, Len, Len, Len, {return (a & b);})
00751
00752 template <size_t Len>
00753 BINARY_COMPUTATION(or_, Len, Len, Len, {return (a | b);})
00754
00755 template <size_t Len>
00756 BINARY_COMPUTATION_SPECIAL(xor_, Len, Len, Len, {
00757 if (le1 == le2) {
00758 result->set(LatticeElement<Len>::constant(0, result->def));
00759 return;
00760 }
00761 if (le1.name == 0 && le2.name == 0) {
00762 result->set(LatticeElement<Len>::constant(le1.offset ^ le2.offset, result->def));
00763 return;
00764 }
00765 result->set(LatticeElement<Len>::nonconstant(result->myName, result->def));
00766 })
00767
00768 template <size_t From, size_t To>
00769 UNARY_COMPUTATION(signExtend, From, To, {return (From==To ? (a) : IntegerOps::signExtend<From, To>(a));})
00770
00771 template <size_t Len>
00772 XVariablePtr<Len> ite(XVariablePtr<1> sel, XVariablePtr<Len> ifTrue, XVariablePtr<Len> ifFalse) {
00773 XVariablePtr<Len> result = new XVariable<Len>();
00774 struct IteConstraint: public Constraint {
00775 XVariablePtr<Len> result;
00776 XVariablePtr<Len> ifTrue;
00777 XVariablePtr<Len> ifFalse;
00778 XVariablePtr<1> sel;
00779 IteConstraint(XVariablePtr<Len> result, XVariablePtr<1> sel, XVariablePtr<Len> ifTrue, XVariablePtr<Len> ifFalse)
00780 : result(result), ifTrue(ifTrue), ifFalse(ifFalse), sel(sel)
00781 {}
00782 virtual void run() const {
00783 LatticeElement<Len> res;
00784 if (sel->get().name != 0 || (sel->get().name == 0 && sel->get().offset == 1)) {
00785 res.merge(ifTrue->get(), result->myName, result->def);
00786 }
00787 if (sel->get().name != 0 || (sel->get().name == 0 && sel->get().offset == 0)) {
00788 res.merge(ifFalse->get(), result->myName, result->def);
00789 }
00790 result->set(res);
00791 }
00792 virtual void markDependencies() {
00793 addDependency(sel);
00794 addDependency(ifTrue);
00795 addDependency(ifFalse);
00796 }
00797 };
00798 (new IteConstraint(result, sel, ifTrue, ifFalse))->activate();
00799 return result;
00800 }
00801
00802 template <size_t Len>
00803 UNARY_COMPUTATION(equalToZero, Len, 1, {return (a == 0);})
00804
00805 template <size_t Len, size_t SCLen>
00806 UNARY_COMPUTATION(generateMask, SCLen, Len, {return IntegerOps::genMask<uint64_t>(a);})
00807
00808 #if 1
00809 template <size_t Len>
00810 BINARY_COMPUTATION_SPECIAL(add, Len, Len, Len, {
00811 if (le1.name == 0 || le2.name == 0) {
00812 result->set(LatticeElement<Len>(le1.name + le2.name, result->def,
00813 le1.negate || le2.negate, le1.offset + le2.offset));
00814 return;
00815 }
00816 if (le1.name == le2.name && le1.negate == !le2.negate) {
00817 result->set(LatticeElement<Len>::constant(le1.offset + le2.offset, result->def));
00818 return;
00819 }
00820 result->set(LatticeElement<Len>::nonconstant(result->myName, result->def));
00821 })
00822 #else
00823 template <size_t Len>
00824 BINARY_COMPUTATION(add, Len, Len, Len, {return (a & b);})
00825
00826 #endif
00827
00828
00829 template <size_t Len>
00830 TERNARY_COMPUTATION_SPECIAL(add3, Len, Len, 1, Len, {
00831 if ((le1.name == 0) + (le2.name == 0) + (le3.name == 0)) {
00832 result->set(LatticeElement<Len>(le1.name + le2.name + le3.name, result->def,
00833 le1.negate || le2.negate || le3.negate,
00834 le1.offset + le2.offset + le3.offset));
00835 return;
00836 }
00837 if (le1.name == le2.name && le3.name == 0 && le1.negate == !le2.negate) {
00838 result->set(LatticeElement<Len>::constant(le1.offset + le2.offset + le3.offset, result->def));
00839 return;
00840 }
00841 result->set(LatticeElement<Len>::nonconstant(result->myName, result->def));
00842 })
00843
00844 template <size_t Len>
00845 TERNARY_COMPUTATION(xor3, Len, Len, Len, Len, {return (a ^ b ^ c);})
00846
00847 template <size_t Len>
00848 XVariablePtr<Len> addWithCarries(XVariablePtr<Len> a, XVariablePtr<Len> b, XVariablePtr<1> carryIn,
00849 XVariablePtr<Len>& carries) {
00850 XVariablePtr<Len + 1> aa = unsignedExtend<Len, Len + 1>(a);
00851 XVariablePtr<Len + 1> bb = unsignedExtend<Len, Len + 1>(b);
00852 XVariablePtr<Len + 1> result = add3(aa, bb, carryIn);
00853 carries = extract<1, Len + 1>(xor3(aa, bb, result));
00854 return extract<0, Len>(result);
00855 }
00856
00857 template <size_t Len, size_t SALen>
00858 BINARY_COMPUTATION(rotateLeft, Len, SALen, Len, {
00859 return IntegerOps::rotateLeft<Len>(a, b);
00860 })
00861
00862 template <size_t Len, size_t SALen>
00863 BINARY_COMPUTATION(rotateRight, Len, SALen, Len, {
00864 return IntegerOps::rotateRight<Len>(a, b);
00865 })
00866
00867 template <size_t Len, size_t SALen>
00868 BINARY_COMPUTATION(shiftLeft, Len, SALen, Len, {
00869 return IntegerOps::shiftLeft<Len>(a, b);
00870 })
00871
00872 template <size_t Len, size_t SALen>
00873 BINARY_COMPUTATION(shiftRight, Len, SALen, Len, {
00874 return IntegerOps::shiftRightLogical<Len>(a, b);
00875 })
00876
00877 template <size_t Len, size_t SALen>
00878 BINARY_COMPUTATION(shiftRightArithmetic, Len, SALen, Len, {
00879 return IntegerOps::shiftRightArithmetic<Len>(a, b);
00880 })
00881
00882 template <size_t Len1, size_t Len2>
00883 BINARY_COMPUTATION(signedMultiply, Len1, Len2, Len1 + Len2, {
00884 return (IntegerOps::signExtend<Len1, 64>(a) * IntegerOps::signExtend<Len2, 64>(b));
00885 })
00886
00887 template <size_t Len1, size_t Len2>
00888 BINARY_COMPUTATION(unsignedMultiply, Len1, Len2, Len1 + Len2, {
00889 return (a * b);
00890 })
00891
00892 template <size_t Len1, size_t Len2>
00893 BINARY_COMPUTATION(signedDivide, Len1, Len2, Len1, {
00894 return (IntegerOps::signExtend<Len1, 64>(a) / IntegerOps::signExtend<Len2, 64>(b));
00895 })
00896
00897 template <size_t Len1, size_t Len2>
00898 BINARY_COMPUTATION(signedModulo, Len1, Len2, Len2, {
00899 return (IntegerOps::signExtend<Len1, 64>(a) % IntegerOps::signExtend<Len2, 64>(b))
00900 ;})
00901
00902 template <size_t Len1, size_t Len2>
00903 BINARY_COMPUTATION(unsignedDivide, Len1, Len2, Len1, {
00904 if (0==b) throw std::string("division by zero");
00905 return (a / b);
00906 })
00907
00908 template <size_t Len1, size_t Len2>
00909 BINARY_COMPUTATION(unsignedModulo, Len1, Len2, Len2, {
00910 return (a % b);
00911 })
00912
00913 template <size_t Len>
00914 UNARY_COMPUTATION(leastSignificantSetBit, Len, Len, {
00915 for (int i = 0; i < (int)Len; ++i) {
00916 if (a & IntegerOps::shl1<uint64_t>(i))
00917 return i;
00918 }
00919 return 0;
00920 })
00921
00922 template <size_t Len>
00923 UNARY_COMPUTATION(mostSignificantSetBit, Len, Len, {
00924 for (int i = (int)Len - 1; i >= 0; --i) {
00925 if (a & IntegerOps::shl1<uint64_t>(i))
00926 return i;
00927 }
00928 return 0;
00929 })
00930
00931 XVariablePtr<32> filterIndirectJumpTarget(XVariablePtr<32> x) {
00932 return x;
00933 }
00934 XVariablePtr<32> filterCallTarget(XVariablePtr<32> x) {
00935 return x;
00936 }
00937 XVariablePtr<32> filterReturnTarget(XVariablePtr<32> x) {
00938 return x;
00939 }
00940
00941 template <size_t Len>
00942 XVariablePtr<Len> readMemory(X86SegmentRegister segreg, XVariablePtr<32> addr, XVariablePtr<1> cond) {
00943 struct ReadMemoryConstraint: public Constraint {
00944 XVariablePtr<Len> result;
00945 MemoryVariable* memory;
00946 XVariablePtr<32> addr;
00947 virtual void run() const {
00948 LatticeElement<Len> resultRaw;
00949 const MemoryWriteSet &mws = memory->get();
00950 mws.getValueAtAddress<Len>(addr->get(), resultRaw, result->myName, result->def);
00951 result->set(resultRaw);
00952 }
00953 virtual void markDependencies() {
00954 addDependency(memory);
00955 addDependency(addr);
00956 }
00957 };
00958 ReadMemoryConstraint* c = new ReadMemoryConstraint();
00959 c->result = new XVariable<Len>();
00960 c->memory = cur_state.memoryWrites;
00961 c->addr = addr;
00962 c->activate();
00963 return c->result;
00964 }
00965
00966 template <size_t Len>
00967 static MemoryVariable* memoryWriteHelper(MemoryVariable* memory, XVariablePtr<32> address, XVariablePtr<Len> data) {
00968 struct C: public Constraint {
00969 MemoryVariable* memory;
00970 XVariablePtr<32> address;
00971 XVariablePtr<Len> data;
00972 MemoryVariable* memoryOut;
00973 virtual void run() const {
00974 MemoryWriteSet mws = memory->get();
00975 mws.addWrite(address->get(), unsignedExtend<Len, 32>(data)->get(), Len / 8);
00976 memoryOut->set(mws);
00977 }
00978 virtual void markDependencies() {addDependency(memory); addDependency(address); addDependency(data);}
00979 };
00980 C* c = new C();
00981 c->memory = memory;
00982 c->address = address;
00983 c->data = data;
00984 c->memoryOut = new MemoryVariable();
00985 c->activate();
00986 return c->memoryOut;
00987 }
00988
00990 template <size_t Len>
00991 void writeMemory(X86SegmentRegister segreg, XVariablePtr<32> addr, XVariablePtr<Len> data, XVariablePtr<1> cond) {
00992 cur_state.memoryWrites = memoryWriteHelper(cur_state.memoryWrites, addr, data);
00993 }
00994
00996 template <size_t nbits>
00997 void writeMemory(X86SegmentRegister segreg, XVariablePtr<32> addr, XVariablePtr<nbits> data, XVariablePtr<32> repeat,
00998 XVariablePtr<1> cond) {
00999
01000 if (0==repeat->get().name) {
01001 for (size_t i=0; i<repeat->get().offset; i++) {
01002 XVariablePtr<32> tmp_addr = add(addr, number<32>(i*nbits/8));
01003 cur_state.memoryWrites = memoryWriteHelper(cur_state.memoryWrites, tmp_addr, data);
01004 }
01005 } else {
01006 cur_state.memoryWrites = memoryWriteHelper(cur_state.memoryWrites, addr, data);
01007 }
01008 }
01009
01010 void hlt() {}
01011
01012 void cpuid() {}
01013
01014 void interrupt(uint8_t num) {
01015 cur_state.setToBottom();
01016 }
01017
01018 void sysenter() {
01019 cur_state.setToBottom();
01020 }
01021
01022 XVariablePtr<64> rdtsc() {
01023 return number<64>(0);
01024 }
01025 void startBlock(uint64_t addr) {}
01026
01027 void finishBlock(uint64_t addr) {}
01028
01033 bool isInstructionExternallyVisible(SgAsmInstruction* insn) const {
01034 return isFunctionEntry(insn);
01035 }
01036
01038 bool isFunctionEntry(SgAsmInstruction *insn) const {
01039 SgAsmFunction *fdefn = containingFunction(insn);
01040 ROSE_ASSERT(fdefn);
01041 SgAsmBlock *first_bb = isSgAsmBlock(fdefn->get_statementList()[0]);
01042 return first_bb->get_id()==insn->get_address();
01043 }
01044
01046 SgAsmFunction *
01047 containingFunction(SgAsmInstruction *insn) const {
01048 SgAsmBlock *bb = isSgAsmBlock(insn->get_parent());
01049 ROSE_ASSERT(bb!=NULL);
01050 SgAsmFunction *fdefn = isSgAsmFunction(bb->get_parent());
01051 ROSE_ASSERT(fdefn!=NULL);
01052 return fdefn;
01053 }
01054
01056 void startInstruction(SgAsmInstruction* insn) {
01057 addr = insn->get_address();
01058 newIp = number<32>(addr);
01059 if (isInstructionExternallyVisible(insn)) {
01060 if (orig_state) {
01061 rsets[addr] = *orig_state;
01062 orig_state = NULL;
01063 } else {
01064 rsets[addr].setToBottom();
01065 }
01066 }
01067 cur_state = rsets[addr];
01068 currentInstruction = isSgAsmx86Instruction(insn);
01069 }
01070
01073 void finishInstruction(SgAsmInstruction* insn) {
01074 currentInstruction = NULL;
01075 SgAsmx86Instruction* insnx = isSgAsmx86Instruction(insn);
01076 ROSE_ASSERT (insnx);
01077 std::vector<uint64_t> succs;
01078 if (newIp->get().name == 0) {
01079
01080 succs.push_back(newIp->get().offset);
01081 } else {
01082
01083 uint64_t nextAddr = insnx->get_address() + insnx->get_raw_bytes().size();
01084 if (!x86InstructionIsUnconditionalBranch(insnx)) {
01085 succs.push_back(nextAddr);
01086 }
01087 if (isAsmBranch(insnx)) {
01088 uint64_t addr = 0;
01089 bool knownTarget = getAsmKnownBranchTarget(insnx, addr);
01090 if (knownTarget) {
01091 succs.push_back(addr);
01092 }
01093 }
01094 }
01095
01096
01097 for (size_t i = 0; i < succs.size(); ++i) {
01098 uint64_t s = succs[i];
01099 rsets[s].mergeIn(cur_state);
01100 }
01101 }
01102
01103 #define ValueType XVariablePtr
01104 #define EIP_LOCATION newIp
01105 #include "ReadWriteRegisterFragment.h"
01106 #undef ValueType
01107
01108 };
01109
01111 class CdeclFunctionPolicy : public FindConstantsPolicy {
01112 VirtualBinCFG::AuxiliaryInformation *info;
01113 public:
01114 CdeclFunctionPolicy(VirtualBinCFG::AuxiliaryInformation *info, RegisterSet *rs)
01115 : FindConstantsPolicy(rs), info(info) {}
01116
01118 void startInstruction(SgAsmInstruction* insn) {
01119
01120
01121 VirtualBinCFG::InstructionToAddressesMap::iterator found = info->incomingEdges.find(insn);
01122 if (found!=info->incomingEdges.end() && found->second.size()>1) {
01123 RegisterSet &rs = rsets[insn->get_address()];
01124 MemoryWriteSet saved = rs.memoryWrites->get();
01125 rs.setToBottom();
01126 rs.memoryWrites->set(saved);
01127 }
01128
01129 FindConstantsPolicy::startInstruction(insn);
01130
01131
01132 LatticeElement<1> df = rsets[insn->get_address()].flag[x86_flag_df]->get();
01133 if (df.name!=0)
01134 writeRegister("df", false_());
01135
01136 #if 0
01137 std::cout <<"Initial RSET for [" <<unparseInstructionWithAddress(insn) <<"]\n" <<cur_state;
01138 #endif
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162 template<size_t Len>
01163 XVariablePtr<Len> and_(XVariablePtr<Len> a, XVariablePtr<Len> b) {
01164 XVariablePtr<Len> result = new XVariable<Len>();
01165 struct IC: public BinaryConstraint<Len, Len, Len> {
01166 IC(XVariablePtr<Len> result, XVariablePtr<Len> var1, XVariablePtr<Len> var2)
01167 : BinaryConstraint<Len, Len, Len>(result, var1, var2)
01168 {}
01169 virtual void run() const {
01170
01171 LatticeElement<Len> le1 = BinaryConstraint<Len, Len, Len>::var1->get();
01172 LatticeElement<Len> le2 = BinaryConstraint<Len, Len, Len>::var2->get();
01173 XVariablePtr<Len> result = BinaryConstraint<Len, Len, Len>::result;
01174
01175
01176 SgAsmx86Instruction *insn = isSgAsmx86Instruction(result->def);
01177 ROSE_ASSERT(insn);
01178 SgAsmExpressionPtrList &opands = insn->get_operandList()->get_operands();
01179
01180 if (!le1.name && !le2.name) {
01181
01182 result->set(LatticeElement<Len>::constant(le1.offset & le2.offset, result->def));
01183 } else {
01184
01185 SgAsmx86RegisterReferenceExpression *op1 = (opands.size()==2 ?
01186 isSgAsmx86RegisterReferenceExpression(opands[0]) : NULL);
01187 if (op1 && insn->get_kind()==x86_and &&
01188 op1->get_descriptor().get_major()==x86_regclass_gpr && op1->get_descriptor().get_minor()==x86_gpr_sp &&
01189 !le2.isTop) {
01190
01191 LatticeElement<Len> newval = le1;
01192 uint32_t alignment = ~(uint32_t)le2.offset + 1;
01193
01194
01195 newval.offset -= alignment;
01196 newval.definingInstruction = insn;
01197 result->set(newval);
01198 } else {
01199
01200 result->set(LatticeElement<Len>());
01201 }
01202 }
01203 }
01204 virtual uint64_t compute(uint64_t, uint64_t) const {
01205 abort();
01206 }
01207 };
01208 (new IC(result, a, b))->activate();
01209 return result;
01210 }
01211 };
01212
01217 class FindConstantsABIPolicy: public FindConstantsPolicy {
01218 public:
01219
01220 SgAsmFunction* find_function(SgAsmInstruction* insn) {
01221 SgNode* n=insn;
01222 while (n && !isSgAsmFunction(n))
01223 n = n->get_parent();
01224 return isSgAsmFunction(n);
01225 }
01226
01227
01228 bool function_contains_address(SgAsmFunction* f, rose_addr_t va) {
01229 for (size_t i=0; i<f->get_statementList().size(); ++i) {
01230 SgAsmBlock* block = isSgAsmBlock(f->get_statementList()[i]);
01231 ROSE_ASSERT(block!=NULL);
01232 for (size_t j=0; j<block->get_statementList().size(); ++j) {
01233 SgAsmInstruction* insn = isSgAsmInstruction(block->get_statementList()[j]);
01234 if (insn && insn->get_address()==va)
01235 return true;
01236 }
01237 }
01238 return false;
01239 }
01240
01241
01242 bool is_abi_compliant(rose_addr_t) {
01243 return true;
01244 }
01245
01246
01247
01248
01249 bool is_abi_function_call(SgAsmInstruction* insn_) {
01250 SgAsmx86Instruction* insn = isSgAsmx86Instruction(insn_);
01251 ROSE_ASSERT(insn!=NULL);
01252 if (insn->get_kind()!=x86_call && insn->get_kind()!=x86_farcall)
01253 return false;
01254 if (newIp->get().name!=0)
01255 return true;
01256 SgAsmFunction *caller = find_function(insn);
01257 rose_addr_t callee = newIp->get().offset;
01258 if (function_contains_address(caller, callee) && caller->get_entry_va()!=callee)
01259 return false;
01260 return is_abi_compliant(callee);
01261 }
01262
01263
01264
01265
01266 void finishInstruction(SgAsmInstruction* insn_) {
01267 SgAsmx86Instruction* insn = isSgAsmx86Instruction(insn_);
01268 ROSE_ASSERT(insn!=NULL);
01269 if (is_abi_function_call(insn)) {
01270 rose_addr_t call_va = insn->get_address();
01271 rose_addr_t next_va = insn->get_address() + insn->get_raw_bytes().size();
01272 RegisterSet rset;
01273 rset.setToBottom();
01274 rset.memoryWrites = rsets[call_va].memoryWrites;
01275 rset.gpr[x86_gpr_bx] = rsets[call_va].gpr[x86_gpr_bx];
01276 rset.gpr[x86_gpr_di] = rsets[call_va].gpr[x86_gpr_di];
01277 rset.gpr[x86_gpr_si] = rsets[call_va].gpr[x86_gpr_si];
01278 rset.gpr[x86_gpr_sp] = rsets[call_va].gpr[x86_gpr_sp];
01279 rset.gpr[x86_gpr_bp] = rsets[call_va].gpr[x86_gpr_bp];
01280 rsets[next_va].mergeIn(rset);
01281 }
01282 FindConstantsPolicy::finishInstruction(insn);
01283 }
01284 };
01285
01286 #endif