00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "ImpliedValue.h"
00011
00012 #include "klee/Constraints.h"
00013 #include "klee/Expr.h"
00014 #include "klee/Solver.h"
00015
00016 #include "klee/Internal/Support/IntEvaluation.h"
00017
00018 #include "klee/util/ExprUtil.h"
00019
00020 #include <iostream>
00021 #include <map>
00022 #include <set>
00023
00024 using namespace klee;
00025
00026
00027
00028 static void _getImpliedValue(ref<Expr> e,
00029 uint64_t value,
00030 ImpliedValueList &results) {
00031 switch (e->getKind()) {
00032 case Expr::Constant: {
00033 assert(value == cast<ConstantExpr>(e)->getConstantValue() &&
00034 "error in implied value calculation");
00035 break;
00036 }
00037
00038
00039
00040 case Expr::NotOptimized: break;
00041
00042 case Expr::Read: {
00043
00044
00045
00046
00047 ReadExpr *re = cast<ReadExpr>(e);
00048 results.push_back(std::make_pair(re,
00049 ConstantExpr::create(value, e->getWidth())));
00050 break;
00051 }
00052
00053 case Expr::Select: {
00054
00055 SelectExpr *se = cast<SelectExpr>(e);
00056
00057 if (ConstantExpr *TrueCE = dyn_cast<ConstantExpr>(se->trueExpr)) {
00058 if (ConstantExpr *FalseCE = dyn_cast<ConstantExpr>(se->falseExpr)) {
00059 if (TrueCE->getConstantValue() != FalseCE->getConstantValue()) {
00060 if (value == TrueCE->getConstantValue()) {
00061 _getImpliedValue(se->cond, 1, results);
00062 } else {
00063 assert(value == FalseCE->getConstantValue() &&
00064 "err in implied value calculation");
00065 _getImpliedValue(se->cond, 0, results);
00066 }
00067 }
00068 }
00069 }
00070 break;
00071 }
00072
00073 case Expr::Concat: {
00074 ConcatExpr *ce = cast<ConcatExpr>(e);
00075 _getImpliedValue(ce->getKid(0), (value >> ce->getKid(1)->getWidth()) & ((1 << ce->getKid(0)->getWidth()) - 1), results);
00076 _getImpliedValue(ce->getKid(1), value & ((1 << ce->getKid(1)->getWidth()) - 1), results);
00077 break;
00078 }
00079
00080 case Expr::Extract: {
00081
00082 break;
00083 }
00084
00085
00086
00087 case Expr::ZExt:
00088 case Expr::SExt: {
00089 CastExpr *ce = cast<CastExpr>(e);
00090 _getImpliedValue(ce->src,
00091 bits64::truncateToNBits(value,
00092 ce->src->getWidth()),
00093 results);
00094 break;
00095 }
00096
00097
00098
00099 case Expr::Add: {
00100 BinaryExpr *be = cast<BinaryExpr>(e);
00101 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left)) {
00102 uint64_t nvalue = ints::sub(value,
00103 CE->getConstantValue(),
00104 CE->getWidth());
00105 _getImpliedValue(be->right, nvalue, results);
00106 }
00107 break;
00108 }
00109 case Expr::Sub: {
00110 BinaryExpr *be = cast<BinaryExpr>(e);
00111 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left)) {
00112 uint64_t nvalue = ints::sub(CE->getConstantValue(),
00113 value,
00114 CE->getWidth());
00115 _getImpliedValue(be->right, nvalue, results);
00116 }
00117 break;
00118 }
00119 case Expr::Mul: {
00120
00121
00122 break;
00123 }
00124
00125 case Expr::UDiv:
00126 case Expr::SDiv:
00127 case Expr::URem:
00128 case Expr::SRem:
00129
00130 break;
00131
00132
00133
00134 case Expr::And: {
00135 BinaryExpr *be = cast<BinaryExpr>(e);
00136 if (be->getWidth() == Expr::Bool) {
00137 if (value) {
00138 _getImpliedValue(be->left, value, results);
00139 _getImpliedValue(be->right, value, results);
00140 }
00141 } else {
00142
00143
00144
00145 }
00146 break;
00147 }
00148 case Expr::Or: {
00149 BinaryExpr *be = cast<BinaryExpr>(e);
00150 if (!value) {
00151 _getImpliedValue(be->left, 0, results);
00152 _getImpliedValue(be->right, 0, results);
00153 } else {
00154
00155 }
00156 break;
00157 }
00158 case Expr::Xor: {
00159 BinaryExpr *be = cast<BinaryExpr>(e);
00160 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left)) {
00161 _getImpliedValue(be->right, value ^ CE->getConstantValue(), results);
00162 }
00163 break;
00164 }
00165
00166
00167 case Expr::Ne:
00168 value = !value;
00169
00170 case Expr::Eq: {
00171 EqExpr *ee = cast<EqExpr>(e);
00172 if (value) {
00173 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left))
00174 _getImpliedValue(ee->right, CE->getConstantValue(), results);
00175 } else {
00176
00177
00178
00179
00180
00181
00182
00183
00184 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left)) {
00185 if (CE->getWidth() == Expr::Bool) {
00186 _getImpliedValue(ee->right, !CE->getConstantValue(), results);
00187 }
00188 }
00189 }
00190 break;
00191 }
00192
00193 default:
00194 break;
00195 }
00196 }
00197
00198 void ImpliedValue::getImpliedValues(ref<Expr> e,
00199 ref<ConstantExpr> value,
00200 ImpliedValueList &results) {
00201 _getImpliedValue(e, value->getConstantValue(), results);
00202 }
00203
00204 void ImpliedValue::checkForImpliedValues(Solver *S, ref<Expr> e,
00205 ref<ConstantExpr> value) {
00206 std::vector<ref<ReadExpr> > reads;
00207 std::map<ref<ReadExpr>, ref<ConstantExpr> > found;
00208 ImpliedValueList results;
00209
00210 getImpliedValues(e, value, results);
00211
00212 for (ImpliedValueList::iterator i = results.begin(), ie = results.end();
00213 i != ie; ++i) {
00214 std::map<ref<ReadExpr>, ref<ConstantExpr> >::iterator it =
00215 found.find(i->first);
00216 if (it != found.end()) {
00217 assert(it->second->getConstantValue() == i->second->getConstantValue() &&
00218 "I don't think so Scott");
00219 } else {
00220 found.insert(std::make_pair(i->first, i->second));
00221 }
00222 }
00223
00224 findReads(e, false, reads);
00225 std::set< ref<ReadExpr> > readsSet(reads.begin(), reads.end());
00226 reads = std::vector< ref<ReadExpr> >(readsSet.begin(), readsSet.end());
00227
00228 std::vector<ref<Expr> > assumption;
00229 assumption.push_back(EqExpr::create(e, value));
00230
00231
00232
00233
00234
00235
00236
00237 for (std::vector< ref<ReadExpr> >::iterator i = reads.begin(),
00238 ie = reads.end(); i != ie; ++i) {
00239 ReadExpr *re = i->get();
00240 assumption.push_back(UltExpr::create(re->index,
00241 ConstantExpr::alloc(re->updates.root->size,
00242 kMachinePointerType)));
00243 }
00244
00245 ConstraintManager assume(assumption);
00246 for (std::vector< ref<ReadExpr> >::iterator i = reads.begin(),
00247 ie = reads.end(); i != ie; ++i) {
00248 ref<ReadExpr> var = *i;
00249 ref<ConstantExpr> possible;
00250 bool success = S->getValue(Query(assume, var), possible);
00251 assert(success && "FIXME: Unhandled solver failure");
00252 std::map<ref<ReadExpr>, ref<ConstantExpr> >::iterator it = found.find(var);
00253 bool res;
00254 success = S->mustBeTrue(Query(assume, EqExpr::create(var, possible)), res);
00255 assert(success && "FIXME: Unhandled solver failure");
00256 if (res) {
00257 if (it != found.end()) {
00258 assert(possible->getConstantValue() == it->second->getConstantValue());
00259 found.erase(it);
00260 }
00261 } else {
00262 if (it!=found.end()) {
00263 ref<Expr> binding = it->second;
00264 llvm::cerr << "checkForImpliedValues: " << e << " = " << value << "\n"
00265 << "\t\t implies " << var << " == " << binding
00266 << " (error)\n";
00267 assert(0);
00268 }
00269 }
00270 }
00271
00272 assert(found.empty());
00273 }