Fix instrumentation side effects; we had been erroneously moving the PC when handling...
[dyninst.git] / dyninstAPI / src / multiTramp.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 // Code to install and remove instrumentation from a running process.
33
34 #include "multiTramp.h"
35 #include "baseTramp.h"
36 #include "miniTramp.h"
37 #include "instPoint.h"
38 #include "process.h"
39 #include "function.h"
40 #if defined(cap_instruction_api)
41 #include "instructionAPI/h/InstructionDecoder.h"
42 #else
43 #include "parseAPI/src/InstrucIter.h"
44 #endif // defined(cap_instruction_api)
45 #include "BPatch.h"
46 // Need codebuf_t, Address
47 #include "codegen.h"
48 #include <sstream>
49
50 using namespace Dyninst;
51
52 unsigned int multiTramp::id_ctr = 1;
53
54 multiTramp *multiTramp::getMulti(int id, AddressSpace *p) {
55     return p->findMultiTrampById(id);
56 }
57
58 baseTrampInstance *multiTramp::getBaseTrampInstance(instPointInstance *point,
59                                                     callWhen when) const {
60     // How do we instrument this point at the desired address
61
62     // And a safety note;
63     assert(point->multi() == this);
64
65     generatedCodeObject *insn = insns_[point->addr()];
66     assert(insn);
67
68     switch (when) {
69     case callPreInsn: {
70         //inst_printf("Matching preBTI\n");
71         baseTrampInstance *preBTI = dynamic_cast<baseTrampInstance *>(insn->previous_);
72         if (preBTI) return preBTI;
73         break;
74     }
75     case callPostInsn: {
76         //inst_printf("Matching postBTI\n");
77         baseTrampInstance *postBTI = dynamic_cast<baseTrampInstance *>(insn->fallthrough_);
78         if (postBTI) return postBTI;
79         break;
80     }
81     case callBranchTargetInsn: {
82         //inst_printf("Matching targetBTI\n");
83         baseTrampInstance *BTI = dynamic_cast<baseTrampInstance *>(insn->target_);
84         if (BTI) return BTI;
85         break;                
86     }
87     default:
88         assert(0);
89         break;
90     }
91     // Didn't find a match.
92     return NULL;
93 }
94
95 // Reverse mapping: I have an address, and I want a BTI
96 baseTrampInstance *multiTramp::getBaseTrampInstanceByAddr(Address addr) const {
97     // Note: this is a slight modification of instToUninst, but has a
98     // different target.
99
100     generatedCFG_t::iterator cfgIter(generatedCFG_);
101     generatedCodeObject *obj = NULL;
102     
103     while ((obj = cfgIter++)) {
104         baseTrampInstance *i = dynamic_cast<baseTrampInstance *>(obj);
105         if (i && i->isInInstance(addr))
106             return i;
107     }
108
109     return NULL;
110 }
111
112 // Begin the long and arduous task of deleting a multiTramp.
113
114 void multiTramp::removeCode(generatedCodeObject *subObject) {
115     // One of our baseTramps just went away; let's see what's going on.
116     // Or we're going away from a top level.
117     baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(subObject);
118     relocatedInstruction *reloc = dynamic_cast<relocatedInstruction *>(subObject);
119     trampEnd *te = dynamic_cast<trampEnd *>(subObject);
120     replacedInstruction *ri = dynamic_cast<replacedInstruction *>(subObject);
121
122     // Have _no_ idea how to handle one of these guys going away.
123     assert(!reloc);
124     assert(!te);
125     assert(trampEnd_);
126
127     // Un-replace an instruction? Not right now...
128     // TODO
129     assert(!ri);
130
131     bool doWeDelete = false;
132
133     if (subObject == NULL) doWeDelete = true;
134     
135     if (bti) {
136         // We in-line baseTramps, which means if a baseTrampInstance goes away,
137         // we need to regenerate it in toto. 
138
139         // Go through the generatedCFG, get rid of this instance, and see if there's
140         // still anyone left.
141
142         bool stillInst = false;
143         bool foundBTI = false;
144
145         generatedCFG_t::iterator cfgIter(generatedCFG_);
146         generatedCodeObject *obj = NULL;
147
148         while ((obj = cfgIter++)) {
149             baseTrampInstance *tmp = dynamic_cast<baseTrampInstance *>(obj);
150             if (!tmp) {
151                 continue;
152             }
153             // We loop through everything on purpose to determine whether
154             // there are other instrumented points.
155             if (tmp == bti) {
156                 if (tmp->previous_ && 
157                     (tmp->previous_->fallthrough_ == tmp)) {
158                     tmp->previous_->setFallthrough(tmp->fallthrough_);
159                 }
160                 else if (tmp->previous_ && 
161                     (tmp->previous_->target_ == tmp)) {
162                     // Edge instrumentation...
163                     tmp->previous_->setTarget(tmp->fallthrough_);
164                 }
165                 else {
166                     // Assert we're the first thing in line.
167                     assert(tmp == generatedCFG_.start());
168                     generatedCFG_.setStart(tmp->fallthrough_);
169                 }
170                 if (tmp->fallthrough_) {
171                     tmp->fallthrough_->setPrevious(tmp->previous_);
172                 }
173                 foundBTI = true;
174                 tmp->removeCode(this);
175             }
176             else {
177                 if (!tmp->isEmpty())
178                     stillInst = true;
179             }
180             if (stillInst && foundBTI)
181                 break;
182         }
183                 
184         if (stillInst) {
185             // There's a baseTrampInstance left. Since we in-lined, this means
186             // we need to regenerate the code. For safety, we make a new multiTramp
187             // in place of this one.
188             multiTramp::replaceMultiTramp(this, doWeDelete);
189         }
190         else {
191             doWeDelete = true;
192         }
193         
194         int found_index = -1;
195         for (unsigned int i = 0; i <deletedObjs.size(); ++i) {
196            if (subObject == deletedObjs[i]) {
197               found_index = i;
198               break;
199            }
200         }
201         if (-1 == found_index) 
202            deletedObjs.push_back(bti);
203     }
204     
205     if ( doWeDelete && isActive_ && ! partlyGone_ ) {
206         mal_printf("Unlinking but not deleting multiTramp %lx [%lx %lx] on "
207                 "grounds that it is actively executing %s[%d]\n",instAddr_,
208                 trampAddr_, trampAddr_+trampSize_, FILE__,__LINE__);
209     }
210
211     // unlink the tramp if we haven't already
212     if ( doWeDelete && ! partlyGone_ ) {
213         disable();
214         partlyGone_ = true;
215     }
216
217     if (doWeDelete && !isActive_) {
218
219         if (proc()->findMultiTrampById(id()) == this) {
220             // Won't leak as the process knows to delete us
221             proc()->removeMultiTramp(this);
222         }
223         
224         // Move everything else to the deleted list
225         generatedCFG_t::iterator cfgIter(generatedCFG_);
226         generatedCodeObject *obj = NULL;
227
228         while ((obj = cfgIter++)) {
229            int found_index = -1;
230            for (unsigned int i = 0; i <deletedObjs.size(); ++i) {
231               if (obj == deletedObjs[i]) {
232                  found_index = i;
233                  break;
234               }
235            }
236            if (-1 == found_index)  {
237               deletedObjs.push_back(obj);
238               obj->removeCode(this);
239            }
240         }
241         generatedCFG_.setStart(NULL);
242
243         proc()->deleteGeneratedCode(this);
244     }   
245     assert(trampEnd_);
246     return;
247 }
248
249    bool multiTramp::safeToFree(codeRange *range) {
250       if (dynamic_cast<multiTramp *>(range) == this)
251          return false;
252
253       generatedCFG_t::iterator cfgIter(generatedCFG_);
254       generatedCodeObject *obj = NULL;
255
256     while ((obj = cfgIter++)) {
257         if (!obj->safeToFree(range))
258             return false;
259     }
260     return true;
261 }
262
263
264 void multiTramp::freeCode() {
265     proc()->inferiorFree(trampAddr_);
266     delete this;
267 }
268
269 multiTramp::~multiTramp() {
270
271     mal_printf("Deleting multi instAddr 0x%lx trampAddr 0x%lx\n",
272                instAddr_,trampAddr_);
273
274     for (unsigned i = 0; i < deletedObjs.size(); i++)
275        if(deletedObjs[i] != NULL) {
276           delete deletedObjs[i];          
277        }
278     deletedObjs.clear();
279
280     generatedCFG_t::iterator cfgIter(generatedCFG_);
281     generatedCodeObject *obj = NULL;
282
283     while ((obj = cfgIter++)) {
284         // Before we delete the object :)
285         if(obj != NULL)
286            delete obj;
287     }
288
289     if (savedCodeBuf_)
290         free(savedCodeBuf_);
291
292     // And this is why we want a process pointer ourselves. Trusting the
293     // function to still be around is... iffy... at best.
294     proc()->removeMultiTramp(this);
295     proc()->inferiorFree(trampAddr_);
296
297     // Everything else is statically allocated
298 }
299
300 // Assumes there is no matching multiTramp at this address
301 int multiTramp::findOrCreateMultiTramp(Address pointAddr, 
302                                        bblInstance *bbl) {
303     AddressSpace *proc = bbl->func()->proc();
304     multiTramp *newMulti = proc->findMultiTrampByAddr(pointAddr);
305     if (newMulti && newMulti->func() == bbl->func()) { 
306         
307         // Check whether we're in trap shape
308         // Sticks to false if it ever is false
309         return newMulti->id();
310     }
311
312     Address startAddr = 0;
313     unsigned size = 0;
314     bool basicBlockTramp = false;
315
316     // On most platforms we instrument an entire basic block at a
317     // time. IA64 does bundles. This is controlled by the static
318     // getMultiTrampFootprint function; so if you want to do something
319     // odd then go poke there. Individual instrumentation _should_
320     // work but is not tested.
321
322     if (!multiTramp::getMultiTrampFootprint(pointAddr,
323                                             proc,
324                                             startAddr,
325                                             size,
326                                             basicBlockTramp)) {
327         // Assert fail?
328         inst_printf("Could not get multiTramp footprint at 0x%lx, ret false\n", pointAddr);
329         return 0;
330     }
331
332     // Cannot make a point here if someone else got there first
333         // We're allowing this for now; we'll go through the motions, and finally
334         // "fake" the actual link phase. Otherwise things get weirdly out of
335         // step.
336
337     newMulti = new multiTramp(startAddr,
338                               size,
339                               bbl->func());
340     
341     // Iterate over the covered instructions and pull each one
342     relocatedInstruction *prev = NULL;
343
344     // There are two ways of handling this... if we're in original code,
345     // run an instructIter over the thing. If not, things get tricky...
346     // We're in a relocated function, but want to use the original instruction
347     // representations (with new targets and sizes. Oy.)
348
349     bool done = false;
350 #if defined(cap_relocation)
351     if (bbl->version() > 0) {
352         done = true;
353       // Relocated!
354       
355       // We assert that we're going over the entire block. This is okay, as the only
356       // platform where we wouldn't is IA-64, which doesn't do function relocation.
357
358       // uhh....
359       pdvector<bblInstance::reloc_info_t::relocInsn::Ptr> &relocInsns = bbl->get_relocs();
360       assert(relocInsns[0]->relocAddr == startAddr);
361       for (unsigned i = 0; i < relocInsns.size(); i++) {
362         relocatedInstruction *reloc = new relocatedInstruction(relocInsns[i]->origInsn,
363                                                                // Original address...
364                                                                relocInsns[i]->origAddr,
365                                                                // Current address...
366                                                                relocInsns[i]->relocAddr,
367                                                                // Target, if set
368                                                                relocInsns[i]->relocTarget,
369                                                                newMulti);
370         newMulti->insns_[relocInsns[i]->relocAddr] = reloc;
371
372         if (prev) {
373           prev->setFallthrough(reloc);
374         }
375         else {
376           // Other initialization?
377           newMulti->setFirstInsn(reloc);
378         }
379         reloc->setPrevious(prev);
380         prev = reloc;
381       }
382     }
383 #endif
384     if (!done) {
385
386 #if defined(cap_instruction_api)
387       size_t offset = 0;
388       using namespace Dyninst::InstructionAPI;
389       const unsigned char* relocatedInsnBuffer =
390       reinterpret_cast<const unsigned char*>(proc->getPtrToInstruction(startAddr));
391       
392       InstructionDecoder decoder(relocatedInsnBuffer, size, proc->getArch());
393       while(offset < size)
394       {
395         Address insnAddr = startAddr + offset;
396
397         relocatedInstruction *reloc = new relocatedInstruction(relocatedInsnBuffer + offset, insnAddr, insnAddr, 0, newMulti);
398         newMulti->insns_[insnAddr] = reloc;
399         if (prev) {
400           prev->setFallthrough(reloc);
401         }
402         else {
403           // Other initialization?
404           newMulti->setFirstInsn(reloc);
405         }
406         reloc->setPrevious(prev);
407         prev = reloc;   
408         offset += decoder.decode()->size();
409         #if defined(arch_sparc)
410         #error "Instruction API not implemented for SPARC yet"
411         // delay slot handling goes here
412         #endif
413       }
414       
415 #else
416       for (InstrucIter insnIter(startAddr, size, proc);
417            insnIter.hasMore(); 
418            insnIter++) {
419         instruction *insn = insnIter.getInsnPtr();
420         Address insnAddr = *insnIter;
421         
422         relocatedInstruction *reloc = new relocatedInstruction(insn, 
423                                                                insnAddr,
424                                                                insnAddr, 
425                                                                0,
426                                                                newMulti);
427         newMulti->insns_[insnAddr] = reloc;
428         
429         if (prev) {
430           prev->setFallthrough(reloc);
431         }
432         else {
433           // Other initialization?
434           newMulti->setFirstInsn(reloc);
435         }
436         reloc->setPrevious(prev);
437         prev = reloc;
438         
439         // SPARC!
440 #if defined(arch_sparc)
441         // Just to avoid cluttering this up
442         // If we have a delay slot, grab the next insn and aggregate,
443         // if it exists. These functions advance the iterator; effectively
444         // we're gluing delay slot and jump together.
445         
446         if (insn->isDCTI()) {
447           instruction *ds, *agg;
448           insnIter.getAndSkipDSandAgg(ds, agg);
449
450           if (ds) {
451             reloc->ds_insn = ds;
452           }
453           if (agg) {
454             reloc->agg_insn = agg;
455           }
456         }
457 #endif // defined(arch_sparc)
458       } 
459 #endif // defined(cap_instruction_api)  
460     }
461
462     assert(prev);
463
464     // Add a trampEnd object for fallthroughs
465     trampEnd *end = NULL;
466     int_basicBlock *fallthroughBlock = NULL;
467
468     if (basicBlockTramp) {
469       fallthroughBlock = bbl->block()->getFallthrough();
470     }
471
472     if (fallthroughBlock) {
473         bblInstance *fallthroughInstance = fallthroughBlock->instVer(bbl->version());
474         // We really need one of these...
475         assert(fallthroughInstance);
476         end = new trampEnd(newMulti, fallthroughInstance->firstInsnAddr());
477     }
478     else {
479         // No fallthrough... 
480         // Could be a real case of no fallthrough, or we could be instrumenting
481         // an instruction at a time due to an indirect jump. Or we could be
482         // on IA-64.
483
484         // In an alternate case of indirect jump - function return. In this case,
485         // we'll add a branch that is never taken (but appears to go to the next 
486         // function, confusing).
487         
488         end = new trampEnd(newMulti, startAddr + size);
489     }
490     
491     assert(end);
492     prev->setFallthrough(end);
493     end->setPrevious(prev);
494     
495     newMulti->trampEnd_ = end;
496
497     // Put this off until we generate
498     //newMulti->updateInstInstances();
499
500     proc->addMultiTramp(newMulti);
501
502     return newMulti->id();
503 }
504
505 // Get the footprint for the multiTramp at this address. The MT may
506 // not exist yet; our instrumentation code needs this.
507 bool multiTramp::getMultiTrampFootprint(Address instAddr,
508                                         AddressSpace *proc,
509                                         Address &startAddr,
510                                         unsigned &size,
511                                         bool &basicBlock)
512 {
513     // We use basic blocks
514     // Otherwise, make one.
515     codeRange *range = proc->findOrigByAddr(instAddr);
516     if (!range) {
517       inst_printf("%s[%d]: no code range for given address 0x%lx!\n", FILE__, __LINE__, instAddr);
518       return false;
519     }
520     bblInstance *bbl = range->is_basicBlockInstance();
521     if (!bbl) {
522         inst_printf("%s[%d]: No basic block instance for addr 0x%lx in createMultiTramp, ret NULL\n",
523                     FILE__, __LINE__, instAddr);
524         return false;
525     }
526
527     // check whether this block is legal to relocate (instrumentation requires
528     // relocation of the basic block)
529     if(!bbl->block()->llb()->canBeRelocated())
530     {
531       inst_printf("%s[%d]: Basic block at 0x%lx cannot be instrumented, ret NULL\n",
532                   FILE__, __LINE__, instAddr);
533         return false;
534     }
535
536     // If the function contains unresolved indirect branches, we have to
537     // assume that the branch could go anywhere (e.g., it could split
538     // this block). So we don't get to use the entire block size, just
539     // the instruction size.
540     if(bbl->func()->ifunc()->instLevel() == HAS_BR_INDIR)
541     {
542         inst_printf("Target function contains unresolved indirect branches\n"
543                     "   Setting multiTramp size to instruction size\n");
544
545         
546         startAddr = instAddr;
547 #if defined(cap_instruction_api)
548         using namespace Dyninst::InstructionAPI;
549         InstructionDecoder decoder((unsigned char*)(proc->getPtrToInstruction(instAddr)),
550                                    InstructionDecoder::maxInstructionLength,
551                                    proc->getArch());
552         Instruction::Ptr instInsn = decoder.decode();
553         size = instInsn->size();
554 #else
555         InstrucIter ah(instAddr,proc);
556         size = ah.getInstruction().size();
557 #endif // defined(cap_instruction_api)
558         basicBlock = false;
559         return true;
560     }
561     
562     // start is the start of the basic block, size is the size
563     startAddr = bbl->firstInsnAddr();
564     size = (unsigned) bbl->getSize();
565     basicBlock = true;
566
567     return true;
568 }
569
570 void multiTramp::updateInstInstances() {
571     // Go over all the instructions in our little CFG-let and insert baseTrampInstances
572     // et. al.
573
574     assert(func());
575
576     generatedCFG_t::iterator cfgIter(generatedCFG_);
577
578     // We need to regenerate if anything changes; that defined as a baseTrampInstance
579     // appearing or disappearing.
580
581
582     generatedCodeObject *obj = NULL;
583     generatedCodeObject *prev = NULL;
584
585     while ((obj = cfgIter++)) {
586         // If we're a relocInsn, see if there's a new pre or post
587         // tramp. If so, stick it in line.
588         // If we've been replaced (replacedInstruction), then swap the
589         // relocInsn for the replacedInstruction
590
591         // If we're the last thing in a chain (of which there may be many),
592         // add a trampEnd if there isn't already one.
593         if (!obj->fallthrough_) {
594             trampEnd *end = dynamic_cast<trampEnd *>(obj);
595
596             // Should have been added in initial generation.
597             assert(end);
598         }
599         
600         relocatedCode *c = dynamic_cast<relocatedCode *>(obj);
601         if (!c) {
602             prev = obj;
603             continue;
604         }
605             
606         const relocatedInstruction *insn = c->relocInsn();
607         assert(insn);
608
609         Address insnAddr = insn->fromAddr_;
610         instPoint *instP = func()->findInstPByAddr(insnAddr);
611         if (!instP) {
612             // There's no instPoint for here, so there's (by definition)
613             // no instrumentation/replacement
614             prev = obj;
615             continue;
616         }            
617
618         baseTramp *preBT = instP->preBaseTramp();
619         
620         if (preBT) {
621             baseTrampInstance *preBTI = preBT->findOrCreateInstance(this);
622             assert(preBTI);
623             // Now insert this guy in line. If it's already there, cool; 
624             // otherwise set the regen flag.
625             if (prev) {
626                 if (prev != preBTI) {
627                     prev->setFallthrough(preBTI);
628                     preBTI->setFallthrough(obj);
629                     preBTI->setPrevious(prev);
630                     obj->setPrevious(preBTI);
631                     changedSinceLastGeneration_ = true;
632                 }
633                 else {
634                     assert(prev->fallthrough_ == obj);
635                 }
636             }
637             else {
638                 // Previous is NULL: we're the first insn. Bump the CFG
639                 // code and set next
640                 generatedCFG_.setStart(preBTI);
641                 preBTI->setFallthrough(obj);
642                 obj->setPrevious(preBTI);
643                 changedSinceLastGeneration_ = true;
644             }
645         }
646
647         baseTramp *postBT = instP->postBaseTramp();
648
649         if (postBT) {
650             baseTrampInstance *postBTI = postBT->findOrCreateInstance(this);
651             assert(postBTI);
652
653             // Append to us.
654             if (obj->fallthrough_ != postBTI) {
655                 postBTI->setFallthrough(obj->fallthrough_);
656                 obj->fallthrough_->setPrevious(postBTI);
657                 obj->setFallthrough(postBTI);
658                 postBTI->setPrevious(obj);
659
660                 changedSinceLastGeneration_ = true;
661             }
662         }
663
664         baseTramp *targetBT = instP->targetBaseTramp();
665
666         if (targetBT) {
667             baseTrampInstance *targetBTI = targetBT->findOrCreateInstance(this);
668             assert(targetBTI);
669             // Set target
670             if (obj->target_) {
671                 assert(obj->target_ == targetBTI);
672             }
673             else {
674                 targetBTI->setPrevious(obj);
675                 obj->setTarget(targetBTI);
676                 // And a tramp end marker goes here as well.
677                 Address origTarget = insn->originalTarget();
678                 targetBTI->setFallthrough(new trampEnd(this, origTarget));
679                 targetBTI->fallthrough_->setPrevious(targetBTI);
680                 changedSinceLastGeneration_ = true;
681             }
682         }
683
684         // See if we've been replaced....
685         AstNodePtr replacedAST = instP->replacedCode_;
686         replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
687         if (ri) assert(replacedAST != AstNodePtr()); // We don't un-replace yet...
688         
689         if ((replacedAST != AstNodePtr()) && (ri == NULL)) {
690             // We've been asked to replace the current instruction...
691             replacedInstruction *newRI = new replacedInstruction(insn, 
692                                                                  replacedAST,
693                                                                  instP,
694                                                                  this);
695             assert(newRI);
696
697             if (obj->previous_ == NULL) {
698                // We were the first thing in the CFG, so 
699                // replace that with newRI
700                generatedCFG_.setStart(newRI);
701             }
702
703             // And now swap into line...
704             newRI->setPrevious(obj->previous_);
705             newRI->setFallthrough(obj->fallthrough_);
706             newRI->setTarget(obj->target_);
707
708             // We can't be the target - only base tramps can be a target...
709             if (newRI->previous_) 
710                 newRI->previous_->setFallthrough(newRI);
711             if (newRI->fallthrough_)
712                 newRI->fallthrough_->setPrevious(newRI);
713             if (newRI->target_)
714                 newRI->target_->setPrevious(newRI);
715
716             cfgIter.find(generatedCFG_, 
717                          newRI);
718             // We stepped back one...
719             cfgIter++;
720             prev = newRI; 
721             continue;
722         }        
723         prev = obj;
724     }
725
726     updateInsnDict();
727
728 }
729
730 // Whaddya know, on IA-64 multiTramps can overlap basic blocks (which can
731 // start inside of bundles). Argh.
732
733 multiTramp::multiTramp(Address addr,
734                        unsigned size,
735                        int_function *func) :
736     generatedCodeObject(),
737     id_(id_ctr++),
738     instAddr_(addr),
739     trampAddr_(0),
740     trampSize_(0),
741     instSize_(size),
742     branchSize_(0),
743     usedTrap_(false),
744     func_(func),
745     proc_(func->proc()),
746     insns_(addrHash4),
747     previousInsnAddrs_(NULL),
748     generatedMultiT_(),
749     savedCodeBuf_(NULL),
750 #if defined( cap_unwind )
751     unwindInformation(NULL),    
752 #endif /* defined( cap_unwind ) */    
753     changedSinceLastGeneration_(false),
754     trampEnd_(NULL),
755     isActive_(false),
756     partlyGone_(false),
757     stompMulti_(NULL)
758 {
759     // .. filled in by createMultiTramp
760     assert(proc());
761     proc()->addMultiTramp(this);
762     mal_printf("new multi id=%d instAddr=%lx func %lx[%lx]\n",
763                id_,instAddr_,func_->ifunc()->getOffset(),
764                func_->get_address());
765     // find the base address at which the function relocation is created, the
766     // first block, in address order, is the first to be laid out in the 
767     // relocated function, it shouldn't be possible for the function to have 
768     // been updated since then, so there can't be new blocks that are not part 
769     // of the relocation, an assertion makes sure that this is the case 
770     int_basicBlock *firstBlock = func_->findBlockByAddr(func_->getAddress());
771     funcBaseInMutatee_ = 
772         firstBlock->instVer( firstBlock->numInstances()-1 )->firstInsnAddr();
773 }
774
775
776 // "Copy" constructor; for in-place replacements.
777 multiTramp::multiTramp(multiTramp *oM) :
778     generatedCodeObject(),
779     id_(oM->id_),
780     instAddr_(oM->instAddr_),
781     trampAddr_(0),
782     trampSize_(0),
783     instSize_(oM->instSize_),
784     branchSize_(0),
785     usedTrap_(false),
786     func_(oM->func_),
787     proc_(oM->proc_),
788     insns_(addrHash4),
789     previousInsnAddrs_(NULL),
790     generatedMultiT_(), // Not copied
791     jumpBuf_(), // Not copied
792     savedCodeBuf_(NULL),
793 #if defined( cap_unwind )
794     unwindInformation(NULL),    
795 #endif /* defined( cap_unwind ) */    
796     changedSinceLastGeneration_(true),
797     trampEnd_(NULL),
798     isActive_(false),
799     partlyGone_(false),
800     funcBaseInMutatee_(oM->funcBaseInMutatee_),
801     stompMulti_(NULL)
802 {
803     // This is superficial and insufficient to recreate the multiTramp; please
804     // call replaceCode with the old tramp as an argument.
805 }
806
807 // Fork constructor.
808 multiTramp::multiTramp(const multiTramp *parMulti, process *child) :
809     generatedCodeObject(parMulti, child),
810     id_(parMulti->id_),
811     instAddr_(parMulti->instAddr_),
812     trampAddr_(parMulti->trampAddr_),
813     trampSize_(parMulti->trampSize_),
814     instSize_(parMulti->instSize_),
815     branchSize_(parMulti->branchSize_),
816     usedTrap_(parMulti->usedTrap_),
817     func_(NULL),
818     proc_(child),
819     insns_(addrHash4),
820     previousInsnAddrs_(NULL),
821     generatedMultiT_(parMulti->generatedMultiT_),
822     jumpBuf_(parMulti->jumpBuf_),
823     savedCodeBuf_(NULL),
824 #if defined( cap_unwind )
825     unwindInformation(NULL),    
826 #endif /* defined( cap_unwind ) */    
827     changedSinceLastGeneration_(parMulti->changedSinceLastGeneration_),
828     trampEnd_(),
829     isActive_(false),
830     partlyGone_(false),
831     funcBaseInMutatee_(parMulti->funcBaseInMutatee_),
832     stompMulti_(NULL)
833 {
834     // TODO:
835     // Copy logical state: insns_ and generatedCFG;
836     // Copy savedCode. 
837     
838     if (parMulti->savedCodeBuf_) {
839         savedCodeBuf_ = malloc(instSize_);
840         memcpy(savedCodeBuf_, parMulti->savedCodeBuf_, instSize_);
841     }
842
843     func_ = child->findFuncByAddr(instAddr_);
844     assert(func_);
845
846     // Get the CFG.
847     
848     generatedCFG_ = generatedCFG_t(parMulti->generatedCFG_, this, child);
849
850     // Now that the CFG is right, we get insns
851     updateInsnDict();
852
853     child->addOrigRange(this);
854
855     // And we should not have been replacing a previous one and had a fork
856     // hit...
857     assert(parMulti->previousInsnAddrs_ == NULL);
858 }
859
860 ////////////
861
862 // To avoid mass include inclusion
863 int_function *multiTramp::func() const { return func_; }
864
865 AddressSpace *multiTramp::proc() const { return proc_; }
866
867 int fooDebugFlag = 0;
868
869 // Some debuggers don't stop at lines very well.
870 void debugBreakpoint() {
871     fooDebugFlag = 1;
872 }
873
874 // Generate the code for a multiTramp
875 // baseInMutator: a pointer to the local copy of a basic block
876 // baseInMutatee: basic block address
877 // offset: offset into the two above.
878 // Since we out-line multiTramps (effectively), we write
879 // a jump into the inputs.
880 bool multiTramp::generateCode(codeGen & /*jumpBuf...*/,
881                               Address /*baseInMutatee*/,
882                               UNW_INFO_TYPE * * /* ignored */) 
883 {
884     if (!hasChanged() && generated_) {
885         // We don't actually use the input code generator yet;
886         // if we go entirely inlined we will.
887         //assert(gen.currAddr(baseInMutatee) == instAddr_);
888         //gen.moveIndex(instSize_);
889         assert(generatedMultiT_.used() > 0);
890         return true;
891     }
892
893     unsigned size_required = 0;
894
895     generatedCFG_t::iterator cfgIter;
896     generatedCodeObject *obj = NULL;
897
898     inst_printf("Generating multiTramp from addr 0x%lx\n",
899                 instAddr_);
900
901     // We might be getting called but nothing changed...
902     if (!generated_) {
903         /*      this is part of the code to ensure that when we add the call to dlopen
904                 at the entry of main on AIX during save the world, any multi that was
905                 already there gets regenerated
906         */
907         assert(!trampAddr_);
908         assert(generatedMultiT_ == NULL);
909         assert(jumpBuf_ == NULL);
910         
911         // A multiTramp is the code sequence for a set of instructions in
912         // a basic block and all baseTramps, etc. that are being used for
913         // those instructions. We use a recursive code generation
914         // technique: for each item in the insns_ vector, generate the
915         // preTramp (if it exists), relocate the instruction, and generate
916         // the postTramp or targetTramp (if they exist). As an
917         // optimization, we don't double-generate base tramps; if
918         // consecutive instructions are instrumented, only one baseTramp
919         // will be generated between them.
920         
921         // We use a vector of instructions to support our iterative
922         // generation technique:
923         // 1) Generate representation of all instructions and tramps
924         // 2) Given offsets for generated code, fix any branches that need it.
925         // 3) Determine the size of the generated code
926         // 4) Allocate memory in the mutatee
927         // 5) Given the final address (determined in step 4), check to see if the
928         //   final code size changes; if retry and repeat.
929         
930         // We use a vector of a vector of instructions. Each instruction
931         // vector represents a single logical stream of instructions,
932         // whether a base tramp or a relocated instruction. All of these
933         // combined represent the multitramp. This multi-level system
934         // allows us to modify instructions easily if necessary.
935         // That part is TODO, btw.
936
937         // Code generation is easy. Iterate through the generatedCFG
938         // object. Fallthrough happens naturally; if there's a target,
939         // pin it in place (which guarantees that it will be generated at that
940         // address) and set the jump.
941
942         // First, we determine how much space we need.
943
944         cfgIter.initialize(generatedCFG_);
945         while ((obj = cfgIter++)) {
946             // If we're the target for someone, pin at this
947             // addr. This means some wasted space; however, it's
948             // easier and allows us to generate in one pass.
949             
950 #if !defined(cap_noaddr_gen)
951             if (obj->previous_ &&
952                 obj->previous_->target_ == obj) {
953                 // We're a target for somebody.
954                 obj->pinnedOffset = size_required;
955             }
956 #endif
957             
958             // Then update the size
959             size_required += obj->maxSizeRequired();
960             //inst_printf("... %d bytes, total %d\n",
961             //obj->maxSizeRequired(), size_required);
962         }
963         // We never re-use multiTramps
964         assert(!trampAddr_);
965
966         inferiorHeapType heapToUse = anyHeap;
967 #if defined(os_aix) && defined(bug_aix_broken_fork)
968         // We need the base tramp to be in allocated heap space, not scavenged
969         // text space, because scavenged text space is _not_ copied on fork.
970         // Argh.
971         if (func()->prettyName() == "__fork") {
972             heapToUse = (inferiorHeapType) (textHeap | dataHeap); // not uncopiedHeap
973         }
974 #endif
975
976         trampAddr_ = proc()->inferiorMalloc(size_required,
977                                             heapToUse,
978                                             instAddr_);
979         inst_printf("%s[%d]: inferiorMalloc returned %x\n", FILE__, __LINE__, trampAddr_);
980         if (!trampAddr_) {
981             fprintf(stderr, "Failed to inferiorMalloc, ret false\n");
982             return false;
983         }
984         generatedMultiT_.allocate(size_required);
985         generatedMultiT_.setAddrSpace(proc());
986         generatedMultiT_.setAddr(trampAddr_);
987         generatedMultiT_.setFunction(func());
988
989         // We don't want to generate the jump buffer until after
990         // we've done the multiTramp; we may need to know
991         // where instructions got moved to if we trap-fill.
992     }
993     else {
994         assert(!changedSinceLastGeneration_);
995         assert(generatedMultiT_ != NULL);
996         assert(jumpBuf_ != NULL);
997         assert(trampAddr_);
998         
999         // We go through the motions again to give everyone
1000         // a chance to say "I need to do something"
1001         size_required = trampSize_;
1002     }
1003     
1004     if (!generated_) {
1005         jumpBuf_.allocate(instSize_);
1006         jumpBuf_.setAddrSpace(proc());
1007
1008         // We set this = true before we call generateBranchToTramp
1009         generated_ = true;
1010         if (!generateBranchToTramp(jumpBuf_)) {
1011             inst_printf("%s[%d]: MT %p needs reloc, can't install\n", 
1012                         __FILE__, __LINE__, this);
1013             return false;
1014         }
1015     }
1016     
1017     
1018     generatedMultiT_.setIndex(0);
1019
1020     UNW_INFO_TYPE **unwind_region = NULL; 
1021 #if defined( cap_unwind )
1022         /* Initialize the unwind information structure. */
1023         if( unwindInformation != NULL ) { free( unwindInformation ); }
1024     unwindInformation = (unw_dyn_info_t *)calloc( 1, sizeof( unw_dyn_info_t ) );
1025     assert( unwindInformation != NULL );
1026     
1027     unwindInformation->format = UNW_INFO_FORMAT_DYNAMIC;
1028     unwindInformation->prev = NULL;
1029     unwindInformation->next = NULL;
1030     
1031     unwindInformation->u.pi.name_ptr = (unw_word_t) "dynamic instrumentation";
1032     unwindInformation->u.pi.handler = (Address) NULL;
1033     
1034     /* Generate the initial region, and then link it in.  This way,
1035        we can pass around a region pointer reference. */
1036     unw_dyn_region_info_t * initialRegion = (unw_dyn_region_info_t *)malloc( _U_dyn_region_info_size( 2 ) );
1037     assert( initialRegion != NULL );
1038     
1039     /* Special format for point ALIAS: a zero-length region. */
1040     initialRegion->insn_count = 0;
1041     initialRegion->op_count = 2;
1042     initialRegion->next = NULL;
1043     
1044     dyn_unw_printf( "%s[%d]: aliasing multitramp to 0x%lx\n", __FILE__, __LINE__, instAddr_ );
1045     _U_dyn_op_alias( & initialRegion->op[0], _U_QP_TRUE, -1, instAddr_ );
1046     _U_dyn_op_stop( & initialRegion->op[1] );
1047     
1048     unwindInformation->u.pi.regions = initialRegion;
1049     
1050     /* For the iterator, below. */
1051     unwind_region = &initialRegion;
1052 #endif /* defined( cap_unwind ) */
1053             
1054     //Call ::generate(...) for each object
1055     generateCodeWorker(size_required, unwind_region);
1056
1057     trampSize_ = generatedMultiT_.used();
1058
1059     // Free up some of that memory...
1060     proc()->inferiorRealloc(trampAddr_, trampSize_);
1061     generatedMultiT_.finalize();
1062
1063     // Now that we know where we're heading, see if we can put in 
1064     // a jump
1065     assert(instAddr_);
1066     assert(instSize_);
1067
1068     changedSinceLastGeneration_ = false;
1069     
1070     //debugBreakpoint();
1071    
1072     return true;
1073 }
1074
1075 #if defined(cap_noaddr_gen)
1076 bool multiTramp::generateCodeWorker(unsigned size_required, 
1077                                     UNW_INFO_TYPE **unwind_region)
1078 {
1079    generatedCFG_t::iterator cfgIter;
1080    generatedCodeObject *obj = NULL;
1081    
1082    inst_printf("address-less generation: local %p, remote 0x%x, size %d\n",
1083                generatedMultiT_.start_ptr(), trampAddr_, size_required);
1084    
1085    cfgIter.initialize(generatedCFG_);
1086    obj = NULL;
1087    while ((obj = cfgIter++)) {
1088       // Target override if necessary
1089       if (obj->target_) {
1090          relocatedInstruction *relocInsn = dynamic_cast<relocatedInstruction *>(obj);
1091          assert(relocInsn);
1092          relocInsn->overrideTarget(obj->target_);
1093       }
1094       generatedMultiT_.setObj(obj);
1095       if( ! obj->generateCode( generatedMultiT_, trampAddr_, unwind_region ) ) {
1096          return false;
1097       }
1098       assert(obj->generated());
1099       // Safety...
1100       assert(generatedMultiT_.used() <= size_required);
1101    }
1102
1103    generatedMultiT_.applyPCRels(trampAddr_);
1104    return true;
1105 }
1106 #else
1107 bool multiTramp::generateCodeWorker(unsigned size_required, 
1108                                     UNW_INFO_TYPE **unwind_region)
1109 {
1110    generatedCFG_t::iterator cfgIter;
1111    generatedCodeObject *obj = NULL;
1112    
1113    inst_printf("multiTramp generation: local %p, remote 0x%x, size %d\n",
1114                generatedMultiT_.start_ptr(), trampAddr_, size_required);
1115    
1116    cfgIter.initialize(generatedCFG_);
1117    obj = NULL;
1118    while ((obj = cfgIter++)) {
1119       if (obj->pinnedOffset) {
1120          // We need to advance the pointer, backfilling
1121          // with noops (or illegals, actually)
1122          // This won't do anything if we're in the right place
1123          assert(generatedMultiT_.used() <= obj->pinnedOffset);
1124          
1125          inst_printf("... NOOP-filling to %d, currently %d\n",
1126                      obj->pinnedOffset, generatedMultiT_.used());
1127          generatedMultiT_.fill(obj->pinnedOffset - generatedMultiT_.used(),
1128                                codeGen::cgNOP);
1129          assert(generatedMultiT_.used() == obj->pinnedOffset);
1130       }
1131         
1132       // Target override if necessary
1133       toAddressPatch override(0);
1134       if (obj->target_) {
1135          relocatedInstruction *relocInsn = dynamic_cast<relocatedInstruction *>(obj);
1136          assert(relocInsn);
1137          override.set_address(obj->target_->pinnedOffset + trampAddr_);
1138          relocInsn->overrideTarget(&override);
1139       }
1140       
1141       generatedMultiT_.setObj(obj);
1142       if( ! obj->generateCode( generatedMultiT_, trampAddr_, unwind_region ) ) {
1143          return false;
1144       }
1145       assert(obj->generated());
1146       // Safety...
1147       assert(generatedMultiT_.used() <= size_required);
1148    }
1149    return true;
1150 }
1151 #endif
1152
1153 bool multiTramp::installCode() {
1154    inst_printf("%s[%d]: installing multiTramp 0x%lx to 0x%lx\n",
1155                FILE__, __LINE__, instAddr_, instAddr_ + instSize_);
1156     // We need to add a jump back and fix any conditional jump
1157     // instrumentation
1158     assert(generatedMultiT_.used() == trampSize_); // Nobody messed with things
1159     assert(generated_);
1160
1161     // Try to branch to the tramp, but if we can't use a trap
1162     if (branchSize_ > instSize_)  {
1163         // Crud. Go with traps.
1164         jumpBuf_.setIndex(0);
1165         if (!generateTrapToTramp(jumpBuf_)) {
1166            inst_printf("%s[%d]: \t failed to generate trap to tramp, ret false\n",
1167                        FILE__, __LINE__);
1168            return false;
1169         }
1170     }
1171     fillJumpBuf(jumpBuf_);
1172
1173     if (!installed_) {
1174         inst_printf("Copying multitramp (inst 0x%lx to 0x%lx) from 0x%p to 0x%lx, %d bytes\n",
1175                     instAddr_, instAddr_+instSize_, generatedMultiT_.start_ptr(), trampAddr_, trampSize_);
1176
1177         bool success = proc()->writeTextSpace((void *)trampAddr_,
1178                                               trampSize_,
1179                                               generatedMultiT_.start_ptr());
1180         if( success ) {
1181             proc()->addOrigRange(this);
1182 #if defined( cap_unwind )
1183             static bool warned_buggy_libunwind = false;
1184             if( unwindInformation != NULL ) {
1185                 unwindInformation->start_ip = trampAddr_;
1186                 unwindInformation->end_ip = trampAddr_ + trampSize_;
1187                 unwindInformation->gp = proc()->proc()->getTOCoffsetInfo( instAddr_ );
1188             
1189                 dyn_unw_printf( "%s[%d]: registering multitramp unwind information for 0x%lx, at 0x%lx-0x%lx, GP 0x%lx\n",
1190                                 __FILE__, __LINE__, instAddr_, unwindInformation->start_ip, unwindInformation->end_ip,
1191                                 unwindInformation->gp );
1192                     if( ! proc()->proc()->insertAndRegisterDynamicUnwindInformation( unwindInformation ) ) 
1193                     {
1194                         if(!warned_buggy_libunwind)
1195                         {
1196                             std::cerr << "Insertion of unwind information via libunwind failed; stack walks outside of instrumented areas may not behave as expected" << std::endl;
1197                             warned_buggy_libunwind = true;
1198                         }
1199                     }
1200             }
1201 #endif /* defined( cap_unwind ) */
1202         }
1203         else { return false; }
1204     }
1205
1206
1207     generatedCFG_t::iterator cfgIter(generatedCFG_);
1208     generatedCodeObject *obj = NULL;
1209     
1210     while ((obj = cfgIter++)) {
1211         obj->installCode();
1212     }
1213     
1214     installed_ = true;
1215     return true;
1216 }
1217
1218 // The multitramp has been installed; now actually put the jump
1219 // in. Also has the fun job of relocating the PC to the new tramp (if
1220 // possible).
1221
1222 bool multiTramp::linkCode() {
1223
1224     inst_printf("%s[%d]: Entering multiTramp::linkCode (%p)\n",
1225                 FILE__, __LINE__, this);
1226
1227     // Relocation should be done before this is called... not sure when though.
1228
1229     // We may already be linked in, and getting called because of a regeneration.
1230     // 
1231     // First, copy out where we're going
1232     assert(installed_);
1233
1234     assert(jumpBuf_.used() == instSize_);
1235     inst_printf("Linking multiTramp 0x%lx to 0x%lx, to 0x%lx to 0x%lx\n",
1236                 instAddr_, instAddr_ + instSize_,
1237                 trampAddr_, trampAddr_ + trampSize_);
1238     if (!linked_) {
1239         codeRange *prevRange = proc()->findModByAddr(instAddr_);
1240         if (prevRange != NULL) {
1241             
1242             inst_printf("%s[%d]: this address already modified: %p (cur) %p (prev)\n",
1243                         FILE__, __LINE__, this, prevRange);
1244
1245             // Someone's already here....
1246             if (prevRange->is_function_replacement()) {
1247                 // Don't install here, just dummy-return true
1248                 inst_printf("Linking at function replacement, skip, ret true\n");
1249                 return true;
1250             }
1251             else if (prevRange->is_replaced_call()) {
1252                 // TODO
1253                 fprintf(stderr, "ERROR: instrumentation stomping on replaced call!\n");
1254                 return true;
1255             }
1256             else if (prevRange->is_multitramp()) {
1257                 inst_printf("%s[%d]: previous range was multiTramp, overwriting\n",
1258                             FILE__, __LINE__);
1259                 // This is okay...
1260             }
1261             else {
1262                 fprintf(stderr, "ERROR: instrumentation stomping on something unknown!\n");
1263                 return true;
1264             }
1265         }
1266         if (!savedCodeBuf_) {
1267             // We may have an old version's savedCode.
1268             
1269             savedCodeBuf_ = malloc(instSize_);
1270             if (!proc()->readTextSpace((void *)instAddr_,
1271                                        instSize_,
1272                                        savedCodeBuf_)) {
1273             }
1274         }
1275         if (!proc()->writeTextSpace((void *)instAddr_,
1276                                     instSize_,
1277                                     jumpBuf_.start_ptr())) {
1278            fprintf(stderr, "ERROR: failed to write %d to 0x%lx\n",
1279                    instSize_, instAddr_);
1280            return false;
1281         }
1282         linked_ = true;
1283     }
1284
1285     // Time to stomp old multiTramps with traps...
1286     if (previousInsnAddrs_ && BPatch::bpatch->isMergeTramp()) {
1287         codeGen gen(16); // Overkill, it's either 1, 4, or 16.
1288         insnCodeGen::generateTrap(gen);
1289
1290         for (unsigned i = 0; i < previousInsnAddrs_->size(); i++) {
1291             pdpair<Address, Address> addrs = (*previousInsnAddrs_)[i];
1292             Address uninst = addrs.first;
1293             Address oldMultiAddr = addrs.second;
1294
1295             if (oldMultiAddr == 0) continue;
1296             if (!insns_.find(uninst)) {
1297                 assert(0);
1298             }
1299             Address newMultiAddr = insns_[uninst]->relocAddr();
1300             
1301             if (!proc()->writeTextSpace((void *)oldMultiAddr,
1302                                         gen.used(),
1303                                         gen.start_ptr())) {
1304                 fprintf(stderr, "ERROR: failed to write %d to %p\n",
1305                         gen.used(), gen.start_ptr());
1306                 return false;
1307             }
1308             proc()->trapMapping.addTrapMapping(oldMultiAddr, newMultiAddr, false);
1309         }
1310
1311         delete previousInsnAddrs_;
1312         previousInsnAddrs_ = NULL;
1313     }
1314
1315
1316     generatedCFG_t::iterator cfgIter(generatedCFG_);
1317     generatedCodeObject *obj = NULL;
1318     
1319     while ((obj = cfgIter++)) {
1320         obj->linkCode();
1321         assert(obj->linked());
1322     }
1323
1324     inst_printf("%s[%d]: returning true from multiTramp::linkCode (%p)\n",
1325                 FILE__, __LINE__, this);
1326     return true;
1327 }
1328
1329 // And a wrapper for the above
1330 multiTramp::mtErrorCode_t multiTramp::linkMultiTramp() {
1331     inst_printf("%s[%d]: multiTramp::linkMultiTramp(%p)\n",
1332                 FILE__, __LINE__, this);
1333
1334     // We can call generate, return an error, then call install anyway.
1335     if (!installed_) {
1336         inst_printf("%s[%d]: multiTramp::linkMultiTramp(%p): not installed, ret mtError\n",
1337                     FILE__, __LINE__, this);
1338         return mtError;
1339     }
1340
1341     assert(!hasChanged()); // since we generated code...
1342
1343     if (linkCode()) {
1344         inst_printf("%s[%d]: multiTramp::linkMultiTramp(%p): linked, ret mtSuccess\n",
1345                     FILE__, __LINE__, this);
1346         return mtSuccess;
1347     }
1348     else {
1349         inst_printf("%s[%d]: multiTramp::linkMultiTramp(%p): failed linko, ret mtError\n",
1350                     FILE__, __LINE__, this);
1351         return mtError;
1352     }
1353 }
1354
1355 multiTramp::mtErrorCode_t multiTramp::installMultiTramp() {
1356
1357     // We can call generate, return an error, then call install anyway.
1358     if (!generated_) return mtError;
1359
1360     assert(!hasChanged()); // Since we generated code...
1361
1362     // See if there is enough room to fit the jump in... then
1363     // decide whether to go ahead or not.
1364
1365     if (installCode()) {
1366       return mtSuccess;
1367     }
1368     else {
1369         return mtError;
1370     }
1371 }
1372
1373 bool multiTramp::enable() {
1374     if (!linked_)
1375         return true;
1376     // Copy in the jumpBuf. Like linkCode
1377     assert(jumpBuf_.used() == instSize_);
1378     
1379     if (!proc()->writeTextSpace((void *)instAddr_,
1380                                 jumpBuf_.used(),
1381                                 jumpBuf_.start_ptr())) 
1382         return false;
1383     return true;
1384 }
1385
1386
1387 bool multiTramp::disable() {
1388     // This could also be "whoops, not ready, skip"
1389     if (!linked_) {
1390         return true;
1391     }
1392
1393     assert(savedCodeBuf_);
1394
1395     bblInstance *bbi = func()->proc()->findOrigByAddr(instAddr_)->
1396         is_basicBlockInstance();
1397     if (bbi && 0 == bbi->version()) {
1398         void *objPtr = func()->obj()->getPtrToInstruction(instAddr_);
1399         if (memcmp(objPtr,savedCodeBuf_,instSize_)) {
1400             mal_printf("WARNING: different bytes in the mappedFile and "
1401                 "multiTramp's saved code buf [%lx %lx], either the code was "
1402                 "overwritten or there's a bug %s[%d]\n",instAddr_,
1403                 instAddr_ + instSize_, FILE__, __LINE__);
1404         }
1405         if (!proc()->writeTextSpace((void *)instAddr_,
1406                                     instSize_,
1407                                     objPtr))
1408             return false;
1409     } 
1410     else {
1411     if (!proc()->writeTextSpace((void *)instAddr_,
1412                                 instSize_,
1413                                 savedCodeBuf_))
1414         return false;
1415     }
1416     return true;
1417 }
1418
1419
1420 Address multiTramp::instToUninstAddr(Address addr) {
1421     if ((addr < trampAddr_) ||
1422         addr > (trampAddr_ + trampSize_))
1423         // Possibly an assert fail? 
1424         return addr;
1425
1426     // Okay, there's two possibilities: we're at an instruction, or
1427     // we're in a base tramp. If we're at an instruction, figure out
1428     // its offset in the original function, add to "uninstAddr_", and
1429     // we're done. If we're in a base tramp, then set it as the _next_
1430     // instruction.
1431
1432     generatedCFG_t::iterator cfgIter(generatedCFG_);
1433     generatedCodeObject *obj = NULL;
1434     
1435     while ((obj = cfgIter++)) {
1436         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
1437         baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
1438         trampEnd *end = dynamic_cast<trampEnd *>(obj);
1439         replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
1440
1441         if (insn && 
1442             (addr >= insn->relocAddr()) &&
1443             (addr < insn->relocAddr() + insn->get_size()))
1444         {
1445             // in exploratory mode, the function relocation may
1446             // have been invalidated due to new code discovery;
1447             // we may have to return the origAddr instead
1448             if (proc()->findBasicBlockByAddr(insn->fromAddr_)) {
1449                 return insn->fromAddr_;
1450             } else {
1451                 return insn->origAddr_;
1452             }
1453         }
1454         if (ri && 
1455             (addr >= ri->get_address()) &&
1456             (addr < ri->get_address() + ri->get_size()))
1457             return ri->uninstrumentedAddr();
1458
1459         if (bti && bti->isInInstance(addr)) {
1460             // If we're pre for an insn, return that;
1461             // else return the insn we're post/target for.
1462             baseTramp *baseT = bti->baseT;
1463             instPoint *point = baseT->instP();
1464             assert(point);
1465
1466             for (unsigned i = 0; i < point->instances.size(); i++) {
1467                 // We check by ID instead of pointer because we may
1468                 // have been replaced by later instrumentation, but 
1469                 // are still being executed.
1470                 if (point->instances[i]->multiID() == id_)
1471                     return point->addr();
1472             }
1473             // No match: bad data structures.
1474             fprintf(stderr, "ERROR: data structures corrupted!\n");
1475             fprintf(stderr, "Looking for 0x%lx\n", addr);
1476             fprintf(stderr, "multiTramp %p reports being 0x%lx to 0x%lx, from 0x%lx to 0x%lx in orig func\n",
1477                     this, trampAddr_, trampAddr_ + trampSize_, instAddr_, instAddr_ + instSize_);
1478             if ( !func()->obj()->isExploratoryModeOn() ) {
1479                 assert(0);
1480             } else {
1481                 // this can happen when a multitramp is marked as active 
1482                 // and the isntrumentation has been removed
1483                 // assert(0);
1484                 return point->addr();
1485             }
1486         }
1487         if (end) {
1488             // Ah hell. 
1489             // Umm... see if we're in the size_ area
1490             if ((end->addrInMutatee_ <= addr) &&
1491                 (addr < (end->addrInMutatee_ + end->size_))) {
1492                 return end->target();
1493             }
1494         }
1495     }
1496
1497     // Ran out of iterator... 
1498     for (unsigned i = 0; i < deletedObjs.size(); i++) {
1499         obj = deletedObjs[i];
1500         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
1501         baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
1502         trampEnd *end = dynamic_cast<trampEnd *>(obj);
1503         replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
1504
1505         if (ri && 
1506             (addr >= ri->get_address()) &&
1507             (addr < ri->get_address() + ri->get_size()))
1508             return ri->uninstrumentedAddr();
1509
1510         if (insn && 
1511             (addr >= insn->relocAddr()) &&
1512             (addr < insn->relocAddr() + insn->get_size()))
1513             return insn->fromAddr_;
1514         if (bti && bti->isInInstance(addr)) {
1515             // If we're pre for an insn, return that;
1516             // else return the insn we're post/target for.
1517             baseTramp *baseT = bti->baseT;
1518             instPoint *point = baseT->instP();
1519             assert(point);
1520
1521             return point->addr();
1522             // We used to check by instances... thing is, we can remove instances
1523             // and still be running inside that instrumentation.
1524
1525         }
1526         if (end) {
1527             // Ah hell. 
1528             // Umm... see if we're in the size_ area
1529             if ((end->addrInMutatee_ <= addr) &&
1530                 (addr < (end->addrInMutatee_ + end->size_))) {
1531                 return end->target();
1532             }
1533         }
1534     }
1535
1536     // Assert: we should never reach here
1537
1538     // DEBUGGING TIME! Break it down...
1539     
1540     generatedCFG_t::iterator debugIter(generatedCFG_);
1541
1542     fprintf(stderr, "ERROR: Multitramp address mapping for addr 0x%lx not found!\n",
1543             addr);
1544
1545     fprintf(stderr, "First pointer in internal CFG: %p\n",
1546             generatedCFG_.start());
1547
1548     while ((obj = debugIter++)) {
1549         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
1550         baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
1551         trampEnd *end = dynamic_cast<trampEnd *>(obj);
1552         replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
1553
1554         if (ri) {
1555             fprintf(stderr, "Replaced instruction from 0x%lx to 0x%lx\n",
1556                     ri->get_address(),
1557                     ri->get_address() + ri->get_size());
1558         }
1559         if (insn) {
1560             fprintf(stderr, "Relocated instruction from 0x%lx to 0x%lx\n",
1561                     insn->relocAddr(), insn->relocAddr() + insn->get_size());
1562         }
1563         if (bti)
1564             fprintf(stderr, "Base tramp instance from 0x%lx to 0x%lx\n",
1565                     bti->trampPreAddr(),
1566                     bti->trampPostAddr() + bti->restoreEndOffset);
1567         if (end) {
1568             fprintf(stderr, "Tramp end from 0x%lx to 0x%lx\n",
1569                     end->addrInMutatee_,
1570                     end->addrInMutatee_ + end->size_);
1571         }
1572     }
1573
1574     // Ran out of iterator... 
1575     fprintf(stderr, "Checking %lu deleted objects\n", (unsigned long) deletedObjs.size());
1576     for (unsigned i = 0; i < deletedObjs.size(); i++) {
1577         obj = deletedObjs[i];
1578         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
1579         baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
1580         trampEnd *end = dynamic_cast<trampEnd *>(obj);
1581         replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
1582
1583         if (ri) {
1584             fprintf(stderr, "<DELETED> Replaced instruction from 0x%lx to 0x%lx\n",
1585                     ri->get_address(),
1586                     ri->get_address() + ri->get_size());
1587         }
1588
1589         if (insn) {
1590             fprintf(stderr, "<DELETED> Relocated instruction from 0x%lx to 0x%lx\n",
1591                     insn->relocAddr(), insn->relocAddr() + insn->get_size());
1592         }
1593         if (bti)
1594             fprintf(stderr, "<DELETED> Base tramp instance from 0x%lx to 0x%lx\n",
1595                     bti->trampPreAddr(),
1596                     bti->trampPostAddr() + bti->restoreEndOffset);
1597         if (end) {
1598             fprintf(stderr, "<DELETED> Tramp end from 0x%lx to 0x%lx\n",
1599                     end->addrInMutatee_,
1600                     end->addrInMutatee_ + end->size_);
1601         }
1602     }
1603
1604     assert(0);
1605     return 0;
1606 }
1607
1608 instPoint *multiTramp::findInstPointByAddr(Address addr) {
1609     // Like the instToUninst above; but this time find the
1610     // closest instPoint that we're in. If we're in a baseTramp
1611     // or relocatedInstruction it's easy. trampEnd goes to predecessor
1612     // if there is one. Returns NULL if we're in instrumentation
1613     // but not at an instPoint (i.e., if we're inside a basic block
1614     // but not at the instPoint).
1615
1616     generatedCFG_t::iterator cfgIter(generatedCFG_);
1617     generatedCodeObject *obj = NULL;
1618     
1619     while ((obj = cfgIter++)) {
1620         if ((obj->get_address() <= addr) &&
1621             (addr < (obj->get_address() + obj->get_size()))) {
1622             const relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
1623             baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
1624             trampEnd *end = dynamic_cast<trampEnd *>(obj);
1625             replacedInstruction *ri = dynamic_cast<replacedInstruction *>(obj);
1626             
1627             if (ri) {
1628                 // We can pull what we need out of oldInsn...
1629                 insn = ri->oldInsn_;
1630             }
1631             if (end) {
1632                 // We don't want the tramp end; so see if there is a previous
1633                 // base tramp or instruction
1634                 insn = dynamic_cast<relocatedInstruction *>(obj->previous_);
1635                 bti = dynamic_cast<baseTrampInstance *>(obj->previous_);
1636             }
1637             assert(insn || bti);
1638
1639             if (insn)
1640                 return func()->findInstPByAddr(addr);
1641             else if (bti) {
1642                 return bti->findInstPointByAddr(addr);
1643             }
1644         }
1645     }
1646     return NULL;
1647 }    
1648
1649 Address multiTramp::uninstToInstAddr(Address addr) {
1650     // The reverse of the above; given an original address,
1651     // find the matching addr in the multiTramp. However,
1652     // there's a bit of a catch -- if there's a preTramp,
1653     // relocate to there.
1654     
1655     if (addr < instAddr()) return 0;
1656     if (addr >= (instAddr() + instSize())) return 0;
1657
1658     assert(generated_);
1659
1660     relocatedCode *insn = NULL;
1661     while (!insns_.find(addr)) {
1662         addr--;
1663         if (addr < instAddr()) return trampAddr_;
1664     }
1665     
1666     insn = insns_[addr];
1667     
1668     if (!insn) {
1669         // This is expected
1670         return 0;
1671     }
1672     // Check for preTramp
1673     baseTrampInstance *pre = dynamic_cast<baseTrampInstance *>(insn->previous_);
1674     if (pre && pre->trampPreAddr()) {
1675         return pre->trampPreAddr();
1676     }
1677
1678     assert(insn->relocAddr());
1679     return insn->relocAddr();
1680 }
1681
1682 ////////////////////////////////////////////////////////////////////
1683 // Key methods
1684 ////////////////////////////////////////////////////////////////////
1685
1686 // This is the key multiTramp mechanism. It is reponsible for creating
1687 // a new (*) multiTramp structure and generating all necessary code
1688 // for the multiTramp, all relocated instructions, baseTramps, miniTramps,
1689 // and on down the line. There are several calling possibilities:
1690 // 
1691 // 1) This is the first time the multiTramp has been generated; we have
1692 //   a skeleton structure that needs to be filled out.
1693 // 2) The multiTramp was generated but not installed; we can throw away the
1694 //   work we've done and start over.
1695 // 3) The multiTramp was generated and installed, and we're doing it again.
1696 //   In this case, we actually make a new structure and keep the old one
1697 //   to track deletion. 
1698 //
1699 // In all cases, check whether the current multiTramp is current given the
1700 // instrumentation state. If not, regenerate the multiTramp; this may be
1701 // done in-place or via replacement.
1702
1703 multiTramp::mtErrorCode_t multiTramp::generateMultiTramp() 
1704 {
1705     updateInstInstances();
1706     if (hasChanged()) {
1707         if (linked_) {
1708             // We're in the process' address space; if we need to change the
1709             // multiTramp, we replace it. replaceMultiTramp takes care of
1710             // all that. 
1711             bool deleteReplaced = false;
1712             bool res = multiTramp::replaceMultiTramp(this, deleteReplaced);
1713             if (res) 
1714                 return mtSuccess;
1715             else
1716                 return mtError;
1717         }
1718         if (installed_ || generated_) {
1719             // Odd case... we generated, but never installed. Huh.
1720             invalidateCode();
1721         }
1722     }
1723     // TODO: generatedCodeObjects return booleans. We need a broader
1724     // error return type, probably #defines
1725     if (!generateCode(jumpBuf_, instAddr_, NULL))
1726         return mtError;
1727
1728     // Relocation...
1729     if (branchSize_ > instSize_)
1730         return mtTryRelocation;
1731
1732     return mtSuccess;
1733 }
1734
1735 void generatedCodeObject::invalidateCode() {
1736     assert(!linked_);
1737     pinnedOffset = 0;
1738     size_ = 0;
1739     addrInMutatee_ = 0;
1740     generated_ = false;
1741     installed_ = false;
1742 }
1743
1744 void multiTramp::invalidateCode() {
1745     generatedCodeObject::invalidateCode();
1746
1747     // Recursive...
1748     generatedCFG_t::iterator cfgIter(generatedCFG_);
1749     generatedCodeObject *obj = NULL;
1750     
1751     while ((obj = cfgIter++)) {
1752         obj->invalidateCode();
1753     }
1754     
1755     if (generatedMultiT_ != NULL) {
1756         generatedMultiT_.invalidate();
1757     }
1758     if (jumpBuf_ != NULL) {
1759         jumpBuf_.invalidate();
1760     }
1761
1762     if (savedCodeBuf_)
1763         free(savedCodeBuf_);
1764     savedCodeBuf_ = NULL;
1765
1766     if (trampAddr_) {
1767         // Allocated but never used; we can immediately delete
1768         proc()->inferiorFree(trampAddr_);
1769     }
1770
1771     trampAddr_ = 0;
1772     trampSize_ = 0;
1773
1774     generated_ = false;
1775     installed_ = false;
1776 }
1777
1778 // Return value: were we replaced with a new one.
1779 bool multiTramp::replaceMultiTramp(multiTramp *oldMulti, 
1780                                    bool &deleteReplaced) {
1781     // We in-line multiTramps; so deleteReplaced is always true.
1782     // It's a suggestion to the caller of what to do with the
1783     // old tramp, and can be ignored.
1784     deleteReplaced = false; // Set to false initially until there's
1785     // a new multiTramp
1786
1787     // Something has changed enough for us to care about it;
1788     // we have a multiTramp that is no longer up to date. So
1789     // fix. Two options: 1) we're actually okay due to changes
1790     // in out-of-line code; 2) we need to replace the current
1791     // multiTramp with a new one and generate it.
1792
1793     // Note: we need to leave the new multiTramp in the same condition
1794     // as the old one; if generated, generate; if installed, install;
1795     // If linked, link. The latter will get automatically handled
1796     // through calls to generateCode, installCode, and linkCode; 
1797     // all we have to do is make sure the data structures are set
1798     // up right.
1799
1800     if (oldMulti->proc()->findMultiTrampById(oldMulti->id())!= oldMulti)
1801     {
1802        //The old multitramp has already been unlinked and removed.
1803        //Don't bother doing the replacement.
1804        return true;
1805     }
1806     
1807     
1808     multiTramp *newMulti = dynamic_cast<multiTramp *>(oldMulti->replaceCode(NULL));
1809     assert(newMulti);
1810
1811     // newMulti either has copies of old data structures (all
1812     // generatedCodeObjects) or the originals, depending on which
1813     // is appropriate. Status flags are not copied; the new
1814     // tramp is neither generated nor linked.
1815     
1816     // Sub the new tramp into the old tramp:
1817     assert(newMulti->proc() == oldMulti->proc());
1818     AddressSpace *proc = oldMulti->proc();
1819     assert(proc->findMultiTrampById(oldMulti->id()) == oldMulti);
1820     assert(oldMulti->id() == newMulti->id());
1821     proc->addMultiTramp(newMulti);
1822
1823     // Generate/install/link; this could be redundant depending on
1824     // the next few calls, or we could be getting called from a
1825     // removed baseTramp.
1826
1827     bool res = false;
1828
1829     if (oldMulti->generated()) {
1830         // We don't want to just call generateMultiTramp; that's possibly
1831         // what called us.
1832         assert(newMulti->jumpBuf_ == NULL);
1833         res = newMulti->generateCode(newMulti->jumpBuf_,
1834                                      newMulti->instAddr_,
1835                                      NULL);
1836         if (!res) return false;
1837     }
1838     if (oldMulti->installed()) {
1839         res = newMulti->installCode();
1840         if (!res) return false;
1841     }
1842     if (oldMulti->linked()) {
1843
1844         // record info about the multi that we're stomping, if there is one
1845         if ( newMulti->previousInsnAddrs_ && 
1846              newMulti->previousInsnAddrs_->size() ) {
1847             oldMulti->stompMulti_ = newMulti;
1848             if (oldMulti->isActive_) {
1849                 newMulti->setIsActive(true);
1850                 newMulti->proc()->proc()->addActiveMulti(newMulti);
1851             }
1852         }
1853
1854         res = newMulti->linkCode();
1855         if (!res) return false;
1856     }
1857
1858     // Caller decides whether to remove the original version
1859     deleteReplaced = true;
1860     return true;
1861 }
1862
1863 generatedCodeObject *generatedCFG_t::copy_int(generatedCodeObject *obj, 
1864                                               generatedCodeObject *par,
1865                                               multiTramp *newMulti,
1866                                               pdvector<generatedCodeObject *> &unused) {
1867     generatedCodeObject *newObj = obj->replaceCode(newMulti);
1868
1869     if (newObj != obj) {
1870         int found_index = -1;
1871         for (unsigned int i = 0; i <unused.size(); ++i) {
1872            if (obj == unused[i]) {
1873               found_index = i;
1874               break;
1875            }
1876         }
1877         if (-1 == found_index) 
1878            unused.push_back(obj);
1879     }
1880
1881     newObj->setPrevious(par);
1882     if (obj->fallthrough_)
1883         newObj->setFallthrough(copy_int(obj->fallthrough_,
1884                                         newObj,
1885                                         newMulti,
1886                                         unused));
1887     if (obj->target_)
1888         newObj->setTarget(copy_int(obj->target_, 
1889                                    newObj,
1890                                    newMulti,
1891                                    unused));
1892     return newObj;
1893 }
1894
1895 generatedCodeObject *generatedCFG_t::fork_int(const generatedCodeObject *parObj, 
1896                                               generatedCodeObject *childPrev,
1897                                               multiTramp *childMulti,
1898                                               process *child) {
1899     // Since you can't do a virtual constructor...
1900     // Could add a fork() method to everyone, but I like the consistency of the
1901     // constructor(..., AddressSpace *) model.
1902     const baseTrampInstance *bti = dynamic_cast<const baseTrampInstance *>(parObj);
1903     const trampEnd *te = dynamic_cast<const trampEnd *>(parObj);
1904     const relocatedInstruction *ri = dynamic_cast<const relocatedInstruction *>(parObj);
1905     const replacedInstruction *repI = dynamic_cast<const replacedInstruction *>(parObj);
1906
1907     generatedCodeObject *childObj = NULL;
1908
1909     if (bti) {
1910         assert(!te);
1911         assert(!ri);
1912         assert(!repI);
1913         // We need to get the child baseTramp. We duck through an instPoint to
1914         // do so. We could also register all baseTramps with the process object,
1915         // but fork is infrequent and so can be expensive.
1916         baseTramp *parBT = bti->baseT;
1917         instPoint *cIP = NULL;
1918         baseTramp *childBT = NULL;
1919
1920         int_function *cFunc = childMulti->func();
1921         assert(cFunc);
1922
1923         cIP = cFunc->findInstPByAddr(parBT->instP()->addr());
1924         assert(cIP);
1925         
1926         // We split here... post and target show up as "pre" to the BT
1927         if (parBT->instP()->preBaseTramp() == parBT) 
1928           childBT = cIP->preBaseTramp();
1929         else if (parBT->instP()->postBaseTramp() == parBT)
1930           childBT = cIP->postBaseTramp();
1931         else if (parBT->instP()->targetBaseTramp() == parBT)
1932           childBT = cIP->targetBaseTramp();
1933         else 
1934           assert(0);
1935         
1936         assert(childBT);
1937         childObj = new baseTrampInstance(bti,
1938                                          childBT,
1939                                          childMulti,
1940                                          child);
1941     }
1942     else if (te) {
1943         assert(!bti);
1944         assert(!ri);
1945         assert(!repI);
1946         childObj = new trampEnd(te, childMulti, child);
1947         childMulti->setTrampEnd(*(trampEnd*) childObj);
1948     } 
1949     else if (ri) {
1950         assert(!bti);
1951         assert(!te);
1952         assert(!repI);
1953         childObj = new relocatedInstruction(ri, childMulti, child);
1954     }
1955     else if (repI) {
1956        assert(!bti);
1957        assert(!te);
1958        assert(!ri);
1959        childObj = new replacedInstruction(repI, childMulti, child);
1960     }
1961     else {
1962        assert(0);
1963     }
1964
1965     assert(childObj);
1966     
1967     assert(childObj->previous_ == NULL);
1968     assert(childObj->target_ == NULL);
1969     assert(childObj->fallthrough_ == NULL);
1970
1971                 
1972     childObj->setPrevious(childPrev);
1973     if (parObj->fallthrough_)
1974         childObj->setFallthrough(fork_int(parObj->fallthrough_,
1975                                           childObj,
1976                                           childMulti,
1977                                           child));
1978     if (parObj->target_)
1979         childObj->setTarget(fork_int(parObj->target_, 
1980                                      childObj,
1981                                      childMulti,
1982                                      child));
1983     return childObj;
1984 }
1985
1986 generatedCFG_t::generatedCFG_t(const generatedCFG_t &parCFG,
1987                                multiTramp *cMT,
1988                                process *child) {
1989     start_ = fork_int(parCFG.start_,
1990                       NULL,
1991                       cMT,
1992                       child);
1993 }
1994     
1995
1996 void generatedCFG_t::replaceCode(generatedCFG_t &oldCFG, multiTramp *newMulti,
1997                                  pdvector<generatedCodeObject *> &unused) {
1998     start_ = copy_int(oldCFG.start_, 
1999                       NULL,
2000                       newMulti,
2001                       unused);
2002 }
2003
2004 void generatedCFG_t::destroy() {
2005     start_ = NULL;
2006 }
2007
2008 void multiTramp::updateInsnDict() {
2009     generatedCFG_t::iterator cfgIter(generatedCFG_);
2010     generatedCodeObject *obj = NULL;
2011     while ((obj = cfgIter++)) {
2012         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
2013         if (insn){
2014             if (insns_.find(insn->fromAddr_))
2015                 assert(insns_[insn->fromAddr_] == insn);
2016             insns_[insn->fromAddr_] = insn;
2017         }
2018         replacedInstruction *replacement = dynamic_cast<replacedInstruction *>(obj);
2019         if (replacement) {
2020             insns_[replacement->oldInsn_->fromAddr_] = replacement;
2021         }            
2022     }
2023 }
2024
2025 // Make an appropriately deep copy, suitable for generating a new
2026 // multiTramp to replace the old. Also make suitable changes in the
2027 // old one setting up replacement (assuming buffers, that sort of thing).
2028 generatedCodeObject *multiTramp::replaceCode(generatedCodeObject *newParent) {
2029     // Don't handle a parent of a multiTramp yet...
2030     assert(newParent == NULL);
2031
2032     // We deep-copy since we represent different areas in memory. First:
2033     // make a new tramp
2034     multiTramp *newMulti = new multiTramp(this);
2035
2036     // We might hand over some of our objects to the new multiTramp;
2037     // and so the generatedCFG will not be legal after this. Make a
2038     // deletion vector to maintain the ones we have to get rid of.
2039     
2040     // This will hold everything; if the multiTramp pointer doesn't
2041     // change, then we can nuke it.
2042
2043     // Copy the generatedCFG CFG.    
2044     // Anything not reused is stuck in deletedObjs
2045     newMulti->generatedCFG_.replaceCode(generatedCFG_, newMulti, deletedObjs);
2046
2047     // Nuke ours, just in case
2048     generatedCFG_.destroy();
2049     
2050     // Update addrs
2051     newMulti->updateInsnDict();
2052
2053     newMulti->constructPreviousInsnList(this);
2054
2055     // Buffers: generatedMultiT_, savedCodeBuf_, and jumpBuf_.
2056     // generatedMultiT_ and jumpBuf_ are multiTramp specific.
2057     assert(newMulti->generatedMultiT_ == NULL);
2058     assert(newMulti->jumpBuf_ == NULL);
2059     // and savedCodeBuf_ we want to take
2060     newMulti->savedCodeBuf_ = savedCodeBuf_;
2061     savedCodeBuf_ = NULL;
2062
2063     partlyGone_ = true; // multi is being unlinked and replaced
2064
2065     // And final checking
2066     assert(newMulti->func_);
2067     assert(newMulti->proc_);
2068
2069     assert(newMulti->instAddr_);
2070     assert(newMulti->instSize_);
2071     assert(newMulti->trampAddr_ == 0);
2072     assert(newMulti->trampSize_ == 0);
2073
2074     return newMulti;
2075 }
2076
2077 void multiTramp::constructPreviousInsnList(multiTramp *oldMulti) {
2078     // Only if we're using merged tramps...
2079     if (!BPatch::bpatch->isMergeTramp())
2080         return;
2081
2082
2083     if (previousInsnAddrs_ == NULL) {
2084         previousInsnAddrs_ = new pdvector<pdpair<Address, Address> >();
2085     }
2086
2087     dictionary_hash_iter<Address, relocatedCode *> insnIter(oldMulti->insns_);
2088     Address uninstAddr;
2089     for (; insnIter; insnIter++) {
2090         uninstAddr = insnIter.currkey();
2091         
2092         const relocatedInstruction *oldRelocInsn = insnIter.currval()->relocInsn();
2093         
2094         assert(oldRelocInsn);
2095
2096         // Okay... we want (reloc addr in old multi), (reloc addr in new multi)
2097         Address oldAddr = oldRelocInsn->relocAddr();
2098
2099         if (!insns_.find(uninstAddr)) {
2100             // Existed in the old, not in the new?
2101             assert(0);
2102         }
2103
2104         previousInsnAddrs_->push_back(pdpair<Address, Address> (uninstAddr, oldAddr));
2105     }
2106 }
2107         
2108
2109
2110 bool multiTramp::hasChanged() {
2111     if (changedSinceLastGeneration_) {
2112         return true;
2113     }
2114     generatedCFG_t::iterator cfgIter(generatedCFG_);
2115     generatedCodeObject *obj = NULL;
2116     
2117     while ((obj = cfgIter++)) {
2118         if (obj->hasChanged()) {
2119             return true;
2120         }
2121     }
2122     return false;
2123 }
2124
2125 relocatedInstruction::relocatedInstruction(const relocatedInstruction *parRI,
2126                                            multiTramp *cMT,
2127                                            process *child) :
2128     relocatedCode(parRI, child),
2129     origAddr_(parRI->origAddr_),
2130     fromAddr_(parRI->fromAddr_),
2131     targetAddr_(parRI->targetAddr_),
2132     multiT(cMT),
2133     targetOverride_(parRI->targetOverride_)
2134 {
2135     insn = parRI->insn->copy();
2136 #if defined(arch_sparc)
2137     if (parRI->ds_insn)
2138         ds_insn = parRI->ds_insn;
2139     else
2140         ds_insn = NULL;
2141     if (parRI->agg_insn)
2142         agg_insn = parRI->agg_insn;
2143     else
2144         agg_insn = NULL;
2145 #endif
2146
2147 }
2148
2149
2150 generatedCodeObject *relocatedInstruction::replaceCode(generatedCodeObject *newParent) {
2151     // Since we are generated in-line, we return a copy
2152     // instead of ourselves.
2153     multiTramp *newMulti = dynamic_cast<multiTramp *>(newParent);
2154     assert(newMulti);
2155
2156     relocatedInstruction *newInsn = new relocatedInstruction(this,
2157                                                              newMulti);
2158     return newInsn;
2159 }
2160
2161 relocatedInstruction::~relocatedInstruction() {
2162     // We need to check if someone else grabbed these pointers... or reference
2163     // count. For now, _do not delete_ since someone else might have
2164     // grabbed the ptr
2165 }
2166
2167 trampEnd::trampEnd(const trampEnd *parEnd,
2168                    multiTramp *cMT,
2169                    process *child) :
2170     generatedCodeObject(parEnd, child),
2171     multi_(cMT),
2172     target_(parEnd->target_)
2173 {}
2174     
2175
2176 // Can end up copying this; return a new one.
2177 generatedCodeObject *trampEnd::replaceCode(generatedCodeObject *obj) {
2178     multiTramp *newMulti = dynamic_cast<multiTramp *>(obj);
2179     assert(newMulti);
2180     trampEnd *newTE = new trampEnd(newMulti, target_);
2181     newMulti->setTrampEnd(*newTE);
2182     return newTE;
2183 }
2184
2185 std::string generatedCodeObject::getTypeString() const
2186 {
2187   return "unknown";
2188 }
2189 std::string baseTrampInstance::getTypeString() const
2190 {
2191   return "a base tramp";
2192 }
2193 std::string relocatedInstruction::getTypeString() const
2194 {
2195   std::stringstream s;
2196   s << "relocated instruction from " << std::hex << fromAddr_;
2197   return s.str();
2198 }
2199 std::string trampEnd::getTypeString() const
2200 {
2201   return "tramp end";
2202 }
2203
2204
2205 // And the code iterator
2206
2207 generatedCodeObject *generatedCFG_t::iterator::operator++(int) {
2208     // If we've hit the bottom of our current stack, pop back and take
2209     // the target route. Otherwise fall through
2210     if (!cur_) return NULL; // Ended, just spin.
2211     
2212     if (cur_->target_) stack_.push_back(cur_->target_);
2213     
2214     if (cur_->fallthrough_) {
2215         if (cur_->fallthrough_->previous_ != cur_) {
2216             fprintf(stderr, "ERROR: broken list: %p->%p->%p != %p\n",
2217                     cur_, cur_->fallthrough_,
2218                     cur_->fallthrough_->previous_,
2219                     cur_);
2220             fprintf(stderr, "current is a %s\n", cur_->getTypeString().c_str());
2221             fprintf(stderr, "previous is a %s\n", cur_->previous_->getTypeString().c_str());
2222             if (cur_->previous_) 
2223                 fprintf(stderr, "Previous pointers: fallthrough %p, target %p\n",
2224                         cur_->previous_->fallthrough_,
2225                         cur_->previous_->target_);
2226             fprintf(stderr, "next is a %s\n", cur_->fallthrough_->getTypeString().c_str());
2227             fprintf(stderr, "next->previous is a %s\n", cur_->fallthrough_->previous_->getTypeString().c_str());
2228         }
2229         assert(cur_->fallthrough_->previous_ == cur_);
2230         cur_ = cur_->fallthrough_;
2231         return cur_->previous_;
2232     }
2233     else {
2234         generatedCodeObject *tmp;
2235         // See if there's anywhere else to go.
2236         tmp = cur_;
2237         if (stack_.size()) {
2238             cur_ = stack_.back();
2239             stack_.pop_back();
2240             return tmp;
2241         }
2242         else {
2243             cur_ = NULL;
2244             return tmp;
2245         }
2246     }
2247     return cur_;
2248 }
2249
2250 generatedCodeObject *generatedCFG_t::iterator::operator*() {
2251     return cur_;
2252 }
2253
2254 void generatedCFG_t::iterator::find(generatedCFG_t &cfg,
2255                                         generatedCodeObject *pointer) {
2256     // This sucks.... and is slow. Reason is we need to keep things synced.
2257     stack_.clear();
2258     cur_ = cfg.start_;
2259
2260     generatedCodeObject *tmp = NULL;
2261
2262     while (cur_ != pointer && cur_ != NULL)
2263         tmp = (*this)++;
2264     
2265     assert(cur_);
2266 }
2267
2268 void generatedCFG_t::iterator::initialize(generatedCFG_t &cfg) {
2269     stack_.clear();
2270     cur_ = cfg.start_;
2271 }
2272
2273
2274 // We don't want duplicates in the CFG, so if obj == this ignore
2275 generatedCodeObject *generatedCodeObject::setPrevious(generatedCodeObject *obj) {
2276     if (obj == this)
2277         return this;
2278     else {
2279         previous_ = obj;
2280         return obj;
2281     }
2282 }
2283
2284 // We don't want duplicates in the CFG, so if obj == this ignore
2285 generatedCodeObject *generatedCodeObject::setTarget(generatedCodeObject *obj) {
2286     if (obj == this)
2287         return this;
2288     else {
2289         target_ = obj;
2290         return obj;
2291     }
2292 }
2293
2294 // We don't want duplicates in the CFG, so if obj == this ignore
2295 generatedCodeObject *generatedCodeObject::setFallthrough(generatedCodeObject *obj) {
2296     if (obj == this)
2297         return this;
2298     else {
2299         fallthrough_ = obj;
2300         return obj;
2301     }
2302 }
2303
2304 bool generatedCodeObject::alreadyGenerated(codeGen &gen,
2305                                            Address baseInMutatee) {
2306     if (generated_) {
2307         if (gen.currAddr(baseInMutatee) != addrInMutatee_) {
2308             fprintf(stderr, "ERROR: current address 0x%p != previous address 0x%p\n",
2309                     (void *)gen.currAddr(baseInMutatee), (void *)addrInMutatee_);
2310         }
2311         assert(gen.currAddr(baseInMutatee) == addrInMutatee_);
2312         assert(size_);
2313         gen.moveIndex(size_);
2314         return true;
2315     }
2316     return false;
2317 }
2318
2319 bool generatedCodeObject::generateSetup(codeGen &gen,
2320                                         Address baseInMutatee) {
2321     addrInMutatee_ = gen.currAddr(baseInMutatee);
2322     return true;
2323 }
2324
2325 bool generatedCodeObject::objIsChild(generatedCodeObject *obj) {
2326     assert(this != NULL);
2327     // Recursive descent. First, base case:
2328     if (fallthrough_ &&
2329         (obj == fallthrough_))
2330         return true;
2331     if (target_ &&
2332         (obj == target_))
2333         return true;
2334     if (fallthrough_ &&
2335         fallthrough_->objIsChild(obj))
2336         return true;
2337     if (target_ &&
2338         target_->objIsChild(obj))
2339         return true;
2340     return false;
2341 }
2342
2343 bool multiTramp::catchupRequired(Address pc, miniTramp *newMT,
2344                                  bool active,
2345                                  codeRange *range) 
2346 {
2347     // range is optional, and might be NULL. It's provided to avoid
2348     // having to do two billion codeRange lookups
2349     if (range == NULL)
2350         range = proc()->findOrigByAddr(pc);
2351     // Oopsie...
2352     if (!range) assert(0);
2353
2354     if (BPatch::bpatch->isMergeTramp()) {
2355         // This is a shortcut. If we're doing mergeTramps, then we
2356         // know the miniTramp wasn't generated into this multitramp -
2357         // it couldn't have been. So we automatically need catchup.
2358         
2359         if (active) return true;
2360         // Otherwise: if we're at the starting address and not active,
2361         // then we're going to _return_ to this multiTramp - return false.
2362         assert(!active);
2363         if (pc == getAddress() ||
2364             pc == instAddr()) {
2365             // We're returning to this point...
2366             return false;
2367         }
2368         else
2369             return true;
2370     }
2371
2372     multiTramp *rangeMulti = range->is_multitramp();
2373     miniTrampInstance *rangeMTI = range->is_minitramp();
2374
2375     assert((rangeMulti != NULL) || (rangeMTI != NULL));
2376
2377     if (rangeMTI) {
2378
2379         catchup_printf("%s[%d]: in mini tramp...\n", FILE__, __LINE__);
2380         
2381         assert(rangeMTI->baseTI->multiT == this);
2382         
2383         // Check to see if we're at an equivalent miniTramp. If not, 
2384         // fall through
2385         if (rangeMTI->mini->instP() == newMT->instP()) {
2386             // This is easier
2387             catchup_printf("%s[%d]: mini tramp is for same instPoint, handing down\n",
2388                            FILE__, __LINE__);
2389             return miniTramp::catchupRequired(rangeMTI->mini, newMT, active);
2390         }
2391         else {
2392             rangeMulti = rangeMTI->baseTI->multiT;
2393             // And we need to fake the PC. Good thing
2394             // it's passed by value...
2395             // Pick the post address; doesn't really matter
2396             pc = rangeMTI->baseTI->trampPostAddr();
2397             catchup_printf("%s[%d]: mini tramp is for different instPoint, iterating with fake PC 0x%lx\n",
2398                            FILE__, __LINE__, pc);
2399         }
2400     }
2401
2402     
2403     assert(rangeMulti == this);
2404
2405
2406     // We're not in miniTramps (or have faked a PC). However, we can't safely do
2407     // a linear comparison because the multiTramp is a CFG -- if we've done 
2408     // branch instrumentation, then we need to check that.
2409     // We also need to worry about being in the baseTrampInstance... the easiest thing
2410     // to do is run through the CFG iterator. We could also codeRange this once
2411     // generation has hit. 
2412     
2413     generatedCFG_t::iterator cfgIter(generatedCFG_);
2414     generatedCodeObject *obj = NULL;
2415
2416     // This is probably overkill, but I want to get it right. Optimize later.
2417     generatedCodeObject *pcObj = NULL;
2418     // This is the baseTrampInstance for the new instrumentation.
2419     baseTrampInstance *newBTI = NULL;
2420     
2421     while ((obj = cfgIter++)) {
2422         relocatedInstruction *insn = dynamic_cast<relocatedInstruction *>(obj);
2423         baseTrampInstance *bti = dynamic_cast<baseTrampInstance *>(obj);
2424         trampEnd *end = dynamic_cast<trampEnd *>(obj);
2425
2426         // Check to see if we're at the instPoint
2427         if (insn && 
2428             (pc >= insn->relocAddr()) &&
2429             (pc < insn->relocAddr() + insn->get_size())) {
2430             pcObj = insn;
2431         }
2432         else if (bti) {
2433             // Can be either the instPoint or the original instruction,
2434             // so check both
2435             if (bti->isInInstance(pc)) {
2436                 pcObj = bti;
2437             }
2438             if (bti->baseT == newMT->baseT)
2439                 newBTI = bti;
2440         }
2441         else if (end) {
2442             if ((end->addrInMutatee_ <= pc) &&
2443                 (pc < (end->addrInMutatee_ + end->size_))) {
2444                 pcObj = end;
2445             }
2446         }
2447         if ((newBTI != NULL) &&
2448             (pcObj != NULL))
2449             break;
2450     }
2451
2452     assert(newBTI != NULL);
2453     assert(pcObj != NULL);
2454
2455     if (newBTI == pcObj) {
2456         // Argh....
2457         // If we're in pre-insn, then return false. Post-insn, return true
2458         assert(pc >= newBTI->trampPreAddr());
2459         if (pc < (newBTI->trampPreAddr() + newBTI->saveEndOffset))
2460             return false;
2461         if (pc >= newBTI->trampPostAddr())
2462             return true;
2463         assert(0);
2464     }
2465     else {
2466         // So we return true if we've already passed the point. 
2467         // So start with the BTI, and return true if the pcObj is
2468         // the child
2469         return newBTI->objIsChild(pcObj);
2470     }
2471
2472     assert(0);
2473     return false;
2474 }
2475
2476 bool relocatedInstruction::generateCode(codeGen &gen,
2477                                         Address baseInMutatee,
2478                                         UNW_INFO_TYPE ** /* unwindInformation*/ ) 
2479 {
2480   if( ! alreadyGenerated(gen, baseInMutatee) ) {
2481     generateSetup(gen, baseInMutatee);
2482
2483     // addrInMutatee_ == base for this insn
2484     toAddressPatch orig_target(0);
2485     patchTarget *target;
2486     if (!targetOverride_) {
2487        orig_target.set_address(originalTarget());
2488        target = &orig_target;
2489     }
2490     else {
2491        target = targetOverride_;
2492     }
2493
2494     if (!insnCodeGen::generate(gen,
2495                         *insn,
2496                         multiT->proc(),
2497                         origAddr_,
2498                         addrInMutatee_,
2499                         NULL, // fallthrough is not overridden
2500                         target))
2501     {
2502        // We use the override if present, otherwise the original target (which may be
2503        // overridden in function relocation....)
2504        fprintf(stderr, "WARNING: returned false from relocate insn "
2505                "(orig at 0x%lx, from 0x%lx, now 0x%lx)\n", 
2506                origAddr_, fromAddr_, addrInMutatee_);
2507        return false;
2508     }
2509
2510 #if defined(arch_sparc) 
2511     // We pin delay instructions.
2512     if (insn->isDCTI()) {
2513       if (ds_insn) {
2514         inst_printf("... copying delay slot\n");
2515         insnCodeGen::generate(gen,*ds_insn);
2516       }
2517       if (agg_insn) {
2518         inst_printf("... copying aggregate\n");
2519         insnCodeGen::generate(gen,*agg_insn);
2520       }
2521     }
2522 #endif
2523
2524     size_ = gen.currAddr(baseInMutatee) - addrInMutatee_;
2525     generated_ = true;
2526     hasChanged_ = false;
2527   } /* end code generation */
2528     
2529 #if defined( cap_unwind )
2530   /* FIXME: a relocated instruction could easily change the unwind state.
2531      IA64-specific: can we ALIAS into the middle of bundles?
2532      Generally, can a relocated instruction tell how far into a basic block (bundle) it is? */
2533   dyn_unw_printf( "%s[%d]: aliasing relocated instruction to 0x%lx\n", __FILE__, __LINE__, multiT->instAddr() );
2534   unw_dyn_region_info_t * aliasRegion = (unw_dyn_region_info_t *)malloc( _U_dyn_region_info_size( 2 ) );
2535   assert( aliasRegion != NULL );
2536   aliasRegion->insn_count = 0;
2537   aliasRegion->op_count = 2;
2538         
2539   _U_dyn_op_alias( & aliasRegion->op[0], _U_QP_TRUE, -1, multiT->instAddr() );
2540   _U_dyn_op_stop( & aliasRegion->op[1] );
2541      
2542   unw_dyn_region_info_t * relocatedRegion = (unw_dyn_region_info_t *)malloc( _U_dyn_region_info_size( 1 ) );
2543   assert( relocatedRegion != NULL );
2544     
2545   relocatedRegion->op_count = 1;
2546   _U_dyn_op_stop( & relocatedRegion->op[0] );
2547                 
2548   /* size_ is in bytes. */
2549 #if defined( arch_ia64 )
2550   relocatedRegion->insn_count = (size_ / 16) * 3;
2551 #else   
2552 #error How do I know how many instructions are in the jump region?
2553 #endif /* defined( arch_ia64 ) */
2554
2555   /* The care and feeding of pointers. */
2556   unw_dyn_region_info_t * prevRegion = * unwindInformation;
2557   prevRegion->next = aliasRegion;
2558   aliasRegion->next = relocatedRegion;
2559   relocatedRegion->next = NULL;
2560   * unwindInformation = relocatedRegion;
2561 #endif /* defined( cap_unwind ) */
2562   return true;
2563 }
2564
2565 bool multiTramp::fillJumpBuf(codeGen &gen) {
2566
2567     // We play a cute trick with the rest of the overwritten space: fill it with
2568     // traps. If one is hit, we can transfer the PC into the multiTramp without
2569     // further problems. Cute, eh?
2570     if (proc()->canUseTraps()) {
2571         while (gen.used() < instSize()) {
2572             Address origAddr = gen.currAddr(instAddr_);
2573             Address addrInMulti = uninstToInstAddr(origAddr);
2574             if (addrInMulti) {
2575                // addrInMulti may be 0 if our trap instruction does not
2576                // map onto a real instruction
2577                proc()->trapMapping.addTrapMapping(origAddr, addrInMulti, false);
2578             }
2579             insnCodeGen::generateTrap(gen);
2580         }
2581     }
2582     else {
2583         // Don't want to use traps, but we still need to fill
2584         // this up. So instead we use noops. 
2585         insnCodeGen::generateNOOP(gen, instSize() - gen.used());
2586     }
2587     return true;
2588 }
2589
2590
2591 /* Generate a jump to a base tramp. Return the size of the instruction
2592    generated at the instrumentation point. */
2593
2594 // insn: buffer to generate code
2595
2596 // Again, IA64 has its own version. TODO: can it use the same mechanism we use here?
2597 bool multiTramp::generateBranchToTramp(codeGen &gen)
2598 {
2599     assert(instAddr_);
2600     assert(trampAddr_);
2601     unsigned origUsed = gen.used();
2602
2603     // TODO: we can use shorter branches, ya know.
2604     unsigned long jumpSizeNeeded = instruction::jumpSize(instAddr_, trampAddr_,
2605                                                          proc()->getAddressWidth());
2606
2607     if (instSize_ <  jumpSizeNeeded) { // jumpSizeNeeded > 0...
2608         branchSize_ = jumpSizeNeeded;
2609         // Return value: do we continue making the tramp?
2610         // Yes... we'll just use a trap later
2611         return true;
2612     }
2613 #if defined(arch_sparc)
2614     int dist = (trampAddr_ - instAddr_);
2615     if (!instruction::offsetWithinRangeOfBranchInsn(dist) &&
2616         func()->is_o7_live()) {
2617         branchSize_ = (unsigned) -1;
2618         return true;
2619     }
2620 #endif
2621     insnCodeGen::generateBranch(gen, instAddr_, trampAddr_);
2622
2623     branchSize_ = gen.used() - origUsed;
2624
2625     return true;
2626 }
2627
2628 bool multiTramp::generateTrapToTramp(codeGen &gen) {
2629     if (!proc()->canUseTraps())  {
2630        inst_printf("%s[%d]: process cannot use traps, attempting to use trap, ret false\n", FILE__, __LINE__);
2631         return false;
2632     }
2633
2634     // We're doing a trap. Now, we know that trap addrs are reported
2635     // as "finished" address... so use that one (not instAddr_)
2636     proc()->trapMapping.addTrapMapping(gen.currAddr(instAddr_), trampAddr_, true);
2637     unsigned start = gen.used();
2638     insnCodeGen::generateTrap(gen);
2639     branchSize_ = gen.used() - start;
2640
2641     usedTrap_ = true;
2642
2643     inst_printf("TRAPPING TO TRAMP AT 0x%lx (%d bytes)\n", instAddr_, instSize_);
2644
2645     return true;
2646 }
2647
2648 void *multiTramp::getPtrToInstruction(Address addr) const {
2649     if (!installed_) return NULL;
2650     if (addr < trampAddr_) return NULL;
2651     if (addr >= (trampAddr_ + trampSize_)) return NULL;
2652
2653     addr -= trampAddr_;
2654     assert(generatedMultiT_ != NULL);
2655     return generatedMultiT_.get_ptr(addr);
2656 }
2657
2658 unsigned multiTramp::maxSizeRequired() {
2659     // A jump to the multiTramp, 
2660     return instruction::maxJumpSize(proc()->getAddressWidth());
2661 }
2662
2663 relocatedInstruction::relocatedInstruction(instruction *i,
2664                       Address o, Address f, Address t,
2665                       multiTramp *m) :
2666    relocatedCode(),
2667    insn(i),
2668 #if defined(arch_sparc)
2669    ds_insn(NULL),
2670    agg_insn(NULL),
2671 #endif
2672    origAddr_(o), 
2673    fromAddr_(f), 
2674    targetAddr_(t),
2675    multiT(m), 
2676    targetOverride_(NULL) 
2677 {
2678 }
2679
2680 relocatedInstruction::relocatedInstruction(relocatedInstruction *prev,
2681                                            multiTramp *m) :
2682    relocatedCode(),
2683    insn(prev->insn),
2684 #if defined(arch_sparc)
2685    ds_insn(prev->ds_insn),
2686    agg_insn(prev->agg_insn),
2687 #endif
2688    origAddr_(prev->origAddr_), fromAddr_(prev->fromAddr_),
2689    targetAddr_(prev->targetAddr_),
2690    multiT(m),
2691    targetOverride_(prev->targetOverride_) 
2692 {
2693 }
2694 #if defined(cap_instruction_api)
2695 relocatedInstruction::relocatedInstruction(const unsigned char* insnPtr, Address o, Address f, Address t,
2696                       multiTramp *m) :
2697    relocatedCode(),
2698 #if defined(arch_sparc)
2699    ds_insn(NULL),
2700    agg_insn(NULL),
2701 #endif
2702    origAddr_(o), 
2703    fromAddr_(f), 
2704    targetAddr_(t),
2705    multiT(m), 
2706    targetOverride_(NULL) 
2707 {
2708   const codeBuf_t *buf = reinterpret_cast<const codeBuf_t*>(insnPtr);
2709   insn = new instruction;
2710   insn->setInstruction(const_cast<codeBuf_t*>(buf), (Address)(o));
2711 }
2712 #endif
2713
2714 replacedInstruction::replacedInstruction(const relocatedInstruction *i,
2715                                          AstNodePtr ast,
2716                                          instPoint *p, 
2717                                          multiTramp *m) :
2718    relocatedCode(),
2719    oldInsn_(i),
2720    ast_(ast),
2721    point_(p),
2722    multiT_(m) 
2723 {
2724 }
2725
2726 replacedInstruction::replacedInstruction(replacedInstruction *prev,
2727                                          multiTramp *m) :
2728    relocatedCode(),
2729    oldInsn_(prev->oldInsn_),
2730    ast_(prev->ast_),
2731    point_(prev->point_),
2732    multiT_(m) 
2733 {
2734 }
2735
2736 generatedCodeObject *generatedCodeObject::nextObj()
2737 {
2738    if (fallthrough_)
2739       return fallthrough_;
2740    return target_;
2741 }
2742
2743 void trampEnd::changeTarget(Address newTarg) 
2744
2745     target_ = newTarg; 
2746 }
2747
2748 void multiTramp::setTrampEnd(trampEnd &newTramp)
2749 {
2750     trampEnd_ = &newTramp;
2751 }
2752
2753
2754 void multiTramp::updateTrampEnd(instPoint *point)
2755 {
2756     int_basicBlock * fallThroughB = point->block()->getFallthrough();
2757     if ( ! fallThroughB ) {
2758         return; // don't need to make any changes
2759     }
2760     assert( trampEnd_ ); // should exist if there's a fallthroughBlock
2761
2762     Address endTarget = trampEnd_->target(); // current target
2763
2764     // figure out the right target
2765     bblInstance * fallThroughBBI = fallThroughB->instVer( 
2766         fallThroughB->numInstances() -1 );
2767     if ( endTarget == fallThroughBBI->firstInsnAddr() ) {
2768         return; // no changes necessary
2769     }
2770     mal_printf("%s[%d] trampEnd at %lx in multi [%lx %lx]: target is %lx will "
2771             "point it to block originally at %lx"
2772             ", but now at %lx\n", FILE__,__LINE__,trampEnd_->get_address(), 
2773             addrInMutatee_, 
2774             addrInMutatee_ + get_size(), endTarget, 
2775             fallThroughB->origInstance()->firstInsnAddr(), 
2776             fallThroughBBI->firstInsnAddr() );
2777
2778     // trigger new code generation just for the trampEnd
2779     trampEnd_->changeTarget( fallThroughBBI->firstInsnAddr() );
2780     codeGen endGen(getAddress() + get_size() - trampEnd_->get_address());
2781     trampEnd_->generateCode(endGen, trampEnd_->get_address(), NULL);
2782     assert ( endGen.used() <= trampEnd_->get_size() );
2783
2784     // copy the newly generated code to the mutatee
2785     proc()->writeTextSpace((void*)trampEnd_->get_address(), 
2786                             trampEnd_->get_size(), 
2787                             endGen.start_ptr());
2788 }
2789
2790 void multiTramp::setIsActive(bool value) 
2791
2792     if (value != isActive_) {
2793         mal_printf("changing isactive to %d for multiTramp %lx [%lx %lx]\n",
2794                 value, instAddr_, trampAddr_, trampAddr_+trampSize_);
2795     }
2796     isActive_ = value; 
2797 }