dwarfExprParser.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #include <stack>
00032 #include <stdio.h>
00033 #include "dynutil/h/dyn_regs.h"
00034 #include "dwarf/h/dwarfExprParser.h"
00035 #include "dwarf/h/dwarfResult.h"
00036 #include "common/h/debug_common.h"
00037 #include "dynutil/h/VariableLocation.h"
00038 #include "dynutil/h/ProcReader.h"
00039 #include "common/h/Types.h"
00040 
00041 using namespace std;
00042 
00043 namespace Dyninst {
00044 namespace Dwarf {
00045 
00046 bool decodeDwarfExpression(Dwarf_Locdesc *dwlocs,
00047                            long int *initialStackValue,
00048                            VariableLocation &loc,
00049                            Dyninst::Architecture arch) {
00050    SymbolicDwarfResult res(loc, arch);
00051    if (!decodeDwarfExpression(dwlocs, initialStackValue, 
00052                               res, arch)) return false;
00053    res.val();
00054    return true;
00055 }
00056 
00057 bool decodeDwarfExpression(Dwarf_Locdesc *dwlocs,
00058                            long int *initialStackValue,
00059                            ProcessReader *reader,
00060                            Address pc,
00061                            Dwarf_Debug dbg,
00062                            Dyninst::Architecture arch,
00063                            MachRegisterVal &end_result) {
00064    ConcreteDwarfResult res(reader, arch, pc, dbg);
00065    if (!decodeDwarfExpression(dwlocs, initialStackValue, 
00066                               res, arch)) return false;
00067    if (res.err()) return false;
00068    end_result = res.val();
00069    return true;
00070 }
00071 
00072 
00073 
00074 bool decodeDwarfExpression(Dwarf_Locdesc *dwlocs,
00075                            long int *initialStackValue,
00076                            DwarfResult &cons,
00077                            Dyninst::Architecture arch) {
00078    // This is basically a decode passthrough, with the work
00079    // being done by the DwarfResult. 
00080 
00081    dwarf_printf("Entry to decodeDwarfExpression\n");
00082 
00083    int addr_width = getArchAddressWidth(arch);
00084    if (initialStackValue != NULL) {
00085       dwarf_printf("\tInitializing expr stack with 0x%lx\n", initialStackValue);
00086       cons.pushUnsignedVal((Dyninst::MachRegisterVal) *initialStackValue);
00087    }
00088 
00089    Dwarf_Loc *locations = dwlocs->ld_s;
00090    unsigned count = dwlocs->ld_cents;
00091    for ( unsigned int i = 0; i < count; i++ ) 
00092    {
00093       dwarf_printf("\tAtom %d of %d: val 0x%x\n", i, count, locations[i].lr_atom);
00094       /* lit0 - lit31 : the constants 0..31 */
00095       if ( DW_OP_lit0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_lit31 ) 
00096       {
00097          dwarf_printf("\t\t Pushing unsigned val 0x%lx\n", locations[i].lr_atom - DW_OP_lit0);
00098          cons.pushUnsignedVal((Dyninst::MachRegisterVal) (locations[i].lr_atom - DW_OP_lit0));
00099          continue;
00100       }
00101 
00102       /* reg0 - reg31: named registers (not their constants) */
00103       if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 ) 
00104       {
00105          dwarf_printf("\t\t Pushing reg %s\n",MachRegister::DwarfEncToReg(locations[i].lr_atom - DW_OP_reg0,
00106                                                                           arch).name().c_str());
00107 
00108          cons.pushReg(MachRegister::DwarfEncToReg(locations[i].lr_atom - DW_OP_reg0,
00109                                                   arch));
00110          continue;
00111       }
00112 
00113       /* breg0 - breg31: register contents plus an optional offset */
00114       if ( DW_OP_breg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_breg31 ) 
00115       {
00116          dwarf_printf("\t\t Pushing reg %s + %d\n",MachRegister::DwarfEncToReg(locations[i].lr_atom - DW_OP_reg0,
00117                                                                                arch).name().c_str(),
00118                       locations[i].lr_number);
00119          cons.readReg(MachRegister::DwarfEncToReg(locations[i].lr_atom - DW_OP_breg0,
00120                                                   arch));
00121          cons.pushSignedVal((Dyninst::MachRegisterVal) locations[i].lr_number);
00122          cons.pushOp(DwarfResult::Add);
00123          continue;
00124       }
00125 
00126       switch( locations[i].lr_atom ) {
00127          // This is the same thing as breg, just with an encoded instead of literal
00128          // register.
00129          // The register is in lr_number
00130          // The offset is in lr_number2
00131          case DW_OP_bregx:
00132             dwarf_printf("\t\t Pushing reg %s + %d\n",MachRegister::DwarfEncToReg(locations[i].lr_number,
00133                                                                                   arch).name().c_str(),
00134                          locations[i].lr_number2);
00135             
00136             cons.readReg(MachRegister::DwarfEncToReg(locations[i].lr_number, arch));
00137             cons.pushSignedVal(locations[i].lr_number2);
00138             cons.pushOp(DwarfResult::Add);
00139             break;
00140 
00141          case DW_OP_regx:
00142             dwarf_printf("\t\t Pushing reg %s\n",MachRegister::DwarfEncToReg(locations[i].lr_number,
00143                                                                                   arch).name().c_str());
00144             cons.pushReg(MachRegister::DwarfEncToReg(locations[i].lr_number, arch));
00145             break;
00146             
00147          case DW_OP_nop:
00148             dwarf_printf("\t\t NOP\n");
00149             break;
00150 
00151          case DW_OP_addr:
00152          case DW_OP_const1u:
00153          case DW_OP_const2u:
00154          case DW_OP_const4u:
00155          case DW_OP_const8u:
00156          case DW_OP_constu:
00157             dwarf_printf("\t\t Pushing unsigned 0x%lx\n", locations[i].lr_number);
00158             cons.pushUnsignedVal(locations[i].lr_number);
00159             break;
00160 
00161          case DW_OP_const1s:
00162          case DW_OP_const2s:
00163          case DW_OP_const4s:
00164          case DW_OP_const8s:
00165          case DW_OP_consts:
00166             dwarf_printf("\t\t Pushing signed 0x%lx\n", locations[i].lr_number);
00167             cons.pushSignedVal(locations[i].lr_number);
00168             break;
00169 
00170          case DW_OP_fbreg:
00171             dwarf_printf("\t\t Pushing FB + 0x%lx\n", locations[i].lr_number);
00172             cons.pushFrameBase();
00173             cons.pushSignedVal(locations[i].lr_number);
00174             cons.pushOp(DwarfResult::Add);
00175             break;
00176 
00177          case DW_OP_dup: 
00178             dwarf_printf("\t\t Pushing dup\n");
00179            cons.pushOp(DwarfResult::Pick, 0);
00180             break;
00181 
00182          case DW_OP_drop:
00183             dwarf_printf("\t\t Pushing drop\n");
00184             cons.pushOp(DwarfResult::Drop, 0);
00185             break;
00186 
00187          case DW_OP_pick: 
00188             dwarf_printf("\t\t Pushing pick %d\n", locations[i].lr_number);
00189             cons.pushOp(DwarfResult::Pick, locations[i].lr_number);
00190             break;
00191 
00192          case DW_OP_over: 
00193             dwarf_printf("\t\t Pushing pick 1\n");
00194             cons.pushOp(DwarfResult::Pick, 1);
00195             break;
00196 
00197          case DW_OP_swap: 
00198             dwarf_printf("\t\t Pushing swap\n");
00199             cons.pushOp(DwarfResult::Pick, 1);
00200             cons.pushOp(DwarfResult::Drop, 2);
00201             break;
00202 
00203          case DW_OP_rot: 
00204             dwarf_printf("\t\t Pushing rotate\n");
00205             cons.pushOp(DwarfResult::Pick, 2);
00206             cons.pushOp(DwarfResult::Pick, 2);
00207             cons.pushOp(DwarfResult::Drop, 3);
00208             cons.pushOp(DwarfResult::Drop, 3);
00209             break;
00210 
00211          case DW_OP_deref:
00212             dwarf_printf("\t\t Pushing deref %d\n", addr_width);
00213             cons.pushOp(DwarfResult::Deref, addr_width);
00214             break;
00215 
00216          case DW_OP_deref_size:
00217             dwarf_printf("\t\t Pushing deref %d\n", locations[i].lr_number);
00218             cons.pushOp(DwarfResult::Deref, locations[i].lr_number);
00219             break;
00220 
00221          case DW_OP_call_frame_cfa:
00222             // This is a reference to the CFA as computed by stack walking information.
00223             // The current order is:
00224             // Variable: reference frame base (fbreg, above)
00225             // Frame base: reference CFA
00226             // CFA: offset from stack pointer
00227             dwarf_printf("\t\t Pushing CFA\n");
00228             cons.pushCFA();
00229             break;
00230 
00231          case DW_OP_abs:
00232             dwarf_printf("\t\t Pushing abs\n");
00233             cons.pushOp(DwarfResult::Abs);
00234             break;
00235 
00236          case DW_OP_and:
00237             dwarf_printf("\t\t Pushing and\n");
00238             cons.pushOp(DwarfResult::And);
00239             break;
00240 
00241          case DW_OP_div:
00242             dwarf_printf("\t\t Pushing div\n");
00243             cons.pushOp(DwarfResult::Div);
00244             break;
00245 
00246          case DW_OP_minus:
00247             dwarf_printf("\t\t Pushing sub\n");
00248             cons.pushOp(DwarfResult::Sub);
00249             break;
00250 
00251          case DW_OP_mod:
00252             cons.pushOp(DwarfResult::Mod);
00253             break;
00254 
00255          case DW_OP_mul:
00256             cons.pushOp(DwarfResult::Mul);
00257             break;
00258 
00259          case DW_OP_neg:
00260             cons.pushSignedVal(-1);
00261             cons.pushOp(DwarfResult::Mul);
00262             break;
00263 
00264          case DW_OP_not:
00265             cons.pushOp(DwarfResult::Not);
00266             break;
00267 
00268          case DW_OP_or:
00269             cons.pushOp(DwarfResult::Or);
00270             break;
00271 
00272          case DW_OP_plus:
00273             dwarf_printf("\t\t Pushing add\n");
00274             cons.pushOp(DwarfResult::Add);
00275             break;
00276 
00277          case DW_OP_plus_uconst:
00278             dwarf_printf("\t\t Pushing add 0x%x\n", locations[i].lr_number);
00279 
00280             cons.pushOp(DwarfResult::Add, locations[i].lr_number);
00281             break;
00282 
00283          case DW_OP_shl:
00284             cons.pushOp(DwarfResult::Shl);
00285             break;
00286 
00287          case DW_OP_shr:
00288             cons.pushOp(DwarfResult::Shr);
00289             break;
00290          
00291          case DW_OP_shra:
00292             cons.pushOp(DwarfResult::ShrArith);
00293             break;
00294 
00295          case DW_OP_xor:
00296             cons.pushOp(DwarfResult::Xor);
00297             break;
00298 
00299          case DW_OP_le:
00300             cons.pushOp(DwarfResult::LE);
00301             break;
00302 
00303          case DW_OP_ge:
00304             cons.pushOp(DwarfResult::GE);
00305             break;
00306 
00307          case DW_OP_eq:
00308             cons.pushOp(DwarfResult::Eq);
00309             break;
00310 
00311          case DW_OP_ne:
00312             cons.pushOp(DwarfResult::Neq);
00313             break;
00314 
00315          case DW_OP_lt:
00316             cons.pushOp(DwarfResult::LT);
00317             break;
00318 
00319          case DW_OP_gt:
00320             cons.pushOp(DwarfResult::GT);
00321             break;
00322 
00323          case DW_OP_bra: {
00324             // Conditional branch... 
00325             // It needs immediate evaluation so we can continue processing
00326             // the DWARF. 
00327             Dyninst::MachRegisterVal value;
00328 
00329             if (!cons.eval(value)) {
00330                // Error in dwarf, or we're doing static. I'm not worrying about
00331                // encoding a conditional branch in static eval right now. 
00332                return false;
00333             }
00334             
00335             if (value == 0) break;
00336             // Do not break; fall through to skip
00337          }
00338          case DW_OP_skip: {
00339             int bytes = (int)(Dwarf_Signed)locations[i].lr_number;
00340             unsigned int target = (unsigned int) locations[i].lr_offset + bytes;
00341             
00342             int j = i;
00343             if ( bytes < 0 ) {
00344                for ( j = i - 1; j >= 0; j-- ) {
00345                   if ( locations[j].lr_offset == target ) { break; }
00346                } /* end search backward */
00347             } else {
00348                for ( j = i + 1; j < dwlocs->ld_cents; j ++ ) {
00349                   if ( locations[j].lr_offset == target ) { break; }
00350                } /* end search forward */
00351             } /* end if positive offset */
00352             
00353             /* Because i will be incremented the next time around the loop. */
00354             i = j - 1; 
00355             break;
00356          }
00357             
00358          default:
00359             return false;
00360       } /* end operand switch */
00361    } /* end iteration over Dwarf_Loc entries. */
00362 
00363    return true;
00364 }
00365 
00366 }
00367 
00368 }
00369 
00370 #if 0
00371 
00372 #if defined(arch_x86_64)
00373 
00374 #define IA32_MAX_MAP 7
00375 #define AMD64_MAX_MAP 15
00376 static int const amd64_register_map[] =
00377   {
00378     0,  // RAX
00379     2,  // RDX
00380     1,  // RCX
00381     3,  // RBX
00382     6,  // RSI
00383     7,  // RDI
00384     5,  // RBP
00385     4,  // RSP
00386     8, 9, 10, 11, 12, 13, 14, 15    // gp 8 - 15
00387     /* This is incomplete. The x86_64 ABI specifies a mapping from
00388        dwarf numbers (0-66) to ("architecture number"). Without a
00389        corresponding mapping for the SVR4 dwarf-machine encoding for
00390        IA-32, however, it is not meaningful to provide this mapping. */
00391   };
00392 
00393 
00394 int Dyninst::Register_DWARFtoMachineEnc32(int n)
00395 {
00396    return n;
00397 }
00398 
00399 
00400 int Dyninst::Register_DWARFtoMachineEnc64(int n)
00401 {
00402    if (n <= AMD64_MAX_MAP)
00403       return amd64_register_map[n];
00404    return n;
00405 }
00406 
00407 #endif
00408 
00409 #endif
00410 
00411 
00412 
00413 #if 0
00414 bool Dyninst::decodeDwarfExpression(Dwarf_Locdesc *dwlocs,
00415                                     long int *initialStackValue,
00416                                     VariableLocation *loc, bool &isLocSet,
00417                                     ProcessReader *reader,
00418                                     Dyninst::Architecture arch,
00419                                     long int &end_result)
00420 {
00421    /* Initialize the stack. */
00422    int addr_width = getArchAddressWidth(arch);
00423    std::stack< long int > opStack = std::stack<long int>();
00424    if ( initialStackValue != NULL ) { opStack.push( * initialStackValue ); }
00425 
00426    Dwarf_Loc *locations = dwlocs->ld_s;
00427    unsigned count = dwlocs->ld_cents;
00428    for ( unsigned int i = 0; i < count; i++ ) 
00429    {
00430       /* Handle the literals w/o 32 case statements. */
00431       if ( DW_OP_lit0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_lit31 ) 
00432       {
00433          dwarf_printf( "pushing named constant: %d\n", locations[i].lr_atom - DW_OP_lit0 );
00434          opStack.push( locations[i].lr_atom - DW_OP_lit0 );
00435          continue;
00436       }
00437 
00438       /* Haandle registers w/o 32 case statements. */
00439       if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 ) 
00440       {
00441          /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
00442          dwarf_printf( "location is named register %d\n", 
00443                        DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width) );
00444          //loc->stClass = storageRegOffset;
00445          if (loc) 
00446          {
00447             loc->stClass = storageReg;
00448             loc->refClass = storageNoRef;
00449             loc->frameOffset = 0;
00450             loc->reg = DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width);
00451             loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width);
00452             //loc->frameOffset = 0;
00453             isLocSet = true;
00454          }
00455          continue;
00456       } 
00457 
00458       /* Haandle registers w/o 32 case statements. */
00459       if ( DW_OP_breg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_breg31 ) 
00460       {
00461          dwarf_printf( "setting storage class to named register, regNum to %d, offset %d\n", DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width), locations[i].lr_number );
00462          long int to_push = 0;
00463          if (loc) {
00464             loc->stClass = storageRegOffset;
00465             loc->refClass = storageNoRef;
00466             loc->frameOffset = locations[i].lr_number ;
00467             loc->reg = DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width);
00468             loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width);
00469             to_push = static_cast<long int>(locations[i].lr_number);
00470          }
00471          else if (reader) {
00472             Dyninst::MachRegister r = DwarfToDynReg(locations[i].lr_atom - DW_OP_breg0,
00473                                                     arch);
00474             Dyninst::MachRegisterVal v;
00475             bool result = reader->GetReg(r, v);
00476             if (!result) {
00477                return false;
00478             }
00479             to_push = (long int) v + locations[i].lr_number;
00480          }
00481             
00482          opStack.push(to_push); 
00483          continue;
00484       }
00485 
00486       switch( locations[i].lr_atom ) 
00487       {
00488          case DW_OP_addr:
00489          case DW_OP_const1u:
00490          case DW_OP_const2u:
00491          case DW_OP_const4u:
00492          case DW_OP_const8u:
00493          case DW_OP_constu:
00494             dwarf_printf( "pushing unsigned constant %lu\n", 
00495                           (unsigned long)locations[i].lr_number );
00496             opStack.push(static_cast<long int>(locations[i].lr_number));
00497             break;
00498 
00499          case DW_OP_const1s:
00500          case DW_OP_const2s:
00501          case DW_OP_const4s:
00502          case DW_OP_const8s:
00503          case DW_OP_consts:
00504             dwarf_printf( "pushing signed constant %ld\n", 
00505                           (signed long)(locations[i].lr_number) );
00506             opStack.push(static_cast<long int>(locations[i].lr_number));
00507             break;
00508 
00509          case DW_OP_regx:
00510             /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
00511             dwarf_printf( "location is register %d\n", 
00512                           DWARF_TO_MACHINE_ENC_W(locations[i].lr_number, addr_width) );
00513             if (loc) {
00514                loc->stClass = storageReg;
00515                loc->refClass = storageNoRef;
00516                loc->reg = (int) DWARF_TO_MACHINE_ENC_W(locations[i].lr_number, addr_width); 
00517                loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_number, addr_width); 
00518                loc->frameOffset = 0;
00519                isLocSet = true;
00520             }
00521             break;
00522 
00523          case DW_OP_fbreg:
00524          {
00525             dwarf_printf( "setting storage class to frame base\n" );
00526             //if ( storageClass != NULL ) { * storageClass = storageFrameOffset; }
00527             long int to_push = 0;
00528             if (loc) {
00529                loc->stClass = storageRegOffset;
00530                loc->refClass = storageNoRef;
00531                loc->frameOffset = 0;
00532                loc->mr_reg = Dyninst::FrameBase;
00533                to_push = static_cast<long int>(locations[i].lr_number);
00534             }
00535             else if (reader) {
00536                Dyninst::MachRegister r = Dyninst::FrameBase;
00537                Dyninst::MachRegisterVal v;
00538                bool result = reader->GetReg(r, v);
00539                if (!result) {
00540                   return false;
00541                }
00542                to_push = (long int) v + locations[i].lr_number;               
00543             }
00544             opStack.push(to_push);
00545          } break;          
00546          case DW_OP_bregx: 
00547          {
00548             dwarf_printf( "setting storage class to register, regNum to %d\n", 
00549                           locations[i].lr_number );
00550             long int to_push = 0;
00551             if (loc) {
00552                loc->stClass = storageRegOffset;
00553                loc->refClass = storageNoRef;
00554                loc->reg = (int) DWARF_TO_MACHINE_ENC_W( locations[i].lr_number, addr_width );
00555                loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W( locations[i].lr_number, addr_width );
00556                loc->frameOffset = 0;
00557                to_push = static_cast<long int>(locations[i].lr_number2);
00558             }
00559             else if (reader) {
00560                Dyninst::MachRegister r = DwarfToDynReg(locations[i].lr_number, arch);
00561                Dyninst::MachRegisterVal v;
00562                bool result = reader->GetReg(r, v);
00563                if (!result) {
00564                   return false;
00565                }
00566                to_push = (long int) v + locations[i].lr_number2;
00567             }
00568             opStack.push(to_push);
00569          } break;
00570          case DW_OP_dup:
00571             DWARF_FALSE_IF( opStack.size() < 1, 
00572                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00573             opStack.push( opStack.top() );
00574             break;
00575 
00576          case DW_OP_drop:
00577             DWARF_FALSE_IF( opStack.size() < 1, 
00578                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00579             opStack.pop();
00580             break;
00581 
00582          case DW_OP_pick: 
00583          {
00584             /* Duplicate the entry at index locations[i].lr_number. */
00585             std::stack< long int > temp = std::stack< long int >();
00586             
00587             for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
00588             {
00589                temp.push( opStack.top() ); opStack.pop();
00590             }
00591             
00592             long int dup = opStack.top();
00593             
00594             for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
00595             {
00596                opStack.push( temp.top() ); temp.pop();
00597             }
00598             
00599             opStack.push( dup );
00600          } break;
00601 
00602          case DW_OP_over: 
00603          {
00604             DWARF_FALSE_IF( opStack.size() < 2, 
00605                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00606             long int first = opStack.top(); opStack.pop();
00607             long int second = opStack.top(); opStack.pop();
00608             opStack.push( second ); opStack.push( first ); opStack.push( second );
00609          } break;
00610          
00611          case DW_OP_swap: 
00612          {
00613             DWARF_FALSE_IF( opStack.size() < 2, 
00614                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00615             long int first = opStack.top(); opStack.pop();
00616             long int second = opStack.top(); opStack.pop();
00617             opStack.push( first ); opStack.push( second );
00618          } break;
00619          
00620          case DW_OP_deref:
00621          {
00622             if (!reader)
00623                break;
00624             long int addr = opStack.top(); opStack.pop();
00625             unsigned long to_push = 0;
00626             bool bresult = false;
00627             if (addr_width == 4) {
00628                uint32_t v;
00629                bresult = reader->ReadMem(addr, &v, sizeof(v));
00630                to_push = (unsigned long) v;
00631             }
00632             else if (addr_width == 8) {
00633                uint64_t v;
00634                bresult = reader->ReadMem(addr, &v, sizeof(v));
00635                to_push = (unsigned long) v;
00636             }
00637             DWARF_FALSE_IF(!bresult,
00638                            "%s[%d]: Could not read from %lx\n", addr);
00639             opStack.push(to_push);
00640             break;
00641          }
00642          case DW_OP_deref_size:
00643          {
00644             if (!reader)
00645                break;
00646             long int addr = opStack.top(); opStack.pop();
00647             int width = locations[i].lr_number;
00648             unsigned long to_push = 0;
00649             bool bresult = false;
00650             if (width == 1) {
00651                uint8_t v;
00652                bresult = reader->ReadMem(addr, &v, sizeof(v));
00653                to_push = (unsigned long) v;
00654             }
00655             if (width == 2) {
00656                uint16_t v;
00657                bresult = reader->ReadMem(addr, &v, sizeof(v));
00658                to_push = (unsigned long) v;
00659             }
00660             if (width == 4) {
00661                uint32_t v;
00662                bresult = reader->ReadMem(addr, &v, sizeof(v));
00663                to_push = (unsigned long) v;
00664             }
00665             else if (width == 8) {
00666                uint64_t v;
00667                bresult = reader->ReadMem(addr, &v, sizeof(v));
00668                to_push = (long int) v;
00669             }
00670             DWARF_FALSE_IF(!bresult,
00671                            "%s[%d]: Could not read from %lx\n", addr);
00672             opStack.push(to_push);
00673             break;
00674          }
00675 
00676          case DW_OP_rot: 
00677          {
00678             DWARF_FALSE_IF( opStack.size() < 3, 
00679                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00680             long int first = opStack.top(); opStack.pop();
00681             long int second = opStack.top(); opStack.pop();
00682             long int third = opStack.top(); opStack.pop();
00683             opStack.push( first ); opStack.push( third ); opStack.push( second );
00684          } break;
00685 
00686          case DW_OP_abs: 
00687          {
00688             DWARF_FALSE_IF( opStack.size() < 1, 
00689                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00690             long int top = opStack.top(); opStack.pop();
00691             opStack.push( abs( top ) );
00692          } break;
00693          
00694          case DW_OP_and: 
00695          {
00696             DWARF_FALSE_IF( opStack.size() < 2, 
00697                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00698             long int first = opStack.top(); opStack.pop();
00699             long int second = opStack.top(); opStack.pop();
00700             opStack.push( second & first );
00701          } break;
00702 
00703          case DW_OP_div: 
00704          {
00705             DWARF_FALSE_IF( opStack.size() < 2, 
00706                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00707             long int first = opStack.top(); opStack.pop();
00708             long int second = opStack.top(); opStack.pop();
00709         DWARF_FALSE_IF(((second != 0) && (first == 0)),
00710                "%s[%d]: invalid stack, div operation with %d / %d, returning false\n",
00711                __FILE__, __LINE__, second, first);
00712         
00713         if((second == 0) && (first == 0)) 
00714           opStack.push(0);
00715         else
00716           opStack.push( second / first );
00717          } break;
00718 
00719          case DW_OP_minus: 
00720          {
00721             DWARF_FALSE_IF( opStack.size() < 2, 
00722                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00723             long int first = opStack.top(); opStack.pop();
00724             long int second = opStack.top(); opStack.pop();
00725             opStack.push( second - first );
00726          } break;
00727 
00728          case DW_OP_mod: 
00729          {
00730             DWARF_FALSE_IF( opStack.size() < 2, 
00731                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00732             long int first = opStack.top(); opStack.pop();
00733             long int second = opStack.top(); opStack.pop();
00734         DWARF_FALSE_IF(((second != 0) && (first == 0)),
00735                "%s[%d]: invalid stack, mod operation with %d mod %d, returning false\n",
00736                __FILE__, __LINE__, second, first);
00737         
00738         if((second == 0) && (first == 0)) 
00739           opStack.push(0);
00740         else
00741           opStack.push( second % first );
00742          } break;
00743 
00744          case DW_OP_mul: 
00745          {
00746             DWARF_FALSE_IF( opStack.size() < 2, 
00747                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00748             long int first = opStack.top(); opStack.pop();
00749             long int second = opStack.top(); opStack.pop();
00750             opStack.push( second * first );
00751          } break;
00752 
00753          case DW_OP_neg: 
00754          {
00755             DWARF_FALSE_IF( opStack.size() < 1, 
00756                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00757             long int first = opStack.top(); opStack.pop();
00758             opStack.push( first * (-1) );
00759          } break;
00760          
00761          case DW_OP_not: 
00762          {
00763             DWARF_FALSE_IF( opStack.size() < 1, 
00764                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00765             long int first = opStack.top(); opStack.pop();
00766             opStack.push( ~ first );
00767          } break;
00768 
00769          case DW_OP_or: 
00770          {
00771             DWARF_FALSE_IF( opStack.size() < 2, 
00772                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00773             long int first = opStack.top(); opStack.pop();
00774             long int second = opStack.top(); opStack.pop();
00775             opStack.push( second | first );
00776          } break;
00777 
00778          case DW_OP_plus: 
00779          {
00780             DWARF_FALSE_IF( opStack.size() < 2, 
00781                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00782             long int first = opStack.top(); opStack.pop();
00783             long int second = opStack.top(); opStack.pop();
00784             opStack.push( second + first );
00785          } break;
00786 
00787          case DW_OP_plus_uconst: 
00788          {
00789             DWARF_FALSE_IF( opStack.size() < 1, 
00790                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00791             long int first = opStack.top(); opStack.pop();
00792             opStack.push(static_cast<long int>(first + locations[i].lr_number));
00793          } break;
00794          
00795          case DW_OP_shl: 
00796          {
00797             DWARF_FALSE_IF( opStack.size() < 2, 
00798                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00799             long int first = opStack.top(); opStack.pop();
00800             long int second = opStack.top(); opStack.pop();
00801             opStack.push( second << first );
00802          } break;
00803 
00804          case DW_OP_shr: 
00805          {
00806             DWARF_FALSE_IF( opStack.size() < 2, 
00807                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00808             long int first = opStack.top(); opStack.pop();
00809             long int second = opStack.top(); opStack.pop();
00810             
00811             opStack.push( (long int)((unsigned long)second >> (unsigned long)first) );
00812          } break;
00813          
00814          case DW_OP_shra: 
00815          {
00816             DWARF_FALSE_IF( opStack.size() < 2, 
00817                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00818             long int first = opStack.top(); opStack.pop();
00819             long int second = opStack.top(); opStack.pop();
00820             opStack.push( second >> first );
00821          } break;
00822 
00823          case DW_OP_xor: 
00824          {
00825             DWARF_FALSE_IF( opStack.size() < 2, 
00826                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00827             long int first = opStack.top(); opStack.pop();
00828             long int second = opStack.top(); opStack.pop();
00829             opStack.push( second ^ first );
00830          } break;
00831 
00832          case DW_OP_le: 
00833          {
00834             DWARF_FALSE_IF( opStack.size() < 2, 
00835                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00836             long int first = opStack.top(); opStack.pop();
00837             long int second = opStack.top(); opStack.pop();
00838             opStack.push( first <= second ? 1 : 0 );
00839          } break;
00840 
00841          case DW_OP_ge: 
00842          {
00843             DWARF_FALSE_IF( opStack.size() < 2, 
00844                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00845             long int first = opStack.top(); opStack.pop();
00846             long int second = opStack.top(); opStack.pop();
00847             opStack.push( first >= second ? 1 : 0 );
00848          } break;
00849 
00850          case DW_OP_eq: 
00851          {
00852             DWARF_FALSE_IF( opStack.size() < 2, 
00853                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00854             long int first = opStack.top(); opStack.pop();
00855             long int second = opStack.top(); opStack.pop();
00856             opStack.push( first == second ? 1 : 0 );
00857          } break;
00858 
00859          case DW_OP_lt: 
00860          {
00861             DWARF_FALSE_IF( opStack.size() < 2, 
00862                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00863             long int first = opStack.top(); opStack.pop();
00864             long int second = opStack.top(); opStack.pop();
00865             opStack.push( first < second ? 1 : 0 );
00866          } break;
00867 
00868          case DW_OP_gt: 
00869          {
00870             DWARF_FALSE_IF( opStack.size() < 2, 
00871                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00872             long int first = opStack.top(); opStack.pop();
00873             long int second = opStack.top(); opStack.pop();
00874             opStack.push( first > second ? 1 : 0 );
00875          } break;
00876 
00877          case DW_OP_ne: 
00878          {
00879             DWARF_FALSE_IF( opStack.size() < 2, 
00880                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00881             long int first = opStack.top(); opStack.pop();
00882             long int second = opStack.top(); opStack.pop();
00883             opStack.push( first != second ? 1 : 0 );
00884          } break;
00885 
00886          case DW_OP_bra:
00887          {
00888             DWARF_FALSE_IF( opStack.size() < 1, 
00889                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
00890             if ( opStack.top() == 0 ) { break; }
00891             opStack.pop();
00892          }
00893          case DW_OP_skip: 
00894          {
00895             int bytes = (int)(Dwarf_Signed)locations[i].lr_number;
00896             unsigned int target = (unsigned int) locations[i].lr_offset + bytes;
00897             
00898             int j = i;
00899             if ( bytes < 0 ) {
00900                for ( j = i - 1; j >= 0; j-- ) {
00901                   if ( locations[j].lr_offset == target ) { break; }
00902                } /* end search backward */
00903             } else {
00904                for ( j = i + 1; j < dwlocs->ld_cents; j ++ ) {
00905                   if ( locations[j].lr_offset == target ) { break; }
00906                } /* end search forward */
00907             } /* end if positive offset */
00908             
00909             /* Because i will be incremented the next time around the loop. */
00910             i = j - 1;
00911          } break;
00912 
00913          case DW_OP_piece:
00914             /* For multi-part variables, which we don't handle. */
00915             //bperr ( "Warning: dyninst does not handle multi-part variables.\n" );
00916             break;
00917 
00918          case DW_OP_nop:
00919             break;
00920 
00921          case DW_OP_call_frame_cfa: {
00922             long int to_push = 0;
00923             if (loc) {
00924                loc->stClass = storageRegOffset;
00925                loc->refClass = storageNoRef;
00926                loc->frameOffset = 0;
00927                loc->mr_reg = Dyninst::FrameBase;
00928             }
00929             else if (reader) {
00930                Dyninst::MachRegister r = Dyninst::FrameBase;
00931                Dyninst::MachRegisterVal v;
00932                bool result = reader->GetReg(r, v);
00933                if (!result) {
00934                   return false;
00935                }
00936             }
00937             opStack.push(to_push);
00938             break;
00939          }
00940          default:
00941             printf( "Unrecognized or non-static location opcode 0x%x, aborting.\n", locations[i].lr_atom );
00942             return false;
00943             break;
00944       } /* end operand switch */
00945    } /* end iteration over Dwarf_Loc entries. */
00946    
00947    if (opStack.empty()) {
00948       dwarf_printf( "ignoring malformed location list (stack empty at end of list).\n" );
00949       return isLocSet;
00950    }
00951    dwarf_printf( "Dwarf expression returning %d\n", opStack.top() );
00952    end_result = opStack.top();
00953    return true;
00954 }
00955 
00956 #endif
00957 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1