dwarfResult.C

Go to the documentation of this file.
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    // frameOffset will be set with an add operation
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       // No register, so default to StorageAddr
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    // This is "fill in as we see examples" code. 
00057    // Right now, the only use I know of is add. 
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    // I don't believe this is legal
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    // Someday this will matter...
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    // Someday this will matter...
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          // 2 argument
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1