Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / instPoint.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: instPoint.C,v 1.55 2008/09/08 16:44:03 bernat Exp $
33 // instPoint code
34
35
36 #include <assert.h>
37 #include "dyninstAPI/src/symtab.h"
38 #include "dyninstAPI/src/process.h"
39 #include "dyninstAPI/src/inst.h"
40 #include "dyninstAPI/src/instP.h"
41 #include "dyninstAPI/src/ast.h"
42 #include "dyninstAPI/src/util.h"
43 #include "common/h/stats.h"
44 #include "dyninstAPI/src/debug.h"
45 #include "dyninstAPI/src/instPoint.h"
46 #include "dyninstAPI/src/miniTramp.h"
47 #include "dyninstAPI/src/baseTramp.h"
48
49 #if defined(cap_instruction_api)
50 #include "instructionAPI/h/InstructionDecoder.h"
51 using namespace Dyninst::InstructionAPI;
52 #else
53 #include "dyninstAPI/src/InstrucIter.h"
54 #endif // defined(cap_instruction_api)
55
56 #include "dyninstAPI/src/function.h"
57 #include "dyninstAPI/src/image-func.h"
58 #include "dyninstAPI/src/arch.h"
59 #include "dyninstAPI/src/mapped_object.h"
60 #include "dyninstAPI/src/emitter.h"
61 #if defined(arch_x86_64)
62 // For 32/64-bit mode knowledge
63 #include "dyninstAPI/src/emit-x86.h"
64 #endif
65
66 unsigned int instPointBase::id_ctr = 1;
67
68 dictionary_hash <std::string, unsigned> primitiveCosts(::Dyninst::stringhash);
69
70 #if defined(rs6000_ibm_aix4_1)
71   extern void resetBRL(process *p, Address loc, unsigned val); //inst-power.C
72   extern void resetBR( process *p, Address loc);               //inst-power.C
73 #endif
74
75 miniTramp *instPoint::addInst(AstNodePtr ast,
76                               callWhen when,
77                               callOrder order,
78                               bool trampRecursive,
79                               bool noCost) {
80     // This only adds a new minitramp; code generation and any actual
81     // _work_ is put off until later.
82
83     baseTramp *baseT = getBaseTramp(when);
84     if (!baseT) return NULL;
85
86     // Will complain if we have multiple miniTramps that don't agree
87     baseT->setRecursive(trampRecursive);
88     
89     miniTramp *miniT = new miniTramp(when,
90                                      ast,
91                                      baseT,
92                                      noCost);
93     
94     assert (miniT);
95     
96     // Sets prev and next members of the mt
97     if (!baseT->addMiniTramp(miniT, order)) {
98         inst_printf("Basetramp failed to add miniTramp, ret false\n");
99         delete miniT;
100         return NULL;
101     }
102
103     hasAnyInstrumentation_ = true;
104     hasNewInstrumentation_ = true;
105     
106     return miniT;
107 }
108
109 bool instPoint::replaceCode(AstNodePtr ast) {
110     // We inject a "replacedInstruction" into all known multitramps,
111     // then trigger generation and installation.
112     
113     // Actually, the multiTramp is set up to pull information out
114     // of the instPoints (rather than "push"), so we set up our 
115     // data structures and let 'er rip.
116
117     replacedCode_ = ast;
118
119     // Set flags appropriately...
120     hasAnyInstrumentation_ = true;
121     hasNewInstrumentation_ = true;
122
123     pdvector<instPoint *> dontcare;
124
125     // The better way to do this would be to hand the "go!" logic
126     // back up to BPatch. However, this is a bigger change than I want
127     // to make right now...
128
129     return func()->performInstrumentation(false, dontcare);
130
131 #if 0    
132     if (!generateInst()) {
133         fprintf(stderr, "Code generation failed in replaceCode, ret false\n");
134         return false;
135     }
136
137     if (!installInst()) {
138         fprintf(stderr, "Code installation failed in replaceCode, ret false\n");
139         return false;
140     }
141
142     if (!linkInst()) {
143         fprintf(stderr, "Code link failed in replaceCode, ret false\n");
144         return false;
145     }
146
147     return true;
148 #endif
149 }
150
151 // Get the appropriate base tramp structure. Cannot rely on
152 // multiTramps existing.
153
154 baseTramp *instPoint::getBaseTramp(callWhen when) 
155 {
156         switch(when) {
157                 case callPreInsn:
158                         if (!preBaseTramp_) 
159                         {
160                                 preBaseTramp_ = new baseTramp(this, when);
161                         }
162                         return preBaseTramp_;
163                         break;
164                 case callPostInsn:
165                         if (!postBaseTramp_) 
166                         {
167                                 postBaseTramp_ = new baseTramp(this, when);
168                         }
169                         return postBaseTramp_;
170                         break;
171                 case callBranchTargetInsn:
172                         if (!targetBaseTramp_) 
173                         {
174                                 targetBaseTramp_ = new baseTramp(this, when);
175                         }
176                         return targetBaseTramp_;
177                         break;
178                 default:
179                         assert(0);
180                         break;
181         }
182         return NULL;
183 }
184
185 bool instPoint::match(Address a) const { 
186         if (a == addr()) return true;
187
188         for (unsigned i = 0; i < instances.size(); i++)
189                 if (instances[i]->addr() == a)
190                         return true;
191         return false;
192 }
193
194 instPoint *instPoint::createArbitraryInstPoint(Address addr, 
195                 AddressSpace *proc,
196                 int_function *func) 
197 {
198         // See if we get lucky
199         if (!func) 
200                 return NULL;
201
202         //Create all non-arbitrary instPoints before creating arbitrary ones.
203         func->funcEntries();
204         func->funcExits();
205         func->funcCalls();
206   
207   inst_printf("Creating arbitrary point at 0x%x\n", addr);
208   instPoint *newIP = func->findInstPByAddr(addr);
209   if (newIP) return newIP;
210
211   // Check to see if we're creating the new instPoint on an
212   // instruction boundary. First, get the instance...
213
214     bblInstance *bbl = func->findBlockInstanceByAddr(addr);
215     if (!bbl) {
216         inst_printf("Address not in known code, ret null\n");
217         fprintf(stderr, "%s[%d]: Address not in known code, ret null\n", FILE__, __LINE__);
218         return NULL;
219     }
220     int_basicBlock *block = bbl->block();
221     assert(block);
222
223     // Some blocks cannot be relocated; since instrumentation requires
224     // relocation of the block, don't even bother.
225     if(!block->llb()->canBeRelocated())
226     {
227         inst_printf("Address is in unrelocatable block, ret null\n");
228         return NULL;
229     }    
230
231     // For now: we constrain the address to be in the original instance
232     // of the basic block.
233     if (block->origInstance() != bbl) {
234         fprintf(stderr, "%s[%d]: Address not in original basic block instance\n", FILE__, __LINE__);
235         return NULL;
236     }
237 #if defined(cap_instruction_api)
238     const unsigned char* buffer = reinterpret_cast<unsigned char*>(proc->getPtrToInstruction(bbl->firstInsnAddr()));
239     InstructionDecoder decoder (buffer, bbl->getSize());
240     decoder.setMode(proc->getAddressWidth() == 8);
241     Instruction::Ptr i;
242     Address currentInsn = bbl->firstInsnAddr();
243     while((i = decoder.decode()) && (currentInsn < addr))
244     {
245         currentInsn += i->size();
246     }
247     if(currentInsn != addr)
248     {
249       inst_printf("Unaligned try for instruction iterator, ret null\n");
250       fprintf(stderr, "%s[%d]: Unaligned try for instruction iterator, ret null\n", FILE__, __LINE__);
251       return NULL; // Not aligned
252     }
253     newIP = new instPoint(proc,
254                           i,
255                           addr,
256                           block);
257 #if defined(arch_sparc)
258 #error "Instruction API not yet implemented for SPARC, cap_instruction_api is illegal"
259 #endif // defined(arch_sparc)
260 #else
261     InstrucIter newIter(bbl);
262     while ((*newIter) < addr) newIter++;
263     if (*newIter != addr) {
264         inst_printf("Unaligned try for instruction iterator, ret null\n");
265         fprintf(stderr, "%s[%d]: Unaligned try for instruction iterator at %lx (block start %lx), ret null\n", 
266                 FILE__, __LINE__, addr, bbl->firstInsnAddr());
267         return NULL; // Not aligned
268     }
269 #if defined(arch_sparc)
270     // Can't instrument delay slots
271     if (newIter.hasPrev()) {
272       InstrucIter prevInsn(newIter);
273       prevInsn--;      
274       if (prevInsn.getInstruction().isDCTI()) {
275         inst_printf("%s[%d]:  can't instrument delay slot\n", FILE__, __LINE__);
276         fprintf(stderr, "%s[%d]:  can't instrument delay slot\n", FILE__, __LINE__);
277         return NULL;
278       }
279     }
280 #endif // defined(arch_sparc)
281     newIP = new instPoint(proc,
282                           newIter.getInstruction(),
283                           addr,
284                           block);
285 #endif // defined(cap_instruction_api)
286     
287     if (!commonIPCreation(newIP)) {
288         delete newIP;
289         inst_printf("Failed common IP creation, ret null\n");
290         return NULL;
291     }
292     
293     func->addArbitraryPoint(newIP);
294
295     return newIP;
296 }
297  
298 bool instPoint::commonIPCreation(instPoint *ip) {
299     // Delay until generation....
300     //newIP->updateInstances();
301
302     // But tell people we exist.
303     ip->func()->registerInstPointAddr(ip->addr(), ip);
304
305     return true;
306 }
307
308 // We do on-the-fly generation of Instances... as a result, we may have
309 // versions of functions (frex, relocation) that do not have associated
310 // Instances. This function updates the Instance list and makes sure
311 // that everything works right.
312
313 bool instPoint::updateInstances() {
314     if (func()->version() == funcVersion)
315         return false;
316
317     // Otherwise there's work to do...
318
319     if (updateInstancesBatch()) 
320         updateInstancesFinalize();
321
322     return true;
323 }
324
325 // Create the instPoint data structures, but don't do any instrumentation
326 // setup. Returns true if there is further work to be done.
327
328 bool instPoint::updateInstancesBatch() {
329     unsigned i;
330
331     reloc_printf("updateInstancesBatch for instPoint at 0x%lx\n",
332                  addr());
333
334     if (func()->version() == funcVersion) {
335         reloc_printf(".... func version %d == our version %d, no work, returning\n",
336                      func()->version(), funcVersion);
337         return false;
338     }
339     else if (func()->version() < funcVersion) {
340         reloc_printf("DEBUG: func version %d, our version %d, block instances %d, our instances %d\n",
341                 func()->version(), funcVersion, 
342                 block()->instances().size(),
343                 instances.size());
344         const pdvector<bblInstance *> &bbls = block()->instances();
345         assert(bbls.size() <= instances.size());
346         for (unsigned i = instances.size(); i > bbls.size(); i--) {
347             instPointInstance *inst = instances[i-1];
348             instances.pop_back();
349             // Delete...
350             func()->unregisterInstPointAddr(inst->addr(), this);
351         }
352
353         // Safety check....
354         for (unsigned i = 0; i < instances.size(); i++) {
355             reloc_printf("%s[%d]: checking IPI block %p against block %p, entry %d\n",
356                          FILE__, __LINE__, instances[i]->block(), bbls[i], i);
357             assert(instances[i]->block() == bbls[i]);
358         }
359
360         funcVersion = func()->version();
361         return false;
362     }
363     else {
364         // For each instance of the basic block we're attached to,
365         // make an instPointInstance with the appropriate addr
366         // Might be smaller as well...
367         
368         const pdvector<bblInstance *> &bbls = block()->instances();
369         reloc_printf("Func version > our version, adding instances (us %d, func %d\n",
370                      bbls.size(), instances.size());
371         assert(instances.size() < bbls.size());
372         for (i = instances.size(); i < bbls.size(); i++) {
373             bblInstance *bblI = bbls[i];
374             
375             Address newAddr = bblI->equivAddr(block()->origInstance(), addr());
376
377             // However, check if we can do a multiTramp at this point (as we may have
378             // overwritten with a jump). If we can't, then skip the instance.
379             unsigned multiID_ = multiTramp::findOrCreateMultiTramp(newAddr, proc());
380             reloc_printf("... found multi ID %d for addl instance %d\n",
381                          multiID_, i);
382             if (multiID_) {
383                 instPointInstance *ipInst = new instPointInstance(newAddr,
384                                                                   bblI,
385                                                                   this);
386                 
387                 instances.push_back(ipInst);
388                 // Register with the process before asking for a multitramp
389                 inst_printf("Registering IP %p at 0x%lx (%d)\n",
390                             this, newAddr, i);
391                 func()->registerInstPointAddr(newAddr, this);
392             }
393         }
394         funcVersion = func()->version();
395         return true;
396     }
397     return false;
398 }
399
400 bool instPoint::updateInstancesFinalize() {
401     // We need all instances to stay in step; so if the first (default)
402     // instance is generated/installed/linked, then make sure any new
403     // instances are the same.
404     
405     // If we can't be instrumented - well, we shouldn't have an instPoint
406     // here, but oh well. Just return.
407     if (!instances.size()) return true;
408     
409     
410     // Check whether there's something at my address...
411     for (unsigned i = 0; i < instances.size(); i++) {
412         if (!instances[i]->multi()) {
413             instances[i]->multiID_ = multiTramp::findOrCreateMultiTramp(instances[i]->addr(),
414                                                                         proc());
415             if (instances[i]->multi()) {
416                 if (shouldGenerateNewInstances_) {
417                     instances[i]->multi()->generateMultiTramp();
418                 }
419                 if (shouldInstallNewInstances_) {
420                     instances[i]->multi()->installMultiTramp();
421                 }
422                 if (shouldLinkNewInstances_) {
423                     instances[i]->multi()->linkMultiTramp();
424                 }
425             }
426         }
427     }
428     return true;
429 }
430
431 // Blah blah blah...
432 miniTramp *instPoint::instrument(AstNodePtr ast,
433                                  callWhen when,
434                                  callOrder order,
435                                  bool trampRecursive,
436                                  bool noCost) {
437     miniTramp *mini = addInst(ast, when, order, trampRecursive, noCost);
438     if (!mini) {
439         cerr << "instPoint::instrument: failed addInst, ret NULL" << endl;
440         return NULL;
441     }
442
443     pdvector<instPoint *> ignored;
444     func()->performInstrumentation(false,
445                                    ignored);
446
447     // Obsolete version below... we now use function-level control.
448 #if 0
449     if (!generateInst()) {
450         cerr << "instPoint::instrument: failed generateInst, ret NULL" << endl;
451         return NULL;
452     }
453
454     if (!installInst()) {
455         cerr << "instPoint::instrument: failed installInst, ret NULL" << endl;
456         return NULL;
457     }
458
459     if (!linkInst()) {
460         cerr << "instPoint::instrument: failed linkInst, ret NULL" << endl;
461         return NULL;
462     }
463 #endif
464     return mini;
465 }
466
467 // Generate the correct code for all baseTramps touched by the
468 // miniTramps at this point. May cause regeneration of the multiTramps
469 // as well. Complicated.
470 // The code generated by this is explicitly _not_ injected into the process;
471 // that is, while it might be copied into the address space, it is not linked
472 // by any jumps. This allows for us to atomically add multiple different
473 // instPoints at the same time.
474
475 // Return value... we used to return false if any generation failed. However,
476 // if we relocate a function then generating into the entry point of the original
477 // will fail, and that's 'bad'. So we now return true if anyone succeeded.
478
479 // Generating the initial instance (for the original function) may trigger relocation
480 // of the function. So we special-case the first instance to determine whether relocation
481 // is necessary. It's possible that later instances will want relocation as well; however,
482 // this should only happen if the initial instance required it as well. 
483
484 instPoint::result_t instPoint::generateInst() {
485     stats_instru.startTimer(INST_GENERATE_TIMER);
486     stats_instru.incrementCounter(INST_GENERATE_COUNTER);
487     updateInstances();
488
489     bool desireRelocation = false;
490     bool success = false;
491     bool noMultiTramp = false;
492
493     for (unsigned i = 0; i < instances.size(); i++) {
494         switch (instances[i]->generateInst()) {
495         case instPointInstance::noMultiTramp:
496             // This can happen if there is another modification
497             // type at this location; this is only a failure
498             // if nothing else covers it.
499             noMultiTramp = true;
500             break;
501         case instPointInstance::instOfSharedBlock:
502             // We've instrumented a shared block, which is not desired.
503             // We want to force relocation of this function to ensure
504             // that we can remove the sharing. This may indirectly cause
505             // relocation of the sharing functions, but we don't care about
506             // that. 
507             desireRelocation = true;
508             break;
509         case instPointInstance::mTrampTooBig:
510             // We need to branch, but the branch is bigger than
511             // the block. Oops. 
512             // We don't do any work here; instead, we'll pass this up the
513             // chain and see how big the function needs to be from the function
514             // level.
515             desireRelocation = true;
516             break;
517         case instPointInstance::generateFailed:
518             break;
519         case instPointInstance::generateSucceeded:
520             success = true;
521             break;
522         case instPointInstance::pointPreviouslyModified:
523             // This case doesn't matter.
524             break;
525         default:
526             assert(0 && "Impossible case in switch"); 
527             break;
528         }
529     }
530     shouldGenerateNewInstances_ = true;
531     stats_instru.stopTimer(INST_GENERATE_TIMER);
532
533     if (noMultiTramp) assert(0);
534     if (desireRelocation) return tryRelocation;
535     if (success) return generateSucceeded;
536     return generateFailed;
537 }
538
539 // See above return value comment...
540
541 instPoint::result_t instPoint::installInst() {
542     stats_instru.startTimer(INST_INSTALL_TIMER);
543     stats_instru.incrementCounter(INST_INSTALL_COUNTER);
544     bool success = false;
545     bool noMT = false;
546     for (unsigned i = 0; i < instances.size(); i++) {
547         switch (instances[i]->installInst()) {
548         case instPointInstance::installSucceeded:
549             success = true;
550             break;
551         case instPointInstance::installFailed:
552             break;
553         case instPointInstance::noMultiTramp:
554             noMT = true;
555             break;
556         default:
557             assert(0);
558         }
559     }
560     shouldInstallNewInstances_ = true;
561     stats_instru.stopTimer(INST_INSTALL_TIMER);
562
563     if (success)
564         return installSucceeded;
565     else if (noMT)
566         return wasntGenerated;
567     else
568         return installFailed;
569 }
570
571 // Return false if the PC is within the jump range of any of our
572 // multiTramps
573 bool instPoint::checkInst(pdvector<Address> &checkPCs) 
574 {
575     
576     for (unsigned sI = 0; sI < checkPCs.size(); sI++) {
577         Address pc = checkPCs[sI];
578         for (unsigned iI = 0; iI < instances.size(); iI++) {
579             multiTramp *mt = instances[iI]->multi();
580             // No multi -> not installed.
581             if (!mt) continue;
582             if ((pc > mt->instAddr()) &&
583                 (pc < (mt->instAddr() + mt->instSize()))) {
584                 // We have a conflict. Now, we may still be able to make this 
585                 // work; if we're not conflicting on the actual branch, we
586                 // may have trap-filled the remainder which allows us to
587                 // catch and transfer.
588                 if (pc < (mt->instAddr() + mt->branchSize())) {
589                     // We're in the jump area, conflict.
590                     fprintf(stderr, "MT conflict (MT from 0x%p to 0x%p, 0x%p to 0x%p dangerous), PC 0x%p\n",
591                             (void *)mt->instAddr(),
592                             (void *)(mt->instAddr() + mt->instSize()), 
593                             (void *)mt->instAddr(),
594                             (void *)(mt->instAddr() + mt->branchSize()),
595                             (void *)pc);
596                     return false;
597                 }
598             }
599         }
600     }
601 #if defined(cap_relocation)
602     // Yay check relocation
603     if (!func()->relocationCheck(checkPCs))
604         return false;
605 #endif
606
607     return true;
608 }
609
610 // See comment in generateInst w.r.t. return value
611 //  If update_trap_table is true then update the mutatee's trap
612 //   table with any traps that we added.  We may not want to do
613 //   this yet if we're dealing with insertion sets, since large
614 //   updates are more efficient than smaller ones.
615 instPoint::result_t instPoint::linkInst(bool update_trap_table) {
616     bool success = false;
617     bool noMT = false;
618     stats_instru.startTimer(INST_LINK_TIMER);
619     stats_instru.incrementCounter(INST_LINK_COUNTER);
620
621     for (unsigned i = 0; i < instances.size(); i++) {
622         switch (instances[i]->linkInst()) {
623         case instPointInstance::linkSucceeded:
624             success = true;
625             break;
626         case instPointInstance::linkFailed:
627             break;
628         case instPointInstance::noMultiTramp:
629             noMT = true;
630             break;
631         default:
632             assert(0);
633         }
634     }
635
636     if (update_trap_table) {
637       proc()->trapMapping.flush();
638     }
639
640     shouldLinkNewInstances_ = true;
641
642     stats_instru.stopTimer(INST_LINK_TIMER);
643
644     // It's been installed, so nothing new.
645     hasNewInstrumentation_ = false;
646     
647     if (success)
648         return linkSucceeded;
649     else if (noMT)
650         return wasntInstalled;
651     else
652         return linkFailed;
653 }
654
655 instPointInstance *instPoint::getInstInstance(Address addr) {
656     for (unsigned i = 0; i < instances.size(); i++) {
657         if (instances[i]->addr() == addr)
658             return instances[i];
659     }
660     return NULL;
661 }
662
663 int instPoint_count = 0;
664
665 instPoint::instPoint(AddressSpace *proc,
666 #if defined(cap_instruction_api)
667     Dyninst::InstructionAPI::Instruction::Ptr insn,
668 #else                     
669                         instruction insn,
670 #endif
671                      Address addr,
672                      int_basicBlock *block) :
673     instPointBase(insn, otherPoint),
674     funcVersion(-1),
675     callee_(NULL),
676     isDynamic_(false),
677     preBaseTramp_(NULL),
678     postBaseTramp_(NULL),
679     targetBaseTramp_(NULL),
680     replacedCode_(),
681     proc_(proc),
682     img_p_(NULL),
683     block_(block),
684     addr_(addr),
685     shouldGenerateNewInstances_(false),
686     shouldInstallNewInstances_(false),
687     shouldLinkNewInstances_(false),
688     hasNewInstrumentation_(false),
689     hasAnyInstrumentation_(false)
690 {
691 #if defined(ROUGH_MEMORY_PROFILE)
692     instPoint_count++;
693     if ((instPoint_count % 10) == 0)
694         fprintf(stderr, "instPoint_count: %d (%d)\n",
695                 instPoint_count, instPoint_count*sizeof(instPoint));
696 #endif
697 }
698
699 // Process specialization of a parse-time instPoint
700 instPoint::instPoint(AddressSpace *proc,
701                      image_instPoint *img_p,
702                      Address addr,
703                      int_basicBlock *block) :
704     instPointBase(img_p->insn(),
705                   img_p->getPointType(),
706                   img_p->id()),
707     funcVersion(-1),
708     callee_(NULL),
709     isDynamic_(img_p->isDynamic()),
710     preBaseTramp_(NULL),
711     postBaseTramp_(NULL),
712     targetBaseTramp_(NULL),
713     replacedCode_(),
714      proc_(proc),
715     img_p_(img_p),
716     block_(block),
717     addr_(addr),
718     shouldGenerateNewInstances_(false),
719     shouldInstallNewInstances_(false),
720     shouldLinkNewInstances_(false),
721     hasNewInstrumentation_(false),
722     hasAnyInstrumentation_(false)
723 {
724 #if defined(ROUGH_MEMORY_PROFILE)
725     instPoint_count++;
726     if ((instPoint_count % 10) == 0)
727         fprintf(stderr, "instPoint_count: %d (%d)\n",
728                 instPoint_count, instPoint_count*sizeof(instPoint));
729 #endif
730 }
731
732 // Copying over from fork
733 instPoint::instPoint(instPoint *parP,
734                      int_basicBlock *child,
735                      process *childP) :
736     instPointBase(parP->insn(),
737                   parP->getPointType(),
738                   parP->id()),
739     funcVersion(parP->funcVersion),
740     callee_(NULL), // Will get set later
741     isDynamic_(parP->isDynamic_),
742     preBaseTramp_(NULL),
743     postBaseTramp_(NULL),
744     targetBaseTramp_(NULL),
745     replacedCode_(parP->replacedCode_),
746     proc_(childP),
747     img_p_(parP->img_p_),
748     block_(child),
749     addr_(parP->addr()),
750     shouldGenerateNewInstances_(parP->shouldGenerateNewInstances_),
751     shouldInstallNewInstances_(parP->shouldInstallNewInstances_),
752     shouldLinkNewInstances_(parP->shouldLinkNewInstances_),
753     hasNewInstrumentation_(parP->hasNewInstrumentation_),
754     hasAnyInstrumentation_(parP->hasAnyInstrumentation_)
755 {
756 }
757                   
758
759 instPoint *instPoint::createParsePoint(int_function *func,
760                                        image_instPoint *img_p) {    
761     // Now we need the addr and block so we can toss this to
762     // commonIPCreation.
763
764     inst_printf("Creating parse point for function %s, type %d\n",
765                 func->symTabName().c_str(),
766                 img_p->getPointType());
767
768
769     Address offsetInFunc = img_p->offset() - img_p->func()->getOffset();
770     Address absAddr = offsetInFunc + func->getAddress();
771
772     instPoint *newIP = func->findInstPByAddr(absAddr);
773         if (newIP) {
774                 fprintf(stderr, "WARNING: already have parsed point at addr 0x%lx\n",
775                         absAddr);
776                         return NULL;
777         }
778     inst_printf("Parsed offset: 0x%x, in func 0x%x, absolute addr 0x%x\n",
779                 img_p->offset(),
780                 offsetInFunc,
781                 absAddr);
782     
783     int_basicBlock *block = func->findBlockByAddr(absAddr);
784     if (!block) return false; // Not in the function...
785     assert(block);
786
787     newIP = new instPoint(func->proc(),
788                           img_p,
789                           absAddr,
790                           block);
791     
792     if (!commonIPCreation(newIP)) {
793         delete newIP;
794         return NULL;
795     }
796
797     return newIP;
798 }
799
800 instPoint *instPoint::createForkedPoint(instPoint *parP,
801                                         int_basicBlock *childB,
802                                         process *childP) {
803     int_function *func = childB->func();
804     instPoint *existingInstP = func->findInstPByAddr(parP->addr());
805     if (existingInstP) {
806        //One instPoint may be covering multiple instPointTypes, e.g.
807        // a one instruction function with an entry and exit point at
808        // the same point.
809        return existingInstP; 
810     }
811
812     // Make a copy of the parent instPoint. We don't have multiTramps yet,
813     // which is okay; just get the ID right.
814     instPoint *newIP = new instPoint(parP, childB, childP);
815
816     // Add to the process
817     if (parP->instances.size() == 0) {
818         // We created but never actually instrumented. However, 
819         // we still need to let the function know we exist, mimicing the
820         // behavior in commonIPcreation
821         func->registerInstPointAddr(newIP->addr(), newIP);
822     }
823     else {
824         for (unsigned i = 0; i < parP->instances.size(); i++) {
825             instPointInstance *pI = parP->instances[i];
826             instPointInstance *nI = new instPointInstance(pI->addr_,
827                                                           childB->instVer(i), 
828                                                           newIP);
829             // could also call childB->func()->findBlockInstance...
830             
831             nI->multiID_ = pI->multiID_;
832             newIP->instances.push_back(nI);
833             func->registerInstPointAddr(pI->addr_, newIP);
834         }
835     }
836
837     // And make baseTramp-age. If we share one, the first guy
838     // waits and the second guy makes, so we can be absolutely
839     // sure that we've made instPoints before we go trying to 
840     // make baseTramps.
841     
842     baseTramp *parPre = parP->preBaseTramp_;
843     if (parPre) {
844         assert(parPre->instP() == parP);
845         
846         newIP->preBaseTramp_ = new baseTramp(parPre, childP);
847         newIP->preBaseTramp_->instP_ = newIP;
848     }
849
850
851     baseTramp *parPost = parP->postBaseTramp_;
852     if (parPost) {
853         assert(parPost->instP() == parP);
854         
855         newIP->postBaseTramp_ = new baseTramp(parPost, childP);
856         newIP->postBaseTramp_->instP_ = newIP;
857     }
858
859     baseTramp *parTarget = parP->targetBaseTramp_;
860     if (parTarget) {
861         assert(parTarget->instP() == parP);
862
863         // Unlike others, can't share, so make now.
864         newIP->targetBaseTramp_ = new baseTramp(parTarget, childP);
865         newIP->targetBaseTramp_->instP_ = newIP;
866     }
867
868     return newIP;
869 }    
870     
871     
872 instPoint::~instPoint() {
873         for (unsigned i = 0; i < instances.size(); i++) {
874         delete instances[i];
875     }
876     instances.clear();
877     // callee isn't ours...
878     // multitramps will get deleted themselves...
879
880     
881
882     if (preBaseTramp_) delete preBaseTramp_;
883     if (postBaseTramp_) delete postBaseTramp_;
884     if (targetBaseTramp_) delete targetBaseTramp_;
885     
886 }
887
888
889
890 bool instPoint::instrSideEffect(Frame &frame)
891 {
892     bool modified = false;
893     
894     for (unsigned i = 0; i < instances.size(); i++) {
895         instPointInstance *target = instances[i];
896
897         // May not exist if instrumentation was overridden by (say)
898         // a relocated function.
899         if (!target->multi()) {
900             continue;
901         }
902         
903         // Question: generalize into "if the PC is in instrumentation,
904         // move to the equivalent address?" 
905         // Sure....
906         
907         // See previous call-specific version below; however, this
908         // _should_ work.
909
910         Address newPC = target->multi()->uninstToInstAddr(frame.getPC());
911         if (newPC) {
912             if (frame.setPC(newPC))
913                 modified = true;
914         }
915         // That's if we want to move into instrumentation. Mental note:
916         // check to see if we're handling return points correctly; we should
917         // be. If calls ever end basic blocks, we'll have to fix this.
918     }
919     return modified;
920 }
921
922 instPoint::catchup_result_t instPoint::catchupRequired(Address pc,
923                                                        miniTramp *mt,
924                                                        bool active) 
925 {
926     // If the PC isn't in a multiTramp that corresponds to one of
927     // our instances, return noMatch_c
928
929     // If the PC is in an older version of the current multiTramp,
930     // return missed
931     
932     // If we're in a miniTramp chain, then hand it off to the 
933     // multitramp.
934
935     // Otherwise, hand it off to the multiTramp....
936     codeRange *range = proc()->findOrigByAddr(pc);
937     assert(range);
938
939     multiTramp *rangeMT = range->is_multitramp();
940     miniTrampInstance *rangeMTI = range->is_minitramp();
941
942     if ((rangeMT == NULL) &&
943         (rangeMTI == NULL)) {
944         // We _cannot_ be in the jump footprint. So we missed.
945         catchup_printf("%s[%d]: Could not find instrumentation match for pc at 0x%lx\n",
946                        FILE__, __LINE__, pc);
947         //range->print_range(pc);
948         
949
950         return noMatch_c;
951     }
952
953     if (rangeMTI) {
954         // Back out to the multiTramp for now
955         rangeMT = rangeMTI->baseTI->multiT;
956     }
957
958     assert(rangeMT != NULL);
959
960     unsigned curID = rangeMT->id();
961
962     catchup_printf("%s[%d]: PC in instrumentation, multiTramp ID %d\n", 
963                    FILE__, __LINE__, curID);
964
965     bool found = false;
966     
967     for (unsigned i = 0; i < instances.size(); i++) {
968         catchup_printf("%s[%d]: checking instance %d against target %d\n",
969                        FILE__, __LINE__, instances[i]->multiID(), curID);
970         if (instances[i]->multiID() == curID) {
971             found = true;
972             // If not the same one, we replaced. Return missed.
973             if (instances[i]->multi() != rangeMT) {
974                 catchup_printf("%s[%d]: Found multiTramp, pointers different - replaced code, ret missed\n",
975                                FILE__, __LINE__);
976                 return missed_c;
977             }
978             else {
979                 // It is the same one; toss into low-level logic
980                 if (rangeMT->catchupRequired(pc, mt, active, range)) {
981                     catchup_printf("%s[%d]: Found multiTramp, instance returns catchup required, ret missed\n",
982                                    FILE__, __LINE__);
983                     return missed_c;
984                 }
985                 else {
986                     catchup_printf("%s[%d]: Found multiTramp, instance returns catchup unnecessary, ret not missed\n",
987                                    FILE__, __LINE__);                    
988                     return notMissed_c;
989                 }
990             }
991             break;
992         }
993     }
994     
995     assert(!found);
996
997     // This means we must be in an old multiTramp... possibly one on the deleted
998     // list due to replacement. Let's return that we missed.
999
1000     catchup_printf("%s[%d]: multiTramp instance not found, returning noMatch\n", FILE__, __LINE__);
1001
1002     return missed_c;
1003 }
1004
1005 int_basicBlock *instPoint::block() const { 
1006     assert(block_);
1007     return block_;
1008 }
1009
1010 int_function *instPoint::func() const {
1011     return block()->func();
1012 }
1013
1014 // allowTrap shouldn't really go here; problem is, 
1015 // multiple instPoints might use the same multiTramp,
1016 // and I'm not sure how to handle it.
1017 instPointInstance::result_t instPointInstance::generateInst() {
1018     // Do all the hard work; this will create a complete
1019     // instrumentation structure and copy it into the address
1020     // space, but not link it up. We do that later. It may also
1021     // change the multiTramp we have a pointer to, though that's
1022     // handled through the multi() wrapper.    
1023
1024     // Putting this in here for now...
1025     // We may be trying to instrument a point that was already modified
1026     // for another reason; in particular, a jump to a relocated function.
1027     // In this case we don't have a multiTramp, but we don't really
1028     // want one. I'm going to look that up here, since the state of the
1029     // data structures is _weird_ in this case. 
1030
1031     if (!multi()) {
1032         multiID_ = multiTramp::findOrCreateMultiTramp(addr(),
1033                                                       proc());
1034     }
1035     if (!multi()) {
1036         if (multiID_ != 0) {
1037             // Okay, we have a multiTramp ID, but nothing matching it. Check to see if someone
1038             // already got to our block.
1039             codeRange *range = proc()->findModByAddr(block()->firstInsnAddr());
1040             if (range) {
1041                 // See if it's a multiTramp
1042                 if (!proc()->findMultiTrampByAddr(block()->firstInsnAddr())) {
1043                     // We have a non-multitramp-thingie. Return that we're not
1044                     // generating, and why.
1045                     return instPointInstance::pointPreviouslyModified;
1046                 }
1047             }
1048         }
1049         return noMultiTramp;
1050     }
1051     multiTramp::mtErrorCode_t errCode = multi()->generateMultiTramp();
1052
1053     if (errCode == multiTramp::mtError) {
1054         return generateFailed;
1055     }
1056     // Can and will set our multiTramp ID if there isn't one already;
1057     // if there is, will reuse that slot in the multiTramp dictionary.
1058     // This allows us to regenerate multiTramps without having to 
1059     // worry about changing pointers.
1060
1061 #if defined(cap_relocation)
1062
1063     // We may need to relocate if either of the following is true:
1064     // 1) The block we instrumented is shared; we relocate to eliminate
1065     // the sharing.
1066     // 2) The branch to the tramp (e.g., "tramp size") is larger than
1067     // the block. 
1068     // 
1069     // Relocation is tricky to get right; in particular, we desire the following:
1070     // 1) Determine the relocation requirements of _all_ blocks in the function before
1071     // creating the prototype relocated function. This is an efficiency requirement.
1072     // 2) The state of all instances of an instPoint should be equivalent. 
1073     //
1074     // So we determine the relocation needs of the function here, and pass that
1075     // back to instPoint::generate; it can summarize the requirements for its
1076     // instances and hand that back up the chain. 
1077
1078     if (block_->block()->needsRelocation()) {
1079         // We're part of a shared block.
1080         return instOfSharedBlock;
1081     }
1082
1083     if (errCode == multiTramp::mtTryRelocation) {
1084         return mTrampTooBig;
1085     }
1086
1087 #endif
1088
1089     return generateSucceeded;
1090 }
1091
1092 instPointInstance::result_t instPointInstance::installInst() {
1093 #if 0
1094 #if defined(cap_relocation)
1095     // This is harmless to call if there isn't a relocation in-flight
1096
1097     reloc_printf("%s[%d]: instPointInstance calling relocationInstall for primary func %s\n",
1098                  FILE__, __LINE__, func()->prettyName().c_str());
1099
1100     func()->relocationInstall();
1101
1102     // the original relocation may force others; install them too
1103     for(unsigned i=0; i < force_reloc.size(); i++)
1104     {
1105         reloc_printf("%s[%d]: instPointInstance calling relocationInstall for forced func %s\n",
1106                      FILE__, __LINE__, force_reloc[i]->prettyName().c_str());
1107         force_reloc[i]->relocationInstall();
1108     }
1109 #endif
1110 #endif
1111
1112     if (!multi()) {
1113         // Alternative: keep a set of sequence #s for generated/
1114         // installed/linked. We tried to generate and failed (prolly
1115         // due to stepping on a relocated function), so fail here
1116         // but don't assert.
1117         return noMultiTramp;
1118     }
1119
1120     // We now "install", that is copy the generated code into the 
1121     // addr space. This doesn't link.
1122     
1123     if (multi()->installMultiTramp() != multiTramp::mtSuccess) {
1124         return installFailed;
1125     }
1126     return installSucceeded;
1127 }
1128
1129 instPointInstance::result_t instPointInstance::linkInst() {
1130 #if 0
1131 #if defined(cap_relocation)
1132     // This is ignored (for now), is handled in updateInstInstances...
1133     pdvector<codeRange *> overwrittenObjs;
1134     // This is harmless to call if there isn't a relocation in-flight
1135     func()->relocationLink(overwrittenObjs);
1136
1137     for(unsigned i=0; i < force_reloc.size(); i++)
1138     {
1139         force_reloc[i]->relocationLink(overwrittenObjs);
1140     }
1141 #endif
1142 #endif
1143
1144     if (!multi()) return noMultiTramp;
1145     
1146     if (multi()->linkMultiTramp() != multiTramp::mtSuccess) {
1147         return linkFailed;
1148     }
1149     return linkSucceeded;
1150 }
1151
1152 multiTramp *instPointInstance::multi() const {
1153     if (multiID_ == 0)
1154         return NULL;
1155     return multiTramp::getMulti(multiID_, proc());
1156 }
1157
1158 void instPointInstance::updateMulti(unsigned id) {
1159     if (multiID_)
1160         assert(id == multiID_);
1161     else
1162         multiID_ = id;
1163 }
1164
1165 AddressSpace *instPointInstance::proc() const {
1166     return point->proc();
1167 }
1168
1169 int_function *instPointInstance::func() const {
1170     return point->func();
1171 }
1172
1173 Address instPoint::callTarget() const {
1174     if (img_p_->callTarget() == 0) return 0;
1175
1176     // We can have an absolute addr... lovely.
1177     if (img_p_->targetIsAbsolute())
1178         return img_p_->callTarget();
1179
1180     // Return the shifted kind...
1181     return img_p_->callTarget() + func()->obj()->codeBase();
1182 }
1183
1184 bool instPoint::optimizeBaseTramps(callWhen when) 
1185 {
1186    baseTramp *tramp = getBaseTramp(when);
1187
1188    if (tramp)
1189       return tramp->doOptimizations();
1190
1191    return false;
1192 }
1193
1194 std::string instPoint::getCalleeName()
1195 {
1196    int_function *f = findCallee();
1197    if (f)
1198       return f->symTabName();
1199    return img_p_->getCalleeName();
1200 }