windows build fixes and some more work on symtab serialization
[dyninst.git] / dyninstAPI / src / BPatch_snippet.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: BPatch_snippet.C,v 1.108 2008/06/19 19:52:55 legendre Exp $
43
44 #define BPATCH_FILE
45
46 #include <string.h>
47
48 #include "common/h/Time.h"
49 #include "common/h/timing.h"
50
51 #include "BPatch.h"
52 #include "BPatch_addressSpace.h"
53 #include "BPatch_snippet.h"
54 #include "BPatch_type.h"
55 #include "BPatch_function.h"
56 #include "BPatch_collections.h"
57 #include "BPatch_Vector.h"
58
59 #include "addressSpace.h"
60 #include "mapped_object.h" // for savetheworld
61 #include "mapped_module.h"
62 #include "ast.h"
63 #include "symtab.h"
64 #include "process.h"
65 #include "instPoint.h"
66 #include "registerSpace.h"
67
68 #include "symtabAPI/h/Type.h"
69 #include "symtabAPI/h/Variable.h"
70
71
72 using namespace Dyninst;
73 using namespace Dyninst::SymtabAPI;
74
75 // Need REG_MT_POS, defined in inst-<arch>...
76
77 #if defined(arch_x86) || defined(arch_86_64)
78 #include "inst-x86.h"
79 #elif defined(arch_power)
80 #include "inst-power.h"
81 #elif defined(arch_ia64)
82 #include "inst-ia64.h"
83 #elif defined(arch_sparc)
84 #include "inst-sparc.h"
85 #endif
86
87
88 //  This will be removed:
89 int BPatch_snippet::PDSEP_astMinCost()
90 {
91   return ast_wrapper->minCost();
92 }
93
94 /*
95  * BPatch_snippet::BPatch_snippet
96  *
97  * The default constructor was exposed as public, so we're
98  * stuck with it even though that _should_ be an error.
99  * For now, make it a null node (and hope nobody ever
100  * tries to generate code)
101  */
102 BPatch_snippet::BPatch_snippet() {
103     ast_wrapper = AstNodePtr(AstNode::nullNode());
104 }
105
106
107 /*
108  * BPatch_snippet::BPatch_snippet
109  *
110  * Copy constructor for BPatch_snippet.
111  */
112 void BPatch_snippet::BPatch_snippetInt(const BPatch_snippet &src)
113 {
114     ast_wrapper = src.ast_wrapper;
115 }
116
117
118 /*
119  * BPatch_snippet::operator=
120  *
121  * Assignment operator for BPatch_snippet.  Needed to ensure that the
122  * reference counts for the asts contained in the snippets is correct.
123  */
124 BPatch_snippet &BPatch_snippet::operator_equals(const BPatch_snippet &src)
125 {
126     // Check for x = x
127     if (&src == this)
128         return *this;
129
130     // We'll now contain another reference to the ast in the other snippet
131     ast_wrapper = src.ast_wrapper;
132
133     return *this;
134 }
135
136
137 /*
138  * BPatch_snippet:getCost
139  *
140  * Returns the estimated cost of executing the snippet, in seconds.
141  */
142 float BPatch_snippet::getCostInt()
143 {
144   // Currently represents the maximum possible cost of the snippet.  For
145   // instance, for the statement "if(cond) <stmtA> ..."  the cost of <stmtA>
146   // is currently included, even if it's actually not called.  Feel free to
147   // change the maxCost call below to ast->minCost or ast->avgCost if the
148   // semantics need to be changed.
149   timeLength costv = timeLength(ast_wrapper->maxCost(), getCyclesPerSecond());
150   float retCost = static_cast<float>(costv.getD(timeUnit::sec()));
151   return retCost;
152 }
153 /*
154  * BPatch_snippet:getCostAtPoint
155  *
156  * Returns the estimated cost of executing the snippet at the provided point, in seconds.
157  */
158 float BPatch_snippet::getCostAtPointInt(BPatch_point *pt)
159 {
160   // Currently represents the maximum possible cost of the snippet.  For
161   // instance, for the statement "if(cond) <stmtA> ..."  the cost of <stmtA>
162   // is currently included, even if it's actually not called.  Feel free to
163   // change the maxCost call below to ast->minCost or ast->avgCost if the
164   // semantics need to be changed.
165     if (!pt) return 0.0;
166     if (!pt->point) return 0.0;
167
168     int unitCostInCycles = ast_wrapper->maxCost() +
169         pt->point->getPointCost() +
170         getInsnCost(trampPreamble);
171
172     timeLength unitCost(unitCostInCycles, getCyclesPerSecond());
173     float frequency = 1.0f;
174     timeLength value = unitCost * frequency;
175
176   float retCost = static_cast<float>(value.getD(timeUnit::sec()));
177   return retCost;
178 }
179
180 bool BPatch_snippet::is_trivialInt()
181 {
182   return (ast_wrapper == NULL);
183 }
184
185
186 /*
187  * BPatch_snippet::~BPatch_snippet
188  *
189  * Destructor for BPatch_snippet.  Deallocates memory allocated by the
190  * snippet.  Well, decrements a reference count.
191  */
192 void BPatch_snippet::BPatch_snippet_dtor()
193 {
194     //if (ast_wrapper) delete ast_wrapper;
195 }
196
197
198 AstNodePtr generateVariableBase(const BPatch_snippet &lOperand)
199 {
200   AstNodePtr variableBase;
201   if(lOperand.ast_wrapper->getoType() == AstNode::variableValue)
202   {
203     variableBase = AstNode::operandNode(AstNode::variableAddr, lOperand.ast_wrapper->getOVar());
204   }
205   else if(lOperand.ast_wrapper->getoType() == AstNode::variableAddr)
206   {
207     variableBase = lOperand.ast_wrapper;
208   }
209   else
210   {
211     variableBase = AstNode::operatorNode(getAddrOp, lOperand.ast_wrapper);
212   }
213   return variableBase;
214 }
215
216
217 //
218 // generateArrayRef - Construct an Ast expression for an array.
219 //
220 AstNodePtr generateArrayRef(const BPatch_snippet &lOperand, 
221                             const BPatch_snippet &rOperand)
222 {
223     if (lOperand.ast_wrapper == AstNodePtr()) return AstNodePtr();
224     if (rOperand.ast_wrapper == AstNodePtr()) return AstNodePtr();
225
226     if (lOperand.ast_wrapper->getType() == NULL) 
227          BPatch_reportError(BPatchSerious, 109,
228                             "array reference has no type information");
229
230     //  We have to be a little forgiving of the
231     typeArray *arrayType = lOperand.ast_wrapper->getType()->getSymtabType()->getArrayType();
232     if (!arrayType) {
233         if (lOperand.ast_wrapper->getType() == NULL) 
234             BPatch_reportError(BPatchSerious, 109,
235                                "array reference has no type information");
236         else {
237             fprintf(stderr, "%s[%d]:  error here: type is %s\n", FILE__, __LINE__,lOperand.ast_wrapper->getType()->getName());
238             BPatch_reportError(BPatchSerious, 109,
239                                "array reference has array reference to non-array type");
240         }
241         return AstNodePtr();
242     }
243
244     Type *elementType = arrayType->getBaseType();
245
246     assert(elementType);
247     long int elementSize = elementType->getSize();
248
249     // check that the type of the right operand is an integer.
250     //  We have to be a little forgiving of this parameter, since we could 
251     //  be indexing using a funcCall snippet, for which no return type is available.
252     //  Ideally we could always know this information, but until then, if no
253     //  type information is available, assume that the user knows what they're doing
254     //  (just print a warning, don't fail).
255
256     BPatch_type *indexType = const_cast<BPatch_type *>(rOperand.ast_wrapper->getType());
257     if (!indexType) {
258         char err_buf[512];
259         sprintf(err_buf, "%s[%d]:  %s %s\n",
260                 __FILE__, __LINE__,
261                 "Warning:  cannot ascertain type of index parameter is of integral type, ",
262                 "This is not a failure... but be warned that type-checking has failed. ");
263         BPatch_reportError(BPatchWarning, 109, err_buf);
264       
265     }
266     else if (strcmp(indexType->getName(), "int")
267              && strcmp(indexType->getName(), "short")
268              && strcmp(indexType->getName(), "long")
269              && strcmp(indexType->getName(), "signed")
270              && strcmp(indexType->getName(), "unsigned int")
271              && strcmp(indexType->getName(), "unsigned short")
272              && strcmp(indexType->getName(), "unsigned long")
273              && strcmp(indexType->getName(), "unsigned")) {
274         char err_buf[256];
275         sprintf(err_buf, "%s[%d]: non-integer array index type %s\n",
276                 __FILE__, __LINE__,  indexType->getName());
277         fprintf(stderr, "%s\n", err_buf);
278         BPatch_reportError(BPatchSerious, 109, err_buf);
279         return AstNodePtr();
280     }
281     //fprintf(stderr, "%s[%d]:  indexing with type %s\n", __FILE__, __LINE__, 
282     //        indexType->getName());
283
284     //
285     // Convert a[i] into *(&a + (* i sizeof(element)))
286     //
287
288     AstNodePtr arrayBase = generateVariableBase(lOperand);
289     AstNodePtr ast = AstNode::operandNode(AstNode::DataIndir,
290                                       AstNode::operatorNode(plusOp,
291                                                             arrayBase,
292                                                             AstNode::operatorNode(timesOp,
293                                                                                   AstNode::operandNode(AstNode::Constant,
294                                                                                                        (void *)elementSize),
295                                                                                   rOperand.ast_wrapper)));
296     if(!elementType->getUpPtr())
297         new BPatch_type(elementType);
298     ast->setType((BPatch_type *)elementType -> getUpPtr());
299
300     return AstNodePtr(ast);
301 }
302
303
304 //
305 // generateFieldRef - Construct an Ast expression for an structure field.
306 //
307 AstNodePtr generateFieldRef(const BPatch_snippet &lOperand, 
308                                    const BPatch_snippet &rOperand)
309 {
310     if (lOperand.ast_wrapper == AstNodePtr()) return AstNodePtr();
311     if (rOperand.ast_wrapper == AstNodePtr()) return AstNodePtr();
312
313     if (lOperand.ast_wrapper->getType() == NULL) 
314          BPatch_reportError(BPatchSerious, 109,
315                             "array reference has no type information");
316
317     typeStruct *structType = lOperand.ast_wrapper->getType()->getSymtabType()->getStructType();
318     if (!structType) {
319         BPatch_reportError(BPatchSerious, 109,
320                "structure reference has no type information, or structure reference to non-structure type");
321         return AstNodePtr();
322     }
323
324     // check that the type of the right operand is a string.
325     BPatch_type *fieldType = const_cast<BPatch_type *>(rOperand.ast_wrapper->getType());
326     if (rOperand.ast_wrapper->getoType()!=AstNode::ConstantString 
327         || !fieldType
328         || strcmp(fieldType->getName(), "char *")) {
329         // XXX - Should really check if this is a short/long too
330         BPatch_reportError(BPatchSerious, 109,
331                            "field name is not of type char *");
332         return AstNodePtr();
333     }
334     
335     vector<Field *> *fields;
336     Field *field = NULL;
337
338     // check that the name of the right operand is a field of the left operand
339     fields = structType->getComponents();
340
341     unsigned int i;
342
343     for (i=0; i < fields->size(); i++) {
344       field = (*fields)[i];
345       if (!strcmp(field->getName().c_str(), (const char *) rOperand.ast_wrapper->getOValue()))
346         break;
347     }
348     if (i==fields->size()) {
349       BPatch_reportError(BPatchSerious, 109,
350                          "field name not found in structure");
351       return AstNodePtr();
352     }
353
354     if (! field ) return AstNodePtr();
355     long int offset = (field->getOffset() / 8);
356
357     //
358     // Convert s.f into *(&s + offset(s,f))
359     //
360     AstNodePtr structBase = generateVariableBase(lOperand);
361     
362     AstNodePtr ast = AstNode::operandNode(AstNode::DataIndir,
363                                AstNode::operatorNode(plusOp,
364                                                      structBase,
365                                                      AstNode::operandNode(AstNode::Constant,
366                                                                           (void *)offset)));
367     if(!field->getType()->getUpPtr())
368         new BPatch_type(field->getType());
369     ast->setType((BPatch_type *)field->getType()->getUpPtr());
370
371     return AstNodePtr(ast);
372 }
373
374 /*
375  * BPatch_arithExpr::BPatch_arithExpr
376  *
377  * Construct a snippet representing a binary arithmetic operation.
378  *
379  * op           The desired operation.
380  * lOperand     The left operand for the operation.
381  * rOperand     The right operand.
382  */
383 void BPatch_arithExpr::BPatch_arithExprBin(BPatch_binOp op,
384         const BPatch_snippet &lOperand, const BPatch_snippet &rOperand)
385 {
386 #if 0
387     fprintf(stderr, "%s[%d]:  welcome to BPatch_arithExprBin: types (l,r):", FILE__, __LINE__);
388     fprintf(stderr, " %s, %s\n",lOperand.ast_wrapper->getType() ? lOperand.ast_wrapper->getType()->getName() : "<no type>",  rOperand.ast_wrapper->getType() ? rOperand.ast_wrapper->getType()->getName() : "<no type>");
389 #endif
390     assert(BPatch::bpatch != NULL);
391
392     opCode astOp = undefOp; // Quiet the compiler
393     switch(op) {
394       case BPatch_assign:
395         astOp = storeOp;
396         break;
397       case BPatch_plus:
398         astOp = plusOp;
399         break;
400       case BPatch_minus:
401         astOp = minusOp;
402         break;
403       case BPatch_divide:
404         astOp = divOp;
405         break;
406       case BPatch_times:
407         astOp = timesOp;
408         break;
409       case BPatch_mod:
410         /* XXX Not yet implemented. */
411         assert(0);
412         break;
413       case BPatch_ref:
414           ast_wrapper = generateArrayRef(lOperand, rOperand);
415           if (ast_wrapper == NULL) {
416               BPatch_reportError(BPatchSerious, 100 /* what # to use? */,
417                                  "could not generate array reference.");
418               BPatch_reportError(BPatchSerious, 100,
419                                  "resulting snippet is invalid.");
420           }
421           return;         
422           break;
423       case BPatch_fieldref:
424           ast_wrapper = generateFieldRef(lOperand, rOperand);
425           if (ast_wrapper == NULL) {
426               BPatch_reportError(BPatchSerious, 100 /* what # to use? */,
427                                  "could not generate field reference.");
428               BPatch_reportError(BPatchSerious, 100,
429                                  "resulting snippet is invalid.");
430           }
431           return;
432           break;
433       case BPatch_seq:
434           {
435               pdvector<AstNodePtr > sequence;
436               sequence.push_back(lOperand.ast_wrapper);
437               sequence.push_back(rOperand.ast_wrapper);
438               
439               ast_wrapper = AstNode::sequenceNode(sequence);
440               ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
441               return;
442           }
443     default:
444         /* XXX handle error */
445         assert(0);
446     };
447
448     ast_wrapper = AstNodePtr(AstNode::operatorNode(astOp,
449                                                    lOperand.ast_wrapper,
450                                                    rOperand.ast_wrapper));
451     ast_wrapper->setType(lOperand.ast_wrapper->getType());
452     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
453 }
454
455
456 /*
457  * BPatch_arithExpr::BPatch_arithExpr
458  *
459  * Construct a snippet representing a unary arithmetic operation.
460  *
461  * op           The desired operation.
462  * lOperand     The left operand for the operation.
463  */
464 void BPatch_arithExpr::BPatch_arithExprUn(BPatch_unOp op, 
465     const BPatch_snippet &lOperand)
466 {
467    assert(BPatch::bpatch != NULL);
468    
469    switch(op) {
470       case BPatch_negate: {
471           AstNodePtr negOne = AstNode::operandNode(AstNode::Constant, 
472                                                  (void *)-1);
473           BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
474           assert(type != NULL);         
475           negOne->setType(type);
476           ast_wrapper =  AstNodePtr(AstNode::operatorNode(timesOp,
477                                                           negOne,
478                                                           lOperand.ast_wrapper));
479           break;
480       }         
481    case BPatch_addr:  {
482      ast_wrapper = AstNodePtr(generateVariableBase(lOperand));
483        // create a new type which is a pointer to type 
484        BPatch_type *baseType = const_cast<BPatch_type *> 
485            (lOperand.ast_wrapper->getType());
486        BPatch_type *type = BPatch::bpatch->createPointer("<PTR>", 
487                                                          baseType, sizeof(void *));
488        assert(type);
489        ast_wrapper->setType(type);
490        break;
491    }
492
493    case BPatch_deref: {
494 #if 0
495        // Handle constant addresses...
496        if (lOperand.ast_wrapper->getoType() == AstNode::Constant) {
497            ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::DataAddr,
498                                                          const_cast<void *>(lOperand.ast_wrapper->getOValue())));
499        }
500        else {
501            ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::DataIndir, lOperand.ast_wrapper));
502        }
503 #endif
504           ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::DataIndir, lOperand.ast_wrapper));
505
506           BPatch_type *type = const_cast<BPatch_type *> (lOperand.ast_wrapper->getType());
507           if (!type || (type->getDataClass() != BPatch_dataPointer)) {
508               ast_wrapper->setType(BPatch::bpatch->stdTypes->findType("int"));
509           } else {
510               ast_wrapper->setType(type->getConstituentType());
511 //              ast_wrapper->setType(dynamic_cast<BPatch_typePointer *>(type)->getConstituentType());
512           }
513           break;
514       }
515          
516       default:
517          /* XXX handle error */
518          assert(0);
519    };
520    
521    ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
522 }
523
524 /*
525  * BPatch_boolExpr::BPatch_boolExpr
526  *
527  * Constructs a snippet representing a boolean expression.
528  *
529  * op           The operator for the boolean expression.
530  * lOperand     The left operand.
531  * rOperand     The right operand.
532  */
533 void BPatch_boolExpr::BPatch_boolExprInt(BPatch_relOp op,
534                                          const BPatch_snippet &lOperand,
535                                          const BPatch_snippet &rOperand)
536 {
537     opCode astOp = undefOp;
538     switch(op) {
539       case BPatch_lt:
540         astOp = lessOp;
541         break;
542       case BPatch_eq:
543         astOp = eqOp;
544         break;
545       case BPatch_gt:
546         astOp = greaterOp;
547         break;
548       case BPatch_le:
549         astOp = leOp;
550         break;
551       case BPatch_ne:
552         astOp = neOp;
553         break;
554       case BPatch_ge:
555         astOp = geOp;
556         break;
557       case BPatch_and:
558         astOp = andOp;
559         break;
560       case BPatch_or:
561         astOp = orOp;
562         break;
563       default:
564         /* XXX Handle the error case here */
565         assert( 0 );
566     };
567     
568     ast_wrapper = AstNodePtr(AstNode::operatorNode(astOp, lOperand.ast_wrapper, rOperand.ast_wrapper));
569     assert(BPatch::bpatch != NULL);
570     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
571 }
572
573
574 /*
575  * BPatch_constExpr::BPatch_constExpr
576  *
577  * Constructs a snippet representing a constant integer value.
578  *
579  * value        The desired value.
580  */
581  
582 void BPatch_constExpr::BPatch_constExprSignedInt( signed int value ) {
583         assert( BPatch::bpatch != NULL );
584
585         ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant,
586                                                                  (void *)(unsigned long) value));
587         ast_wrapper->setTypeChecking( BPatch::bpatch->isTypeChecked() );
588         
589         BPatch_type * type = BPatch::bpatch->stdTypes->findType( "int" );
590         assert( type != NULL );
591         ast_wrapper->setType( type );
592 }
593
594 void BPatch_constExpr::BPatch_constExprUnsignedInt( unsigned int value ) {
595         assert( BPatch::bpatch != NULL );
596         
597         ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant,
598                                                                  (void *)(unsigned long) value));
599         ast_wrapper->setTypeChecking( BPatch::bpatch->isTypeChecked() );
600         
601         BPatch_type * type = BPatch::bpatch->stdTypes->findType( "unsigned int" );
602         assert( type != NULL );
603         ast_wrapper->setType( type );
604         }
605
606 void BPatch_constExpr::BPatch_constExprSignedLong( signed long value ) {
607         assert( BPatch::bpatch != NULL );
608         
609         ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant,
610                                                                  (void *)(unsigned long) value));
611         ast_wrapper->setTypeChecking( BPatch::bpatch->isTypeChecked() );
612         
613         BPatch_type * type = BPatch::bpatch->stdTypes->findType( "long" );
614         assert( type != NULL );
615         ast_wrapper->setType( type );
616         }
617
618 void BPatch_constExpr::BPatch_constExprUnsignedLong( unsigned long value ) {
619         assert( BPatch::bpatch != NULL );
620         
621         ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant,
622                                                                  (void *)(unsigned long) value));
623         ast_wrapper->setTypeChecking( BPatch::bpatch->isTypeChecked() );
624         
625         BPatch_type * type = BPatch::bpatch->stdTypes->findType( "unsigned long" );
626         assert( type != NULL );
627         ast_wrapper->setType( type );
628         }
629
630 /*
631  * BPatch_constExpr::BPatch_constExpr
632  *
633  * Constructs a snippet representing a constant string value.
634  *
635  * value        The desired constant string.
636  */
637 void BPatch_constExpr::BPatch_constExprCharStar(const char *value)
638 {
639     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::ConstantString, (void *)const_cast<char *>(value)));
640
641     assert(BPatch::bpatch != NULL);
642     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
643
644     BPatch_type *type = BPatch::bpatch->stdTypes->findType("char *");
645     assert(type != NULL);
646
647     ast_wrapper->setType(type);
648 }
649
650
651 /*
652  * BPatch_constExpr::BPatch_constExpr
653  *
654  * Constructs a snippet representing a constant pointer.
655  *
656  * value        The desired constant pointer.
657  */
658 void BPatch_constExpr::BPatch_constExprVoidStar(const void *value)
659 {
660     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant, (void *)const_cast<void *>(value)));
661
662     assert(BPatch::bpatch != NULL);
663     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
664
665     BPatch_type *type = BPatch::bpatch->stdTypes->findType("void *");
666     assert(type != NULL);
667
668     ast_wrapper->setType(type);
669 }
670
671 void BPatch_constExpr::BPatch_constExprLongLong(long long value) 
672 {
673    ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Constant, (void *)(long)value));
674
675     assert(BPatch::bpatch != NULL);
676     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
677     
678     BPatch_type* type = BPatch::bpatch->stdTypes->findType("long long");
679
680     assert(type != NULL);
681     ast_wrapper->setType(type);
682 }
683
684 #ifdef IBM_BPATCH_COMPAT
685
686 char *BPatch_variableExpr::getNameWithLength(char *buffer, int max)
687 {
688   if (max > strlen(name)) {
689     strcpy (buffer, name);
690     return buffer;
691   } else {
692     strncpy (buffer, name, max-1)[max-1]='\0';
693   }
694   return NULL;
695 }
696
697 void *BPatch_variableExpr::getAddressInt()
698 {
699   //  for AIX this may be broken, in the case where the mutator is 32b
700   //  and the mutatee is 64b. 
701   return address;
702 }
703
704
705 void BPatch_constExpr::BPatch_constExprFloat(float value)
706 {
707         // XXX fix me, puting value into int register.
708         int ivalue = (int) value;
709         BPatch_constExpr((int) ivalue);
710 }
711
712 #endif
713
714
715
716 /*
717  * BPatch_regExpr::BPatch_regExpr
718  *
719  * Constructs a snippet representing a register.
720  *
721  * value        index of register.
722  *
723  * Note:  introduced for paradyn-seperation (paradyn needs access
724  *        to register REG_MT_POS)  -- there are other ways to do this.
725  *        This happens to be expedient -- not sure if we want to be
726  *        really exposing this to API users.  Thus this class may be
727  *        temporary -- avoid using it.
728  */
729
730 void BPatch_regExpr::BPatch_regExprInt(unsigned int value)
731 {
732     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::DataReg, (void *)(unsigned long int) value));
733
734     assert(BPatch::bpatch != NULL);
735     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
736
737     BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
738     assert(type != NULL);
739
740     ast_wrapper->setType(type);
741 }
742
743 /*
744  * BPatch_funcCallExpr::BPatch_funcCallExpr
745  *
746  * Constructs a snippet representing a function call.
747  *
748  * func         Identifies the function to call.
749  * args         A vector of the arguments to be passed to the function.
750  */
751 void BPatch_funcCallExpr::BPatch_funcCallExprInt(
752     const BPatch_function &func,
753     const BPatch_Vector<BPatch_snippet *> &args)
754 {
755     pdvector<AstNodePtr> ast_args;
756
757     unsigned int i;
758     for (i = 0; i < args.size(); i++) {
759         assert(args[i]->ast_wrapper);
760         ast_args.push_back(args[i]->ast_wrapper);
761     }
762
763     //  jaw 08/03  part of cplusplus bugfix -- using pretyName
764     //  to generate function calls can lead to non uniqueness probs
765     //  in the case of overloaded callee functions.
766
767     ast_wrapper = AstNodePtr(AstNode::funcCallNode(func.lowlevel_func(), ast_args));
768
769     assert(BPatch::bpatch != NULL);
770     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
771
772     BPatch_type *ret_type = const_cast<BPatch_function &>(func).getReturnType();
773       ast_wrapper->setType(ret_type);
774         /*** ccw 24 jul 2003 ***/
775         /*      at this point, if saveworld is turned on, check
776                 to see if func is in a shared lib. if it
777                 is marked that shared lib as dirtyCalled()
778         */
779 #if defined(cap_save_the_world)
780
781       AddressSpace *as = func.getAddSpace()->getAS();
782       process* proc = dynamic_cast<process *>(as);
783
784       //        process *proc = func.getProc()->llproc;
785         
786         // We can't define isSharedLib as constant everywhere, so strip
787         // the const definition here.
788         BPatch_function &stripFunc = const_cast<BPatch_function &> (func);
789         if( proc && proc->collectSaveWorldData && stripFunc.isSharedLib()){
790             stripFunc.lowlevel_func()->obj()->setDirtyCalled();
791         }
792 #endif
793 }
794
795 /*
796  * BPatch_funcJumpExpr::BPatch_funcJumpExpr
797  *
798  * Constructs a snippet representing a jump to a function without
799  * linkage.
800  *
801  * func Identifies the function to jump to.  */
802 #if defined(sparc_sun_solaris2_4) \
803  || defined(alpha_dec_osf4_0) \
804  || defined(i386_unknown_linux2_0) \
805  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
806  || defined(i386_unknown_nt4_0) \
807  || defined(os_linux)
808 void BPatch_funcJumpExpr::BPatch_funcJumpExprInt(
809     const BPatch_function &func)
810 {
811     ast_wrapper = AstNodePtr(AstNode::funcReplacementNode(func.lowlevel_func()));
812     assert(BPatch::bpatch != NULL);
813     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
814 }
815 #else
816 void BPatch_funcJumpExpr::BPatch_funcJumpExprInt(
817     const BPatch_function & /* func */)
818 {
819     BPatch_reportError(BPatchSerious, 109,
820                        "BPatch_funcJumpExpr is not implemented on this platform");
821 }
822 #endif
823
824
825 /*
826  * BPatch_ifExpr::BPatch_ifExpr
827  *
828  * Constructs a snippet representing a conditional expression.
829  *
830  * conditional          The conditional.
831  * tClause              A snippet to execute if the conditional is true.
832  */
833 void BPatch_ifExpr::BPatch_ifExprInt(const BPatch_boolExpr &conditional,
834                                      const BPatch_snippet &tClause)
835 {
836     ast_wrapper = AstNodePtr(AstNode::operatorNode(ifOp, conditional.ast_wrapper, tClause.ast_wrapper));
837
838     assert(BPatch::bpatch != NULL);
839     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
840 }
841
842
843 /*
844  * BPatch_ifExpr::BPatch_ifExpr
845  *
846  * Constructs a snippet representing a conditional expression with an else
847  * clause.
848  *
849  * conditional          The conditional.
850  * tClause              A snippet to execute if the conditional is true.
851  */
852 void BPatch_ifExpr::BPatch_ifExprWithElse(const BPatch_boolExpr &conditional,
853                                           const BPatch_snippet &tClause,
854                                           const BPatch_snippet &fClause)
855 {
856     ast_wrapper = AstNodePtr(AstNode::operatorNode(ifOp, 
857                                                    conditional.ast_wrapper, 
858                                                    tClause.ast_wrapper, 
859                                                    fClause.ast_wrapper));
860
861     assert(BPatch::bpatch != NULL);
862     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
863 }
864
865
866 /*
867  * BPatch_nullExpr::BPatch_nullExpr
868  *
869  * Construct a null snippet that can be used as a placeholder.
870  */
871 void BPatch_nullExpr::BPatch_nullExprInt()
872 {
873     ast_wrapper = AstNodePtr(AstNode::nullNode());
874
875     assert(BPatch::bpatch != NULL);
876     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
877 }
878
879
880 /*
881  * BPatch_paramExpr::BPatch_paramExpr
882  *
883  * Construct a snippet representing a parameter of the function in which
884  * the snippet is inserted.
885  *
886  * n    The position of the parameter (0 is the first parameter, 1 the second,
887  *      and so on).
888  */
889 void BPatch_paramExpr::BPatch_paramExprInt(int n)
890 {
891     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::Param,
892                                                              (void *)(long)n));
893
894     assert(BPatch::bpatch != NULL);
895     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
896 }
897
898
899 /*
900  * BPatch_retExpr::BPatch_retExpr
901  *
902  * Construct a snippet representing a return value from the function in which
903  * the snippet is inserted.
904  *
905  */
906 void BPatch_retExpr::BPatch_retExprInt()
907 {
908     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::ReturnVal, (void *)0));
909
910     assert(BPatch::bpatch != NULL);
911     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
912 }
913
914 /*
915  * BPatch_registerExpr::BPatch_registerExpr
916  *
917  * Construct a snippet representing a register in original code. Can be read
918  * or written.
919  *
920  */
921 void BPatch_registerExpr::BPatch_registerExprInt(BPatch_register reg)
922 {
923     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::origRegister, 
924                                                       (void *)(long)reg.number_));
925     
926     assert(BPatch::bpatch != NULL);
927
928     // Registers can hold a lot of different types...
929     ast_wrapper->setTypeChecking(false);
930     //ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
931 }
932
933 /*
934  * BPatch_sequence::BPatch_sequence
935  *
936  * Construct a snippet representing a sequence of snippets.
937  *
938  * items        The snippets that are to make up the sequence.
939  */
940 void BPatch_sequence::BPatch_sequenceInt(const BPatch_Vector<BPatch_snippet *> &items)
941 {
942     if (items.size() == 0) {
943         // XXX do something to indicate an error
944         return;
945     }
946
947     assert(BPatch::bpatch != NULL);
948
949     pdvector<AstNodePtr >sequence;
950     for (unsigned i = 0; i < items.size(); i++) {
951         assert(items[i]->ast_wrapper);
952         sequence.push_back(items[i]->ast_wrapper);
953     }
954     ast_wrapper = AstNodePtr(AstNode::sequenceNode(sequence));
955
956     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
957 }
958
959
960 /*
961  * BPatch_variableExpr::BPatch_variableExpr
962  *
963  * Construct a snippet representing a variable of the given type and the passed
964  *   ast.
965  *
966  * in_process   The BPatch_process that the variable resides in.
967  * in_address   The address of the variable in the inferior's address space.
968  * type         The type of the variable.
969  * ast          The ast expression for the variable
970  */
971 BPatch_variableExpr::BPatch_variableExpr(char *in_name,
972                                          BPatch_addressSpace *in_addSpace,
973                                          AddressSpace *in_lladdSpace,
974                                          AstNodePtr ast_wrapper_,
975                                          BPatch_type *typ,
976                                          void* in_address) :
977   name(in_name), 
978   appAddSpace(in_addSpace), 
979   lladdrSpace(in_lladdSpace),
980   address(in_address), 
981   scope(NULL), 
982   isLocal(false),
983   type(typ)  
984 {
985     ast_wrapper = ast_wrapper_;
986     assert(ast_wrapper);
987
988     assert(BPatch::bpatch != NULL);
989     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
990
991     ast_wrapper->setType(type);
992
993     size = type->getSize();
994 }
995
996 BPatch_variableExpr::BPatch_variableExpr(BPatch_addressSpace *in_addSpace,
997                                          AddressSpace *ll_addSpace, int_variable *iv,
998                                          BPatch_type *type)
999   : name(NULL),
1000     appAddSpace(in_addSpace),
1001     lladdrSpace(ll_addSpace),
1002     address(NULL),
1003     scope(NULL),
1004     isLocal(false),
1005     type(type)
1006 {  
1007   const image_variable* img_var = NULL;
1008   if(iv)
1009   {
1010     name = iv->symTabName().c_str();
1011     address = reinterpret_cast<void*>(iv->getAddress());
1012     intvar = iv;
1013     img_var = iv->ivar();
1014   }
1015   size = type->getSize();
1016   if(img_var)
1017   {
1018     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::variableValue, img_var));
1019   }
1020   else
1021   {
1022     ast_wrapper = AstNodePtr(AstNode::operandNode(AstNode::DataAddr, (void*)(NULL)));
1023   }
1024   
1025
1026   ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1027   ast_wrapper->setType(type); 
1028 }
1029
1030
1031 BPatch_variableExpr* BPatch_variableExpr::makeVariableExpr(BPatch_addressSpace* in_addSpace,
1032                                                  int_variable* v,
1033                                                  BPatch_type* type)
1034 {
1035   AddressSpace* llAS = v->mod()->proc();
1036   return new BPatch_variableExpr(in_addSpace, llAS, v, type);
1037 }
1038
1039 BPatch_variableExpr* BPatch_variableExpr::makeVariableExpr(BPatch_addressSpace* in_addSpace,
1040                                                            AddressSpace* in_llAddSpace,
1041                                                            std::string name,
1042                                                            void* offset,
1043                                                            BPatch_type* type)
1044 {
1045     
1046     int_variable* v = in_llAddSpace->getAOut()->getDefaultModule()->createVariable(name, 
1047                                                                                    reinterpret_cast<Address>(offset), 
1048                                                                                    type->getSize());
1049     return new BPatch_variableExpr(in_addSpace, in_llAddSpace, v, type);
1050 }
1051
1052
1053 unsigned int BPatch_variableExpr::getSizeInt() CONST_EXPORT
1054 {
1055   return size;
1056 }
1057
1058 /*
1059  * BPatch_variableExpr::getType
1060  *
1061  *    Return the variable's type
1062  *
1063 */
1064 const BPatch_type *BPatch_variableExpr::getTypeInt()
1065 {
1066   if (!type)
1067     return BPatch::bpatch->type_Untyped;
1068   return type;
1069 }
1070 #ifdef NOTDEF
1071 const BPatch_type *BPatch_variableExpr::getTypeConst() CONST_EXPORT
1072 {
1073     return ast_wrapper->getType();
1074 }
1075 #endif
1076
1077 /*
1078  * BPatch_variableExpr::setType
1079  *
1080  *    Set the variable's type
1081  *
1082 */
1083 bool BPatch_variableExpr::setTypeInt(BPatch_type *newType)
1084 {
1085     size = newType->getSize();
1086     type = newType;
1087     ast_wrapper->setType(newType);
1088     return true;
1089 }
1090 /*
1091  * BPatch_variableExpr::seSize
1092  *
1093  *    Set the variable's size
1094  *
1095 */
1096 bool BPatch_variableExpr::setSizeInt(int sz)
1097 {
1098     size = sz;
1099     return true;
1100 }
1101
1102
1103 /*
1104  * BPatch_variableExpr::BPatch_variableExpr
1105  *
1106  * Construct a snippet representing a variable of the given type at the given
1107  * address.
1108  *
1109  * in_addSpace  The BPatch_addressSpace that the variable resides in.
1110  * in_address   The address of the variable in the inferior's address space.
1111  * in_register  The register of the variable in the inferior's address space.
1112  * type         The type of the variable.
1113  * in_storage   Enum of how this variable is stored.
1114  */
1115 BPatch_variableExpr::BPatch_variableExpr(BPatch_addressSpace *in_addSpace,
1116                                          AddressSpace *in_lladdrSpace,
1117                                          void *in_address,
1118                                          int in_register,
1119                                          BPatch_type *typ,
1120                                          BPatch_storageClass in_storage,
1121                                          BPatch_point *scp) :
1122    appAddSpace(in_addSpace), 
1123    lladdrSpace(in_lladdrSpace),
1124    address(in_address),
1125    type(typ)
1126 {
1127    vector<AstNodePtr> variableASTs;
1128    AstNodePtr variableAst;
1129    
1130    if (!type)
1131      type = BPatch::bpatch->type_Untyped;
1132    switch (in_storage) {
1133       case BPatch_storageAddr:
1134           variableAst = AstNodePtr(AstNode::operandNode(AstNode::DataAddr, address));
1135           isLocal = false;
1136          break;
1137       case BPatch_storageAddrRef:
1138          assert( 0 ); // Not implemented yet.
1139          isLocal = false;
1140          break;
1141       case BPatch_storageReg:
1142          variableAst = AstNodePtr(AstNode::operandNode(AstNode::origRegister, 
1143                                                            (void *)(long)in_register));
1144          isLocal = true;
1145          break;
1146       case BPatch_storageRegRef:
1147          assert( 0 ); // Not implemented yet.
1148          isLocal = true;
1149          break;
1150       case BPatch_storageRegOffset:
1151          variableAst = AstNodePtr(AstNode::operandNode(AstNode::RegOffset, 
1152                                         AstNode::operandNode(AstNode::DataAddr,
1153                                                              address)));
1154          variableAst->setOValue( (void *)(long int)in_register );
1155          isLocal = true;
1156          break;
1157       case BPatch_storageFrameOffset:
1158          variableAst = AstNodePtr(AstNode::operandNode(AstNode::FrameAddr, address));
1159          isLocal = true;
1160          break;
1161    }
1162
1163    variableAst->setTypeChecking(BPatch::bpatch->isTypeChecked());
1164    variableAst->setType(type);
1165    variableASTs.push_back(variableAst);
1166    ast_wrapper = AstNode::variableNode(variableASTs);
1167    //    ast_wrapper = variableAst;    
1168    assert(BPatch::bpatch != NULL);
1169    ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1170    
1171    size = type->getSize();
1172    ast_wrapper->setType(type);
1173    
1174    scope = scp;
1175 }
1176
1177 /*
1178  * BPatch_variableExpr::BPatch_variableExpr
1179  *
1180  * Construct a snippet representing a variable of the given type at the given
1181  * address.
1182  *
1183  * in_addSpace  The BPatch_addressSpace that the variable resides in.
1184  * lv           The local variable handle
1185  * type             The type of the variable.
1186  *
1187  */
1188 BPatch_variableExpr::BPatch_variableExpr(BPatch_addressSpace *in_addSpace, 
1189                                          AddressSpace *in_lladdSpace,
1190                                          BPatch_localVar *lv, BPatch_type *typ, 
1191                                          BPatch_point *scp):
1192    appAddSpace(in_addSpace),
1193    lladdrSpace(in_lladdSpace),
1194    type(typ)
1195 {
1196     //Create Ast's for all members in the location list.
1197     //This will likely be done only for local variables within a function
1198     if (!type)
1199       type = BPatch::bpatch->type_Untyped;
1200
1201     Address baseAddr =  scp->getFunction()->lowlevel_func()->obj()->codeBase();
1202     vector<AstNodePtr> variableASTs;
1203     vector<pair<Offset, Offset> > *ranges = new vector<pair<Offset, Offset> >;
1204     vector<Dyninst::SymtabAPI::VariableLocation> *locs = lv->getSymtabVar()->getLocationLists();
1205     vector<Dyninst::SymtabAPI::VariableLocation> newlocs;
1206         
1207
1208     // Get the frame pointer location list for the local variable's function
1209     vector<Dyninst::SymtabAPI::VariableLocation> *fplocs = 
1210                                 scp->getFunction()->lowlevel_func()->ifunc()->getSymtabFunction()->getFramePtr();
1211
1212     for(unsigned i=0; i<locs->size(); i++) {
1213
1214         Address varlowPC, varhiPC;
1215         varlowPC = ((*locs)[i].lowPC) + baseAddr;
1216         varhiPC = ((*locs)[i].hiPC) + baseAddr;
1217
1218         BPatch_storageClass in_storage = lv->convertToBPatchStorage(& (*locs)[i]);
1219
1220         if (in_storage == BPatch_storageFrameOffset && fplocs != NULL) { 
1221        // Merge varaible and frame pointer's location list
1222
1223            for(unsigned j=0; j<fplocs->size(); j++) {
1224                  Address fplowPC, fphiPC;
1225                  fplowPC = ((*fplocs)[j].lowPC) + baseAddr;
1226                  fphiPC = ((*fplocs)[j].hiPC) + baseAddr;
1227                 
1228                    /* Combine fplocs->frameOffset to loc->frameOffset
1229    
1230                     6 cases
1231                     1) varlowPC > fphiPC > fplowPC - no overlap - no push
1232                     2) fphiPC > varlowPC > fplowPC - one push
1233                     3) fphiPC > fplowPC > varlowPC - one push
1234                     4) fphiPC > varhiPC > fplowPC - one push
1235                     5) fphiPC > fplowPC > varhiPC - no overlap - no push
1236                     6) fphiPC > varhiPC > varlowPC> fpilowPC - one push 
1237                    
1238                    */
1239         
1240                  Dyninst::SymtabAPI::VariableLocation newloc;
1241                  newloc.stClass = (*locs)[i].stClass ;
1242                  newloc.refClass = (*locs)[i].refClass;
1243                  newloc.reg = (*locs)[i].reg;
1244                  newloc.frameOffset =(*locs)[i].frameOffset +  (*fplocs)[j].frameOffset;
1245                  
1246                  if ( (varlowPC > fplowPC && varlowPC >= fphiPC) || (varhiPC <= fplowPC && varhiPC < fplowPC) ) {
1247                     //nothing
1248                  } else if ( varlowPC >= fplowPC && fphiPC >= varhiPC) {
1249                     newloc.lowPC = varlowPC;
1250                     newloc.hiPC = varhiPC;
1251                     newlocs.push_back(newloc);
1252                  } else if (varlowPC >= fplowPC && varlowPC < fphiPC) {
1253                    newloc.lowPC = varlowPC;
1254                    newloc.hiPC = fphiPC;
1255                    newlocs.push_back(newloc);
1256                 } else if (varlowPC < fplowPC && varlowPC < fphiPC ) { // varhiPC > fplowPC && varhiPC > fphiPC
1257                    newloc.lowPC = fplowPC;
1258                    newloc.hiPC = fphiPC;
1259                    newlocs.push_back(newloc);
1260                 } else if (varhiPC > fplowPC && varhiPC < fphiPC) {
1261                    newloc.lowPC = fplowPC;
1262                    newloc.hiPC = varhiPC;
1263                    newlocs.push_back(newloc);
1264                 }
1265            } // fploc iteration
1266        } else { // if not storageFrameOffset or fplocs == NULL
1267
1268          Dyninst::SymtabAPI::VariableLocation newloc;
1269          newloc.stClass = (*locs)[i].stClass ;
1270          newloc.refClass = (*locs)[i].refClass;
1271          newloc.reg = (*locs)[i].reg;
1272          newloc.frameOffset =(*locs)[i].frameOffset;
1273          
1274          newloc.lowPC = varlowPC;
1275          newloc.hiPC = varhiPC;
1276          
1277          newlocs.push_back(newloc);
1278
1279        }
1280     } // loc iteration
1281
1282     for(unsigned i=0; i<newlocs.size(); i++){
1283         AstNodePtr variableAst;
1284         BPatch_storageClass in_storage = lv->convertToBPatchStorage(& newlocs[i]);
1285         void *in_address = (void *) newlocs[i].frameOffset;
1286         int in_register = newlocs[i].reg;
1287         switch (in_storage) {
1288             case BPatch_storageAddr:
1289                 variableAst = AstNode::operandNode(AstNode::DataAddr, in_address);
1290                 isLocal = false;
1291                 address = in_address;
1292                 break;
1293             case BPatch_storageAddrRef:
1294                 //assert( 0 ); // Not implemented yet.
1295                 continue;
1296             case BPatch_storageReg:
1297                 variableAst = AstNode::operandNode(AstNode::origRegister, 
1298                                                    (void *)(long)in_register);
1299                 isLocal = true;
1300                 break;
1301             case BPatch_storageRegRef:
1302                 //assert( 0 ); // Not implemented yet.
1303                 continue;
1304             case BPatch_storageRegOffset:
1305                 variableAst = AstNode::operandNode(AstNode::RegOffset, 
1306                                                    AstNode::operandNode(AstNode::DataAddr,
1307                                                                         in_address));
1308                 variableAst->setOValue( (void *)(long int)in_register );
1309                 isLocal = true;
1310                 break;
1311             case BPatch_storageFrameOffset:
1312                 variableAst = AstNode::operandNode(AstNode::FrameAddr, in_address);
1313                 isLocal = true;
1314                 break;
1315         }
1316         variableAst->setTypeChecking(BPatch::bpatch->isTypeChecked());
1317         variableAst->setType(type);
1318         variableASTs.push_back(variableAst);
1319         ranges->push_back(pair<Offset, Offset>(newlocs[i].lowPC,newlocs[i].hiPC));
1320     }
1321     ast_wrapper = AstNodePtr(AstNode::variableNode(variableASTs, ranges));
1322     //    ast_wrapper = variableAst;    
1323     assert(BPatch::bpatch != NULL);
1324     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1325
1326     ast_wrapper->setType(type);
1327     size = type->getSize();
1328
1329     scope = scp;
1330 }
1331
1332
1333
1334
1335 /*
1336  * BPatch_variableExpr::readValue
1337  *
1338  * Read the value of a variable in a thread's address space.
1339  *
1340  * dst          A pointer to a buffer in which to place the value of the
1341  *              variable.  It is assumed to be the same size as the variable.
1342  */
1343 bool BPatch_variableExpr::readValueInt(void *dst)
1344 {
1345   if (isLocal) {
1346     char msg[2048];
1347     sprintf(msg, "variable %s is not a global variable, cannot read using readValue()",name);
1348     BPatch_reportError(BPatchWarning, 109,msg);
1349     return false;
1350   }
1351
1352   if (size) {
1353       lladdrSpace->readDataSpace(address, size, dst, true);
1354       return true;
1355   }
1356   else {
1357       return false;
1358   }
1359 }
1360
1361
1362 /*
1363  * BPatch_variableExpr::readValue
1364  *
1365  * Read the a given number of bytes starting at the base address of a variable
1366  * in the a thread's address space.
1367  *
1368  * dst          A pointer to a buffer in which to place the value of the
1369  *              variable.  It is assumed to be the same size as the variable.
1370  * len          Number of bytes to read.
1371  */
1372 bool BPatch_variableExpr::readValueWithLength(void *dst, int len)
1373 {
1374   if (isLocal) {
1375     char msg[2048];
1376     sprintf(msg, "variable %s is not a global variable, cannot read using readValue()",name);
1377     BPatch_reportError(BPatchWarning, 109,msg);
1378     return false;
1379   }
1380
1381   lladdrSpace->readDataSpace(address, len, dst, true);
1382   return true;
1383 }
1384
1385
1386 /*
1387  * BPatch_variableExpr::writeValue
1388  *
1389  * Write a value into a variable in a thread's address space.
1390  *
1391  * dst          A pointer to a buffer in which to place the value of the
1392  *              variable.  It is assumed to be the same size as the variable.
1393  *
1394  * returns false if the type info isn't available (i.e. we don't know the size)
1395  */
1396
1397 bool BPatch_variableExpr::writeValueInt(const void *src, bool /* saveWorld */)
1398 {
1399   if (isLocal) {
1400     char msg[2048];
1401     sprintf(msg, "variable %s is not a global variable, cannot write",name);
1402     BPatch_reportError(BPatchWarning, 109,msg);
1403     return false;
1404   }
1405
1406   if (size) {
1407       if (!lladdrSpace->writeDataSpace(address, size, src)) {
1408           fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
1409       }          
1410       return true;
1411   }
1412   else {
1413       return false;
1414   }
1415 }
1416
1417
1418 /*
1419  * BPatch_variableExpr::writeValue
1420  *
1421  * Write the a given number of bytes starting at the base address of a
1422  * variable in the a thread's address space.
1423  *
1424  * dst          A pointer to a buffer in which to place the value of the
1425  *              variable.  It is assumed to be the same size as the variable.
1426  */
1427 bool BPatch_variableExpr::writeValueWithLength(const void *src, int len, bool /*saveWorld*/)
1428 {
1429   if (isLocal) {
1430     char msg[2048];
1431     sprintf(msg, "variable %s is not a global variable, cannot write",name);
1432     BPatch_reportError(BPatchWarning, 109,msg);
1433     return false;
1434   }
1435
1436   if (!lladdrSpace->writeDataSpace(address, len, src)) {
1437       fprintf(stderr, "%s[%d]:  writeDataSpace failed\n", FILE__, __LINE__);
1438   }          
1439   return true;
1440 }
1441
1442 AddressSpace *BPatch_variableExpr::getAS()
1443 {
1444    return lladdrSpace;
1445 }
1446
1447 const char *BPatch_variableExpr::getNameInt()
1448 {
1449   return name;
1450 }
1451
1452 void *BPatch_variableExpr::getBaseAddrInt()
1453 {
1454   return address;
1455 }
1456 /*
1457  * getComponents() - return variable expressions for all of the fields
1458  *     in the passed structure/union.
1459  */
1460 BPatch_Vector<BPatch_variableExpr *> *BPatch_variableExpr::getComponentsInt()
1461 {
1462     const BPatch_Vector<BPatch_field *> *fields;
1463     BPatch_Vector<BPatch_variableExpr *> *retList = new BPatch_Vector<BPatch_variableExpr *>;
1464     fields = getType()->getComponents();
1465     if (fields == NULL) return NULL;
1466     for (unsigned int i=0; i < fields->size(); i++) {
1467        
1468        BPatch_field *field = (*fields)[i];
1469        long int offset = (field->getOffset() / 8);
1470        BPatch_variableExpr *newVar;
1471        
1472        // convert to *(&basrVar + offset)
1473        AstNodePtr fieldExpr = AstNode::operandNode(AstNode::DataIndir,
1474                                                    AstNode::operatorNode(plusOp,
1475                                                                          generateVariableBase(*this),
1476                                                    AstNode::operandNode(AstNode::Constant, (void *)offset)));
1477        if( field->getType() != NULL ) {
1478            AstNodePtr newAst = fieldExpr;
1479            newVar = new BPatch_variableExpr(const_cast<char *> (field->getName()),
1480                                             appAddSpace, lladdrSpace,
1481                                             newAst,
1482                                             field->getType(),
1483                                             (char*)address + offset);
1484            retList->push_back(newVar);
1485        } else {
1486            bperr( "Warning: not returning field '%s' with NULL type.\n", field->getName() );
1487        }
1488     }
1489     return retList;
1490 }
1491
1492 /*
1493  * BPatch_breakPointExpr::BPatch_breakPointExpr
1494  *
1495  * Construct a snippet representing a breakpoint.
1496  *
1497  */
1498 void BPatch_breakPointExpr::BPatch_breakPointExprInt()
1499 {
1500     pdvector<AstNodePtr > null_args;
1501
1502     ast_wrapper = AstNodePtr(AstNode::funcCallNode("DYNINST_snippetBreakpoint", null_args));
1503
1504     assert(BPatch::bpatch != NULL);
1505
1506     ast_wrapper->setType(BPatch::bpatch->type_Untyped);
1507     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1508 }
1509
1510
1511 /*
1512  * BPatch_effectiveAddressExpr::BPatch_effectiveAddressExpr
1513  *
1514  * Construct a snippet representing an effective address.
1515  */
1516 void BPatch_effectiveAddressExpr::BPatch_effectiveAddressExprInt(int _which)
1517 {
1518 #if defined(i386_unknown_nt4_0)
1519   assert(_which >= 0 && _which <= 2);
1520 #elif defined (__XLC__) || defined(__xlC__)
1521   assert(_which >= 0 && _which <= 1);
1522 #else
1523   assert(_which >= 0 && _which <= (int) BPatch_instruction::nmaxacc_NP);
1524 #endif
1525   ast_wrapper = AstNodePtr(AstNode::memoryNode(AstNode::EffectiveAddr, _which));
1526 };
1527
1528
1529 /*
1530  * BPatch_bytesAccessedExpr::BPatch_bytesAccessedExpr
1531  *
1532  * Construct a snippet representing the number of bytes accessed.
1533  */
1534 void BPatch_bytesAccessedExpr::BPatch_bytesAccessedExprInt(int _which)
1535 {
1536 #if defined(i386_unknown_nt4_0)
1537   assert(_which >= 0 && _which <= 2);
1538 #elif defined (__XLC__) || defined(__xlC__)
1539   assert(_which >= 0 && _which <= 1);
1540 #else
1541   assert(_which >= 0 && _which <= (int)BPatch_instruction::nmaxacc_NP);
1542 #endif
1543   ast_wrapper = AstNodePtr(AstNode::memoryNode(AstNode::BytesAccessed, _which));
1544 };
1545
1546
1547 void BPatch_ifMachineConditionExpr::BPatch_ifMachineConditionExprInt(const BPatch_snippet &tClause)
1548 {
1549     ast_wrapper = AstNodePtr(AstNode::operatorNode(ifMCOp, tClause.ast_wrapper));
1550     
1551     assert(BPatch::bpatch != NULL);
1552     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1553 };
1554
1555 void BPatch_threadIndexExpr::BPatch_threadIndexExprInt()
1556 {
1557     ast_wrapper = AstNodePtr(AstNode::threadIndexNode());
1558     
1559     assert(BPatch::bpatch != NULL);
1560     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1561     BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
1562     assert(type != NULL);
1563     //ast_wrapper->setType(type);
1564     
1565 }
1566
1567 void BPatch_tidExpr::BPatch_tidExprInt(BPatch_process *proc)
1568 {
1569   BPatch_Vector<BPatch_function *> thread_funcs;
1570   proc->getImage()->findFunction("dyn_pthread_self", thread_funcs);
1571   if (thread_funcs.size() != 1)
1572   {
1573     fprintf(stderr, "[%s:%u] - Internal Dyninst error.  Found %lu copies of "
1574             "DYNINSTthreadIndex.  Expected 1\n", __FILE__, __LINE__, (long) thread_funcs.size());
1575     if (!thread_funcs.size())
1576       return;
1577   }
1578   BPatch_function *thread_func = thread_funcs[0];
1579   
1580   pdvector<AstNodePtr> args;
1581   ast_wrapper = AstNodePtr(AstNode::funcCallNode(thread_func->lowlevel_func(), args));
1582
1583   assert(BPatch::bpatch != NULL);
1584   ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1585   BPatch_type *type = BPatch::bpatch->stdTypes->findType("long");
1586   assert(type != NULL);
1587   ast_wrapper->setType(type);
1588 }
1589
1590 // BPATCH INSN EXPR
1591
1592 void BPatch_insnExpr::BPatch_insnExprInt(BPatch_instruction *insn) {
1593     ast_wrapper = AstNodePtr(AstNode::insnNode(insn));
1594 }
1595
1596 bool BPatch_insnExpr::overrideLoadAddressInt(BPatch_snippet &l) {
1597     // We can assert our AST is an insn type...
1598     // Don't hand back insnAst to anyone else
1599     AstInsnNode *insnAst = dynamic_cast<AstInsnNode *>(ast_wrapper.get());
1600     assert(insnAst);
1601
1602     return insnAst->overrideLoadAddr(l.ast_wrapper);
1603 }
1604
1605 bool BPatch_insnExpr::overrideStoreAddressInt(BPatch_snippet &s) {
1606     // We can assert our AST is an insn type...
1607     AstInsnNode *insnAst = dynamic_cast<AstInsnNode *>(ast_wrapper.get());
1608     assert(insnAst);
1609
1610     return insnAst->overrideStoreAddr(s.ast_wrapper);
1611 }
1612
1613
1614 /* BPatch_stopThreadExpr 
1615  *
1616  *  This snippet type stops the thread that executes it.  It
1617  *  evaluates a calculation snippet and triggers a callback to the
1618  *  user program with the result of the calculation and a pointer to
1619  *  the BPatch_point at which the snippet was inserted
1620  */
1621 void BPatch_stopThreadExpr::BPatch_stopThreadExprInt
1622       (const BPatchStopThreadCallback &bp_cb,
1623        const BPatch_snippet &calculation) 
1624 {
1625     //register the callback 
1626     StopThreadCallback *cb = new StopThreadCallback(bp_cb);
1627     getCBManager()->registerCallback(evtStopThread, cb);
1628
1629     // create callback ID argument
1630     int cb_id = process::getStopThreadCB_ID((Address)bp_cb); 
1631     AstNodePtr idNode = AstNode::operandNode(AstNode::Constant, (void*)(long) cb_id );
1632     assert(BPatch::bpatch != NULL);
1633     BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
1634     assert(type != NULL);
1635     idNode->setType(type);
1636     
1637     // set up funcCall args
1638     pdvector<AstNodePtr> ast_args;
1639     ast_args.push_back(AstNode::originalAddrNode());
1640     ast_args.push_back(idNode);
1641     ast_args.push_back(calculation.ast_wrapper);
1642
1643     // create func call & set type 
1644     ast_wrapper = AstNodePtr(AstNode::funcCallNode("DYNINST_stopThread", ast_args));
1645     ast_wrapper->setType(BPatch::bpatch->type_Untyped);
1646     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1647 }
1648
1649 void BPatch_originalAddressExpr::BPatch_originalAddressExprInt() {
1650     ast_wrapper = AstNodePtr(AstNode::originalAddrNode());
1651
1652     assert(BPatch::bpatch != NULL);
1653     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1654     BPatch_type *type = BPatch::bpatch->stdTypes->findType("long");
1655     assert(type != NULL);
1656     ast_wrapper->setType(type);
1657 }
1658
1659 void BPatch_actualAddressExpr::BPatch_actualAddressExprInt() {
1660     ast_wrapper = AstNodePtr(AstNode::actualAddrNode());
1661
1662     assert(BPatch::bpatch != NULL);
1663     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1664     BPatch_type *type = BPatch::bpatch->stdTypes->findType("long");
1665     assert(type != NULL);
1666     ast_wrapper->setType(type);
1667 }
1668
1669 void BPatch_dynamicTargetExpr::BPatch_dynamicTargetExprInt() {
1670     ast_wrapper = AstNodePtr(AstNode::dynamicTargetNode());
1671
1672     assert(BPatch::bpatch != NULL);
1673     ast_wrapper->setTypeChecking(BPatch::bpatch->isTypeChecked());
1674     BPatch_type *type = BPatch::bpatch->stdTypes->findType("long");
1675     assert(type != NULL);
1676     ast_wrapper->setType(type);
1677 }
1678