00001 #include "dwarf/h/dwarfResult.h"
00002 #include "dynutil/h/VariableLocation.h"
00003 #include "dwarf/h/dwarfFrameParser.h"
00004 #include "dynutil/h/ProcReader.h"
00005 #include "dynutil/h/dyntypes.h"
00006 #include "dynutil/h/dyn_regs.h"
00007 #include "common/h/Types.h"
00008 #include "common/h/debug_common.h"
00009 #include <iostream>
00010 #include "common/h/debug_common.h"
00011
00012 using namespace Dyninst;
00013 using namespace Dwarf;
00014 using namespace std;
00015
00016 #define CHECK_OPER(n) if (operands.size() < n) { error = true; break; }
00017
00018 void SymbolicDwarfResult::pushReg(MachRegister reg) {
00019 dwarf_printf("\t\tPush %s\n", reg.name().c_str());
00020
00021 if (var.stClass != storageUnset) { error = true; }
00022 var.stClass = storageReg;
00023 var.refClass = storageNoRef;
00024 var.frameOffset = 0;
00025 var.mr_reg = reg;
00026 }
00027
00028 void SymbolicDwarfResult::readReg(MachRegister reg) {
00029 dwarf_printf("\t\t Read %s\n", reg.name().c_str());
00030
00031 if (var.stClass != storageUnset) { error = true; }
00032 var.stClass = storageRegOffset;
00033 var.refClass = storageNoRef;
00034
00035 var.frameOffset = 0;
00036 var.mr_reg = reg;
00037 }
00038
00039 void SymbolicDwarfResult::pushUnsignedVal(MachRegisterVal val) {
00040 dwarf_printf("\t\t Push 0x%lx\n", val);
00041
00042 if (var.stClass == storageUnset) {
00043
00044 var.stClass = storageAddr;
00045 }
00046 operands.push(val);
00047 }
00048
00049 void SymbolicDwarfResult::pushSignedVal(MachRegisterVal val) {
00050 dwarf_printf("\t\t Push 0x%lx\n", val);
00051
00052 operands.push(val);
00053 }
00054
00055 void SymbolicDwarfResult::pushOp(Operator op) {
00056
00057
00058 dwarf_printf("Push op %d\n", op);
00059
00060 switch (op) {
00061 case Add:
00062 CHECK_OPER(1);
00063 if (var.stClass == storageUnset) { error = true; }
00064 var.frameOffset += operands.top();
00065 operands.pop();
00066 break;
00067 default:
00068 error = true;
00069 }
00070 }
00071
00072 void SymbolicDwarfResult::pushOp(Operator op,
00073 unsigned u) {
00074 dwarf_printf("Push op pair %d,%u\n", op, u);
00075
00076 switch(op) {
00077 case Add:
00078 var.frameOffset += u;
00079 break;
00080 default:
00081 error = true;
00082 }
00083 }
00084
00085 void SymbolicDwarfResult::pushFrameBase() {
00086 dwarf_printf("Push frame base\n");
00087
00088 readReg(FrameBase);
00089 }
00090
00091 void SymbolicDwarfResult::pushCFA() {
00092 dwarf_printf("Push CFA\n");
00093
00094 readReg(CFA);
00095 }
00096
00097 VariableLocation &SymbolicDwarfResult::val() {
00098 if (!operands.empty()) {
00099 var.frameOffset += operands.top();
00100 operands.pop();
00101 }
00102 return var;
00103 }
00104
00105 void ConcreteDwarfResult::pushReg(MachRegister) {
00106
00107 error = true;
00108 }
00109
00110 void ConcreteDwarfResult::readReg(MachRegister reg) {
00111 Dyninst::MachRegisterVal v;
00112 if (!reader->GetReg(reg, v)) error = true;
00113 push(v);
00114 dwarf_printf("readReg %s, got 0x%lx, queue size %d\n",
00115 reg.name().c_str(), v, operands.size());
00116 }
00117
00118 void ConcreteDwarfResult::pushUnsignedVal(MachRegisterVal v) {
00119
00120 push(v);
00121 dwarf_printf("pushUnsigned 0x%lx, queue size %d\n", v, operands.size());
00122 }
00123
00124 void ConcreteDwarfResult::pushSignedVal(MachRegisterVal v) {
00125
00126 push(v);
00127 dwarf_printf("pushSigned 0x%lx, queue size %d\n", v, operands.size());
00128 }
00129
00130
00131 void ConcreteDwarfResult::pushOp(Operator op) {
00132 MachRegisterVal v;
00133 MachRegisterVal first;
00134 MachRegisterVal second;
00135
00136 switch (op) {
00137 case Add:
00138 CHECK_OPER(2);
00139 v = peek(1) + peek(0);
00140 dwarf_printf("AddOp: 0x%lx + 0x%lx = 0x%lx\n", peek(1), peek(0), v);
00141 popRange(0, 1);
00142 push(v);
00143 break;
00144 case Sub:
00145 CHECK_OPER(2);
00146 v = peek(1) - peek(0);
00147 dwarf_printf("SubOp: 0x%lx + 0x%lx = 0x%lx\n", peek(1), peek(0), v);
00148 popRange(0, 1);
00149 push(v);
00150 break;
00151 case Mul:
00152 CHECK_OPER(2);
00153 v = peek(1) * peek(0);
00154 popRange(0, 1);
00155 push(v);
00156 break;
00157 case Div:
00158 CHECK_OPER(2);
00159 if (peek(0) == 0) { error = true; break; }
00160 v = peek(1) / peek(0);
00161 popRange(0, 1);
00162 push(v);
00163 break;
00164 case Mod:
00165 CHECK_OPER(2);
00166 if (peek(0) == 0) { error = true; break; }
00167 v = peek(1) % peek(0);
00168 popRange(0, 1);
00169 push(v);
00170 break;
00171 case And:
00172 CHECK_OPER(2);
00173 v = peek(1) & peek(0);
00174 popRange(0, 1);
00175 push(v);
00176 break;
00177 case Or:
00178 CHECK_OPER(2);
00179 v = peek(1) | peek(0);
00180 popRange(0, 1);
00181 push(v);
00182 break;
00183 case Not:
00184 CHECK_OPER(1);
00185 v = ~peek(0);
00186 pop(0);
00187 push(v);
00188 break;
00189 case Xor:
00190 CHECK_OPER(2);
00191 v = peek(0) ^ peek(0);
00192 popRange(0, 1);
00193 push(v);
00194 break;
00195 case Abs:
00196 CHECK_OPER(1);
00197 v = ::abs((long) peek(0));
00198 pop(0);
00199 push(v);
00200 break;
00201 case Shl:
00202 CHECK_OPER(2);
00203 v = peek(1) << peek(0);
00204 popRange(0, 1);
00205 push(v);
00206 break;
00207 case Shr:
00208 CHECK_OPER(2);
00209 v = ((unsigned long) peek(1)) >> ((unsigned long) peek(0));
00210 popRange(0, 1);
00211 push(v);
00212 break;
00213 case ShrArith:
00214 CHECK_OPER(2);
00215 v = ((long) peek(1)) + ((long) peek(0));
00216 popRange(0, 1);
00217 push(v);
00218 break;
00219 case GE:
00220 CHECK_OPER(2);
00221 second = peek(1);
00222 first = peek(0);
00223 popRange(0, 1);
00224 push((second >= first) ? 1 : 0);
00225 break;
00226 case LE:
00227 CHECK_OPER(2);
00228 second = peek(1);
00229 first = peek(0);
00230 popRange(0, 1);
00231 push((second <= first) ? 1 : 0);
00232 break;
00233 case GT:
00234 CHECK_OPER(2);
00235 second = peek(1);
00236 first = peek(0);
00237 popRange(0, 1);
00238 push((second > first) ? 1 : 0);
00239 break;
00240 case LT:
00241 CHECK_OPER(2);
00242 second = peek(1);
00243 first = peek(0);
00244 popRange(0, 1);
00245 push((second < first) ? 1 : 0);
00246 break;
00247 case Eq:
00248 CHECK_OPER(2);
00249 second = peek(1);
00250 first = peek(0);
00251 popRange(0, 1);
00252 push((second == first) ? 1 : 0);
00253 break;
00254 case Neq:
00255 CHECK_OPER(2);
00256 second = peek(1);
00257 first = peek(0);
00258 popRange(0, 1);
00259 push((second != first) ? 1 : 0);
00260 break;
00261 case Deref:
00262 case Pick:
00263 case Drop:
00264 default:
00265
00266 error = true;
00267 break;
00268 }
00269 dwarf_printf("\t After queue manipulation, size %d\n", operands.size());
00270 }
00271
00272 void ConcreteDwarfResult::pushOp(Operator op, unsigned ref) {
00273 switch (op) {
00274 case Add:
00275 pushUnsignedVal(ref);
00276 pushOp(Add);
00277 break;
00278 case Deref: {
00279 CHECK_OPER(1);
00280 MachRegisterVal v;
00281 switch(ref) {
00282 case 1: {
00283 unsigned char c;
00284 if (!reader->ReadMem(peek(0), &c, sizeof(c))) error = true;
00285 v = c;
00286 break;
00287 }
00288 case 2: {
00289 unsigned short s;
00290 if (!reader->ReadMem(peek(0), &s, sizeof(s))) error = true;
00291 v = s;
00292 break;
00293 }
00294 case 4: {
00295 uint32_t u;
00296 if (!reader->ReadMem(peek(0), &u, sizeof(u))) error = true;
00297 v = u;
00298 break;
00299 }
00300 case 8: {
00301 uint64_t u;
00302 if (!reader->ReadMem(peek(0), &u, sizeof(u))) error = true;
00303 v = u;
00304 dwarf_printf("Memory read from 0x%lx: 0x%lx\n", peek(0), u);
00305 break;
00306 }
00307 default:
00308 error = true;
00309 v = 0;
00310 break;
00311 }
00312 push(v);
00313 break;
00314 }
00315 case Pick:
00316 CHECK_OPER(ref);
00317 push(peek(ref));
00318 break;
00319 case Drop:
00320 CHECK_OPER(ref);
00321 pop(ref);
00322 break;
00323 default:
00324 error = true;
00325 break;
00326 }
00327 }
00328
00329 void ConcreteDwarfResult::pushFrameBase() {
00330 error = true;
00331 }
00332
00333 void ConcreteDwarfResult::pushCFA() {
00334 DwarfFrameParser::Ptr cfaParser = DwarfFrameParser::create(dbg, arch);
00335 MachRegisterVal cfa;
00336 FrameErrors_t err;
00337 dwarf_printf("Getting CFA value...\n");
00338 if (!cfaParser->getRegValueAtFrame(pc,
00339 CFA,
00340 cfa,
00341 reader,
00342 err)) error = true;
00343 dwarf_printf("Got CFA value 0x%lx\n", cfa);
00344 pushUnsignedVal(cfa);
00345 }
00346
00347 MachRegisterVal ConcreteDwarfResult::peek(int index) {
00348 dwarf_printf("peek @ %d, returning index %d of size %d\n",
00349 index, operands.size() - (index + 1), operands.size());
00350 return operands[operands.size() - (index + 1)];
00351 }
00352
00353 void ConcreteDwarfResult::pop(int num) {
00354 dwarf_printf("pop @ %d, deleting index %d of size %d\n",
00355 num, operands.size() - (num + 1), operands.size());
00356 operands.erase(operands.begin() + (operands.size() - (num + 1)));
00357 }
00358
00359 void ConcreteDwarfResult::popRange(int start, int end) {
00360 dwarf_printf("popRange %d .. %d of %d\n", start, end, operands.size());
00361 std::vector<MachRegisterVal>::iterator b, e;
00362 if (start > end) {
00363 b = operands.begin() + (operands.size() - (start + 1));
00364 e = operands.begin() + (operands.size() - end);
00365 }
00366 else {
00367 b = operands.begin() + (operands.size() - (end + 1));
00368 e = operands.begin() + (operands.size() - start);
00369 }
00370 operands.erase(b, e);
00371 dwarf_printf("\t After popRange, size %d\n", operands.size());
00372 }
00373
00374 void ConcreteDwarfResult::push(MachRegisterVal v) {
00375 operands.push_back(v);
00376 }
00377
00378 bool ConcreteDwarfResult::eval(MachRegisterVal &v) {
00379 if (err()) return false;
00380 v = val();
00381 return true;
00382 }
00383
00384 MachRegisterVal ConcreteDwarfResult::val() {
00385 dwarf_printf("Eval: returning top value 0x%lx, stack size %d\n",
00386 operands.back(), operands.size());
00387 return operands.back();
00388 }