00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00079
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
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
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
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
00128
00129
00130
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
00223
00224
00225
00226
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
00325
00326
00327 Dyninst::MachRegisterVal value;
00328
00329 if (!cons.eval(value)) {
00330
00331
00332 return false;
00333 }
00334
00335 if (value == 0) break;
00336
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 }
00347 } else {
00348 for ( j = i + 1; j < dwlocs->ld_cents; j ++ ) {
00349 if ( locations[j].lr_offset == target ) { break; }
00350 }
00351 }
00352
00353
00354 i = j - 1;
00355 break;
00356 }
00357
00358 default:
00359 return false;
00360 }
00361 }
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,
00379 2,
00380 1,
00381 3,
00382 6,
00383 7,
00384 5,
00385 4,
00386 8, 9, 10, 11, 12, 13, 14, 15
00387
00388
00389
00390
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
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
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
00439 if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 )
00440 {
00441
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
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
00453 isLocSet = true;
00454 }
00455 continue;
00456 }
00457
00458
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
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
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
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 }
00903 } else {
00904 for ( j = i + 1; j < dwlocs->ld_cents; j ++ ) {
00905 if ( locations[j].lr_offset == target ) { break; }
00906 }
00907 }
00908
00909
00910 i = j - 1;
00911 } break;
00912
00913 case DW_OP_piece:
00914
00915
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 }
00945 }
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