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