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